diff --git a/.gitignore b/.gitignore index 09f29ab487f..9c499abb026 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ tools/asmsplitter/c/* ctx.c tools/*dSYM/ graphs/ +.netcoredbg_hist # Assets *.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 64975a34b22..36c8901b097 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,21 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment ve project(Ship VERSION 8.0.6 LANGUAGES C CXX) include(CMake/soh-cvars.cmake) include(CMake/lus-cvars.cmake) -set(PROJECT_BUILD_NAME "MacReady Golf" CACHE STRING "" FORCE) + +set(NATO_PHONETIC_ALPHABET + "Alfa" "Bravo" "Charlie" "Delta" "Echo" "Foxtrot" "Golf" "Hotel" + "India" "Juliett" "Kilo" "Lima" "Mike" "November" "Oscar" "Papa" + "Quebec" "Romeo" "Sierra" "Tango" "Uniform" "Victor" "Whiskey" + "Xray" "Yankee" "Zulu" +) + +# Get the patch version number from the project version +math(EXPR PATCH_INDEX "${PROJECT_VERSION_PATCH}") + +# Use the patch number to select the correct word +list(GET NATO_PHONETIC_ALPHABET ${PATCH_INDEX} PROJECT_PATCH_WORD) + +set(PROJECT_BUILD_NAME "MacReady ${PROJECT_PATCH_WORD}" CACHE STRING "" FORCE) set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "" FORCE) execute_process( diff --git a/OTRExporter b/OTRExporter index 2cfdb396090..467f36589b0 160000 --- a/OTRExporter +++ b/OTRExporter @@ -1 +1 @@ -Subproject commit 2cfdb3960900ba059f570b2ded2fed3494a96a9b +Subproject commit 467f36589b0d6fe6c7f9d248945650a459bce768 diff --git a/README.md b/README.md index 233ef86d9e3..c8405989242 100644 --- a/README.md +++ b/README.md @@ -70,12 +70,17 @@ Congratulations, you are now sailing with the Ship of Harkinian! Have fun! | Tab | Toggle Alternate assets | | Ctrl+R | Reset | +# Project Overview +Ship of Harkinian (SOH) is built atop a custom library dubbed libultraship (LUS). Back in the N64 days, there was an SDK distributed to developers named libultra; LUS is designed to mimic the functionality of libultra on modern hardware. In addition, we are dependant on the source code provided by the OOT decompilation project. + +In order for the game to function, you will require a **legally aquired** ROM for Ocarina of Time. Click [here](https://ship.equipment/) to check the compatability of your specific rom. Any copyrighted assets are extracted from the ROM and reformated as a .otr archive file which the code uses. + ### Graphics Backends Currently, there are three rendering APIs supported: DirectX11 (Windows), OpenGL (all platforms), and Metal (MacOS). You can change which API to use in the `Settings` menu of the menubar, which requires a restart. If you're having an issue with crashing, you can change the API in the `shipofharkinian.json` file by finding the line `gfxbackend:""` and changing the value to `sdl` for OpenGL. DirectX 11 is the default on Windows. # Custom Assets -Custom assets are packed in `.otr` files. To use custom assets, place them in the `mods` folder. +Custom assets are packed in `.otr` archive files. To use custom assets, place them in the `mods` folder. If you're interested in creating and/or packing your own custom asset `.otr` files, check out the following tools: * [**retro - OTR generator**](https://github.com/HarbourMasters64/retro) @@ -93,6 +98,15 @@ If you want to playtest a continuous integration build, you can find them at the * [macOS](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-mac.zip) * [Linux](https://nightly.link/HarbourMasters/Shipwright/workflows/generate-builds/develop/soh-linux.zip) +### Further Reading +More detailed documentation can be found in the 'docs' directory, including the afformentioned [building instructions](docs/BUILDING.md). + +*[Credits](docs/CREDITS.md) +*[Custom Music](docs/CUSTOM_MUSIC.md) +*[Controler Maping](docs/GAME_CONTROLLER_DB.md) +*[Modding](docs/MODDING.md) +*[Versioning](docs/VERSIONING.md) + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL new file mode 100644 index 00000000000..6e3cbc204f2 --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_0 b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_0 new file mode 100644 index 00000000000..34ff33a7105 --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_0 @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_1 b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_1 new file mode 100644 index 00000000000..e406505e8e5 --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_1 @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_2 b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_2 new file mode 100644 index 00000000000..d937553564d --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_2 @@ -0,0 +1,7 @@ + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_3 b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_3 new file mode 100644 index 00000000000..87fb8da0153 --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_3 @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_4 b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_4 new file mode 100644 index 00000000000..6e436b142b5 --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_tri_4 @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_0 b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_0 new file mode 100644 index 00000000000..ed4b6e1c0fb --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_0 @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_1 b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_1 new file mode 100644 index 00000000000..d2728aae47a --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_1 @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_2 b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_2 new file mode 100644 index 00000000000..eb0050c03c9 --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_2 @@ -0,0 +1,6 @@ + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_3 b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_3 new file mode 100644 index 00000000000..f124650c8cb --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_3 @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_4 b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_4 new file mode 100644 index 00000000000..2bbe7895e42 --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/gGIBossSoulSkullDL_vtx_4 @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_Gem_eyes b/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_Gem_eyes new file mode 100644 index 00000000000..07364ba3a24 --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_Gem_eyes @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_black b/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_black new file mode 100644 index 00000000000..6aee093d9cf --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_black @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_eyes b/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_eyes new file mode 100644 index 00000000000..c08beb94a1d --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_eyes @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_horns b/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_horns new file mode 100644 index 00000000000..78d2a531c59 --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_horns @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_surface b/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_surface new file mode 100644 index 00000000000..e15a4dce412 --- /dev/null +++ b/soh/assets/custom/objects/object_boss_soul/mat_gGIBossSoulSkullDL_skull_surface @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_boss_soul/noise_tex b/soh/assets/custom/objects/object_boss_soul/noise_tex new file mode 100644 index 00000000000..aaf4e331f15 Binary files /dev/null and b/soh/assets/custom/objects/object_boss_soul/noise_tex differ diff --git a/soh/assets/custom/objects/object_boss_soul/noise_tex_copy b/soh/assets/custom/objects/object_boss_soul/noise_tex_copy new file mode 100644 index 00000000000..a6d6cf945e1 Binary files /dev/null and b/soh/assets/custom/objects/object_boss_soul/noise_tex_copy differ diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/eff_unknown_10_i8 b/soh/assets/custom/objects/object_gi_fishing_pole/eff_unknown_10_i8 new file mode 100644 index 00000000000..174f53cb7b6 Binary files /dev/null and b/soh/assets/custom/objects/object_gi_fishing_pole/eff_unknown_10_i8 differ diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/eff_unknown_10_i8_png b/soh/assets/custom/objects/object_gi_fishing_pole/eff_unknown_10_i8_png new file mode 100644 index 00000000000..174f53cb7b6 Binary files /dev/null and b/soh/assets/custom/objects/object_gi_fishing_pole/eff_unknown_10_i8_png differ diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL new file mode 100644 index 00000000000..49ed9b0e5a9 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_0 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_0 new file mode 100644 index 00000000000..747739cb74d --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_0 @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_1 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_1 new file mode 100644 index 00000000000..6a28afee117 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_1 @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_2 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_2 new file mode 100644 index 00000000000..0f07ec61610 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_2 @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_3 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_3 new file mode 100644 index 00000000000..b3bccf78ab2 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_3 @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_4 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_4 new file mode 100644 index 00000000000..7aa7522e8a8 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_4 @@ -0,0 +1,341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_5 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_5 new file mode 100644 index 00000000000..e815ce7edb3 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_5 @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_6 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_6 new file mode 100644 index 00000000000..1c9bb3d9e9a --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_6 @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_7 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_7 new file mode 100644 index 00000000000..fff6a9fee63 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_tri_7 @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_0 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_0 new file mode 100644 index 00000000000..810b26e0c76 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_0 @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_1 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_1 new file mode 100644 index 00000000000..69b125a3e0b --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_1 @@ -0,0 +1,209 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_2 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_2 new file mode 100644 index 00000000000..606a6ab098a --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_2 @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_3 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_3 new file mode 100644 index 00000000000..8d8b43d0f45 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_3 @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_4 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_4 new file mode 100644 index 00000000000..802a69d2621 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_4 @@ -0,0 +1,672 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_5 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_5 new file mode 100644 index 00000000000..4137d75a2d9 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_5 @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_6 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_6 new file mode 100644 index 00000000000..7ce420cfcb9 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_6 @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_7 b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_7 new file mode 100644 index 00000000000..381565a0e4f --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_7 @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_cull b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_cull new file mode 100644 index 00000000000..47672f31f15 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/gFishingPoleGiDL_vtx_cull @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_black b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_black new file mode 100644 index 00000000000..26808af42b4 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_black @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_f3dlite_material_006 b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_f3dlite_material_006 new file mode 100644 index 00000000000..3db97957e48 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_f3dlite_material_006 @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_line b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_line new file mode 100644 index 00000000000..d08aa632ae5 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_line @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_accent_001 b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_accent_001 new file mode 100644 index 00000000000..3fff6a27026 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_accent_001 @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_handle_metal b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_handle_metal new file mode 100644 index 00000000000..9633e2458f1 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_handle_metal @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_metal_001 b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_metal_001 new file mode 100644 index 00000000000..332c12c8dff --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_metal_001 @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_white b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_white new file mode 100644 index 00000000000..4b12ae0fbb0 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_reel_white @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_wood b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_wood new file mode 100644 index 00000000000..82b446f53c8 --- /dev/null +++ b/soh/assets/custom/objects/object_gi_fishing_pole/mat_gFishingPoleGiDL_wood @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL new file mode 100644 index 00000000000..0e068a1b2af --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_tri_0 b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_tri_0 new file mode 100644 index 00000000000..39f541204b7 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_tri_0 @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_tri_1 b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_tri_1 new file mode 100644 index 00000000000..8b223d8e35d --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_tri_1 @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_vtx_0 b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_vtx_0 new file mode 100644 index 00000000000..266582a03a6 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_vtx_0 @@ -0,0 +1,268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_vtx_1 b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_vtx_1 new file mode 100644 index 00000000000..dfcc8cc0de8 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_vtx_1 @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_vtx_cull b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_vtx_cull new file mode 100644 index 00000000000..38adb91be53 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_a_button/gOcarinaAButtonDL_vtx_cull @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_a_button/mat_gOcarinaAButtonDL_f3dlite_ocarina_A_button_edge b/soh/assets/custom/objects/object_ocarina_a_button/mat_gOcarinaAButtonDL_f3dlite_ocarina_A_button_edge new file mode 100644 index 00000000000..45ceb1d429e --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_a_button/mat_gOcarinaAButtonDL_f3dlite_ocarina_A_button_edge @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_a_button/mat_gOcarinaAButtonDL_f3dlite_ocarina_A_button_surface b/soh/assets/custom/objects/object_ocarina_a_button/mat_gOcarinaAButtonDL_f3dlite_ocarina_A_button_surface new file mode 100644 index 00000000000..0ed7292b818 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_a_button/mat_gOcarinaAButtonDL_f3dlite_ocarina_A_button_surface @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_a_button/noise_tex b/soh/assets/custom/objects/object_ocarina_a_button/noise_tex new file mode 100644 index 00000000000..aaf4e331f15 Binary files /dev/null and b/soh/assets/custom/objects/object_ocarina_a_button/noise_tex differ diff --git a/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL new file mode 100644 index 00000000000..0bcb321686f --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_tri_0 b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_tri_0 new file mode 100644 index 00000000000..825b236e811 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_tri_0 @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_tri_1 b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_tri_1 new file mode 100644 index 00000000000..8b7f7ff56d5 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_tri_1 @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_vtx_0 b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_vtx_0 new file mode 100644 index 00000000000..f3d8371d49a --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_vtx_0 @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_vtx_1 b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_vtx_1 new file mode 100644 index 00000000000..682f39ebb86 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_vtx_1 @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_vtx_cull b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_vtx_cull new file mode 100644 index 00000000000..38adb91be53 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL_vtx_cull @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_down_button/mat_gOcarinaCDownButtonDL_f3dlite_ocarina_C_button_edge b/soh/assets/custom/objects/object_ocarina_c_down_button/mat_gOcarinaCDownButtonDL_f3dlite_ocarina_C_button_edge new file mode 100644 index 00000000000..b741478fb44 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_down_button/mat_gOcarinaCDownButtonDL_f3dlite_ocarina_C_button_edge @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_down_button/mat_gOcarinaCDownButtonDL_f3dlite_ocarina_C_button_surface b/soh/assets/custom/objects/object_ocarina_c_down_button/mat_gOcarinaCDownButtonDL_f3dlite_ocarina_C_button_surface new file mode 100644 index 00000000000..9b7410f6fa5 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_down_button/mat_gOcarinaCDownButtonDL_f3dlite_ocarina_C_button_surface @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_down_button/noise_tex b/soh/assets/custom/objects/object_ocarina_c_down_button/noise_tex new file mode 100644 index 00000000000..aaf4e331f15 Binary files /dev/null and b/soh/assets/custom/objects/object_ocarina_c_down_button/noise_tex differ diff --git a/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL new file mode 100644 index 00000000000..be037cfe218 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_tri_0 b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_tri_0 new file mode 100644 index 00000000000..bda98fe0a61 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_tri_0 @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_tri_1 b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_tri_1 new file mode 100644 index 00000000000..937dd564d1d --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_tri_1 @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_vtx_0 b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_vtx_0 new file mode 100644 index 00000000000..e84ec90461d --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_vtx_0 @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_vtx_1 b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_vtx_1 new file mode 100644 index 00000000000..fd2bf7af91e --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_vtx_1 @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_vtx_cull b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_vtx_cull new file mode 100644 index 00000000000..38adb91be53 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL_vtx_cull @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_left_button/mat_gOcarinaCLeftButtonDL_f3dlite_ocarina_C_button_edge b/soh/assets/custom/objects/object_ocarina_c_left_button/mat_gOcarinaCLeftButtonDL_f3dlite_ocarina_C_button_edge new file mode 100644 index 00000000000..5bef8486777 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_left_button/mat_gOcarinaCLeftButtonDL_f3dlite_ocarina_C_button_edge @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_left_button/mat_gOcarinaCLeftButtonDL_f3dlite_ocarina_C_button_surface b/soh/assets/custom/objects/object_ocarina_c_left_button/mat_gOcarinaCLeftButtonDL_f3dlite_ocarina_C_button_surface new file mode 100644 index 00000000000..2d1b57f5b60 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_left_button/mat_gOcarinaCLeftButtonDL_f3dlite_ocarina_C_button_surface @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_left_button/noise_tex b/soh/assets/custom/objects/object_ocarina_c_left_button/noise_tex new file mode 100644 index 00000000000..aaf4e331f15 Binary files /dev/null and b/soh/assets/custom/objects/object_ocarina_c_left_button/noise_tex differ diff --git a/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL new file mode 100644 index 00000000000..9d41daa33df --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_tri_0 b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_tri_0 new file mode 100644 index 00000000000..f008c7abcbe --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_tri_0 @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_tri_1 b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_tri_1 new file mode 100644 index 00000000000..1767f6fe300 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_tri_1 @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_vtx_0 b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_vtx_0 new file mode 100644 index 00000000000..f3039179f8d --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_vtx_0 @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_vtx_1 b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_vtx_1 new file mode 100644 index 00000000000..1c79e5a8671 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_vtx_1 @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_vtx_cull b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_vtx_cull new file mode 100644 index 00000000000..38adb91be53 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL_vtx_cull @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_right_button/mat_gOcarinaCRightButtonDL_f3dlite_ocarina_C_button_edge b/soh/assets/custom/objects/object_ocarina_c_right_button/mat_gOcarinaCRightButtonDL_f3dlite_ocarina_C_button_edge new file mode 100644 index 00000000000..1cb97f9e37a --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_right_button/mat_gOcarinaCRightButtonDL_f3dlite_ocarina_C_button_edge @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_right_button/mat_gOcarinaCRightButtonDL_f3dlite_ocarina_C_button_surface b/soh/assets/custom/objects/object_ocarina_c_right_button/mat_gOcarinaCRightButtonDL_f3dlite_ocarina_C_button_surface new file mode 100644 index 00000000000..70fc9e85da6 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_right_button/mat_gOcarinaCRightButtonDL_f3dlite_ocarina_C_button_surface @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_right_button/noise_tex b/soh/assets/custom/objects/object_ocarina_c_right_button/noise_tex new file mode 100644 index 00000000000..aaf4e331f15 Binary files /dev/null and b/soh/assets/custom/objects/object_ocarina_c_right_button/noise_tex differ diff --git a/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL new file mode 100644 index 00000000000..36b1ff7a2f6 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_tri_0 b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_tri_0 new file mode 100644 index 00000000000..f46f7c5655e --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_tri_0 @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_tri_1 b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_tri_1 new file mode 100644 index 00000000000..80954ffe27a --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_tri_1 @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_vtx_0 b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_vtx_0 new file mode 100644 index 00000000000..a35cf324ab5 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_vtx_0 @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_vtx_1 b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_vtx_1 new file mode 100644 index 00000000000..09a4018d34b --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_vtx_1 @@ -0,0 +1,251 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_vtx_cull b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_vtx_cull new file mode 100644 index 00000000000..38adb91be53 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL_vtx_cull @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_up_button/mat_gOcarinaCUpButtonDL_f3dlite_ocarina_C_button_edge b/soh/assets/custom/objects/object_ocarina_c_up_button/mat_gOcarinaCUpButtonDL_f3dlite_ocarina_C_button_edge new file mode 100644 index 00000000000..301ec9fc437 --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_up_button/mat_gOcarinaCUpButtonDL_f3dlite_ocarina_C_button_edge @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_up_button/mat_gOcarinaCUpButtonDL_f3dlite_ocarina_C_button_surface b/soh/assets/custom/objects/object_ocarina_c_up_button/mat_gOcarinaCUpButtonDL_f3dlite_ocarina_C_button_surface new file mode 100644 index 00000000000..a9a701d154b --- /dev/null +++ b/soh/assets/custom/objects/object_ocarina_c_up_button/mat_gOcarinaCUpButtonDL_f3dlite_ocarina_C_button_surface @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/object_ocarina_c_up_button/noise_tex b/soh/assets/custom/objects/object_ocarina_c_up_button/noise_tex new file mode 100644 index 00000000000..aaf4e331f15 Binary files /dev/null and b/soh/assets/custom/objects/object_ocarina_c_up_button/noise_tex differ diff --git a/soh/assets/custom/textures/parameter_static/gBossSoul.rgba32.png b/soh/assets/custom/textures/parameter_static/gBossSoul.rgba32.png new file mode 100755 index 00000000000..9fe2ac4042e Binary files /dev/null and b/soh/assets/custom/textures/parameter_static/gBossSoul.rgba32.png differ diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h index 181ebd43400..3f9039e35f0 100644 --- a/soh/assets/soh_assets.h +++ b/soh/assets/soh_assets.h @@ -44,6 +44,21 @@ static const ALIGN_ASSET(2) char gTitleRandomizerSubtitleTex[] = dgTitleRandomiz #define dgTitleBossRushSubtitleTex "__OTR__objects/object_mag/gTitleBossRushSubtitleTex" static const ALIGN_ASSET(2) char gTitleBossRushSubtitleTex[] = dgTitleBossRushSubtitleTex; +#define dgOcarinaAButtonDL "__OTR__objects/object_ocarina_a_button/gOcarinaAButtonDL" +static const ALIGN_ASSET(2) char gOcarinaAButtonDL[] = dgOcarinaAButtonDL; + +#define dgOcarinaCLeftButtonDL "__OTR__objects/object_ocarina_c_left_button/gOcarinaCLeftButtonDL" +static const ALIGN_ASSET(2) char gOcarinaCLeftButtonDL[] = dgOcarinaCLeftButtonDL; + +#define dgOcarinaCRightButtonDL "__OTR__objects/object_ocarina_c_right_button/gOcarinaCRightButtonDL" +static const ALIGN_ASSET(2) char gOcarinaCRightButtonDL[] = dgOcarinaCRightButtonDL; + +#define dgOcarinaCUpButtonDL "__OTR__objects/object_ocarina_c_up_button/gOcarinaCUpButtonDL" +static const ALIGN_ASSET(2) char gOcarinaCUpButtonDL[] = dgOcarinaCUpButtonDL; + +#define dgOcarinaCDownButtonDL "__OTR__objects/object_ocarina_c_down_button/gOcarinaCDownButtonDL" +static const ALIGN_ASSET(2) char gOcarinaCDownButtonDL[] = dgOcarinaCDownButtonDL; + #define dgTriforcePiece0DL "__OTR__objects/object_triforce_piece_0/gTriforcePiece0DL" static const ALIGN_ASSET(2) char gTriforcePiece0DL[] = dgTriforcePiece0DL; @@ -56,6 +71,12 @@ static const ALIGN_ASSET(2) char gTriforcePiece2DL[] = dgTriforcePiece2DL; #define dgTriforcePieceCompletedDL "__OTR__objects/object_triforce_completed/gTriforcePieceCompletedDL" static const ALIGN_ASSET(2) char gTriforcePieceCompletedDL[] = dgTriforcePieceCompletedDL; +#define dgBossSoulSkullDL "__OTR__objects/object_boss_soul/gGIBossSoulSkullDL" +static const ALIGN_ASSET(2) char gBossSoulSkullDL[] = dgBossSoulSkullDL; + +#define dgFishingPoleGiDL "__OTR__objects/object_gi_fishing_pole/gFishingPoleGiDL" +static const ALIGN_ASSET(2) char gFishingPoleGiDL[] = dgFishingPoleGiDL; + #define dgMysteryItemDL "__OTR__objects/object_mystery_item/gMysteryItemDL" static const ALIGN_ASSET(2) char gMysteryItemDL[] = dgMysteryItemDL; @@ -76,6 +97,9 @@ static const ALIGN_ASSET(2) char gArrowDownTex[] = dgArrowDown; #define dgTriforcePiece "__OTR__textures/parameter_static/gTriforcePiece" static const ALIGN_ASSET(2) char gTriforcePieceTex[] = dgTriforcePiece; +#define dgBossSoul "__OTR__textures/parameter_static/gBossSoul" +static const ALIGN_ASSET(2) char gBossSoulTex[] = dgBossSoul; + #define dgFileSelMQButtonTex "__OTR__textures/title_static/gFileSelMQButtonTex" static const ALIGN_ASSET(2) char gFileSelMQButtonTex[] = dgFileSelMQButtonTex; diff --git a/soh/assets/xml/GC_MQ_D/code/sys_matrix.xml b/soh/assets/xml/GC_MQ_D/code/sys_matrix.xml index b39033d5976..28a2adc4c6b 100644 --- a/soh/assets/xml/GC_MQ_D/code/sys_matrix.xml +++ b/soh/assets/xml/GC_MQ_D/code/sys_matrix.xml @@ -1,5 +1,5 @@ - - + + diff --git a/soh/assets/xml/GC_MQ_PAL_F/code/sys_matrix.xml b/soh/assets/xml/GC_MQ_PAL_F/code/sys_matrix.xml index a3fed368bef..52e78bcb118 100644 --- a/soh/assets/xml/GC_MQ_PAL_F/code/sys_matrix.xml +++ b/soh/assets/xml/GC_MQ_PAL_F/code/sys_matrix.xml @@ -1,5 +1,5 @@ - - + + diff --git a/soh/assets/xml/GC_NMQ_D/code/sys_matrix.xml b/soh/assets/xml/GC_NMQ_D/code/sys_matrix.xml index ed2a859c655..3811322d38b 100644 --- a/soh/assets/xml/GC_NMQ_D/code/sys_matrix.xml +++ b/soh/assets/xml/GC_NMQ_D/code/sys_matrix.xml @@ -1,5 +1,5 @@ - - + + diff --git a/soh/assets/xml/GC_NMQ_PAL_F/code/sys_matrix.xml b/soh/assets/xml/GC_NMQ_PAL_F/code/sys_matrix.xml index d2143f4e488..486cb244d8e 100644 --- a/soh/assets/xml/GC_NMQ_PAL_F/code/sys_matrix.xml +++ b/soh/assets/xml/GC_NMQ_PAL_F/code/sys_matrix.xml @@ -1,5 +1,5 @@ - - + + diff --git a/soh/assets/xml/N64_PAL_10/code/sys_matrix.xml b/soh/assets/xml/N64_PAL_10/code/sys_matrix.xml index 706c249d454..7877d0bdf6b 100644 --- a/soh/assets/xml/N64_PAL_10/code/sys_matrix.xml +++ b/soh/assets/xml/N64_PAL_10/code/sys_matrix.xml @@ -1,5 +1,5 @@ - - + + diff --git a/soh/assets/xml/N64_PAL_11/code/sys_matrix.xml b/soh/assets/xml/N64_PAL_11/code/sys_matrix.xml index 97b57a57c76..cee1835e9be 100644 --- a/soh/assets/xml/N64_PAL_11/code/sys_matrix.xml +++ b/soh/assets/xml/N64_PAL_11/code/sys_matrix.xml @@ -1,5 +1,5 @@ - - + + diff --git a/soh/include/functions.h b/soh/include/functions.h index 77d57899754..82b03e6375d 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -181,6 +181,8 @@ void __osSetWatchLo(u32); EnItem00* Item_DropCollectible(PlayState* play, Vec3f* spawnPos, s16 params); EnItem00* Item_DropCollectible2(PlayState* play, Vec3f* spawnPos, s16 params); void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry giEntry); +void EnItem00_SetupAction(EnItem00* this, EnItem00ActionFunc actionFunc); +void func_8001E5C8(EnItem00* this, PlayState* play); void Item_DropCollectibleRandom(PlayState* play, Actor* fromActor, Vec3f* spawnPos, s16 params); void EffectBlure_ChangeType(EffectBlure* this, int type); void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2); @@ -413,6 +415,7 @@ f32 Actor_WorldDistXZToPoint(Actor* actor, Vec3f* refPoint); void func_8002DBD0(Actor* actor, Vec3f* result, Vec3f* arg2); f32 Actor_HeightDiff(Actor* actorA, Actor* actorB); f32 Player_GetHeight(Player* player); +s32 Player_ActionChange_2(Player* player, PlayState* play); f32 func_8002DCE4(Player* player); s32 func_8002DD6C(Player* player); s32 func_8002DD78(Player* player); @@ -424,7 +427,7 @@ void Actor_MountHorse(PlayState* play, Player* player, Actor* horse); s32 func_8002DEEC(Player* player); void func_8002DF18(PlayState* play, Player* player); s32 func_8002DF38(PlayState* play, Actor* actor, u8 csMode); -s32 func_8002DF54(PlayState* play, Actor* actor, u8 arg2); +s32 Player_SetCsActionWithHaltedActors(PlayState* play, Actor* actor, u8 arg2); void func_8002DF90(DynaPolyActor* dynaActor); void func_8002DFA4(DynaPolyActor* dynaActor, f32 arg1, s16 arg2); s32 Player_IsFacingActor(Actor* actor, s16 angle, PlayState* play); @@ -452,11 +455,11 @@ u32 Actor_TextboxIsClosing(Actor* actor, PlayState* play); s8 func_8002F368(PlayState* play); void Actor_GetScreenPos(PlayState* play, Actor* actor, s16* x, s16* y); u32 Actor_HasParent(Actor* actor, PlayState* play); -// TODO: Rename the follwing 3 functions using whatever scheme we use when we rename func_8002F434 and func_8002F554. +// TODO: Rename the follwing 3 functions using whatever scheme we use when we rename Actor_OfferGetItem and func_8002F554. s32 GiveItemEntryWithoutActor(PlayState* play, GetItemEntry getItemEntry); s32 GiveItemEntryFromActor(Actor* actor, PlayState* play, GetItemEntry getItemEntry, f32 xzRange, f32 yRange); -void GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemEntry getItemEntry); -s32 func_8002F434(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange); +s32 GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemEntry getItemEntry); +s32 Actor_OfferGetItem(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange); void func_8002F554(Actor* actor, PlayState* play, s32 getItemId); void func_8002F580(Actor* actor, PlayState* play); u32 Actor_HasNoParent(Actor* actor, PlayState* play); @@ -570,8 +573,6 @@ void Flags_UnsetRandomizerInf(RandomizerInf flag); u16 func_80037C30(PlayState* play, s16 arg1); s32 func_80037D98(PlayState* play, Actor* actor, s16 arg2, s32* arg3); s32 func_80038290(PlayState* play, Actor* actor, Vec3s* arg2, Vec3s* arg3, Vec3f arg4); -GetItemEntry GetChestGameRandoGetItem(s8 room, s16 ogDrawId, PlayState* play); -s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, PlayState* play); // ? func_80038600(?); u16 DynaSSNodeList_GetNextNodeIdx(DynaSSNodeList*); @@ -1104,6 +1105,7 @@ s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input); u8 PlayerGrounded(Player* player); void Player_SetBootData(PlayState* play, Player* player); s32 Player_InBlockingCsMode(PlayState* play, Player* player); +s32 Player_TryCsAction(PlayState* play, Actor* actor, s32 csAction); s32 Player_InCsMode(PlayState* play); s32 func_8008E9C4(Player* player); s32 Player_IsChildWithHylianShield(Player* player); diff --git a/soh/include/macros.h b/soh/include/macros.h index 93f7e17c61b..6288efe59f2 100644 --- a/soh/include/macros.h +++ b/soh/include/macros.h @@ -184,7 +184,6 @@ extern GraphicsContext* __gfxCtx; #define POLY_XLU_DISP __gfxCtx->polyXlu.p // #region SOH [General] // Upstream TODO: Document reasoning for these only existing in SoH -#define WORLD_OVERLAY_DISP __gfxCtx->worldOverlay.p #define POLY_KAL_DISP __gfxCtx->polyKal.p // #endregion #define OVERLAY_DISP __gfxCtx->overlay.p diff --git a/soh/include/variables.h b/soh/include/variables.h index 692d1b2f82e..5c97b26b8a8 100644 --- a/soh/include/variables.h +++ b/soh/include/variables.h @@ -97,6 +97,7 @@ extern "C" extern u16 gEquipMasks[4]; extern u16 gEquipNegMasks[4]; extern u32 gUpgradeMasks[8]; + extern u32 gUpgradeNegMasks[8]; extern u8 gEquipShifts[4]; extern u8 gUpgradeShifts[8]; extern u16 gUpgradeCapacities[8][4]; diff --git a/soh/include/z64.h b/soh/include/z64.h index 97f68341d67..6d79cbc0401 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -92,7 +92,6 @@ typedef struct { /* 0x00000 */ u16 headMagic; // GFXPOOL_HEAD_MAGIC /* 0x00008 */ Gfx polyOpaBuffer[0x2FC0]; /* 0x0BF08 */ Gfx polyXluBuffer[0x1000]; - /* 0xXXXXX */ Gfx worldOverlayBuffer[0x1000]; /* 0x0BF08 */ Gfx polyKalBuffer[0x1000]; /* 0x0FF08 */ Gfx overlayBuffer[0x800]; /* 0x11F08 */ Gfx workBuffer[0x100]; @@ -140,7 +139,6 @@ typedef struct OSScTask { typedef struct GraphicsContext { /* 0x0000 */ Gfx* polyOpaBuffer; // Pointer to "Zelda 0" /* 0x0004 */ Gfx* polyXluBuffer; // Pointer to "Zelda 1" - /* 0xXXX */ Gfx* worldOverlayBuffer; // Pointer to "Paris" /* 0xXXX */ Gfx* polyKalBuffer; // Pointer to "Rome" /* 0x0008 */ char unk_008[0x08]; // Unused, could this be pointers to "Zelda 2" / "Zelda 3" /* 0x0010 */ Gfx* overlayBuffer; // Pointer to "Zelda 4" @@ -160,7 +158,6 @@ typedef struct GraphicsContext { /* 0x02A8 */ TwoHeadGfxArena overlay; // "Zelda 4" /* 0x02B8 */ TwoHeadGfxArena polyOpa; // "Zelda 0" /* 0x02C8 */ TwoHeadGfxArena polyXlu; // "Zelda 1" - /* 0x0XXX */ TwoHeadGfxArena worldOverlay; // When in Paris... /* 0x0XXX */ TwoHeadGfxArena polyKal; // When in Rome... /* 0x02D8 */ u32 gfxPoolIdx; /* 0x02DC */ u16* curFrameBuffer; @@ -920,7 +917,10 @@ typedef struct { /* 0x0266 */ u8 worldMapPoints[20]; // 0 = hidden; 1 = displayed; 2 = highlighted /* 0x027A */ u8 tradeQuestLocation; /* 0x027C */ SkelAnime playerSkelAnime; -} PauseContext; // size = 0x2C0 + // #region SOH [Randomizer] + /* 0x02C0 */ u8 randoQuestMode; // 0 = Off (normal quest menu); 1 = On (Misc Collectibles menu) + // #endregion +} PauseContext; // size = 0x2C1 typedef enum { /* 00 */ GAMEOVER_INACTIVE, diff --git a/soh/include/z64actor.h b/soh/include/z64actor.h index 82c8611d101..156f1d6797d 100644 --- a/soh/include/z64actor.h +++ b/soh/include/z64actor.h @@ -7,6 +7,8 @@ #include "z64collision_check.h" #include "z64bgcheck.h" #include "soh/Enhancements/item-tables/ItemTableTypes.h" +#include "z64actor_enum.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" #define ACTOR_NUMBER_MAX 2000 #define INVISIBLE_ACTOR_MAX 20 @@ -264,7 +266,12 @@ typedef enum { /* 0x17 */ ITEM00_TUNIC_ZORA, /* 0x18 */ ITEM00_TUNIC_GORON, /* 0x19 */ ITEM00_BOMBS_SPECIAL, - /* 0x20 */ ITEM00_BOMBCHU, + /* 0x1A */ ITEM00_BOMBCHU, + /* 0x1B */ ITEM00_SOH_DUMMY, + /* 0x1C */ ITEM00_SOH_GIVE_ITEM_ENTRY, + /* 0x1D */ ITEM00_SOH_GIVE_ITEM_ENTRY_GI, + /* 0x1E */ ITEM00_MAX, + /* 0xFF */ ITEM00_NONE = 0xFF } Item00Type; struct EnItem00; @@ -282,8 +289,13 @@ typedef struct EnItem00 { /* 0x15A */ s16 unk_15A; /* 0x15C */ f32 scale; /* 0x160 */ ColliderCylinder collider; - s16 ogParams; + // #region SOH [Randomizer] GetItemEntry randoGiEntry; + RandomizerCheck randoCheck; + RandomizerInf randoInf; + /* */ s16 ogParams; + /* */ GetItemEntry itemEntry; + // #endregion } EnItem00; // size = 0x1AC // Only A_OBJ_SIGNPOST_OBLONG and A_OBJ_SIGNPOST_ARROW are used in room files. @@ -337,22 +349,6 @@ typedef enum { } ActorCategory; //#define DEFINE_ACTOR(_0, enum, _2) enum, -#define DEFINE_ACTOR_INTERNAL(_0, enum, _2) enum, -#define DEFINE_ACTOR_UNSET(enum) enum, -#define DEFINE_ACTOR(_0, enum, _2) DEFINE_ACTOR_INTERNAL(_0, enum, _2) - -#ifdef __cplusplus -enum ActorID : int { -#else -enum ActorID { -#endif - #include "tables/actor_table.h" - /* 0x0192 */ ACTOR_ID_MAX // originally "ACTOR_DLF_MAX" -}; - -#undef DEFINE_ACTOR -#undef DEFINE_ACTOR_INTERNAL -#undef DEFINE_ACTOR_UNSET typedef enum { DOORLOCK_NORMAL, diff --git a/soh/include/z64actor_enum.h b/soh/include/z64actor_enum.h new file mode 100644 index 00000000000..1b0a6b986d3 --- /dev/null +++ b/soh/include/z64actor_enum.h @@ -0,0 +1,19 @@ +#pragma once + +#ifndef Z64ACTOR_ENUM_H +#define Z64ACTOR_ENUM_H + +#define DEFINE_ACTOR_INTERNAL(_0, enum, _2) enum, +#define DEFINE_ACTOR_UNSET(enum) enum, +#define DEFINE_ACTOR(_0, enum, _2) DEFINE_ACTOR_INTERNAL(_0, enum, _2) + +enum ActorID { +#include "tables/actor_table.h" + /* 0x0192 */ ACTOR_ID_MAX // originally "ACTOR_DLF_MAX" +}; + +#undef DEFINE_ACTOR +#undef DEFINE_ACTOR_INTERNAL +#undef DEFINE_ACTOR_UNSET + +#endif \ No newline at end of file diff --git a/soh/include/z64item.h b/soh/include/z64item.h index 1fc919a45f6..214d8271187 100644 --- a/soh/include/z64item.h +++ b/soh/include/z64item.h @@ -311,6 +311,21 @@ typedef enum { /* 0xFF */ ITEM_NONE = 0xFF } ItemID; +typedef enum { + EQUIP_FLAG_SWORD_KOKIRI = 1 << 0, + EQUIP_FLAG_SWORD_MASTER = 1 << 1, + EQUIP_FLAG_SWORD_BGS = 1 << 2, + EQUIP_FLAG_SHIELD_DEKU = 1 << 4, + EQUIP_FLAG_SHIELD_HYLIAN = 1 << 5, + EQUIP_FLAG_SHIELD_MIRROR = 1 << 6, + EQUIP_FLAG_TUNIC_KOKIRI = 1 << 8, + EQUIP_FLAG_TUNIC_GORON = 1 << 9, + EQUIP_FLAG_TUNIC_ZORA = 1 << 10, + EQUIP_FLAG_BOOTS_KOKIRI = 1 << 12, + EQUIP_FLAG_BOOTS_IRON = 1 << 13, + EQUIP_FLAG_BOOTS_HOVER = 1 << 14, +} EquipmentFlag; + #define ITEM_TRADE_CHILD ITEM_WEIRD_EGG #define ITEM_TRADE_ADULT ITEM_POCKET_EGG @@ -372,7 +387,7 @@ typedef enum { /* 0x35 */ GI_GAUNTLETS_SILVER, /* 0x36 */ GI_GAUNTLETS_GOLD, /* 0x37 */ GI_SCALE_SILVER, - /* 0x38 */ GI_SCALE_GOLD, + /* 0x38 */ GI_SCALE_GOLDEN, /* 0x39 */ GI_STONE_OF_AGONY, /* 0x3A */ GI_GERUDO_CARD, /* 0x3B */ GI_OCARINA_FAIRY, // uses Ocarina of Time message ID @@ -574,6 +589,7 @@ typedef enum { /* 0x7A */ GID_SONG_TIME, /* 0x7B */ GID_SONG_STORM, /* 0x7C */ GID_TRIFORCE_PIECE, + /* */ GID_FISHING_POLE, /* 0x7C */ GID_MAXIMUM } GetItemDrawID; diff --git a/soh/include/z64save.h b/soh/include/z64save.h index c7bee045fc1..0233819cef3 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; @@ -147,11 +148,6 @@ typedef struct { /* 0x24 */ s32 tempCollectFlags; } FaroresWindData; // size = 0x28 -typedef struct { - RandomizerCheck check; - RandomizerGetData get; -} ItemLocationRando; - typedef struct { RandomizerCheck check; RandomizerCheck hintedCheck; @@ -161,11 +157,6 @@ typedef struct { char hintText[200]; } HintLocationRando; -typedef struct { - RandomizerSettingKey key; - u8 value; -} RandoSetting; - typedef struct { /* 0x0000 */ s32 entranceIndex; // start of `save` substruct, originally called "memory" /* 0x0004 */ s32 linkAge; // 0: Adult; 1: Child (see enum `LinkAge`) @@ -285,42 +276,15 @@ typedef struct { /* */ u16 pendingSaleMod; /* */ uint8_t questId; /* */ uint32_t isBossRushPaused; - /* */ uint8_t bossRushOptions[BOSSRUSH_OPTIONS_AMOUNT]; + /* */ uint8_t bossRushOptions[BR_OPTIONS_MAX]; /* */ u8 pendingIceTrapCount; /* */ SohStats sohStats; /* */ FaroresWindData backupFW; - /* */ RandomizerCheckTrackerData checkTrackerData[RC_MAX]; + /* */ u8 maskMemory; // #endregion // #region SOH [Randomizer] // Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer - /* */ RandoSetting randoSettings[300]; - /* */ ItemLocationRando itemLocations[RC_MAX]; - /* */ HintLocationRando hintLocations[50]; - /* */ EntranceOverride entranceOverrides[ENTRANCE_OVERRIDES_MAX_COUNT]; - /* */ char childAltarText[250]; - /* */ char adultAltarText[750]; - /* */ RandomizerCheck rewardCheck[9]; - /* */ char ganonHintText[300]; - /* */ char gregHintText[250]; - /* */ char ganonText[250]; - /* */ char dampeText[150]; - /* */ char sheikText[200]; - /* */ char sariaText[150]; - /* */ char warpMinuetText[100]; - /* */ char warpBoleroText[100]; - /* */ char warpSerenadeText[100]; - /* */ char warpRequiemText[100]; - /* */ char warpNocturneText[100]; - /* */ char warpPreludeText[100]; - /* */ RandomizerCheck masterSwordHintCheck; - /* */ RandomizerCheck lightArrowHintCheck; - /* */ RandomizerCheck sariaCheck; - /* */ RandomizerCheck gregCheck; - /* */ RandomizerCheck dampeCheck; - /* */ char inputSeed[1024]; - /* */ u32 finalSeed; - /* */ u8 seedIcons[5]; - /* */ u16 randomizerInf[10]; + /* */ u16 randomizerInf[17]; /* */ u8 mqDungeonCount; /* */ u16 adultTradeItems; /* */ u8 triforcePiecesCollected; @@ -363,6 +327,18 @@ typedef enum { /* 0x06 */ HS_DAMPE_RACE } HighScores; +// the score value for the fishing minigame also stores many flags. +#define HS_FISH_LENGTH_CHILD 0x7F // mask for record length of catch as child. +#define HS_FISH_LENGTH_ADULT 0x7F000000 // mask for record length of catch as adult. +#define HS_FISH_PLAYED_CHILD 0x100 // set when first talking to owner as child +#define HS_FISH_PLAYED_ADULT 0x200 // set when first talking to owner as adult +#define HS_FISH_PRIZE_CHILD 0x400 // won the Piece of Heart +#define HS_FISH_PRIZE_ADULT 0x800 // won the Golden Scale +#define HS_FISH_STOLE_HAT 0x1000 // Pond owner is visibly bald as Adult Link. +#define HS_FISH_CHEAT_CHILD 0x80 // used Sinking Lure as child to catch record fish +#define HS_FISH_CHEAT_ADULT 0x80000000 // used Sinking Lure as adult to catch record fish +#define HS_FISH_PLAYED 0x10000 // incremented for every play. controls weather. + typedef enum { /* 0 */ SUNSSONG_INACTIVE, /* 1 */ SUNSSONG_START, // the suns ocarina effect signals that the song has finished playing diff --git a/soh/include/z64scene.h b/soh/include/z64scene.h index 1c2267a05b5..697c9750348 100644 --- a/soh/include/z64scene.h +++ b/soh/include/z64scene.h @@ -2,6 +2,8 @@ #define Z64SCENE_H #include "command_macros_base.h" +#include "libultraship/libultra.h" +#include "z64math.h" typedef struct { /* 0x00 */ uintptr_t vromStart; diff --git a/soh/include/z64scene_enum.h b/soh/include/z64scene_enum.h new file mode 100644 index 00000000000..068d1c42f9a --- /dev/null +++ b/soh/include/z64scene_enum.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef Z64SCENE_ENUM_H +#define Z64SCENE_ENUM_H +#define DEFINE_SCENE(_0, _1, enum, _3, _4, _5) enum, + +#ifdef __cplusplus +enum SceneID : int { +#else +enum SceneID { +#endif +#include "tables/scene_table.h" + /* 0x6E */ SCENE_ID_MAX +}; + +#undef DEFINE_SCENE +#endif \ No newline at end of file diff --git a/soh/soh/Enhancements/TimeSavers/FasterHeavyBlockLift.cpp b/soh/soh/Enhancements/TimeSavers/FasterHeavyBlockLift.cpp new file mode 100644 index 00000000000..73909cbdad8 --- /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 = va_arg(args, Actor*); + + 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 = va_arg(args, LinkAnimationHeader*); + + // 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 = va_arg(args, Actor*); + + heldActor->shape.rot.x -= 3510; + } + }); +} diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp new file mode 100644 index 00000000000..aca290f7992 --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp @@ -0,0 +1,48 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" + +extern "C" { +#include "z64save.h" +#include "functions.h" +#include "soh/Enhancements/randomizer/randomizer_entrance.h" +extern PlayState* gPlayState; +extern SaveContext gSaveContext; +} + +void SkipIntro_Register() { + REGISTER_VB_SHOULD(VB_PLAY_TRANSITION_CS, { + // If we're playing rando and if starting age is adult and/or overworld spawns are shuffled we need to skip + // the cutscene regardless of the enhancement being on. + bool adultStart = gSaveContext.linkAge == LINK_AGE_ADULT; + bool shuffleOverworldSpawns = + OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_OVERWORLD_SPAWNS).Is(true); + if ((CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), IS_RANDO) || + (IS_RANDO && (adultStart || shuffleOverworldSpawns))) && + gSaveContext.cutsceneIndex == 0xFFF1) { + // Calculate spawn location. Start with vanilla, Link's house. + int32_t spawnEntrance = ENTR_LINKS_HOUSE_0; + // If we're not in rando, we can skip all of the below. + if (IS_RANDO) { + // If starting age is shuffled, use vanilla adult spawn/prelude warp. + if (adultStart) { + spawnEntrance = ENTR_TEMPLE_OF_TIME_7; + } + // If we're shuffling overworld spawns we'll need to get the Entrance Override + if (shuffleOverworldSpawns) { + // If we're shuffling overworld spawns the adult spawn is ENTR_HYRULE_FIELD_10 instead of + // ENTR_TEMPLE_OF_TIME_7, so that spawn and Prelude don't share an entrance. + if (adultStart) { + spawnEntrance = ENTR_HYRULE_FIELD_10; + } + spawnEntrance = Entrance_PeekNextIndexOverride(spawnEntrance); + } + } + // Skip the intro cutscene for whatever the spawnEntrance is calculated to be. + if (gSaveContext.entranceIndex == spawnEntrance) { + gSaveContext.cutsceneIndex = 0; + *should = false; + } + } + }); +} diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp new file mode 100644 index 00000000000..74898284343 --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp @@ -0,0 +1,148 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" + +extern "C" { + #include "macros.h" + #include "src/overlays/actors/ovl_En_Ko/z_en_ko.h" + #include "z64save.h" + #include "functions.h" + #include "variables.h" +} + +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex() + +/** + * This will override the transitions into the blue warp cutscenes, set any appropriate flags, and + * set the entrance index to where you would normally end up after the blue warp cutscene. This + * should also account for the difference between your first and following visits to the blue warp. + */ +void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_list originalArgs) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + uint8_t isBlueWarpCutscene = 0; + // Deku Tree Blue warp + if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) { + gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_11; + 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; + isBlueWarpCutscene = 1; + // Jabu Jabu's Blue warp + } else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_0 && gSaveContext.cutsceneIndex == 0xFFF0) { + gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_0; + 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 + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_DEKU_TREE_SPROUT); + + if (IS_RANDO) { + gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_3; + } else { + gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12; + } + + 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; + 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 + gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4800; + Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); + + gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_9; + 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; + 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; + isBlueWarpCutscene = 1; + } + + if (isBlueWarpCutscene) { + if (gSaveContext.entranceIndex != ENTR_LAKE_HYLIA_9) { + // Normally set in the blue warp cutscene + gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000; + } + + *should = false; + gSaveContext.cutsceneIndex = 0; + } + + // This is outside the above condition because we want to handle both first and following visits to the blue warp + if (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(); + } + } +} + +/** + * While we could rely on the Item_Give that's normally called, it's not very clear to the player that they + * received the item when skipping the blue warp cutscene, so we'll prevent that and queue it up to be given + * to the player instead. + */ +void SkipBlueWarp_ShouldGiveItem(GIVanillaBehavior _, bool* should, va_list originalArgs) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + *should = false; + } +} + +// Todo: Move item queueing here + +/** + * This ensures the Kokiri blocking the forest exit checks if you are eligible to leave the forest + * every frame, instead of only at init. The reason we need to do this is when we skip the blue warp cutscene + * you end up getting the Kokiri Emerald after the actor has init'd, so the actor doesn't know you have it + */ +void EnKo_MoveWhenReady(EnKo* enKo, PlayState* play) { + func_80A995CC(enKo, play); + + if ((enKo->actor.params & 0xFF) == ENKO_TYPE_CHILD_3) { + if (GameInteractor_Should(VB_OPEN_KOKIRI_FOREST, CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD))) { + enKo->collider.dim.height -= 200; + Path_CopyLastPoint(enKo->path, &enKo->actor.world.pos); + enKo->actionFunc = func_80A99384; + } + } +} + +void SkipBlueWarp_OnActorUpdate(void* actorPtr) { + EnKo* enKo = static_cast(actorPtr); + + if ( + (enKo->actor.params & 0xFF) == ENKO_TYPE_CHILD_3 && + enKo->actionFunc == func_80A995CC && + CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) + ) { + enKo->actionFunc = EnKo_MoveWhenReady; + } +} + +/** + * This will ensure that the Deku Tree Sprout considers the Forest Temple finished when you skip the blue warp cutscene. + * Typically this checks for if you have the medallion, and when skipping the cutscene at this point you don't have it yet. + */ +void SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished(GIVanillaBehavior _, bool* should, va_list originalArgs) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_11 && gSaveContext.cutsceneIndex == 0xFFF1) { + *should = Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); + } + } +} + +void SkipBlueWarp_Register() { + GameInteractor::Instance->RegisterGameHookForID(ACTOR_EN_KO, SkipBlueWarp_OnActorUpdate); + GameInteractor::Instance->RegisterGameHookForID(VB_PLAY_TRANSITION_CS, SkipBlueWarp_ShouldPlayTransitionCS); + GameInteractor::Instance->RegisterGameHookForID(VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished); + GameInteractor::Instance->RegisterGameHookForID(VB_GIVE_ITEM_FROM_BLUE_WARP, SkipBlueWarp_ShouldGiveItem); +} diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipDekuTreeIntro.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipDekuTreeIntro.cpp new file mode 100644 index 00000000000..7000aa39199 --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipDekuTreeIntro.cpp @@ -0,0 +1,22 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" + +extern "C" { + #include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" +} + +/** + * This will skip the Deku Tree intro, and simply open the mouth as you approach it. +*/ +void SkipDekuTreeIntro_Register() { + REGISTER_VB_SHOULD(VB_PLAY_DEKU_TREE_INTRO_CS, { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + BgTreemouth* treeMouth = va_arg(args, BgTreemouth*); + Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH); + Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + BgTreemouth_SetupAction(treeMouth, func_808BC6F8); + *should = false; + } + }); +} diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp new file mode 100644 index 00000000000..7fa7b99f6b4 --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp @@ -0,0 +1,39 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" + +extern "C" { + #include "z64save.h" + #include "functions.h" + extern PlayState* gPlayState; + extern SaveContext gSaveContext; +} + +void SkipLostWoodsBridge_Register() { + /** + * This skips the cutscene where you speak to Saria on the bridge in Lost Woods, where she gives you the Fairy Ocarina. + */ + REGISTER_VB_SHOULD(VB_PLAY_TRANSITION_CS, { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); + if (GameInteractor_Should(VB_GIVE_ITEM_FAIRY_OCARINA, true)) { + Item_Give(gPlayState, ITEM_OCARINA_FAIRY); + } + *should = false; + } + } + }); + + /** + * While we could rely on the Item_Give that's normally called (and that we have above), it's not very clear to the player + * that they received the item when skipping the cutscene, so we'll prevent it, and queue it up to be given instead. + */ + REGISTER_VB_SHOULD(VB_GIVE_ITEM_FAIRY_OCARINA, { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + *should = false; + } + }); + + // Todo: Move item queueing here +} diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipToGivingZeldasLetter.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipToGivingZeldasLetter.cpp new file mode 100644 index 00000000000..357125db84f --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipToGivingZeldasLetter.cpp @@ -0,0 +1,45 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" + +extern "C" { + #include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h" +} + +/** + * This overrides Zelda's update function to effectively skip the dialog and cutscenes played when + * you meet with her in Hyrule Castle Courtyard. As you approach her she will turn around, and talking + * with her will place you at the very last dialog option where she gives you the letter. + */ + +u16 EnZl4_GiveItemTextId(PlayState* play, Actor* actor) { + return 0x207D; +} + +void EnZl4_SkipToGivingZeldasLetter(EnZl4* enZl4, PlayState* play) { + if (enZl4->csState == 0 && enZl4->actor.xzDistToPlayer < 700.0f && EnZl4_SetNextAnim(enZl4, 3)) { + Audio_PlayFanfare(NA_BGM_APPEAR); + enZl4->csState = 8; // ZL4_CS_PLAN + } else { + Npc_UpdateTalking(play, &enZl4->actor, &enZl4->interactInfo.talkState, enZl4->collider.dim.radius + 60.0f, EnZl4_GiveItemTextId, func_80B5B9B0); + func_80B5BB78(enZl4, play); + + if (enZl4->interactInfo.talkState != NPC_TALK_STATE_IDLE) { + enZl4->talkState = 6; + enZl4->actionFunc = EnZl4_Cutscene; + } + } +} + +void SkipToGivingZeldasLetter_OnActorInit(void* actorPtr) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + EnZl4* enZl4 = static_cast(actorPtr); + if (enZl4->actionFunc != EnZl4_Cutscene || enZl4->csState != 0) return; + + enZl4->actionFunc = EnZl4_SkipToGivingZeldasLetter; + } +} + +void SkipToGivingZeldasLetter_Register() { + GameInteractor::Instance->RegisterGameHookForID(ACTOR_EN_ZL4, SkipToGivingZeldasLetter_OnActorInit); +} diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp new file mode 100644 index 00000000000..fe578c8313e --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp @@ -0,0 +1,67 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" + +extern "C" { + #include "z64save.h" + #include "functions.h" + extern SaveContext gSaveContext; +} + +void SkipZeldaFleeingCastle_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_list originalArgs) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_0 && gSaveContext.cutsceneIndex == 0xFFF1) { + // Normally set in the cutscene + gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4AAA; + + gSaveContext.cutsceneIndex = 0; + *should = false; + } + } +} + +/** + * When this cutscene is skipped, walking up to the bridge to castle town triggers a quick fade in/out + * which can be confusing to beginners, because they need to then fetch the Ocarina of Time from the water. + * To make it more obvious what happened, we'll play the sound of the Ocarina dropping into the water. + */ +static int framesSinceSpawn = 0; +static HOOK_ID itemOcarinaUpdateHook = 0; +static HOOK_ID sceneInitHook = 0; + +void SkipZeldaFleeingCastle_OnActorUpdate(void* actorPtr) { + Actor* actor = static_cast(actorPtr); + + framesSinceSpawn++; + if (framesSinceSpawn > 20) { + Audio_PlayActorSound2(actor, NA_SE_EV_BOMB_DROP_WATER); + + GameInteractor::Instance->UnregisterGameHookForPtr(itemOcarinaUpdateHook); + GameInteractor::Instance->UnregisterGameHook(sceneInitHook); + itemOcarinaUpdateHook = 0; + sceneInitHook = 0; + } +} + +void SkipZeldaFleeingCastle_OnActorInit(void* actorPtr) { + Actor* actor = static_cast(actorPtr); + + if ( + actor->params == 3 && + CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) + ) { + framesSinceSpawn = 0; + itemOcarinaUpdateHook = GameInteractor::Instance->RegisterGameHookForPtr((uintptr_t)actorPtr, SkipZeldaFleeingCastle_OnActorUpdate); + sceneInitHook = GameInteractor::Instance->RegisterGameHook([] (int16_t sceneNum) { + GameInteractor::Instance->UnregisterGameHookForPtr(itemOcarinaUpdateHook); + GameInteractor::Instance->UnregisterGameHook(sceneInitHook); + itemOcarinaUpdateHook = 0; + sceneInitHook = 0; + }); + } +} + +void SkipZeldaFleeingCastle_Register() { + GameInteractor::Instance->RegisterGameHookForID(ACTOR_ITEM_OCARINA, SkipZeldaFleeingCastle_OnActorInit); + GameInteractor::Instance->RegisterGameHookForID(VB_PLAY_TRANSITION_CS, SkipZeldaFleeingCastle_ShouldPlayTransitionCS); +} diff --git a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp new file mode 100644 index 00000000000..78a6801756d --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp @@ -0,0 +1,30 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" + +extern "C" { + #include "z64save.h" + #include "macros.h" + #include "variables.h" + #include "functions.h" + extern PlayState* gPlayState; + extern SaveContext gSaveContext; +} + +/** + * This simply skips the Mido interaction in Kokiri Forest, once you equip the Kokiri + * Sword and Deku Shield he will move out of the way without you needing to talk to him. + */ +void MoveMidoInKokiriForest_Register() { + REGISTER_VB_SHOULD(VB_MOVE_MIDO_IN_KOKIRI_FOREST, { + if ( + CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO) && + !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) && + (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU) && + (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI) + ) { + Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD); + *should = true; + } + }); +} diff --git a/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp b/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp new file mode 100644 index 00000000000..68fe71da666 --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp @@ -0,0 +1,15 @@ +#include "TimeSavers.h" + +void TimeSavers_Register() { + // SkipCutscene + // Story + SkipBlueWarp_Register(); + SkipDekuTreeIntro_Register(); + SkipLostWoodsBridge_Register(); + SkipToGivingZeldasLetter_Register(); + SkipZeldaFleeingCastle_Register(); + SkipIntro_Register(); + // SkipMiscInteractions + MoveMidoInKokiriForest_Register(); + FasterHeavyBlockLift_Register(); +} diff --git a/soh/soh/Enhancements/TimeSavers/TimeSavers.h b/soh/soh/Enhancements/TimeSavers/TimeSavers.h new file mode 100644 index 00000000000..d45ed7f1085 --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/TimeSavers.h @@ -0,0 +1,18 @@ +#ifndef TIME_SAVERS_H +#define TIME_SAVERS_H + +void TimeSavers_Register(); + +// SkipCutscene + // Story + void SkipBlueWarp_Register(); + void SkipDekuTreeIntro_Register(); + void SkipLostWoodsBridge_Register(); + void SkipToGivingZeldasLetter_Register(); + void SkipZeldaFleeingCastle_Register(); + void SkipIntro_Register(); +// SkipMiscInteractions + void MoveMidoInKokiriForest_Register(); +void FasterHeavyBlockLift_Register(); + +#endif // TIME_SAVERS_H diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 63414f88c85..c8307858185 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -1,19 +1,33 @@ #include "BossRush.h" #include "soh/OTRGlobals.h" -#include "functions.h" -#include "macros.h" -#include "variables.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include #include #include +extern "C" { + #include "functions.h" + #include "macros.h" + #include "variables.h" + #include "src/overlays/actors/ovl_Boss_Goma/z_boss_goma.h" + #include "src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h" + #include "src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h" + extern PlayState* gPlayState; + + Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point); + #include "textures/icon_item_nes_static/icon_item_nes_static.h" + #include "textures/icon_item_ger_static/icon_item_ger_static.h" + #include "textures/icon_item_fra_static/icon_item_fra_static.h" +} + typedef struct BossRushSetting { std::array name; std::vector> choices; } BossRushSetting; -BossRushSetting BossRushOptions[BOSSRUSH_OPTIONS_AMOUNT] = { +BossRushSetting BossRushOptions[BR_OPTIONS_MAX] = { { { "BOSSES:", "BOSSE:", "BOSS:" }, { @@ -112,15 +126,15 @@ BossRushSetting BossRushOptions[BOSSRUSH_OPTIONS_AMOUNT] = { } }; -const char* BossRush_GetSettingName(uint8_t optionIndex, uint8_t language) { +const char* BossRush_GetSettingName(u8 optionIndex, u8 language) { return BossRushOptions[optionIndex].name[language].c_str(); } -const char* BossRush_GetSettingChoiceName(uint8_t optionIndex, uint8_t choiceIndex, uint8_t language) { +const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 language) { return BossRushOptions[optionIndex].choices[choiceIndex][language].c_str(); } -uint8_t BossRush_GetSettingOptionsAmount(uint8_t optionIndex) { +u8 BossRush_GetSettingOptionsAmount(u8 optionIndex) { return BossRushOptions[optionIndex].choices.size(); } @@ -129,15 +143,15 @@ void BossRush_SpawnBlueWarps(PlayState* play) { // Spawn blue warps in Chamber of Sages based on what bosses have been defeated. if (gSaveContext.linkAge == LINK_AGE_CHILD) { // Forest Medallion (Gohma) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -100, 6, -170, 0, 0, 0, -1, false); } // Fire Medallion (King Dodongo) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 100, 6, -170, 0, 0, 0, -1, false); } // Water Medallion (Barinade) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 199, 6, 0, 0, 0, 0, -1, false); } } else { @@ -146,15 +160,15 @@ void BossRush_SpawnBlueWarps(PlayState* play) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -199, 6, 0, 0, 0, 0, -1, false); } // Forest Medallion (Phantom Ganondorf) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -100, 6, -170, 0, 0, 0, -1, false); } // Fire Medallion (Volvagia) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 100, 6, -170, 0, 0, 0, -1, false); } // Water Medallion (Morpha) - if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 199, 6, 0, 0, 0, 0, -1, false); } // Spirit Medallion (Twinrova) @@ -168,8 +182,44 @@ void BossRush_SpawnBlueWarps(PlayState* play) { } } -void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { +void BossRush_SetEquipment(u8 linkAge) { + std::array brButtonItems; + std::array brCButtonSlots; + + // Set Child Equipment. + if (linkAge == LINK_AGE_CHILD) { + brButtonItems = { + ITEM_SWORD_KOKIRI, ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE + }; + + brCButtonSlots = { SLOT_STICK, SLOT_NUT, SLOT_BOMB, SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }; + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); + // Set Adult equipment. + } else { + brButtonItems = { ITEM_SWORD_MASTER, ITEM_BOW, ITEM_HAMMER, ITEM_BOMB, + ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }; + + brCButtonSlots = { SLOT_BOW, SLOT_HAMMER, SLOT_BOMB, SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }; + + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_GORON); + } + + // Button Items + for (int button = 0; button < ARRAY_COUNT(gSaveContext.equips.buttonItems); button++) { + gSaveContext.equips.buttonItems[button] = brButtonItems[button]; + } + + // C buttons + for (int button = 0; button < ARRAY_COUNT(gSaveContext.equips.cButtonSlots); button++) { + gSaveContext.equips.cButtonSlots[button] = brCButtonSlots[button]; + } +} + +void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { // If warping from Chamber of Sages, choose the correct boss room to teleport to. if (play->sceneNum == SCENE_CHAMBER_OF_THE_SAGES) { // Gohma & Phantom Ganon @@ -202,10 +252,13 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { // Ganondork } else if (warpPosX == -199 && warpPosZ == 0) { play->nextEntranceIndex = ENTR_GANONDORF_BOSS_0; + } else { + SPDLOG_ERROR("[BossRush]: Unknown blue warp in chamber of sages at position ({}, {}). Warping back to chamber of sages.", warpPosX, warpPosZ); + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; } // If coming from a boss room, teleport back to Chamber of Sages and set flag. } else { - play->nextEntranceIndex = SCENE_HAIRAL_NIWA2; + play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; if (CheckDungeonCount() == 3) { play->linkAgeOnLoad = LINK_AGE_ADULT; @@ -223,6 +276,10 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { } } } + + play->transitionTrigger = TRANS_TRIGGER_START; + play->transitionType = TRANS_TYPE_FADE_WHITE; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE_SLOW; } void BossRush_HandleBlueWarpHeal(PlayState* play) { @@ -235,29 +292,25 @@ void BossRush_HandleBlueWarpHeal(PlayState* play) { } void BossRush_HandleCompleteBoss(PlayState* play) { - if (!IS_BOSS_RUSH) { - return; - } - gSaveContext.isBossRushPaused = 1; switch (play->sceneNum) { case SCENE_DEKU_TREE_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE); + Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP); break; case SCENE_DODONGOS_CAVERN_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN); + Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP); break; case SCENE_JABU_JABU_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY); + Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP); break; case SCENE_FOREST_TEMPLE_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE); + Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); break; case SCENE_FIRE_TEMPLE_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE); + Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP); break; case SCENE_WATER_TEMPLE_BOSS: - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE); + Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP); break; case SCENE_SPIRIT_TEMPLE_BOSS: Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE); @@ -308,7 +361,7 @@ void BossRush_InitSave() { } // Set health - uint16_t health = 16; + u16 health = 16; switch (gSaveContext.bossRushOptions[BR_OPTIONS_HEARTS]) { case BR_CHOICE_HEARTS_7: health *= 7; @@ -418,7 +471,7 @@ void BossRush_InitSave() { } // Upgrades - uint8_t upgradeLevel = 1; + u8 upgradeLevel = 1; if (gSaveContext.bossRushOptions[BR_OPTIONS_AMMO] == BR_CHOICE_AMMO_MAXED) { upgradeLevel = 3; } @@ -432,13 +485,13 @@ void BossRush_InitSave() { // Set flags and Link's age based on chosen settings. if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_ADULT || gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) { - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY); + Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP); + Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP); + Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP); if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) { - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE); - Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE); + Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); + Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP); + Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP); Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE); Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE); } @@ -450,40 +503,214 @@ void BossRush_InitSave() { } } -void BossRush_SetEquipment(uint8_t linkAge) { +static void* sSavePromptNoChoiceTexs[] = { + (void*)gPauseNoENGTex, + (void*)gPauseNoGERTex, + (void*)gPauseNoFRATex +}; - std::array brButtonItems; - std::array brCButtonSlots; +void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { + va_list args; + va_copy(args, originalArgs); - // Set Child Equipment. - if (linkAge == LINK_AGE_CHILD) { - brButtonItems = { - ITEM_SWORD_KOKIRI, ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE - }; + switch (id) { + // Allow not healing before ganon + case VB_GANON_HEAL_BEFORE_FIGHT: { + if (gSaveContext.bossRushOptions[BR_OPTIONS_HEAL] == BR_CHOICE_HEAL_NEVER) { + *should = false; + } + break; + } + // Replace the blue warp transitions with ones that lead back to the chamber of sages + case VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE: { + DoorWarp1* blueWarp = va_arg(args, DoorWarp1*); + BossRush_HandleBlueWarp(gPlayState, blueWarp->actor.world.pos.x, blueWarp->actor.world.pos.z); + *should = false; + break; + } + // Spawn clean blue warps (no ruto, adult animation, etc) + case VB_SPAWN_BLUE_WARP: { + switch (gPlayState->sceneNum) { + case SCENE_DEKU_TREE_BOSS: { + BossGoma* bossGoma = va_arg(args, BossGoma*); + static Vec3f roomCenter = { -150.0f, 0.0f, -350.0f }; + Vec3f childPos = roomCenter; + + for (s32 i = 0; i < 10000; i++) { + if ((fabsf(childPos.x - GET_PLAYER(gPlayState)->actor.world.pos.x) < 100.0f && + fabsf(childPos.z - GET_PLAYER(gPlayState)->actor.world.pos.z) < 100.0f) || + (fabsf(childPos.x - bossGoma->actor.world.pos.x) < 150.0f && + fabsf(childPos.z - bossGoma->actor.world.pos.z) < 150.0f)) { + childPos.x = Rand_CenteredFloat(400.0f) + -150.0f; + childPos.z = Rand_CenteredFloat(400.0f) + -350.0f; + } else { + break; + } + } + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, childPos.x, bossGoma->actor.world.pos.y, childPos.z, 0, 0, 0, WARP_DUNGEON_ADULT, false); + break; + } + case SCENE_DODONGOS_CAVERN_BOSS: { + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, WARP_DUNGEON_ADULT, false); + break; + } + case SCENE_JABU_JABU_BOSS: { + static Vec3f sWarpPos[] = { + { 10.0f, 0.0f, 30.0f }, + { 260.0f, 0.0f, -470.0f }, + { -240.0f, 0.0f, -470.0f }, + }; + + s32 sp7C = 2; + for (s32 i = 2; i > 0; i -= 1) { + if (Math_Vec3f_DistXYZ(&sWarpPos[i], &GET_PLAYER(gPlayState)->actor.world.pos) < + Math_Vec3f_DistXYZ(&sWarpPos[i - 1], &GET_PLAYER(gPlayState)->actor.world.pos)) { + sp7C = i - 1; + } + } + + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, sWarpPos[sp7C].x, sWarpPos[sp7C].y, sWarpPos[sp7C].z, 0, 0, 0, WARP_DUNGEON_ADULT, false); + break; + } + case SCENE_FOREST_TEMPLE_BOSS: { + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 14.0f, -33.0f, -3315.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + break; + } + case SCENE_FIRE_TEMPLE_BOSS: { + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 0.0f, 100.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + break; + } + case SCENE_WATER_TEMPLE_BOSS: { + BossMo* bossMo = va_arg(args, BossMo*); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, bossMo->actor.world.pos.x, -280.0f, bossMo->actor.world.pos.z, 0, 0, 0, WARP_DUNGEON_ADULT, true); + break; + } + case SCENE_SPIRIT_TEMPLE_BOSS: { + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + break; + } + case SCENE_SHADOW_TEMPLE_BOSS: { + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, -50.0f, 0.0f, 400.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + break; + } + default: { + SPDLOG_WARN("[BossRush]: Blue warp spawned in unhandled scene, ignoring"); + return; + } + } + *should = false; + break; + } + // Skip past the "Save?" window when pressing B while paused and instead close the menu. + case VB_CLOSE_PAUSE_MENU: { + if (CHECK_BTN_ALL(gPlayState->state.input[0].press.button, BTN_B)) { + *should = true; + } + break; + } + // Show "No" twice because the player can't continue. + case VB_RENDER_YES_ON_CONTINUE_PROMPT: { + Gfx** disp = va_arg(args, Gfx**); + *disp = KaleidoScope_QuadTextureIA8(*disp, sSavePromptNoChoiceTexs[gSaveContext.language], 48, 16, 12); + *should = false; + break; + } + // Break the dodongo breakable floor immediately so the player can jump in the hole immediately. + case VB_BG_BREAKWALL_BREAK: { + *should = true; + break; + } + // Skip past the "Save?" window when dying and go to the "Continue?" screen immediately. + case VB_TRANSITION_TO_SAVE_SCREEN_ON_DEATH: { + PauseContext* pauseCtx = va_arg(args, PauseContext*); + pauseCtx->state = 0xF; + *should = false; + break; + } + // Prevent saving + case VB_BE_ABLE_TO_SAVE: + // Disable doors so the player can't leave the boss rooms backwards. + case VB_BE_ABLE_TO_OPEN_DOORS: + // There's no heart containers in boss rush + case VB_SPAWN_HEART_CONTAINER: + // Rupees are useless in boss rush + case VB_RENDER_RUPEE_COUNTER: { + *should = false; + break; + } + // Prevent warning spam + default: { + break; + } + } - brCButtonSlots = { SLOT_STICK, SLOT_NUT, SLOT_BOMB, SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }; + va_end(args); +} - Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); - Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); - // Set Adult equipment. - } else { - brButtonItems = { ITEM_SWORD_MASTER, ITEM_BOW, ITEM_HAMMER, ITEM_BOMB, - ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }; +void BossRush_OnActorInitHandler(void* actorRef) { + Actor* actor = static_cast(actorRef); - brCButtonSlots = { SLOT_BOW, SLOT_HAMMER, SLOT_BOMB, SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }; + if (actor->id == ACTOR_DEMO_SA && gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES) { + BossRush_SpawnBlueWarps(gPlayState); + Actor_Kill(actor); + GET_PLAYER(gPlayState)->actor.world.rot.y = GET_PLAYER(gPlayState)->actor.shape.rot.y = 27306; + return; + } - Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); - Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); - Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_GORON); + // Remove chests, mainly for the chest in King Dodongo's boss room. + // Remove bushes, used in Gohma's arena. + // Remove pots, used in Barinade's and Ganondorf's arenas. + if (actor->id == ACTOR_EN_KUSA || actor->id == ACTOR_OBJ_TSUBO || actor->id == ACTOR_EN_BOX) { + Actor_Kill(actor); + return; } +} - // Button Items - for (int button = 0; button < ARRAY_COUNT(gSaveContext.equips.buttonItems); button++) { - gSaveContext.equips.buttonItems[button] = brButtonItems[button]; +void BossRush_OnSceneInitHandler(s16 sceneNum) { + // Unpause the timer when the scene loaded isn't the Chamber of Sages. + if (sceneNum != SCENE_CHAMBER_OF_THE_SAGES) { + gSaveContext.isBossRushPaused = 0; } +} - // C buttons - for (int button = 0; button < ARRAY_COUNT(gSaveContext.equips.cButtonSlots); button++) { - gSaveContext.equips.cButtonSlots[button] = brCButtonSlots[button]; +void BossRush_OnBossDefeatHandler(void* refActor) { + BossRush_HandleCompleteBoss(gPlayState); +} + +void BossRush_OnBlueWarpUpdate(void* actor) { + DoorWarp1* blueWarp = static_cast(actor); + + if (blueWarp->warpTimer > 160) { + BossRush_HandleBlueWarp(gPlayState, blueWarp->actor.world.pos.x, blueWarp->actor.world.pos.z); } } + +void BossRush_RegisterHooks() { + static u32 onVanillaBehaviorHook = 0; + static u32 onSceneInitHook = 0; + static u32 onActorInitHook = 0; + static u32 onBossDefeatHook = 0; + static u32 onActorUpdate = 0; + + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { + GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); + GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); + GameInteractor::Instance->UnregisterGameHook(onActorInitHook); + GameInteractor::Instance->UnregisterGameHook(onBossDefeatHook); + GameInteractor::Instance->UnregisterGameHookForID(onActorUpdate); + + onVanillaBehaviorHook = 0; + onSceneInitHook = 0; + onActorInitHook = 0; + onBossDefeatHook = 0; + onActorUpdate = 0; + + if (!IS_BOSS_RUSH) return; + + onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnVanillaBehaviorHandler); + onSceneInitHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnSceneInitHandler); + onActorInitHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnActorInitHandler); + onBossDefeatHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnBossDefeatHandler); + onActorUpdate = GameInteractor::Instance->RegisterGameHookForID(ACTOR_DOOR_WARP1, BossRush_OnBlueWarpUpdate); + }); +} diff --git a/soh/soh/Enhancements/boss-rush/BossRush.h b/soh/soh/Enhancements/boss-rush/BossRush.h index caa6ce86e5a..292cbaf26ad 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.h +++ b/soh/soh/Enhancements/boss-rush/BossRush.h @@ -1,20 +1,16 @@ #pragma once -#include "BossRushTypes.h" -#include "variables.h" +#include "z64.h" #ifdef __cplusplus extern "C" { #endif -void BossRush_SpawnBlueWarps(PlayState* play); -void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ); -void BossRush_HandleBlueWarpHeal(PlayState* play); -void BossRush_InitSave(); -void BossRush_SetEquipment(uint8_t linkAge); -void BossRush_HandleCompleteBoss(PlayState* play); -const char* BossRush_GetSettingName(uint8_t optionIndex, uint8_t language); -const char* BossRush_GetSettingChoiceName(uint8_t optionIndex, uint8_t choiceIndex, uint8_t language); -uint8_t BossRush_GetSettingOptionsAmount(uint8_t optionIndex); + void BossRush_HandleBlueWarpHeal(PlayState* play); + void BossRush_InitSave(); + const char* BossRush_GetSettingName(u8 optionIndex, u8 language); + const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 language); + u8 BossRush_GetSettingOptionsAmount(u8 optionIndex); + void BossRush_RegisterHooks(); #ifdef __cplusplus }; #endif diff --git a/soh/soh/Enhancements/boss-rush/BossRushTypes.h b/soh/soh/Enhancements/boss-rush/BossRushTypes.h index e39cba997a9..cf4d3aaba19 100644 --- a/soh/soh/Enhancements/boss-rush/BossRushTypes.h +++ b/soh/soh/Enhancements/boss-rush/BossRushTypes.h @@ -1,6 +1,5 @@ #pragma once -#define BOSSRUSH_OPTIONS_AMOUNT 12 #define BOSSRUSH_MAX_OPTIONS_ON_SCREEN 6 typedef enum { @@ -15,7 +14,8 @@ typedef enum { BR_OPTIONS_LONGSHOT, BR_OPTIONS_HOVERBOOTS, BR_OPTIONS_BUNNYHOOD, - BR_OPTIONS_TIMER + BR_OPTIONS_TIMER, + BR_OPTIONS_MAX, } BossRushOptionEnums; typedef enum { diff --git a/soh/soh/Enhancements/cheat_hook_handlers.cpp b/soh/soh/Enhancements/cheat_hook_handlers.cpp new file mode 100644 index 00000000000..ef69d61745b --- /dev/null +++ b/soh/soh/Enhancements/cheat_hook_handlers.cpp @@ -0,0 +1,56 @@ +#include +#include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/Enhancements/enhancementTypes.h" + +extern "C" { +#include "macros.h" +#include "variables.h" + +extern SaveContext gSaveContext; +extern PlayState* gPlayState; +} + +void CheatsOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { + switch (id) { + case VB_DEKU_STICK_BREAK: { + if (CVarGetInteger(CVAR_CHEAT("DekuStickCheat"), DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) { + *should = false; + } + break; + } + case VB_DEKU_STICK_BE_ON_FIRE: { + if (CVarGetInteger(CVAR_CHEAT("DekuStickCheat"), DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE) { + Player* player = GET_PLAYER(gPlayState); + player->unk_860 = 200; // Keeps the stick's flame lit + player->unk_85C = 1.0f; // Ensures the stick is the proper length + *should = true; + } + break; + } + case VB_DEKU_STICK_BURN_OUT: { + if (CVarGetInteger(CVAR_CHEAT("DekuStickCheat"), DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) { + *should = false; + } + break; + } + case VB_DEKU_STICK_BURN_DOWN: { + if (CVarGetInteger(CVAR_CHEAT("DekuStickCheat"), DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) { + *should = false; + } + break; + } + } +} + +static uint32_t onVanillaBehaviorHook = 0; +void CheatsRegisterHooks() { + GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) mutable { + + GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); + onVanillaBehaviorHook = 0; + onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(CheatsOnVanillaBehaviorHandler); + + }); +} diff --git a/soh/soh/Enhancements/cheat_hook_handlers.h b/soh/soh/Enhancements/cheat_hook_handlers.h new file mode 100644 index 00000000000..88a79f2859f --- /dev/null +++ b/soh/soh/Enhancements/cheat_hook_handlers.h @@ -0,0 +1,6 @@ +#ifndef CHEAT_HOOK_HANDLERS_H +#define CHEAT_HOOK_HANDLERS_H + +void CheatsRegisterHooks(); + +#endif // CHEAT_HOOK_HANDLERS_H diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp index a5c1364b88f..a3745ee72ec 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp @@ -2145,7 +2145,6 @@ void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) { } void SohInputEditorWindow::DrawElement() { - ImGui::Begin("Controller Configuration###sohControllerConfigWindowV1", &mIsVisible); ImGui::BeginTabBar("##ControllerConfigPortTabs"); DrawLinkTab(); DrawIvanTab(); @@ -2154,5 +2153,4 @@ void SohInputEditorWindow::DrawElement() { DrawDebugPortTab(3); } ImGui::EndTabBar(); - ImGui::End(); } diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index b0e81c16ca4..deb4ce8f5f6 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -220,6 +220,7 @@ static std::map cosmeticOptions = { COSMETIC_OPTION("Consumable.DDHeartBorder", "DD Heart Border", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, true, true), COSMETIC_OPTION("Consumable.Magic", "Magic", COSMETICS_GROUP_CONSUMABLE, ImVec4( 0, 200, 0, 255), false, true, false), COSMETIC_OPTION("Consumable.MagicActive", "Magic Active", COSMETICS_GROUP_CONSUMABLE, ImVec4(250, 250, 0, 255), false, true, true), + COSMETIC_OPTION("Consumable_MagicInfinite", "Infinite Magic", COSMETICS_GROUP_CONSUMABLE, ImVec4( 0, 0, 200, 255), false, true, true), COSMETIC_OPTION("Consumable.MagicBorder", "Magic Border", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, false, true), COSMETIC_OPTION("Consumable.MagicBorderActive", "Magic Border Active", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, false, true), COSMETIC_OPTION("Consumable.GreenRupee", "Green Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4( 50, 255, 50, 255), false, true, true), diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp index e552a9672d9..c24b83fb69e 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp @@ -3,7 +3,9 @@ #include #include #include -#include +#include +#include +#include using namespace std::literals::string_literals; @@ -14,57 +16,210 @@ static const std::unordered_map textBoxSpecialCharacters = { { "è", 0x95 }, { "é", 0x96 }, { "ê", 0x97 }, { "ë", 0x98 }, { "ï", 0x99 }, { "ô", 0x9A }, { "ö", 0x9B }, { "ù", 0x9C }, { "û", 0x9D }, { "ü", 0x9E } }; -static const std::unordered_map colors = { { "w", QM_WHITE }, { "r", QM_RED }, { "g", QM_GREEN }, +static const std::unordered_map percentColors = { { "w", QM_WHITE }, { "r", QM_RED }, { "g", QM_GREEN }, { "b", QM_BLUE }, { "c", QM_LBLUE }, { "p", QM_PINK }, { "y", QM_YELLOW }, { "B", QM_BLACK } }; +static const std::unordered_map altarIcons = { + { "0", ITEM_KOKIRI_EMERALD }, + { "1", ITEM_GORON_RUBY }, + { "2", ITEM_ZORA_SAPPHIRE }, + { "8", ITEM_MEDALLION_LIGHT }, + { "3", ITEM_MEDALLION_FOREST }, + { "4", ITEM_MEDALLION_FIRE }, + { "5", ITEM_MEDALLION_WATER }, + { "6", ITEM_MEDALLION_SPIRIT }, + { "7", ITEM_MEDALLION_SHADOW }, + { "l", ITEM_ARROW_LIGHT }, + { "b", ITEM_KEY_BOSS }, + { "o", ITEM_SWORD_MASTER }, + { "c", ITEM_OCARINA_FAIRY }, + { "i", ITEM_OCARINA_TIME }, + { "L", ITEM_BOW_ARROW_LIGHT }, + { "k", ITEM_TUNIC_KOKIRI }, + { "m", ITEM_DUNGEON_MAP }, + { "C", ITEM_COMPASS }, + { "s", ITEM_SKULL_TOKEN }, + { "g", ITEM_MASK_GORON } +}; + +static std::map pixelWidthTable = { + { " ", 6 }, { "!", 6 }, { "\"", 5 }, { "#", 7 }, { "$", 7 }, { "%", 11 }, { "&", 9 }, { "\'", 3 }, + { "(", 6 }, { ")", 6 }, { "*", 6 }, { "+", 7 }, { ",", 3 }, { "-", 5 }, { ".", 3 }, { "/", 7 }, + { "0", 8 }, { "1", 4 }, { "2", 7 }, { "3", 7 }, { "4", 8 }, { "5", 7 }, { "6", 7 }, { "7", 7 }, + { "8", 7 }, { "9", 7 }, { ":", 5 }, { ";", 5 }, { "<", 7 }, { "=", 9 }, { ">", 7 }, { "?", 9 }, + { "@", 10 }, { "A", 9 }, { "B", 7 }, { "C", 9 }, { "D", 9 }, { "E", 6 }, { "F", 6 }, { "G", 9 }, + { "H", 8 }, { "I", 3 }, { "J", 6 }, { "K", 8 }, { "L", 6 }, { "M", 10 }, { "N", 9 }, { "O", 10 }, + { "P", 7 }, { "Q", 10 }, { "R", 8 }, { "S", 8 }, { "T", 7 }, { "U", 8 }, { "V", 9 }, { "W", 12 }, + { "X", 9 }, { "Y", 8 }, { "Z", 8 }, { "[", 6 }, { "\\", 8 }, { "]", 6 }, { "^", 8 }, { "_", 7 }, + { "`", 4 }, { "a", 6 }, { "b", 7 }, { "c", 6 }, { "d", 7 }, { "e", 7 }, { "f", 5 }, { "g", 7 }, + { "h", 6 }, { "i", 3 }, { "j", 5 }, { "k", 6 }, { "l", 3 }, { "m", 9 }, { "n", 7 }, { "o", 7 }, + { "p", 7 }, { "q", 7 }, { "r", 6 }, { "s", 6 }, { "t", 6 }, { "u", 6 }, { "v", 7 }, { "w", 9 }, + { "x", 6 }, { "y", 7 }, { "z", 6 }, { "{", 6 }, { "¦", 4 }, { "}", 6 }, { "¡", 5 }, { "¢", 7 }, + { "£", 8 }, { "¤", 7 }, { "¥", 8 }, { "|", 4 }, { "§", 12 }, { "¨", 12 }, { "©", 10 }, { "ª", 5 }, + { "«", 8 }, { "¬", 7 }, { "\u00AD", 6 }, { "®", 10 }, { "¯", 8 }, { "°", 12 }, { "±", 12 }, { "²", 5 }, + { "³", 5 }, { "µ", 6 }, { "¶", 8 }, { "·", 4 }, { "¹", 4 }, { "º", 5 }, { "»", 9 }, { "¼", 9 }, + { "½", 9 }, { "¾", 10 }, { "¿", 7 }, { "À", 11 }, { "Á", 9 }, { "Â", 9 }, { "Ã", 9 }, { "Ä", 9 }, + { "Å", 9 }, { "Æ", 12 }, { "Ç", 9 }, { "È", 6 }, { "É", 6 }, { "Ê", 6 }, { "Ë", 6 }, { "Ì", 5 }, + { "Í", 5 }, { "Î", 5 }, { "Ï", 5 }, { "Ð", 10 }, { "Ñ", 9 }, { "Ò", 10 }, { "Ó", 10 }, { "Ô", 10 }, + { "Õ", 10 }, { "Ö", 10 }, { "×", 9 }, { "Ø", 10 }, { "Ù", 8 }, { "Ú", 8 }, { "Û", 8 }, { "Ü", 8 }, + { "Ý", 10 }, { "Þ", 8 }, { "ß", 7 }, { "à", 6 }, { "á", 6 }, { "â", 6 }, { "ã", 6 }, { "ä", 6 }, + { "å", 6 }, { "æ", 11 }, { "ç", 6 }, { "è", 7 }, { "é", 7 }, { "ê", 7 }, { "ë", 7 }, { "ì", 5 }, + { "í", 5 }, { "î", 5 }, { "ï", 5 }, { "ð", 7 }, { "ñ", 7 }, { "ò", 7 }, { "ó", 7 }, { "ô", 7 }, + { "õ", 7 }, { "ö", 7 }, { "÷", 11 }, { "ø", 9 }, { "ù", 7 }, { "ú", 7 }, { "û", 7 }, { "ü", 7 }, + { "ý", 8 }, { "þ", 8 }, { "ÿ", 8 }, { "Œ", 11 }, { "œ", 11 }, { "„", 5 }, { "”", 5 }, { "€", 10 }, + { "Ÿ", 10 }, { "~", 8 } +}; + CustomMessage::CustomMessage(std::string english_, std::string german_, std::string french_, TextBoxType type_, TextBoxPosition position_) - : english(std::move(english_)), german(std::move(german_)), french(std::move(french_)), type(type_), - position(position_) { + : type(type_), position(position_){ + messages[LANGUAGE_ENG] = std::move(english_); + messages[LANGUAGE_GER] = std::move(german_); + messages[LANGUAGE_FRA] = std::move(french_); } -const std::string& CustomMessage::GetEnglish() const { - return english; +CustomMessage::CustomMessage(std::string english_, std::string german_, std::string french_, std::vector colors_, + std::vector capital_, TextBoxType type_, TextBoxPosition position_) { + messages[LANGUAGE_ENG] = std::move(english_); + messages[LANGUAGE_GER] = std::move(german_); + messages[LANGUAGE_FRA] = std::move(french_); + colors = colors_; + capital = capital_; + type = type_; + position = position_; } -const std::string& CustomMessage::GetFrench() const { - if (french.length() > 0) { - return french; +CustomMessage::CustomMessage(std::string english_, TextBoxType type_, TextBoxPosition position_) + : type(type_), position(position_) { + messages[LANGUAGE_ENG] = std::move(english_); +} + +CustomMessage::CustomMessage(std::string english_, std::vector colors_, std::vector capital_, TextBoxType type_, TextBoxPosition position_){ + messages[LANGUAGE_ENG] = std::move(english_); + colors = colors_; + capital = capital_; + type = type_; + position = position_; +} + +CustomMessage::CustomMessage(Text text, TextBoxType type_,TextBoxPosition position_) + : type(type_), position(position_) { + messages[LANGUAGE_ENG] = text.GetEnglish(); + messages[LANGUAGE_GER] = text.GetGerman(); + messages[LANGUAGE_FRA] = text.GetFrench(); +} + +const std::string CustomMessage::GetEnglish(MessageFormat format) const { + return GetForLanguage(LANGUAGE_ENG, format); +} + +const std::string CustomMessage::GetGerman(MessageFormat format) const { + return GetForLanguage(LANGUAGE_GER, format); +} + +const std::string CustomMessage::GetFrench(MessageFormat format) const { + return GetForLanguage(LANGUAGE_FRA, format); +} + +const std::string CustomMessage::GetForCurrentLanguage(MessageFormat format) const { + return GetForLanguage(gSaveContext.language, format); +} + +const std::string CustomMessage::GetForLanguage(uint8_t language, MessageFormat format) const { + std::string output = messages[language].length() > 0 ? messages[language] : messages[LANGUAGE_ENG]; + ProcessMessageFormat(output, format); + return output; +} + +const std::vector CustomMessage::GetAllMessages(MessageFormat format) const{ + std::vector output = messages; + for (auto str : output){ + ProcessMessageFormat(str, format); } - return english; + return output; } -const std::string& CustomMessage::GetGerman() const { - if (german.length() > 0) { - return german; + +void CustomMessage::ProcessMessageFormat(std::string& str, MessageFormat format) const { + if (format == MF_FORMATTED){ + FormatString(str); + } else if (format == MF_CLEAN){ + CleanString(str); + } else if (format == MF_AUTO_FORMAT){ + AutoFormatString(str); } - return english; +} + +const std::vector& CustomMessage::GetCapital() const { + return capital; +} + +void CustomMessage::SetCapital(std::vector capital_){ + capital = capital_; +} +const std::vector& CustomMessage::GetColors() const { + return colors; +} + +void CustomMessage::SetColors(std::vector colors_){ + colors = colors_; } const TextBoxType& CustomMessage::GetTextBoxType() const { return type; } +void CustomMessage::SetTextBoxType(TextBoxType boxType){ + type = boxType; +} + const TextBoxPosition& CustomMessage::GetTextBoxPosition() const { return position; } CustomMessage CustomMessage::operator+(const CustomMessage& right) const { - return CustomMessage(english + right.GetEnglish(), german + right.GetGerman(), french + right.GetFrench()); + std::vector newColors = colors; + std::vector rColors = right.GetColors(); + for (auto color: rColors){ + newColors.push_back(color); + } + std::vector newCapital = capital; + newCapital.insert(newCapital.end(), right.GetCapital().begin(), right.GetCapital().end()); + return CustomMessage(messages[LANGUAGE_ENG] + right.GetEnglish(MF_RAW), + messages[LANGUAGE_GER] + right.GetGerman(MF_RAW), + messages[LANGUAGE_FRA] + right.GetFrench(MF_RAW), + newColors, newCapital, type, position); } CustomMessage CustomMessage::operator+(const std::string& right) const { - return CustomMessage(english + right, german + right, french + right); + return CustomMessage(messages[LANGUAGE_ENG] + right, messages[LANGUAGE_GER] + right, messages[LANGUAGE_FRA] + right); +} + +void CustomMessage::operator+=(const CustomMessage& right) { + messages[LANGUAGE_ENG] += right.GetEnglish(MF_RAW); + messages[LANGUAGE_GER] += right.GetGerman(MF_RAW); + messages[LANGUAGE_FRA] += right.GetFrench(MF_RAW); + colors.insert(colors.end(), right.GetColors().begin(), right.GetColors().end()); + capital.insert(capital.end(), right.GetCapital().begin(), right.GetCapital().end()); } void CustomMessage::operator+=(const std::string& right) { - english += right; - french += right; - german += right; + messages[LANGUAGE_ENG] += right; + messages[LANGUAGE_GER] += right; + messages[LANGUAGE_FRA] += right; } bool CustomMessage::operator==(const CustomMessage& operand) const { - return english == operand.english; + return messages[LANGUAGE_ENG] == operand.messages[LANGUAGE_ENG]; +} + +bool CustomMessage::operator==(const std::string& operand) const { + for (auto str: messages){ + if (str == operand){ + return true; + } + } + return false; } bool CustomMessage::operator!=(const CustomMessage& operand) const { @@ -72,81 +227,263 @@ bool CustomMessage::operator!=(const CustomMessage& operand) const { } void CustomMessage::Replace(std::string&& oldStr, std::string&& newStr) { - for (std::string* str : { &english, &french, &german }) { - size_t position = str->find(oldStr); + for (std::string& str : messages) { + size_t position = str.find(oldStr); while (position != std::string::npos) { - str->replace(position, oldStr.length(), newStr); - position = str->find(oldStr); + str.replace(position, oldStr.length(), newStr); + position = str.find(oldStr); } } - Format(); } -void CustomMessage::Replace(std::string&& oldStr, std::string&& newEnglish, std::string&& newGerman, - std::string&& newFrench) { - size_t position = 0; - position = english.find(oldStr); - while (position != std::string::npos) { - english.replace(position, oldStr.length(), newEnglish); - position = english.find(oldStr); - } - position = french.find(oldStr); - while (position != std::string::npos) { - french.replace(position, oldStr.length(), newFrench); - position = french.find(oldStr); - } - position = german.find(oldStr); - while (position != std::string::npos) { - german.replace(position, oldStr.length(), newGerman); - position = german.find(oldStr); +void CustomMessage::Replace(std::string&& oldStr, CustomMessage newMessage) { + for (uint8_t language = 0; language < LANGUAGE_MAX; language++) { + size_t position = messages[language].find(oldStr); + while (position != std::string::npos) { + messages[language].replace(position, oldStr.length(), newMessage.messages[language]); + position = messages[language].find(oldStr); + } } - Format(); } void CustomMessage::Format(ItemID iid) { - for (std::string* str : { &english, &french, &german }) { - str->insert(0, ITEM_OBTAINED(iid)); + for (std::string &str : messages) { + str.insert(0, ITEM_OBTAINED(iid)); size_t start_pos = 0; - std::replace(str->begin(), str->end(), '&', NEWLINE()[0]); - while ((start_pos = str->find('^', start_pos)) != std::string::npos) { - str->replace(start_pos, 1, WAIT_FOR_INPUT() + ITEM_OBTAINED(iid)); + std::replace(str.begin(), str.end(), '&', NEWLINE()[0]); + while ((start_pos = str.find('^', start_pos)) != std::string::npos) { + str.replace(start_pos, 1, WAIT_FOR_INPUT() + ITEM_OBTAINED(iid)); start_pos += 3; } - std::replace(str->begin(), str->end(), '@', PLAYER_NAME()[0]); + std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]); + ReplaceSpecialCharacters(str); + ReplaceColors(str); + ReplaceAltarIcons(str); } - ReplaceSpecialCharacters(); - ReplaceColors(); *this += MESSAGE_END(); } void CustomMessage::Format() { - for (std::string* str : { &english, &french, &german }) { - std::replace(str->begin(), str->end(), '&', NEWLINE()[0]); - std::replace(str->begin(), str->end(), '^', WAIT_FOR_INPUT()[0]); - std::replace(str->begin(), str->end(), '@', PLAYER_NAME()[0]); + for (std::string& str : messages) { + FormatString(str); + } +} + +void CustomMessage::AutoFormat() { + for (std::string& str : messages) { + AutoFormatString(str); + } +} + +void CustomMessage::Clean() { + for (std::string& str : messages) { + CleanString(str); } - ReplaceSpecialCharacters(); - ReplaceColors(); - *this += MESSAGE_END(); } +void CustomMessage::FormatString(std::string& str) const { + std::replace(str.begin(), str.end(), '&', NEWLINE()[0]); + std::replace(str.begin(), str.end(), '^', WAIT_FOR_INPUT()[0]); + std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]); + ReplaceSpecialCharacters(str); + ReplaceColors(str); + ReplaceAltarIcons(str); + str += MESSAGE_END(); +} + +void DeleteControlCode(std::string& str, std::string code){ + size_t start_pos = 0; + while ((start_pos = str.find(code, start_pos)) != std::string::npos) { + str.replace(start_pos, code.length(), ""); + start_pos += code.length(); + } +} + +void CustomMessage::CleanString(std::string& str) const { + std::replace(str.begin(), str.end(), '&', "\n"[0]); + std::replace(str.begin(), str.end(), '^', " "[0]); + for (const auto& colorPair : percentColors) { + DeleteControlCode(str, "%" + colorPair.first); + } + std::erase(str, '#'); + for (const auto& iconPair : altarIcons) { + DeleteControlCode(str, "$" + iconPair.first); + } +} + +static size_t NextLineLength(const std::string* textStr, const size_t lastNewline, bool hasIcon = false) { + const size_t maxLinePixelWidth = hasIcon ? 200 : 216; + + size_t totalPixelWidth = 0; + size_t currentPos = lastNewline; + + // Looping through the string from the lastNewline until the total + // width of counted characters exceeds the maximum pixels in a line. + size_t nextPosJump = 0; + while (totalPixelWidth < maxLinePixelWidth && currentPos < textStr->length()) { + // Skip over control codes + if (textStr->at(currentPos) == '%') { + nextPosJump = 2; + } else if (textStr->at(currentPos) == '$') { + nextPosJump = 2; + } else if (textStr->at(currentPos) == '@') { + nextPosJump = 1; + // Assume worst case for player name 12 * 8 (widest character * longest name length) + totalPixelWidth += 96; + } else { + // Some characters only one byte while others are two bytes + // So check both possibilities when checking for a character + if (pixelWidthTable.count(textStr->substr(currentPos, 1))) { + totalPixelWidth += pixelWidthTable[textStr->substr(currentPos, 1)]; + nextPosJump = 1; + } else if (pixelWidthTable.count(textStr->substr(currentPos, 2))) { + totalPixelWidth += pixelWidthTable[textStr->substr(currentPos, 2)]; + nextPosJump = 2; + } else { + SPDLOG_DEBUG("Table does not contain " + textStr->substr(currentPos, 1) + "/" + textStr->substr(currentPos, 2)); + SPDLOG_DEBUG("Full string: " + *textStr); + nextPosJump = 1; + } + } + currentPos += nextPosJump; + } + // return the total number of characters we looped through + if (totalPixelWidth > maxLinePixelWidth && textStr->at(currentPos - nextPosJump) != ' ') { + return currentPos - lastNewline - nextPosJump; + } else { + return currentPos - lastNewline; + } +} + +void CustomMessage::AutoFormatString(std::string& str) const { + ReplaceAltarIcons(str); + ReplaceColors(str); + // insert newlines either manually or when encountering a '&' + size_t lastNewline = 0; + const bool hasIcon = str.find('$', 0) != std::string::npos; + size_t lineLength = NextLineLength(&str, lastNewline, hasIcon); + size_t lineCount = 1; + size_t yesNo = str.find("\x1B"s[0], lastNewline); + while (lastNewline + lineLength < str.length() || yesNo != std::string::npos) { + const size_t carrot = str.find('^', lastNewline); + const size_t ampersand = str.find('&', lastNewline); + const size_t lastSpace = str.rfind(' ', lastNewline + lineLength); + size_t waitForInput = str.find(WAIT_FOR_INPUT()[0], lastNewline); + size_t newLine = str.find(NEWLINE()[0], lastNewline); + if (carrot < waitForInput){ + waitForInput = carrot; + } + if (ampersand < newLine){ + newLine = ampersand; + } + if (lineCount != 3 && yesNo < lastNewline + lineLength && yesNo < waitForInput && yesNo < newLine){ + if (lineCount >= 4){ + str.replace(yesNo, 1, "^&&\x1B"); + lineCount = 3; + lastNewline = yesNo + 3; + } else { + while(lineCount < 3){ + str.replace(yesNo, 1, "&\x1B"); + yesNo++; + lineCount++; + } + lastNewline = yesNo; + } + } else { + if (lineCount < 4){ + // replace '&' first if it's within the newline range + if (newLine < lastNewline + lineLength) { + lastNewline = newLine + 1; + // or move the lastNewline cursor to the next line if a '^' is encountered + } else if (waitForInput < lastNewline + lineLength) { + lastNewline = waitForInput + 1; + lineCount = 0; + // some lines need to be split but don't have spaces, look for periods instead + } else if (lastSpace == std::string::npos) { + const size_t lastPeriod = str.rfind('.', lastNewline + lineLength); + str.replace(lastPeriod, 1, ".&"); + lastNewline = lastPeriod + 2; + } else { + str.replace(lastSpace, 1, "&"); + lastNewline = lastSpace + 1; + } + lineCount += 1; + } else { + const size_t lastColor = str.rfind("\x05"s, lastNewline + lineLength); + std::string colorText = ""; + //check if we are on a non default colour, as ^ resets it, and readd if needed + if (lastColor != std::string::npos && str[lastColor+1] != 0){ + colorText = "\x05"s + str[lastColor+1]; + } + // replace '&' first if it's within the newline range + if (ampersand < lastNewline + lineLength) { + str.replace(ampersand, 1, "^" + colorText); + lastNewline = ampersand + 1; + // or move the lastNewline cursor to the next line if a '^' is encountered. + } else if (carrot < lastNewline + lineLength) { + lastNewline = carrot + 1; + // some lines need to be split but don't have spaces, look for periods instead + } else if (lastSpace == std::string::npos) { + const size_t lastPeriod = str.rfind('.', lastNewline + lineLength); + str.replace(lastPeriod, 1, ".^" + colorText); + lastNewline = lastPeriod + 2; + } else { + str.replace(lastSpace, 1, "^" + colorText); + lastNewline = lastSpace + 1; + } + lineCount = 1; + } + lineLength = NextLineLength(&str, lastNewline, hasIcon); + } + yesNo = str.find("\x1B"s[0], lastNewline); + } + ReplaceSpecialCharacters(str); + ReplaceAltarIcons(str); + std::replace(str.begin(), str.end(), '&', NEWLINE()[0]); + std::replace(str.begin(), str.end(), '^', WAIT_FOR_INPUT()[0]); + std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]); + std::replace(str.begin(), str.end(), '_', " "[0]); + str += MESSAGE_END(); +} + +void CustomMessage::InsertNumber(uint8_t num){ + for (std::string& str : messages) { + size_t firstBar = str.find('|'); + if (firstBar != std::string::npos) { + size_t secondBar = str.find('|', firstBar + 1); + if (secondBar != std::string::npos) { + size_t thirdBar = str.find('|', secondBar + 1); + if (thirdBar != std::string::npos) { + if (num == 1) { + str.erase(secondBar, thirdBar - secondBar); + } else { + str.erase(firstBar, secondBar - firstBar); + } + } + } + } + } + //remove the remaining bar + this->Replace("|", ""); + Replace("[[d]]", std::to_string(num)); +} + + void CustomMessage::Capitalize() { - for (std::string* str : { &english, &french, &german }) { - (*str)[0] = std::toupper((*str)[0]); + for (std::string str : messages) { + (str)[0] = std::toupper((str)[0]); } } -void CustomMessage::ReplaceSpecialCharacters() { +void CustomMessage::ReplaceSpecialCharacters(std::string& str) const { // add special characters - for (std::string* str : { &english, &french, &german }) { - for (auto specialCharacterPair : textBoxSpecialCharacters) { - size_t start_pos = 0; - std::string textBoxSpecialCharacterString = ""s; - textBoxSpecialCharacterString += specialCharacterPair.second; - while ((start_pos = str->find(specialCharacterPair.first, start_pos)) != std::string::npos) { - str->replace(start_pos, specialCharacterPair.first.length(), textBoxSpecialCharacterString); - start_pos += textBoxSpecialCharacterString.length(); - } + for (auto specialCharacterPair : textBoxSpecialCharacters) { + size_t start_pos = 0; + std::string textBoxSpecialCharacterString = ""s; + textBoxSpecialCharacterString += specialCharacterPair.second; + while ((start_pos = str.find(specialCharacterPair.first, start_pos)) != std::string::npos) { + str.replace(start_pos, specialCharacterPair.first.length(), textBoxSpecialCharacterString); + start_pos += textBoxSpecialCharacterString.length(); } } } @@ -169,41 +506,77 @@ const char* Interface_ReplaceSpecialCharacters(char text[]) { return textChar; } -void CustomMessage::ReplaceColors() { - for (std::string* str : { &english, &french, &german }) { - for (auto colorPair : colors) { - std::string textToReplace = "%"; - textToReplace += colorPair.first; - size_t start_pos = 0; - while ((start_pos = str->find(textToReplace, start_pos)) != std::string::npos) { - str->replace(start_pos, textToReplace.length(), COLOR(colorPair.second)); - start_pos += textToReplace.length(); - } +void CustomMessage::ReplaceColors(std::string& str) const { + for (const auto& colorPair : percentColors) { + std::string textToReplace = "%"; + textToReplace += colorPair.first; + size_t start_pos = 0; + while ((start_pos = str.find(textToReplace, start_pos)) != std::string::npos) { + str.replace(start_pos, textToReplace.length(), COLOR(colorPair.second)); + start_pos += textToReplace.length(); + } + } + for (auto color: colors) { + if (const size_t firstHashtag = str.find('#'); firstHashtag != std::string::npos) { + str.replace(firstHashtag, 1, COLOR(color)); + if (const size_t secondHashtag = str.find('#', firstHashtag + 1); secondHashtag != std::string::npos) { + str.replace(secondHashtag, 1, COLOR(QM_WHITE)); + } else { + SPDLOG_DEBUG("non-matching hashtags in string: \"%s\"", str); + } } } + // Remove any remaining '#' characters. + std::erase(str, '#'); } -const std::string CustomMessage::MESSAGE_END() const { +void CustomMessage::ReplaceAltarIcons(std::string& str) const { + for (const auto& iconPair : altarIcons) { + std::string textToReplace = "$"; + textToReplace += iconPair.first; + size_t start_pos = 0; + while ((start_pos = str.find(textToReplace, start_pos)) != std::string::npos) { + str.replace(start_pos, textToReplace.length(), ITEM_OBTAINED(iconPair.second)); + start_pos += textToReplace.length(); + } + } +} + +void CustomMessage::InsertNames(std::vector toInsert){ + for(uint8_t a = 0; a < toInsert.size(); a++){ + CustomMessage temp = toInsert[a]; + if ((capital.size() > a) && (capital[a] = true)){ + temp.Capitalize(); + } + Replace("[[" + std::to_string(a+1) + "]]", temp); + } +} + +std::string CustomMessage::MESSAGE_END() { return "\x02"s; } -const std::string CustomMessage::ITEM_OBTAINED(uint8_t x) const { +std::string CustomMessage::ITEM_OBTAINED(uint8_t x) { return "\x13"s + char(x); } -const std::string CustomMessage::NEWLINE() const { +std::string CustomMessage::NEWLINE() { return "\x01"s; } -const std::string CustomMessage::COLOR(uint8_t x) const { - return "\x05"s + char(x); +std::string CustomMessage::COLOR(std::string x) { + return "\x05"s + x; +} + +std::string CustomMessage::POINTS(std::string x) { + return "\x1E"s + x; } -const std::string CustomMessage::WAIT_FOR_INPUT() const { +std::string CustomMessage::WAIT_FOR_INPUT() { return "\x04"s; } -const std::string CustomMessage::PLAYER_NAME() const { +std::string CustomMessage::PLAYER_NAME() { return "\x0F"s; } @@ -225,11 +598,10 @@ bool CustomMessageManager::CreateGetItemMessage(std::string tableID, uint16_t gi } bool CustomMessageManager::CreateMessage(std::string tableID, uint16_t textID, CustomMessage messageEntry) { - messageEntry.Format(); return InsertCustomMessage(tableID, textID, messageEntry); } -CustomMessage CustomMessageManager::RetrieveMessage(std::string tableID, uint16_t textID) { +CustomMessage CustomMessageManager::RetrieveMessage(std::string tableID, uint16_t textID, MessageFormat format) { std::unordered_map::const_iterator foundMessageTable = messageTables.find(tableID); if (foundMessageTable == messageTables.end()) { throw(MessageNotFoundException(tableID, textID)); @@ -240,6 +612,15 @@ CustomMessage CustomMessageManager::RetrieveMessage(std::string tableID, uint16_ throw(MessageNotFoundException(tableID, textID)); } CustomMessage message = foundMessage->second; + + if (format == MF_FORMATTED){ + message.Format(); + } else if (format == MF_AUTO_FORMAT){ + message.AutoFormat(); + } else if (format == MF_CLEAN){ + message.Clean(); + } + return message; } diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.h b/soh/soh/Enhancements/custom-message/CustomMessageManager.h index afb0f51ae74..31455aa40f2 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.h @@ -1,22 +1,33 @@ #pragma once -#include #include #include #include +#include +#include #include "../../../include/z64item.h" #include "../../../include/message_data_textbox_types.h" +#include "../randomizer/3drando/text.hpp" #undef MESSAGE_END -#define QM_WHITE 0x00 -#define QM_RED 0x41 -#define QM_GREEN 0x42 -#define QM_BLUE 0x43 -#define QM_LBLUE 0x44 -#define QM_PINK 0x45 -#define QM_YELLOW 0x46 -#define QM_BLACK 0x47 +#define QM_WHITE "\x00"s +#define QM_RED "\x41" +#define QM_GREEN "\x42" +#define QM_BLUE "\x43" +#define QM_LBLUE "\x44" +#define QM_PINK "\x45" +#define QM_YELLOW "\x46" +#define QM_BLACK "\x47" + +#define HS_HORSE_ARCHERY "\x00"s //HS_HBA is an enum already + +typedef enum { + MF_FORMATTED, + MF_CLEAN, + MF_RAW, + MF_AUTO_FORMAT +} MessageFormat; /** * @brief Encapsulates logic surrounding languages, and formatting strings for OoT's textboxes and @@ -29,17 +40,41 @@ class CustomMessage { CustomMessage() = default; CustomMessage(std::string english_, std::string german_, std::string french_, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); + CustomMessage(std::string english_, std::string german_, std::string french_, std::vector colors_, std::vector capital_ = {}, + TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); + CustomMessage(std::string english_, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); + CustomMessage(std::string english_, std::vector colors_, std::vector capital_ = {}, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); + CustomMessage(Text text, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); - const std::string& GetEnglish() const; - const std::string& GetFrench() const; - const std::string& GetGerman() const; + static std::string MESSAGE_END() ; + static std::string ITEM_OBTAINED(uint8_t x) ; + static std::string NEWLINE() ; + static std::string COLOR(std::string x) ; + static std::string POINTS(std::string x) ;//HIGH_SCORE is also a macro + static std::string WAIT_FOR_INPUT() ; + static std::string PLAYER_NAME() ; + + const std::string GetEnglish(MessageFormat format = MF_FORMATTED) const; + const std::string GetFrench(MessageFormat format = MF_FORMATTED) const; + const std::string GetGerman(MessageFormat format = MF_FORMATTED) const; + const std::string GetForCurrentLanguage(MessageFormat format = MF_FORMATTED) const; + const std::string GetForLanguage(uint8_t language, MessageFormat format = MF_FORMATTED) const; + const std::vector GetAllMessages(MessageFormat format = MF_FORMATTED) const; + void ProcessMessageFormat(std::string& str, MessageFormat format) const; + const std::vector& GetColors() const; + void SetColors(std::vector colors_); + const std::vector& GetCapital() const; + void SetCapital(std::vector capital_); const TextBoxType& GetTextBoxType() const; + void SetTextBoxType(TextBoxType boxType); const TextBoxPosition& GetTextBoxPosition() const; CustomMessage operator+(const CustomMessage& right) const; CustomMessage operator+(const std::string& right) const; void operator+=(const std::string& right); - bool operator==(const CustomMessage& right) const; + void operator+=(const CustomMessage& right); + bool operator==(const CustomMessage& operand) const; + bool operator==(const std::string& operand) const; bool operator!=(const CustomMessage& right) const; /** @@ -54,15 +89,13 @@ class CustomMessage { /** * @brief Finds an instance of oldStr in each language of the CustomMessage, - * and replaces it with the corresponding new string provided for each language. + * and replaces it with the corresponding string in the provided CustomMessage. * Typically used for dynamic variable replacement (i.e. gameplay stats, skulltula count) * * @param oldStr the string to be replaced - * @param newEnglish the new string for the English message - * @param newGerman the new string for the German message - * @param newFrench the new string for the French message + * @param newMessage the message containing the new strings. */ - void Replace(std::string&& oldStr, std::string&& newEnglish, std::string&& newGerman, std::string&& newFrench); + void Replace(std::string&& oldStr, CustomMessage newMessage); /** * @brief Capitalizes the first letter of the string for each language. @@ -73,12 +106,22 @@ class CustomMessage { * @brief Replaces special characters (things like diacritics for non-english langugages) * with the control codes used to display them in OoT's textboxes. */ - void ReplaceSpecialCharacters(); + void ReplaceSpecialCharacters(std::string& str) const; /** * @brief Replaces our color variable strings with the OoT control codes. */ - void ReplaceColors(); + void ReplaceColors(std::string& str) const; + + /** + * @brief Replaces `$` variable strings with OoT control codes. + */ + void ReplaceAltarIcons(std::string& str) const; + + /** + * @brief Replaces [[1]] style variable strings with the provided vector of customMessages + */ + void InsertNames(std::vector toInsert); /** * @brief Replaces various symbols with the control codes necessary to @@ -89,6 +132,15 @@ class CustomMessage { */ void Format(ItemID iid); + /** + * @brief Replaces [[d]] in text with the supplied number, and if plural + * options exist (2 blocks of text surrounded by |) choose the former if it 1, + * and the latter otherwise, deleting the other and the |'s. + * + * @param num the number to insert. + */ + void InsertNumber(uint8_t num); + /** * @brief Replaces various symbols with the control codes necessary to * display them in OoT's textboxes. i.e. special characters, colors, newlines, @@ -96,19 +148,44 @@ class CustomMessage { */ void Format(); + /** + * @brief formats the message specifically to fit in OoT's + * textboxes, and use it's formatting. + */ + void AutoFormat(); + + /** + * @brief Removes all OoT formatting from the message, + * making it a good form for writing into spoiler logs. + */ + void Clean(); + + /** + * @brief Replaces various symbols with the control codes necessary to + * display them in OoT's textboxes for a single string + * . i.e. special characters, colors, newlines, wait for input, etc. + */ + void FormatString(std::string& str) const; + + /** + * @brief formats the string specifically to fit in OoT's + * textboxes, and use it's formatting. + * RANDOTODO whoever knows exactly what this does check my adaption + */ + void AutoFormatString(std::string& str) const; + + /** + * @brief Removes symbols used for control codes from the string, + * leaving raw text + */ + void CleanString(std::string& str) const; + private: - const std::string MESSAGE_END() const; - const std::string ITEM_OBTAINED(uint8_t x) const; - const std::string NEWLINE() const; - const std::string COLOR(uint8_t x) const; - const std::string WAIT_FOR_INPUT() const; - const std::string PLAYER_NAME() const; - - std::string english = ""; - std::string french = ""; - std::string german = ""; + std::vector messages = {"","",""}; TextBoxType type = TEXTBOX_TYPE_BLACK; TextBoxPosition position = TEXTBOX_POS_BOTTOM; + std::vector colors = {}; + std::vector capital = {}; }; typedef std::unordered_map CustomMessageTable; @@ -165,9 +242,10 @@ class CustomMessageManager { * * @param tableID the ID of the custom message table * @param textID the ID of the message you want to retrieve + * @param format the type of formatting to apply to the retrieved message * @return CustomMessage */ - CustomMessage RetrieveMessage(std::string tableID, uint16_t textID); + CustomMessage RetrieveMessage(std::string tableID, uint16_t textID, MessageFormat format = MF_RAW); /** * @brief Empties out the message table identified by tableID. diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 9e0d7ec0dda..4a039987ed4 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -1,61 +1,131 @@ #pragma once +#include "z64.h" +#include "../include/macros.h" + typedef enum { - TEXT_CURSED_SKULLTULA_PEOPLE = 0x22, - TEXT_SARIAS_SONG_FACE_TO_FACE= 0x160, - TEXT_SARIAS_SONG_TEXT_START = 0x160, - TEXT_SARIAS_SONG_TEXT_END = 0x16D, - TEXT_SARIA_SFM = 0x10AD, - TEXT_ITEM_KEY_SMALL = 0x60, - TEXT_ITEM_DUNGEON_MAP = 0x66, - TEXT_ITEM_COMPASS = 0x67, - TEXT_ITEM_KEY_BOSS = 0xC7, - TEXT_DAMPES_DIARY = 0x5003, - TEXT_CHEST_GAME_PROCEED = 0x704C, - TEXT_BUY_BOMBCHU_10_PROMPT = 0x8C, - TEXT_BUY_BOMBCHU_10_DESC = 0xBC, - TEXT_GS_NO_FREEZE = 0xB4, - TEXT_GS_FREEZE = 0xB5, - TEXT_RANDOMIZER_CUSTOM_ITEM = 0xF8, + TEXT_NONE = 0x000, + TEXT_SKULLTULA_PEOPLE_CURSE_BROKEN = 0x0021, + TEXT_SKULLTULA_PEOPLE_IM_CURSED = 0x0022, + TEXT_SKULLTULA_PEOPLE_WELL_BE_CAREFUL = 0x0023, + TEXT_SKULLTULA_PEOPLE_STARTING_TO_WEAKEN = 0x0024, + TEXT_SKULLTULA_PEOPLE_WE_LOOK_LIKE_THIS = 0x0025, + TEXT_SKULLTULA_PEOPLE_GS_TUTORIAL = 0x0026, + TEXT_SKULLTULA_PEOPLE_MAKE_YOU_VERY_RICH = 0x0027, + TEXT_SKULLTULA_PEOPLE_CURSE_HAS_BEEN_BROKEN = 0x0028, + TEXT_SKULLTULA_PEOPLE_SAVING_MY_KIDS = 0x0029, + TEXT_ITEM_KEY_SMALL = 0x0060, + TEXT_ITEM_DUNGEON_MAP = 0x0066, + TEXT_CHEST_GAME_REAL_GAMBLER = 0x006E, + TEXT_ITEM_COMPASS = 0x0067, + TEXT_CHEST_GAME_THANKS_A_LOT = 0x0084, + TEXT_BUY_BOMBCHUS_10_PROMPT = 0x008C, + TEXT_GS_NO_FREEZE = 0x00B4, + TEXT_GS_FREEZE = 0x00B5, + TEXT_BUY_BOMBCHUS_10_DESC = 0x00BC, + TEXT_HEART_PIECE = 0x00C2, + TEXT_HEART_CONTAINER = 0x00C6, + TEXT_ITEM_KEY_BOSS = 0x00C7, + TEXT_BLUE_RUPEE = 0x00CC, + TEXT_RED_RUPEE = 0x00F0, + TEXT_PURPLE_RUPEE = 0x00F1, + TEXT_HUGE_RUPEE = 0x00F2, + TEXT_RANDOMIZER_CUSTOM_ITEM = 0x00F8, + TEXT_NAVI_DEKU_TREE_SUMMONS = 0x0140, + TEXT_NAVI_CMON_BE_BRAVE = 0x0141, + TEXT_NAVI_VISIT_THE_PRINCESS = 0x0142, + TEXT_NAVI_FIND_MALONS_FATHER = 0x0143, + TEXT_NAVI_FIND_THE_PRINCESS = 0x0144, + TEXT_NAVI_WHAT_WOULD_SARIA_SAY = 0x0145, + TEXT_NAVI_IMPA_SAID_DEATH_MOUNTAIN = 0x0146, + TEXT_NAVI_USE_BOMB_FLOWER = 0x0147, + TEXT_NAVI_FAIRY_LIVES_ON_DEATH_MOUNTAIN = 0x0148, + TEXT_NAVI_SARIA_KNOWS_ABOUT_STONES = 0x0149, + TEXT_NAVI_RUTO_INSIDE_JABUS_BELLY = 0x014A, + TEXT_NAVI_COLLECTED_THREE_STONES = 0x014B, + TEXT_NAVI_THREW_SOMETHING_IN_MOAT = 0x014C, + TEXT_NAVI_CHECK_TEMPLE_OF_TIME = 0x014D, + TEXT_NAVI_SHOULD_WE_BELIEVE_SHEIK = 0x014E, + TEXT_UNUSED_014F = 0x014F, + TEXT_NAVI_WHATS_GOING_ON_IN_FOREST = 0x0150, + TEXT_NAVI_CLOUD_OVER_DEATH_MOUNTAIN = 0x0151, + TEXT_NAVI_ARTIC_WIND_IS_BLOWING = 0x0152, + TEXT_NAVI_IRON_BOOTS_WEIGH_A_TON = 0x0153, + TEXT_NAVI_LOOK_FOR_SOMONE_WHO_KNOWS = 0x0154, + TEXT_NAVI_IT_CAME_OUT_OF_THE_WELL = 0x0155, + TEXT_NAVI_WHO_BUILT_THE_SPIRIT_TEMPLE = 0x0156, + TEXT_NAVI_HAVE_YOU_EVER_PLAYED_NOCTURNE = 0x0157, + TEXT_NAVI_WHERE_GANONDORF_WAS_BORN = 0x0158, + TEXT_UNUSED_0159 = 0x0159, + TEXT_NAVI_EQUIP_THE_SILVER_GAUNTLETS = 0x015A, + TEXT_NAVI_WHO_IS_WAITING_FOR_US = 0x015B, + TEXT_NAVI_SAVE_PRINCESS_ZELDA = 0x015C, + TEXT_UNUSED_015D = 0x015D, + TEXT_UNUSED_015E = 0x015E, + TEXT_NAVI_TRY_TO_KEEP_MOVING = 0x015F, + TEXT_SARIAS_SONG_FACE_TO_FACE = 0x0160, + TEXT_SARIAS_SONG_FOREST_SOUNDS = 0x0161, + TEXT_SARIAS_SONG_MR_DARUNIA = 0x0162, + TEXT_SARIAS_SONG_SPIRITUAL_WATER = 0x0163, + TEXT_SARIAS_SONG_SPIRITUAL_FIRE = 0x0164, + TEXT_SARIAS_SONG_DREAD_CASTLE = 0x0165, + TEXT_SARIAS_SONG_DIFFERENT_OCARINA = 0x0166, + TEXT_SARIAS_SONG_EYES_DARKNESS_STORM = 0x0167, + TEXT_SARIAS_SONG_DESERT_GODDESS = 0x0168, + TEXT_SARIAS_SONG_TEMPLES = 0x0169, + TEXT_SARIAS_SONG_FOREST_TEMPLE = 0x016A, + TEXT_SARIAS_SONG_GLAD_NOW = 0x016B, + TEXT_SARIAS_SONG_IMPRISON_GANONDORF = 0x016C, + TEXT_SARIAS_SONG_CHANNELING_POWER = 0x016D, + TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI = 0x01B3, // 0x1yy for Navi msg range + TEXT_MASK_SHOP_SIGN = 0x0207, + TEXT_FROGS_UNDERWATER = 0x022E, + TEXT_GF_HBA_SIGN = 0x031A, + TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN = 0x0346, // 0x3yy for cuttable sign range + TEXT_WARP_MINUET_OF_FOREST = 0x088D, + TEXT_WARP_BOLERO_OF_FIRE = 0x088E, + TEXT_WARP_SERENADE_OF_WATER = 0x088F, + TEXT_WARP_REQUIEM_OF_SPIRIT = 0x0890, + TEXT_WARP_NOCTURNE_OF_SHADOW = 0x0891, + TEXT_WARP_PRELUDE_OF_LIGHT = 0x0892, TEXT_SCRUB_POH = 0x10A2, + TEXT_SARIA_SFM = 0x10AD, TEXT_SCRUB_STICK_UPGRADE = 0x10DC, TEXT_SCRUB_NUT_UPGRADE = 0x10DD, + TEXT_MALON_FIRST_TALK_AFTER_RESCUE = 0x2000, // RANDOTODO SKIP IN RANDO + TEXT_MALON_HOW_IS_EPONA_DOING = 0x2001, + TEXT_MALON_EPONA_LOOKS_GREAT = 0x2002, + TEXT_MALON_OBSTICLE_COURSE = 0x2003, + TEXT_MALON_EVERYONE_TURNING_EVIL = 0x204C, + TEXT_MALON_I_SING_THIS_SONG = 0x2050, + TEXT_MALON_EVERYONE_LIKED_SONG = 0x2051, + TEXT_MALON_EPONA_LIKED_SONG = 0x2052, TEXT_RANDOMIZER_GOSSIP_STONE_HINTS = 0x2053, - TEXT_ALTAR_CHILD = 0x7040, - TEXT_ALTAR_ADULT = 0x7088, - TEXT_GANONDORF = 0x70CC, - TEXT_GANONDORF_NOHINT = 0x70CD, - TEXT_HEART_CONTAINER = 0xC6, - TEXT_HEART_PIECE = 0xC2, - TEXT_BLUE_RUPEE = 0xCC, - TEXT_RED_RUPEE = 0xF0, - TEXT_PURPLE_RUPEE = 0xF1, - TEXT_HUGE_RUPEE = 0xF2, - TEXT_FROGS_UNDERWATER = 0x22E, - TEXT_BEAN_SALESMAN = 0x405E, + TEXT_MALON_INGO_MUST_HAVE_BEEN_TEMPTED = 0x2056, + TEXT_MALON_LINK_HAS_TIME_BUT_NO_RECORD = 0x2090, + TEXT_MALON_LINK_HAS_RECORD = 0x2091, + TEXT_MALON_FIRST_BEAT_THIS_RECORD = 0x2092, + TEXT_BIGGORON_I_MAAAADE_THISSSS = 0x3002, TEXT_MEDIGORON = 0x304C, - TEXT_GRANNYS_SHOP = 0x500C, - TEXT_CARPET_SALESMAN_1 = 0x6077, - TEXT_CARPET_SALESMAN_2 = 0x6078, - TEXT_MARKET_GUARD_NIGHT = 0x7003, - TEXT_FISHERMAN_LEAVE = 0x409E, - TEXT_SHEIK_NEED_HOOK = 0x700F, - TEXT_SHEIK_HAVE_HOOK = 0x7010, - TEXT_SCRUB_RANDOM = 0x9000, - TEXT_SCRUB_RANDOM_FREE = 0x9001, - TEXT_SHOP_ITEM_RANDOM = 0x9100, - TEXT_SHOP_ITEM_RANDOM_CONFIRM = 0x9101, - TEXT_WARP_MINUET_OF_FOREST = 0x88D, - TEXT_WARP_BOLERO_OF_FIRE = 0x88E, - TEXT_WARP_SERENADE_OF_WATER = 0x88F, - TEXT_WARP_REQUIEM_OF_SPIRIT = 0x890, - TEXT_WARP_NOCTURNE_OF_SHADOW = 0x891, - TEXT_WARP_PRELUDE_OF_LIGHT = 0x892, - TEXT_WARP_RANDOM_REPLACED_TEXT = 0x9200, - TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW = 0x9210, - TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN = 0x346, // 0x3yy for cuttable sign range - TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI = 0x1B3, // 0x1yy for Navi msg range - TEXT_SARIAS_SONG_CHANNELING_POWER = 0x016D, + TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME = 0x3052, + TEXT_BIGGORON_BETTER_AT_SMITHING = 0x3053, + TEXT_BIGGORON_BROKEN_KNIFE = 0x3054, + TEXT_BIGGORON_GET_THE_EYEDROPS = 0x3055, + TEXT_BIGGORON_IM_FINISHED_EYES_ITCHY = 0x3056, + TEXT_BIGGORON_WAITING_FOR_YOU = 0x3058, + TEXT_BIGGORON_BROUGHT_THE_EYE_DROPS = 0x3059, + TEXT_BIGGORON_THIS_IS_STIMULATING = 0x305A, + TEXT_BIGGORON_RETURN_AFTER_A_FEW_DAYS = 0x305C, + TEXT_BIGGORON_YOU_ARE_IMPATIENT = 0x305D, + TEXT_BIGGORON_MY_FINEST_WORK = 0x305E, + TEXT_FIRE_TEMPLE_GORON_FALLING_DOORS_SECRET = 0x3069, + TEXT_FIRE_TEMPLE_GORON_FIRE_SECRET = 0x306A, + TEXT_FIRE_TEMPLE_GORON_FLAME_DANCER_SECRET = 0x306B, + TEXT_FIRE_TEMPLE_GORON_SWITCH_SECRET = 0x306C, + TEXT_FIRE_TEMPLE_GORON_OCARINA_SECRET = 0x306D, + TEXT_FIRE_TEMPLE_GORON_PILLAR_SECRET = 0x306E, + TEXT_FIRE_TEMPLE_GORON_HIDDEN_DOOR_SECRET = 0x306F, + TEXT_FIRE_TEMPLE_GORON_SOUNDS_DIFFERENT_SECRET = 0x3070, TEXT_BEAN_SALESMAN_BUY_FOR_10 = 0x405E, TEXT_BEAN_SALESMAN_BUY_FOR_20 = 0x405F, TEXT_BEAN_SALESMAN_BUY_FOR_30 = 0x4060, @@ -71,12 +141,63 @@ typedef enum { TEXT_BEAN_SALESMAN_SET_A_BEAN_TO_C = 0x406A, TEXT_BEAN_SALESMAN_SOLD_OUT = 0x406B, TEXT_BEAN_SALESMAN_WANT_TO_PLANT = 0x406C, + TEXT_FISHING_POND_START = 0x407B, + TEXT_FISHING_TALK_ABOUT_SOMETHING = 0x4088, + TEXT_FISHING_TRY_ANOTHER_LURE = 0x408D, + TEXT_FISHING_SECRETS = 0x408E, + TEXT_FISHING_GOOD_FISHERMAN = 0x408F, + TEXT_FISHING_POND_START_MET = 0x4093, + TEXT_FISHING_DIFFERENT_POND = 0x4094, + TEXT_FISHING_SCRATCHING = 0x4095, + TEXT_FISHING_CLOUDY = 0x4096, + TEXT_FISHING_RELEASE_THIS_ONE = 0x409C, + TEXT_FISHING_TRY_ANOTHER_LURE_WITH_SINKING_LURE = 0x40AF, + TEXT_DAMPES_DIARY = 0x5003, + TEXT_GRANNYS_SHOP = 0x500C, + TEXT_ANJU_PLEASE_BRING_MY_CUCCOS_BACK = 0x5036, + TEXT_ANJU_PLEASE_BRING_4_CUCCOS = 0x5037, + TEXT_ANJU_PLEASE_BRING_3_CUCCOS = 0x5038, + TEXT_ANJU_PLEASE_BRING_2_CUCCOS = 0x5039, + TEXT_ANJU_PLEASE_BRING_1_CUCCO = 0x503A, + TEXT_ANJU_THANKS_FOR_FINDING_MY_CUCCOS = 0x503B, + TEXT_ANJU_ROUND_THEM_UP_OR_YOULL_PAY = 0x503C, + TEXT_ANJU_DONT_TEASE_MY_CUCCOS = 0x503D, + TEXT_HBA_NOT_ON_HORSE = 0x603F, + TEXT_HBA_INITIAL_EXPLAINATION = 0x6040, + TEXT_HBA_WANT_TO_TRY_AGAIN_YES_NO = 0x6041, + TEXT_HBA_ALREADY_HAVE_1000 = 0x6042, + TEXT_CARPET_SALESMAN_CUSTOM_FAIL_TO_BUY = 0x6073, + TEXT_CARPET_SALESMAN_1 = 0x6077, + TEXT_CARPET_SALESMAN_2 = 0x6078, + TEXT_MARKET_GUARD_NIGHT = 0x7003, + TEXT_FISHERMAN_LEAVE = 0x409E, + TEXT_SHEIK_NEED_HOOK = 0x700F, + TEXT_SHEIK_HAVE_HOOK = 0x7010, + TEXT_ALTAR_CHILD = 0x7040, + TEXT_CHEST_GAME_PROCEED = 0x704C, + TEXT_GHOST_SHOP_EXPLAINATION = 0x70F4, + TEXT_GHOST_SHOP_CARD_HAS_POINTS = 0x70F5, + TEXT_GHOST_SHOP_BUY_NORMAL_POE = 0x70F6, + TEXT_GHOST_SHOP_BUY_BIG_POE = 0x70F7, + TEXT_GHOST_SHOP_1000_POINTS = 0x70F8, + TEXT_ALTAR_ADULT = 0x7088, + TEXT_GANONDORF = 0x70CC, + TEXT_GANONDORF_NOHINT = 0x70CD, + TEXT_SCRUB_RANDOM = 0x9000, + TEXT_SCRUB_RANDOM_FREE = 0x9001, + TEXT_SHOP_ITEM_RANDOM = 0x9100, + TEXT_SHOP_ITEM_RANDOM_CONFIRM = 0x9100 + NUM_SHOP_ITEMS, + TEXT_SHOP_ITEM_RANDOM_CONFIRM_END = 0x9100 + (NUM_SHOP_ITEMS * 2) - 1, + TEXT_WARP_RANDOM_REPLACED_TEXT = 0x9200, + TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW = 0x9210, + TEXT_CARPET_SALESMAN_MYSTERIOUS = 0x9211, + TEXT_CARPET_SALESMAN_ARMS_DEALER = 0x9212, } TextIDs; #ifdef __cplusplus typedef struct { - u16 giid; + uint16_t giid; ItemID iid; std::string english; std::string german; diff --git a/soh/soh/Enhancements/debugger/MessageViewer.cpp b/soh/soh/Enhancements/debugger/MessageViewer.cpp index 46c596e9c37..5b23c1876e5 100644 --- a/soh/soh/Enhancements/debugger/MessageViewer.cpp +++ b/soh/soh/Enhancements/debugger/MessageViewer.cpp @@ -198,16 +198,7 @@ void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t lan const CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(tableId, textId); font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition(); switch (language) { - case LANGUAGE_FRA: - font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetFrench(), maxBufferSize); - break; - case LANGUAGE_GER: - font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetGerman(), maxBufferSize); - break; - case LANGUAGE_ENG: - default: - font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetEnglish(), maxBufferSize); - break; + font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetForLanguage(language), maxBufferSize); } msgCtx->msgLength = static_cast(font->msgLength); } diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index a29174331a9..930515ab6ae 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1123,6 +1123,36 @@ void DrawFlagsTab() { } }); } + + // make some buttons to help with fishsanity debugging + uint8_t fsMode = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY); + if (flagTable.flagTableType == RANDOMIZER_INF && + fsMode != RO_FISHSANITY_OFF && fsMode != RO_FISHSANITY_OVERWORLD) { + if (ImGui::Button("Catch All (Child)")) { + for (int k = RAND_INF_CHILD_FISH_1; k <= RAND_INF_CHILD_LOACH_2; k++) { + Flags_SetRandomizerInf((RandomizerInf)k); + } + } + ImGui::SameLine(); + if (ImGui::Button("Uncatch All (Child)")) { + for (int k = RAND_INF_CHILD_FISH_1; k <= RAND_INF_CHILD_LOACH_2; k++) { + Flags_UnsetRandomizerInf((RandomizerInf)k); + } + } + + if (ImGui::Button("Catch All (Adult)")) { + for (int k = RAND_INF_ADULT_FISH_1; k <= RAND_INF_ADULT_LOACH; k++) { + Flags_SetRandomizerInf((RandomizerInf)k); + } + } + ImGui::SameLine(); + if (ImGui::Button("Uncatch All (Adult)")) { + for (int k = RAND_INF_ADULT_FISH_1; k <= RAND_INF_ADULT_LOACH; k++) { + Flags_UnsetRandomizerInf((RandomizerInf)k); + } + } + } + ImGui::TreePop(); } } @@ -1290,7 +1320,7 @@ void DrawEquipmentTab() { "Giant (500)", }; // only display Tycoon wallet if you're in a save file that would allow it. - if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) > RO_SHOPSANITY_ZERO_ITEMS) { + if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET)) { const std::string walletName = "Tycoon (999)"; walletNamesImpl.push_back(walletName); } diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 1de852e3560..c3e01b657cd 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -348,23 +348,10 @@ const std::vector flagTables = { { 0x24, "Market Crowd Text Randomizer" }, { 0x30, "Entered the Market" }, } }, - { "Randomizer Inf Flags", RANDOMIZER_INF, 0x09, { - { RAND_INF_DUNGEONS_DONE_DEKU_TREE, "DUNGEONS_DONE_DEKU_TREE" }, - { RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN, "DUNGEONS_DONE_DODONGOS_CAVERN" }, - { RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY, "DUNGEONS_DONE_JABU_JABUS_BELLY" }, - { RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE, "DUNGEONS_DONE_FOREST_TEMPLE" }, - { RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE, "DUNGEONS_DONE_FIRE_TEMPLE" }, - { RAND_INF_DUNGEONS_DONE_WATER_TEMPLE, "DUNGEONS_DONE_WATER_TEMPLE" }, + { "Randomizer Inf Flags", RANDOMIZER_INF, 16, { { RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" }, { RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" }, - { RAND_INF_TRIALS_DONE_LIGHT_TRIAL, "TRIALS_DONE_LIGHT_TRIAL" }, - { RAND_INF_TRIALS_DONE_FOREST_TRIAL, "TRIALS_DONE_FOREST_TRIAL" }, - { RAND_INF_TRIALS_DONE_FIRE_TRIAL, "TRIALS_DONE_FIRE_TRIAL" }, - { RAND_INF_TRIALS_DONE_WATER_TRIAL, "TRIALS_DONE_WATER_TRIAL" }, - { RAND_INF_TRIALS_DONE_SPIRIT_TRIAL, "TRIALS_DONE_SPIRIT_TRIAL" }, - { RAND_INF_TRIALS_DONE_SHADOW_TRIAL, "TRIALS_DONE_SHADOW_TRIAL" }, - { RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW, "COWS_MILKED_KF_LINKS_HOUSE_COW" }, { RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, "COWS_MILKED_HF_COW_GROTTO_COW" }, { RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, "COWS_MILKED_LLR_STABLES_LEFT_COW" }, @@ -487,7 +474,7 @@ const std::vector flagTables = { { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6" }, { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7" }, { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8" }, - + { RAND_INF_MERCHANTS_CARPET_SALESMAN, "RAND_INF_MERCHANTS_CARPET_SALESMAN" }, { RAND_INF_MERCHANTS_MEDIGORON, "RAND_INF_MERCHANTS_MEDIGORON" }, { RAND_INF_MERCHANTS_GRANNYS_SHOP, "RAND_INF_MERCHANTS_GRANNY_SHOP"}, @@ -506,6 +493,133 @@ const std::vector flagTables = { { RAND_INF_ADULT_FISHING, "RAND_INF_ADULT_FISHING" }, { RAND_INF_10_BIG_POES, "RAND_INF_10_BIG_POES" }, { RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" }, + + { RAND_INF_GOHMA_SOUL, "RAND_INF_GOHMA_SOUL" }, + { RAND_INF_KING_DODONGO_SOUL, "RAND_INF_KING_DODONGO_SOUL" }, + { RAND_INF_BARINADE_SOUL, "RAND_INF_BARINADE_SOUL" }, + { RAND_INF_PHANTOM_GANON_SOUL, "RAND_INF_PHANTOM_GANON_SOUL" }, + { RAND_INF_VOLVAGIA_SOUL, "RAND_INF_VOLVAGIA_SOUL" }, + { RAND_INF_MORPHA_SOUL, "RAND_INF_MORPHA_SOUL" }, + { RAND_INF_BONGO_BONGO_SOUL, "RAND_INF_BONGO_BONGO_SOUL" }, + { RAND_INF_TWINROVA_SOUL, "RAND_INF_TWINROVA_SOUL" }, + { RAND_INF_GANON_SOUL, "RAND_INF_GANON_SOUL" }, + + { RAND_INF_HAS_OCARINA_A, "RAND_INF_HAS_OCARINA_A"}, + { RAND_INF_HAS_OCARINA_C_UP, "RAND_INF_HAS_OCARINA_C_UP" }, + { RAND_INF_HAS_OCARINA_C_DOWN, "RAND_INF_HAS_OCARINA_C_DOWN" }, + { RAND_INF_HAS_OCARINA_C_LEFT, "RAND_INF_HAS_OCARINA_C_LEFT"}, + { RAND_INF_HAS_OCARINA_C_RIGHT, "RAND_INF_HAS_OCARINA_C_RIGHT"}, + + { RAND_INF_CAUGHT_LOACH, "RAND_INF_CAUGHT_LOACH" }, + + { RAND_INF_CAN_SWIM, "RAND_INF_CAN_SWIM" }, + + { RAND_INF_HAS_WALLET, "RAND_INF_HAS_WALLET" }, + + { RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT, "RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT, "RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO, "RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO" }, + { RAND_INF_BEEHIVE_SFM_STORMS_GROTTO, "RAND_INF_BEEHIVE_SFM_STORMS_GROTTO" }, + { RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO, "RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO" }, + { RAND_INF_BEEHIVE_LLR_GROTTO, "RAND_INF_BEEHIVE_LLR_GROTTO" }, + { RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_DMT_COW_GROTTO, "RAND_INF_BEEHIVE_DMT_COW_GROTTO" }, + { RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT, "RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_GC_GROTTO, "RAND_INF_BEEHIVE_GC_GROTTO" }, + { RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT, "RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT, "RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO, "RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO" }, + { RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_ZR_STORMS_GROTTO, "RAND_INF_BEEHIVE_ZR_STORMS_GROTTO" }, + { RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT, "RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT" }, + { RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT, "RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT" }, + { RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA, "RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA" }, + { RAND_INF_BEEHIVE_LH_GROTTO, "RAND_INF_BEEHIVE_LH_GROTTO" }, + { RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO, "RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO" }, + { RAND_INF_BEEHIVE_COLOSSUS_GROTTO, "RAND_INF_BEEHIVE_COLOSSUS_GROTTO" }, + + { RAND_INF_CHILD_FISH_1, "RAND_INF_CHILD_FISH_1" }, + { RAND_INF_CHILD_FISH_2, "RAND_INF_CHILD_FISH_2" }, + { RAND_INF_CHILD_FISH_3, "RAND_INF_CHILD_FISH_3" }, + { RAND_INF_CHILD_FISH_4, "RAND_INF_CHILD_FISH_4" }, + { RAND_INF_CHILD_FISH_5, "RAND_INF_CHILD_FISH_5" }, + { RAND_INF_CHILD_FISH_6, "RAND_INF_CHILD_FISH_6" }, + { RAND_INF_CHILD_FISH_7, "RAND_INF_CHILD_FISH_7" }, + { RAND_INF_CHILD_FISH_8, "RAND_INF_CHILD_FISH_8" }, + { RAND_INF_CHILD_FISH_9, "RAND_INF_CHILD_FISH_9" }, + { RAND_INF_CHILD_FISH_10, "RAND_INF_CHILD_FISH_10" }, + { RAND_INF_CHILD_FISH_11, "RAND_INF_CHILD_FISH_11" }, + { RAND_INF_CHILD_FISH_12, "RAND_INF_CHILD_FISH_12" }, + { RAND_INF_CHILD_FISH_13, "RAND_INF_CHILD_FISH_13" }, + { RAND_INF_CHILD_FISH_14, "RAND_INF_CHILD_FISH_14" }, + { RAND_INF_CHILD_FISH_15, "RAND_INF_CHILD_FISH_15" }, + { RAND_INF_CHILD_LOACH_1, "RAND_INF_CHILD_LOACH_1" }, + { RAND_INF_CHILD_LOACH_2, "RAND_INF_CHILD_LOACH_2" }, + { RAND_INF_ADULT_FISH_1, "RAND_INF_ADULT_FISH_1" }, + { RAND_INF_ADULT_FISH_2, "RAND_INF_ADULT_FISH_2" }, + { RAND_INF_ADULT_FISH_3, "RAND_INF_ADULT_FISH_3" }, + { RAND_INF_ADULT_FISH_4, "RAND_INF_ADULT_FISH_4" }, + { RAND_INF_ADULT_FISH_5, "RAND_INF_ADULT_FISH_5" }, + { RAND_INF_ADULT_FISH_6, "RAND_INF_ADULT_FISH_6" }, + { RAND_INF_ADULT_FISH_7, "RAND_INF_ADULT_FISH_7" }, + { RAND_INF_ADULT_FISH_8, "RAND_INF_ADULT_FISH_8" }, + { RAND_INF_ADULT_FISH_9, "RAND_INF_ADULT_FISH_9" }, + { RAND_INF_ADULT_FISH_10, "RAND_INF_ADULT_FISH_10" }, + { RAND_INF_ADULT_FISH_11, "RAND_INF_ADULT_FISH_11" }, + { RAND_INF_ADULT_FISH_12, "RAND_INF_ADULT_FISH_12" }, + { RAND_INF_ADULT_FISH_13, "RAND_INF_ADULT_FISH_13" }, + { RAND_INF_ADULT_FISH_14, "RAND_INF_ADULT_FISH_14" }, + { RAND_INF_ADULT_FISH_15, "RAND_INF_ADULT_FISH_15" }, + { RAND_INF_ADULT_LOACH, "RAND_INF_ADULT_LOACH" }, + { RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO, "RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO" }, + { RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO, "RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO" }, + { RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO, "RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO" }, + { RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO, "RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO" }, + { RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO, "RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO" }, + { RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO, "RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO" }, + { RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO, "RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO" }, + { RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO, "RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO" }, + { RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO, "RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO" }, + { RAND_INF_FISHING_POLE_FOUND, "RAND_INF_FISHING_POLE_FOUND" }, + { RAND_INF_ZD_FISH_1, "RAND_INF_ZD_FISH_1" }, + { RAND_INF_ZD_FISH_2, "RAND_INF_ZD_FISH_2" }, + { RAND_INF_ZD_FISH_3, "RAND_INF_ZD_FISH_3" }, + { RAND_INF_ZD_FISH_4, "RAND_INF_ZD_FISH_4" }, + { RAND_INF_ZD_FISH_5, "RAND_INF_ZD_FISH_5" }, + + { RAND_INF_HAS_INFINITE_QUIVER, "RAND_INF_HAS_INFINITE_QUIVER" }, + { RAND_INF_HAS_INFINITE_BOMB_BAG, "RAND_INF_HAS_INFINITE_BOMB_BAG" }, + { RAND_INF_HAS_INFINITE_BULLET_BAG, "RAND_INF_HAS_INFINITE_BULLET_BAG" }, + { RAND_INF_HAS_INFINITE_STICK_UPGRADE, "RAND_INF_HAS_INFINITE_STICK_UPGRADE" }, + { RAND_INF_HAS_INFINITE_NUT_UPGRADE, "RAND_INF_HAS_INFINITE_NUT_UPGRADE" }, + { RAND_INF_HAS_INFINITE_MAGIC_METER, "RAND_INF_HAS_INFINITE_MAGIC_METER" }, + { RAND_INF_HAS_INFINITE_BOMBCHUS, "RAND_INF_HAS_INFINITE_BOMBCHUS" }, + { RAND_INF_HAS_INFINITE_MONEY, "RAND_INF_HAS_INFINITE_MONEY" }, + + { RAND_INF_HAS_SKELETON_KEY, "RAND_INF_HAS_SKELETON_KEY" }, + + { RAND_INF_LINKS_POCKET, "RAND_INF_LINKS_POCKET" }, + { RAND_INF_LEARNED_EPONA_SONG, "RAND_INF_LEARNED_EPONA_SONG" }, + { RAND_INF_DARUNIAS_JOY, "RAND_INF_DARUNIAS_JOY" }, + { RAND_INF_KING_ZORA_THAWED, "RAND_INF_KING_ZORA_THAWED" }, + + { RAND_INF_HC_GREAT_FAIRY_REWARD, "RAND_INF_HC_GREAT_FAIRY_REWARD" }, + { RAND_INF_DMT_GREAT_FAIRY_REWARD, "RAND_INF_DMT_GREAT_FAIRY_REWARD" }, + { RAND_INF_DMC_GREAT_FAIRY_REWARD, "RAND_INF_DMC_GREAT_FAIRY_REWARD" }, + { RAND_INF_ZF_GREAT_FAIRY_REWARD, "RAND_INF_ZF_GREAT_FAIRY_REWARD" }, + { RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD, "RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD" }, + { RAND_INF_OGC_GREAT_FAIRY_REWARD, "RAND_INF_OGC_GREAT_FAIRY_REWARD" }, } }, }; diff --git a/soh/soh/Enhancements/debugger/hookDebugger.cpp b/soh/soh/Enhancements/debugger/hookDebugger.cpp new file mode 100644 index 00000000000..b31ddc3966f --- /dev/null +++ b/soh/soh/Enhancements/debugger/hookDebugger.cpp @@ -0,0 +1,111 @@ +#include "hookDebugger.h" +#include "../game-interactor/GameInteractor.h" +#include "../../UIWidgets.hpp" +#include +#include + +static std::unordered_map> hookData; + +const ImVec4 grey = ImVec4(0.75, 0.75, 0.75, 1); +const ImVec4 yellow = ImVec4(1, 1, 0, 1); +const ImVec4 red = ImVec4(1, 0, 0, 1); + +void DrawHookRegisteringInfos(const char* hookName) { + if (hookData[hookName].size() == 0) { + ImGui::TextColored(grey, "No hooks found"); + return; + } + + if (ImGui::BeginTable( + ("Table##" + std::string(hookName)).c_str(), + 4, + ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit + )) { + ImGui::TableSetupColumn("Id"); + ImGui::TableSetupColumn("Type"); + ImGui::TableSetupColumn("Registration Info"); + //ImGui::TableSetupColumn("Stub"); + ImGui::TableSetupColumn("Number of Calls"); + ImGui::TableHeadersRow(); + for (auto& [id, hookInfo] : hookData[hookName]) { + ImGui::TableNextRow(); + + ImGui::TableNextColumn(); + ImGui::Text("%d", id); + + ImGui::TableNextColumn(); + switch (hookInfo.registering.type) { + case HOOK_TYPE_NORMAL: + ImGui::Text("Normal"); + break; + case HOOK_TYPE_ID: + ImGui::Text("Id"); + break; + case HOOK_TYPE_PTR: + ImGui::Text("Ptr"); + break; + case HOOK_TYPE_FILTER: + ImGui::Text("Filter"); + break; + default: + ImGui::TextColored(red, "[UNKNOWN]"); + break; + } + + ImGui::TableNextColumn(); + if (hookInfo.registering.valid) { + ImGui::Text("%s(%d:%d) %s", hookInfo.registering.file, hookInfo.registering.line, hookInfo.registering.column, hookInfo.registering.function); + } else { + ImGui::TextColored(yellow, "[Unavaliable]"); + } + + //TODO: not currently possible + /* + ImGui::TableNextColumn(); + + ImGui::BeginDisabled(); + + bool stubButtonPressed = ImGui::Button(("Stub##" + std::to_string(id)).c_str()); + UIWidgets::SetLastItemHoverText("Stub this hook.\nThis is not possible to automatically undo."); + + if (stubButtonPressed) { + //stub + } + + ImGui::EndDisabled(); + */ + + ImGui::TableNextColumn(); + ImGui::Text("%d", hookInfo.calls); + } + ImGui::EndTable(); + } +} + +void HookDebuggerWindow::DrawElement() { +#ifndef __cpp_lib_source_location + ImGui::TextColored( + yellow, + "Some features of the Hook Debugger are unavaliable because SoH was compiled " + "without \"\" support " + "(\"__cpp_lib_source_location\" not defined in \"\")." + ); +#endif + + for (auto& [hookName, _] : hookData) { + if (ImGui::TreeNode(hookName)) { + DrawHookRegisteringInfos(hookName); + ImGui::TreePop(); + } + } +} + +void HookDebuggerWindow::UpdateElement() { + hookData.clear(); + + #define DEFINE_HOOK(name, _) hookData.insert({#name, GameInteractor::Instance->GetHookData()}); + + #include "../game-interactor/GameInteractor_HookTable.h" + + #undef DEFINE_HOOK +} \ No newline at end of file diff --git a/soh/soh/Enhancements/debugger/hookDebugger.h b/soh/soh/Enhancements/debugger/hookDebugger.h new file mode 100644 index 00000000000..90e6886b5ec --- /dev/null +++ b/soh/soh/Enhancements/debugger/hookDebugger.h @@ -0,0 +1,10 @@ +#include + +class HookDebuggerWindow : public Ship::GuiWindow { + public: + using GuiWindow::GuiWindow; + + void InitElement() override {}; + void DrawElement() override; + void UpdateElement() override; +}; diff --git a/soh/soh/Enhancements/debugger/performanceTimer.cpp b/soh/soh/Enhancements/debugger/performanceTimer.cpp new file mode 100644 index 00000000000..f52a8efaca0 --- /dev/null +++ b/soh/soh/Enhancements/debugger/performanceTimer.cpp @@ -0,0 +1,19 @@ +#pragma once + +#include "performanceTimer.h" + +void StartPerformanceTimer(TimerID timer){ + timeStarted[timer] = std::chrono::high_resolution_clock::now(); +} + +void StopPerformanceTimer(TimerID timer){ + totalTimes[timer] += (std::chrono::high_resolution_clock::now() - timeStarted[timer]); +} + +std::chrono::duration GetPerformanceTimer(TimerID timer){ + return totalTimes[timer]; +} + +void ResetPerformanceTimers(){ + totalTimes = {}; +} \ No newline at end of file diff --git a/soh/soh/Enhancements/debugger/performanceTimer.h b/soh/soh/Enhancements/debugger/performanceTimer.h new file mode 100644 index 00000000000..f4bc8f017c7 --- /dev/null +++ b/soh/soh/Enhancements/debugger/performanceTimer.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include + +typedef enum { + PT_WHOLE_SEED, + PT_LOGIC_RESET, + PT_REGION_RESET, + PT_SPOILER_LOG, + PT_ENTRANCE_SHUFFLE, + PT_SHOPSANITY, + PT_OWN_DUNGEON, + PT_LIMITED_CHECKS, + PT_ADVANCEMENT_ITEMS, + PT_REMAINING_ITEMS, + PT_PLAYTHROUGH_GENERATION, + PT_PARE_DOWN_PLAYTHROUGH, + PT_WOTH, + PT_FOOLISH, + PT_OVERRIDES, + PT_HINTS, + PT_EVENT_ACCESS, + PT_TOD_ACCESS, + PT_ENTRANCE_LOGIC, + PT_LOCATION_LOGIC, + PT_MAX +} TimerID; + +void StartPerformanceTimer(TimerID timer); +void StopPerformanceTimer(TimerID timer); +std::chrono::duration GetPerformanceTimer(TimerID timer); +void ResetPerformanceTimers(); +static std::array, PT_MAX> totalTimes = {}; +static std::array timeStarted = {}; + diff --git a/soh/soh/Enhancements/debugger/valueViewer.cpp b/soh/soh/Enhancements/debugger/valueViewer.cpp index c2b27c79dc0..c03be8ee1c7 100644 --- a/soh/soh/Enhancements/debugger/valueViewer.cpp +++ b/soh/soh/Enhancements/debugger/valueViewer.cpp @@ -35,6 +35,8 @@ std::vector valueTable = { { "Text ID", "play->msgCtx.textId", "TEXTID:", TYPE_U16, true, []() -> void* { return &gPlayState->msgCtx.textId; }, WHITE }, { "Analog Stick X", "play->state.input->cur.stick_x", "AX:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_x; }, WHITE }, { "Analog Stick Y", "play->state.input->cur.stick_y", "AY:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_y; }, WHITE }, + { "getItemID", "Player->getItemId", "ITEM:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemId; }, WHITE }, + { "getItemEntry", "Player->getItemEntry", "IE:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemEntry.itemId; }, WHITE }, /* TODO: Find these (from GZ) "XZ Units Traveled (Camera based speed variable)" f32 0x801C9018 "Movement Angle" x16 0x801DBB1C diff --git a/soh/soh/Enhancements/enemyrandomizer.cpp b/soh/soh/Enhancements/enemyrandomizer.cpp index 67fd202b272..e0f82062c51 100644 --- a/soh/soh/Enhancements/enemyrandomizer.cpp +++ b/soh/soh/Enhancements/enemyrandomizer.cpp @@ -2,6 +2,7 @@ #include "functions.h" #include "macros.h" #include "soh/Enhancements/randomizer/3drando/random.hpp" +#include "soh/Enhancements/randomizer/context.h" #include "soh/Enhancements/enhancementTypes.h" #include "variables.h" #include "soh/OTRGlobals.h" @@ -12,56 +13,100 @@ extern "C" { extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum); +const char* enemyCVarList[] = { + CVAR_ENHANCEMENT("RandomizedEnemyList.Armos"), CVAR_ENHANCEMENT("RandomizedEnemyList.Arwing"), + CVAR_ENHANCEMENT("RandomizedEnemyList.BabyDodongo"), CVAR_ENHANCEMENT("RandomizedEnemyList.Bari"), + CVAR_ENHANCEMENT("RandomizedEnemyList.Beamos"), CVAR_ENHANCEMENT("RandomizedEnemyList.BigSkulltula"), + CVAR_ENHANCEMENT("RandomizedEnemyList.BigStalchild"), CVAR_ENHANCEMENT("RandomizedEnemyList.Biri"), + CVAR_ENHANCEMENT("RandomizedEnemyList.BlackKnuckle"), CVAR_ENHANCEMENT("RandomizedEnemyList.BlueTektite"), + CVAR_ENHANCEMENT("RandomizedEnemyList.Bubble"), CVAR_ENHANCEMENT("RandomizedEnemyList.ClubMoblin"), + CVAR_ENHANCEMENT("RandomizedEnemyList.DarkLink"), CVAR_ENHANCEMENT("RandomizedEnemyList.Dinolfos"), + CVAR_ENHANCEMENT("RandomizedEnemyList.Dodongo"), CVAR_ENHANCEMENT("RandomizedEnemyList.FireKeese"), + CVAR_ENHANCEMENT("RandomizedEnemyList.FloorTile"), CVAR_ENHANCEMENT("RandomizedEnemyList.Floormaster"), + CVAR_ENHANCEMENT("RandomizedEnemyList.FlyingPeahat"), CVAR_ENHANCEMENT("RandomizedEnemyList.FlyingPot"), + CVAR_ENHANCEMENT("RandomizedEnemyList.Freezard"), CVAR_ENHANCEMENT("RandomizedEnemyList.Gibdo"), + CVAR_ENHANCEMENT("RandomizedEnemyList.GohmaLarva"), CVAR_ENHANCEMENT("RandomizedEnemyList.Guay"), + CVAR_ENHANCEMENT("RandomizedEnemyList.IceKeese"), CVAR_ENHANCEMENT("RandomizedEnemyList.InvisSkulltula"), + CVAR_ENHANCEMENT("RandomizedEnemyList.Keese"), CVAR_ENHANCEMENT("RandomizedEnemyList.LargeBaba"), + CVAR_ENHANCEMENT("RandomizedEnemyList.LikeLike"), CVAR_ENHANCEMENT("RandomizedEnemyList.Lizalfos"), + CVAR_ENHANCEMENT("RandomizedEnemyList.MadScrub"), CVAR_ENHANCEMENT("RandomizedEnemyList.NormalWolfos"), + CVAR_ENHANCEMENT("RandomizedEnemyList.PeahatLarva"), CVAR_ENHANCEMENT("RandomizedEnemyList.Redead"), + CVAR_ENHANCEMENT("RandomizedEnemyList.RedTektite"), CVAR_ENHANCEMENT("RandomizedEnemyList.Shabom"), + CVAR_ENHANCEMENT("RandomizedEnemyList.ShellBlade"), CVAR_ENHANCEMENT("RandomizedEnemyList.Skulltula"), + CVAR_ENHANCEMENT("RandomizedEnemyList.SmallBaba"), CVAR_ENHANCEMENT("RandomizedEnemyList.SmallStalchild"), + CVAR_ENHANCEMENT("RandomizedEnemyList.Spike"), CVAR_ENHANCEMENT("RandomizedEnemyList.Stalfos"), + CVAR_ENHANCEMENT("RandomizedEnemyList.Stinger"), CVAR_ENHANCEMENT("RandomizedEnemyList.Tailparasan"), + CVAR_ENHANCEMENT("RandomizedEnemyList.TorchSlug"), CVAR_ENHANCEMENT("RandomizedEnemyList.Wallmaster"), + CVAR_ENHANCEMENT("RandomizedEnemyList.WhiteKnuckle"), CVAR_ENHANCEMENT("RandomizedEnemyList.WhiteWolfos"), + CVAR_ENHANCEMENT("RandomizedEnemyList.WitheredBaba"), +}; + +const char* enemyNameList[] = { + "Armos", "Arwing", "Baby Dodongo", "Bari", + "Beamos", "Big Skulltula", "Stalchild (Big)", "Biri", + "Iron Knuckle (Black)", "Blue Tektite", "Bubble", "Club Moblin", + "Dark Link", "Dinolfos", "Dodongo", "Fire Keese", + "Floor Tile", "Floormaster", "Flying Peahat", "Flying Pot", + "Freezard", "Gibdo", "Gohma Larva", "Guay", + "Ice Keese", "Invisible Skulltula", "Keese", "Large Deku Baba", + "Like-Like", "Lizalfos", "Mad Scrub", "Wolfos (Normal)", + "Peahat Larva", "Redead", "Red Tektite", "Shabom", + "ShellBlade", "Skulltula", "Small Deku Baba", "Stalchild (Small)", + "Spike", "Stalfos", "Stinger", "Tailparasan", + "Torch Slug", "Wallmaster", "Iron Knuckle (White)", "Wolfos (White)", + "Withered Deku Baba", +}; + static EnemyEntry randomizedEnemySpawnTable[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = { - { ACTOR_EN_FIREFLY, 2 }, // Regular Keese - { ACTOR_EN_FIREFLY, 1 }, // Fire Keese - { ACTOR_EN_FIREFLY, 4 }, // Ice Keese - { ACTOR_EN_TEST, 2 }, // Stalfos - { ACTOR_EN_TITE, -1 }, // Tektite (red) + { ACTOR_EN_AM, -1 }, // Armos + { ACTOR_EN_CLEAR_TAG, 1 }, // Arwing + { ACTOR_EN_DODOJR, 0 }, // Baby Dodongo + { ACTOR_EN_VALI, -1 }, // Bari (big jellyfish) + { ACTOR_EN_VM, 1280 }, // Beamos + { ACTOR_EN_ST, 1 }, // Skulltula (big) + { ACTOR_EN_SKB, 20 }, // Stalchild (big) + { ACTOR_EN_BILI, 0 }, // Biri (jellyfish) + { ACTOR_EN_IK, 2 }, // Iron Knuckle (black, standing) { ACTOR_EN_TITE, -2 }, // Tektite (blue) - { ACTOR_EN_WALLMAS, 1 }, // Wallmaster + { ACTOR_EN_BB, -1 }, // Bubble (flying skull enemy) (blue) + { ACTOR_EN_MB, 0 }, // Moblins (Club) + { ACTOR_EN_TORCH2, 0 }, // Dark Link + { ACTOR_EN_ZF, -2 }, // Dinolfos { ACTOR_EN_DODONGO, -1 }, // Dodongo + { ACTOR_EN_FIREFLY, 1 }, // Fire Keese + { ACTOR_EN_YUKABYUN, 0 }, // Flying Floor Tile + { ACTOR_EN_FLOORMAS, 0 }, // Floormaster { ACTOR_EN_PEEHAT, -1 }, // Flying Peahat (big grounded, doesn't spawn larva) - { ACTOR_EN_PEEHAT, 1 }, // Flying Peahat Larva - { ACTOR_EN_ZF, -1 }, // Lizalfos - { ACTOR_EN_ZF, -2 }, // Dinolfos + { ACTOR_EN_TUBO_TRAP, 0 }, // Flying pot + { ACTOR_EN_FZ, 0 }, // Freezard + { ACTOR_EN_RD, 32766 }, // Gibdo (standing) { ACTOR_EN_GOMA, 7 }, // Gohma larva (non-gohma rooms) - { ACTOR_EN_BUBBLE, 0 }, // Shabom (bubble) - { ACTOR_EN_DODOJR, 0 }, // Baby Dodongo - { ACTOR_EN_TORCH2, 0 }, // Dark Link - { ACTOR_EN_BILI, 0 }, // Biri (jellyfish) - { ACTOR_EN_TP, -1 }, // Electric Tailparasan - { ACTOR_EN_ST, 0 }, // Skulltula (normal) - { ACTOR_EN_ST, 1 }, // Skulltula (big) + { ACTOR_EN_CROW, 0 }, // Guay + { ACTOR_EN_FIREFLY, 4 }, // Ice Keese { ACTOR_EN_ST, 2 }, // Skulltula (invisible) - { ACTOR_EN_BW, 0 }, // Torch Slug - { ACTOR_EN_EIYER, 10 }, // Stinger (land) (One in formation, sink under floor and do not activate) - { ACTOR_EN_MB, 0 }, // Moblins (Club) - { ACTOR_EN_DEKUBABA, 0 }, // Deku Baba (small) + { ACTOR_EN_IK, 3 }, // Iron Knuckle (white, standing) + { ACTOR_EN_FIREFLY, 2 }, // Regular Keese { ACTOR_EN_DEKUBABA, 1 }, // Deku Baba (large) - { ACTOR_EN_AM, -1 }, // Armos (enemy variant) + { ACTOR_EN_RR, 0 }, // Like-Like + { ACTOR_EN_ZF, -1 }, // Lizalfos { ACTOR_EN_DEKUNUTS, 768 }, // Mad Scrub (triple attack) (projectiles don't work) - { ACTOR_EN_VALI, -1 }, // Bari (big jellyfish) - { ACTOR_EN_BB, -1 }, // Bubble (flying skull enemy) (blue) - { ACTOR_EN_YUKABYUN, 0 }, // Flying Floor Tile - { ACTOR_EN_VM, 1280 }, // Beamos - { ACTOR_EN_FLOORMAS, 0 }, // Floormaster + { ACTOR_EN_WF, 0 }, // Wolfos (normal) + { ACTOR_EN_PEEHAT, 1 }, // Flying Peahat Larva { ACTOR_EN_RD, 1 }, // Redead (standing) - { ACTOR_EN_RD, 32766 }, // Gibdo (standing) + { ACTOR_EN_TITE, -1 }, // Tektite (red) + { ACTOR_EN_BUBBLE, 0 }, // Shabom (bubble) { ACTOR_EN_SB, 0 }, // Shell Blade - { ACTOR_EN_KAREBABA, 0 }, // Withered Deku Baba - { ACTOR_EN_RR, 0 }, // Like-Like + { ACTOR_EN_ST, 0 }, // Skulltula (normal) + { ACTOR_EN_DEKUBABA, 0 }, // Deku Baba (small) + { ACTOR_EN_SKB, 1 }, // Stalchild (small) { ACTOR_EN_NY, 0 }, // Spike (rolling enemy) - { ACTOR_EN_IK, 2 }, // Iron Knuckle (black, standing) - { ACTOR_EN_IK, 3 }, // Iron Knuckle (white, standing) - { ACTOR_EN_TUBO_TRAP, 0 }, // Flying pot - { ACTOR_EN_FZ, 0 }, // Freezard - { ACTOR_EN_CLEAR_TAG, 1 }, // Arwing - { ACTOR_EN_WF, 0 }, // Wolfos (normal) + { ACTOR_EN_TEST, 2 }, // Stalfos + { ACTOR_EN_EIYER, 10 }, // Stinger (land) (One in formation, sink under floor and do not activate) + { ACTOR_EN_TP, -1 }, // Electric Tailparasan + { ACTOR_EN_BW, 0 }, // Torch Slug + { ACTOR_EN_WALLMAS, 1 }, // Wallmaster { ACTOR_EN_WF, 1 }, // Wolfos (white) - { ACTOR_EN_SKB, 1 }, // Stalchild (small) - { ACTOR_EN_SKB, 20 }, // Stalchild (big) - { ACTOR_EN_CROW, 0 } // Guay + { ACTOR_EN_KAREBABA, 0 }, // Withered Deku Baba // Doesn't work {ACTOR_EN_POH, 0}, // Poe (Seems to rely on other objects?) // Doesn't work {ACTOR_EN_POH, 2}, // Poe (composer Sharp) (Seems to rely on other objects?) @@ -233,14 +278,41 @@ extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t *actorId, f32 *po return 1; } +std::vector selectedEnemyList; + +void GetSelectedEnemies() { + selectedEnemyList.clear(); + if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM) { + for (int i = 0; i < 49; i++) { + if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemyList.All"), 0)) { + selectedEnemyList.push_back(randomizedEnemySpawnTable[i]); + } else if (CVarGetInteger(enemyCVarList[i], 0)) { + selectedEnemyList.push_back(randomizedEnemySpawnTable[i]); + } + } + if (selectedEnemyList.size() == 0) { + selectedEnemyList.push_back(randomizedEnemySpawnTable[0]); + } + } else { + for (int i = 0; i < 49; i++) { + selectedEnemyList.push_back(randomizedEnemySpawnTable[i]); + } + } +} + EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) { + if (selectedEnemyList.size() == 0) { + GetSelectedEnemies(); + } if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) { - uint32_t finalSeed = seed + (IS_RANDO ? gSaveContext.finalSeed : gSaveContext.sohStats.fileCreatedAt); + uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSettings()->GetSeed() : gSaveContext.sohStats.fileCreatedAt); Random_Init(finalSeed); + uint32_t randomNumber = Random(0, RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE); + return selectedEnemyList[randomNumber]; + } else { + uint32_t randomSelectedEnemy = Random(0, selectedEnemyList.size()); + return selectedEnemyList[randomSelectedEnemy]; } - - uint32_t randomNumber = Random(0, RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE); - return randomizedEnemySpawnTable[randomNumber]; } bool IsEnemyFoundToRandomize(int16_t sceneNum, int8_t roomNum, int16_t actorId, int16_t params, float posX) { diff --git a/soh/soh/Enhancements/enemyrandomizer.h b/soh/soh/Enhancements/enemyrandomizer.h index cc68f941868..f819de9bfa7 100644 --- a/soh/soh/Enhancements/enemyrandomizer.h +++ b/soh/soh/Enhancements/enemyrandomizer.h @@ -13,6 +13,10 @@ bool IsEnemyFoundToRandomize(int16_t sceneNum, int8_t roomNum, int16_t actorId, bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy); EnemyEntry GetRandomizedEnemyEntry(uint32_t seed); +extern const char* enemyCVarList[]; +extern const char* enemyNameList[]; +extern void GetSelectedEnemies(); + #ifndef __cplusplus uint8_t GetRandomizedEnemy(PlayState* play, int16_t *actorId, f32 *posX, f32 *posY, f32 *posZ, int16_t *rotX, int16_t *rotY, int16_t *rotZ, int16_t *params); #endif diff --git a/soh/soh/Enhancements/enhancementTypes.h b/soh/soh/Enhancements/enhancementTypes.h index 56160567ae8..3dce64b12cb 100644 --- a/soh/soh/Enhancements/enhancementTypes.h +++ b/soh/soh/Enhancements/enhancementTypes.h @@ -14,6 +14,13 @@ typedef enum { CSMC_SIZE } ChestStyleMatchesContentsType; +typedef enum { + SGIA_DISABLED, + SGIA_JUNK, + SGIA_ALL, + SGIA_SIZE +} SkipGetItemAnimationType; + typedef enum { BUNNY_HOOD_VANILLA, BUNNY_HOOD_FAST_AND_JUMP, diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 7503dbd783c..5e30441db96 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -3,6 +3,7 @@ #ifndef GameInteractor_h #define GameInteractor_h +#include "libultraship/libultraship.h" #include "GameInteractionEffect.h" #include "soh/Enhancements/item-tables/ItemTableTypes.h" #include @@ -67,6 +68,419 @@ typedef enum { /* */ GI_TP_DEST_PRELUDE = ENTR_TEMPLE_OF_TIME_7, } GITeleportDestinations; +typedef enum { + // Vanilla condition: gSaveContext.showTitleCard + VB_SHOW_TITLE_CARD, + // Opt: *EnWonderTalk2 + VB_WONDER_TALK, + // Opt: *ElfMsg + VB_NAVI_TALK, + // 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 + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) + VB_MIDO_CONSIDER_DEKU_TREE_DEAD, + // Opt: *ObjDekujr + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) + VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, + // Opt: *EnKo + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) + VB_OPEN_KOKIRI_FOREST, + // Opt: *EnOwl + // Vanilla condition: EnOwl->actor.xzDistToPlayer < targetDist + VB_OWL_INTERACTION, + // Vanilla condition: EVENTCHKINF_TALON_RETURNED_FROM_CASTLE + VB_MALON_RETURN_FROM_CASTLE, + // Vanilla condition: CUR_UPG_VALUE(UPG_STRENGTH) <= 0 + VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD, + /* Vanilla condition: + ``` + LINK_IS_ADULT && + (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && + !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); + ``` + */ + VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, + // Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SARIA) + VB_BE_ELIGIBLE_FOR_SARIAS_SONG, + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_SONG_EPONA) + VB_MALON_ALREADY_TAUGHT_EPONAS_SONG, + // Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) + VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER, + // Vanilla condition: (!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT + VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER, + // Vanilla condition: !EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT and EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP + VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT, + VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE, + /* Vanilla Condition: + ``` + LINK_IS_ADULT && + gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 && + Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) && + !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); + ``` + */ + VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, + // Opt: *EnGo2 + // Vanilla condition: CUR_CAPACITY(UPG_BOMB_BAG) >= 20 && this->waypoint > 7 && this->waypoint < 12 + VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD, + // Vanilla condition: !CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON) + VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE, + // Opt: *EnMs + // Vanilla condition: gSaveContext.rupees >= sPrices[BEANS_BOUGHT] + VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE, + // 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, + // Opt: *EnTk + // Vanilla condition: this->validDigHere == 1 + VB_BE_VALID_GRAVEDIGGING_SPOT, + // Opt: *EnTk + // Vanilla condition: this->currentReward == 3 + VB_BE_DAMPE_GRAVEDIGGING_GRAND_PRIZE, + // Opt: *EnTk + // Vanilla condition: !Flags_GetItemGetInf(ITEMGETINF_1C) + VB_DAMPE_GRAVEDIGGING_GRAND_PRIZE_BE_HEART_PIECE, + // Opt: *EnShopnuts + /* Vanilla Condition: + ``` + ((this->actor.params == 0x0002) && (Flags_GetItemGetInf(ITEMGETINF_0B))) || + ((this->actor.params == 0x0009) && (Flags_GetInfTable(INFTABLE_192))) || + ((this->actor.params == 0x000A) && (Flags_GetInfTable(INFTABLE_193))) + ``` + */ + VB_BUSINESS_SCRUB_DESPAWN, + // Opt: *EnCow + // Vanilla condition: play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE)) + VB_DESPAWN_HORSE_RACE_COW, + // Opt: *EnHs + // Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30) + VB_DESPAWN_GROG, + // Opt: *EnKo + // Vanilla condition: (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false; + VB_SPAWN_LW_FADO, + // Opt: *EnMk + VB_PLAY_EYEDROP_CREATION_ANIM, + // Opt: *EnDs + VB_PLAY_ODD_POTION_ANIM, + // Opt: *EnMk + // Vanilla condition: INV_CONTENT(ITEM_ODD_MUSHROOM) == ITEM_EYEDROPS + VB_USE_EYEDROP_DIALOGUE, + // Opt: *EnMk + // Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30) + VB_OFFER_BLUE_POTION, + VB_GRANNY_SAY_INSUFFICIENT_RUPEES, + VB_GRANNY_TAKE_MONEY, + // Vanilla condition: Inventory_HasEmptyBottle() == 0 + VB_NEED_BOTTLE_FOR_GRANNYS_ITEM, + // Opt: *EnNiwLady + VB_SET_CUCCO_COUNT, + // Opt: *EnKz + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) + VB_KING_ZORA_THANK_CHILD, + // Opt: *EnKz + // Vanilla condition: this->actor.textId == 0x401A + VB_BE_ABLE_TO_EXCHANGE_RUTOS_LETTER, + // Opt: *EnKz + // Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED) + VB_KING_ZORA_BE_MOVED, + // Vanilla condition: gSaveState.bgsFlag + VB_BIGGORON_CONSIDER_TRADE_COMPLETE, + // Vanilla condition: gSaveState.bgsFlag + VB_BIGGORON_CONSIDER_SWORD_COLLECTED, + // Vanilla condition: Environment_GetBgsDayCount() >= 3 + VB_BIGGORON_CONSIDER_SWORD_FORGED, + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) + VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED, + // Vanilla condition: CHECK_QUEST_ITEM(QUEST_GORON_RUBY) + VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED, + // Opt: *uint16_t + // Vanilla condition: false + VB_OVERRIDE_LINK_THE_GORON_DIALOGUE, + // Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON) + VB_GORONS_CONSIDER_TUNIC_COLLECTED, + // Opt: *EnSyatekiMan + // Vanilla condition: (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50) + VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD, + // Opt: *EnOkarinaTag + // Vanilla condition: !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME) + VB_BE_ELIGIBLE_TO_OPEN_DOT, + // Opt: *BgDyYoseizo + // Vanilla condition: see soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c + VB_BE_ELIGIBLE_FOR_GREAT_FAIRY_REWARD, + // Vanilla condition: see CheckCarpentersFreed in z_en_ge1 and z_en_ge2 + VB_GERUDOS_BE_FRIENDLY, + // Vanilla condition: switch + VB_GTG_GATE_BE_OPEN, + // Opt: *s16 (item id) + /* Vanilla condition: + In one case: + ``` + true + ``` + In the other case: + ``` + (i == ITEM_STICK) || + (i == ITEM_NUT) || + (i == ITEM_BOMB) || + (i == ITEM_BOW) || + ( + (i >= ITEM_BOW_ARROW_FIRE) && + (i <= ITEM_BOW_ARROW_LIGHT) + ) || + (i == ITEM_SLINGSHOT) || + (i == ITEM_BOMBCHU) || + (i == ITEM_BEAN) + ``` + */ + VB_DRAW_AMMO_COUNT, + // Vanilla condition: true + VB_HAVE_OCARINA_NOTE_D4, + // Vanilla condition: true + VB_HAVE_OCARINA_NOTE_D5, + // Vanilla condition: true + VB_HAVE_OCARINA_NOTE_F4, + // Vanilla condition: true + VB_HAVE_OCARINA_NOTE_B4, + // Vanilla condition: true + VB_HAVE_OCARINA_NOTE_A4, + // Vanilla condition: false + VB_SKIP_SCARECROWS_SONG, + // Vanilla condition: true + VB_RENDER_RUPEE_COUNTER, + // Vanilla condition: true + VB_RENDER_KEY_COUNTER, + // Vanilla condition: true + VB_SPAWN_HEART_CONTAINER, + // Vanilla condition: true + VB_BE_ABLE_TO_OPEN_DOORS, + // Vanilla condition: true + VB_REVERT_SPOILING_ITEMS, + // Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP) || BREG(2) + VB_BE_ABLE_TO_PLAY_BOMBCHU_BOWLING, + // Vanilla condition: true + VB_BE_ABLE_TO_SAVE, + // Vanilla condition: true + VB_TRANSITION_TO_SAVE_SCREEN_ON_DEATH, + // Vanilla condition: true + VB_RENDER_YES_ON_CONTINUE_PROMPT, + // Vanilla condition: CHECK_BTN_ALL(input->press.button, BTN_START) + VB_CLOSE_PAUSE_MENU, + // Vanilla condition: true + VB_SPAWN_BLUE_WARP, + // Vanilla condition: this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF + VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, + // Vanilla condition: this->collider.base.acFlags & 2 + VB_BG_BREAKWALL_BREAK, + // Vanilla condition: true + VB_GANON_HEAL_BEFORE_FIGHT, + VB_FREEZE_LINK_FOR_BLOCK_THROW, + VB_MOVE_THROWN_ACTOR, + + /*** Play Cutscenes ***/ + + VB_PLAY_TRANSITION_CS, + // Opt: *EventChkInf flag + VB_PLAY_ENTRANCE_CS, + // Opt: *cutsceneId + VB_PLAY_ONEPOINT_CS, + // Opt: *actor + VB_PLAY_ONEPOINT_ACTOR_CS, + // Opt: *BgTreemouth + VB_PLAY_DEKU_TREE_INTRO_CS, + // Vanilla condition: !EventChkInf except for spirit & shadow temple which are !medallion, and Jabu which always is true + VB_PLAY_BLUE_WARP_CS, + VB_PLAY_DARUNIAS_JOY_CS, + VB_PLAY_SHIEK_BLOCK_MASTER_SWORD_CS, + // Vanilla condition: !EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL + VB_PLAY_PULL_MASTER_SWORD_CS, + VB_PLAY_DROP_FISH_FOR_JABU_CS, + // Vanilla condition: player->getItemId == GI_GAUNTLETS_SILVER + VB_PLAY_NABOORU_CAPTURED_CS, + VB_PLAY_ZELDAS_LULLABY_CS, + // Opt: *EnSa + VB_PLAY_SARIAS_SONG_CS, + VB_PLAY_PRELUDE_OF_LIGHT_CS, + VB_PLAY_MINUET_OF_FOREST_CS, + VB_PLAY_BOLERO_OF_FIRE_CS, + VB_PLAY_SERENADE_OF_WATER_CS, + VB_PLAY_EYEDROPS_CS, + // Opt: *EnOkarinaTag + VB_PLAY_DRAIN_WELL_CS, + // Opt: *EnOkarinaTag + // Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SUN) + VB_PLAY_SUNS_SONG_CS, + // Opt: *EnOkarinaTag + VB_PLAY_ROYAL_FAMILY_TOMB_CS, + VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE, + // Opt: *EnOkarinaTag + VB_PLAY_DOOR_OF_TIME_CS, + VB_PLAY_RAINBOW_BRIDGE_CS, + // Opt: *EnBox + VB_PLAY_SLOW_CHEST_CS, + //*Opt f32 sFishOnHandLength + // Vanilla condition: (s16)sFishingRecordLength < (s16)sFishOnHandLength + VB_SHOULD_CHECK_FOR_FISHING_RECORD, + //*Opt f32 sFishOnHandLength + // Vanilla condition is implied from previous code that could be bypassed by above hook + VB_SHOULD_SET_FISHING_RECORD, + //*Opt *s32 getItemId + VB_SHOULD_GIVE_VANILLA_FISHING_PRIZE, + VB_GIVE_RANDO_FISHING_PRIZE, + VB_PLAY_THROW_ANIMATION, + + /*** Give Items ***/ + + // Opt: *EnBox + VB_GIVE_ITEM_FROM_CHEST, + VB_GIVE_ITEM_FROM_BLUE_WARP, + // Opt: *EnItem00 + VB_GIVE_ITEM_FROM_ITEM_00, + // Opt: *EnSi + VB_GIVE_ITEM_SKULL_TOKEN, + // Opt: *EnCow + VB_GIVE_ITEM_FROM_COW, + // Opt: *EnDns + VB_GIVE_ITEM_FROM_BUSINESS_SCRUB, + // Opt: *EnMk + VB_GIVE_ITEM_FROM_LAB_DIVE, + // Opt: *EnDs + VB_GIVE_ITEM_FROM_GRANNYS_SHOP, + // Opt: *EnNiwLady + VB_GIVE_ITEM_FROM_ANJU_AS_CHILD, + // Opt: *EnNiwLady + VB_GIVE_ITEM_FROM_ANJU_AS_ADULT, + // Opt: *EnKz + // Vanilla condition: !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) + VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, + // Opt: *EnGo2 + VB_GIVE_ITEM_FROM_GORON, + // Opt: *EnJs + VB_CHECK_RANDO_PRICE_OF_CARPET_SALESMAN, + VB_GIVE_ITEM_FROM_CARPET_SALESMAN, + VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN, + // Opt: *EnGm + VB_CHECK_RANDO_PRICE_OF_MEDIGORON, + VB_GIVE_ITEM_FROM_MEDIGORON, + // Opt: *EnMs + VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN, + // Opt: *EnFr + VB_GIVE_ITEM_FROM_FROGS, + // Opt: *EnSkj + VB_GIVE_ITEM_FROM_OCARINA_MEMORY_GAME, + // Opt: *EnSkj + VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG, + VB_GIVE_ITEM_FROM_MAN_ON_ROOF, + // Opt: *EnSyatekiMan + VB_GIVE_ITEM_FROM_SHOOTING_GALLERY, + // Opt: *EnExItem + VB_GIVE_ITEM_FROM_TARGET_IN_WOODS, + // Opt: *EnTa + VB_GIVE_ITEM_FROM_TALONS_CHICKENS, + // Opt: *EnDivingGame + VB_GIVE_ITEM_FROM_DIVING_MINIGAME, + // Opt: *EnGe1 + VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY, + // Opt: *EnSth + VB_GIVE_ITEM_FROM_SKULLTULA_REWARD, + // Opt: *EnHy + VB_GIVE_ITEM_FROM_LOST_DOG, + // Opt: *EnBomBowlPit + VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING, + + VB_GIVE_ITEM_GERUDO_MEMBERSHIP_CARD, + + VB_GIVE_ITEM_FAIRY_OCARINA, + VB_GIVE_ITEM_WEIRD_EGG, + VB_GIVE_ITEM_LIGHT_ARROW, + VB_GIVE_ITEM_STRENGTH_1, + VB_GIVE_ITEM_ZELDAS_LETTER, + VB_GIVE_ITEM_MASTER_SWORD, + VB_GIVE_ITEM_OCARINA_OF_TIME, + VB_GIVE_ITEM_KOKIRI_EMERALD, + VB_GIVE_ITEM_GORON_RUBY, + VB_GIVE_ITEM_ZORA_SAPPHIRE, + VB_GIVE_ITEM_LIGHT_MEDALLION, + VB_GIVE_ITEM_FOREST_MEDALLION, + VB_GIVE_ITEM_FIRE_MEDALLION, + VB_GIVE_ITEM_WATER_MEDALLION, + VB_GIVE_ITEM_SPIRIT_MEDALLION, + VB_GIVE_ITEM_SHADOW_MEDALLION, + + /*** Give Songs ***/ + + VB_GIVE_ITEM_ZELDAS_LULLABY, + VB_GIVE_ITEM_SARIAS_SONG, + VB_GIVE_ITEM_EPONAS_SONG, + VB_GIVE_ITEM_SUNS_SONG, + VB_GIVE_ITEM_SONG_OF_TIME, + VB_GIVE_ITEM_SONG_OF_STORMS, + VB_GIVE_ITEM_MINUET_OF_FOREST, + VB_GIVE_ITEM_BOLERO_OF_FIRE, + VB_GIVE_ITEM_SERENADE_OF_WATER, + VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, + VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, + VB_GIVE_ITEM_PRELUDE_OF_LIGHT, + + /*** Adult Trade ***/ + // Opt: *EnNiwLady + VB_TRADE_POCKET_CUCCO, + // Opt: *EnHs + VB_TRADE_COJIRO, + // Opt: *EnDs + VB_TRADE_ODD_MUSHROOM, + // Opt: *EnKo + VB_TRADE_ODD_POTION, + // Opt: *EnToryo + VB_TRADE_SAW, + // Opt: *EnKz, + VB_TRADE_PRESCRIPTION, + // Opt: *EnMk + VB_TRADE_FROG, + + VB_TRADE_TIMER_ODD_MUSHROOM, + VB_TRADE_TIMER_EYEDROPS, + VB_TRADE_TIMER_FROG, + // Opt: *EnNiwLady + VB_ANJU_SET_OBTAINED_TRADE_ITEM, + + /*** Fixes ***/ + // Vanilla condition: false + VB_FIX_SAW_SOFTLOCK, + + /*** Cheats? ***/ + VB_DEKU_STICK_BE_ON_FIRE, + VB_DEKU_STICK_BREAK, + VB_DEKU_STICK_BURN_DOWN, + VB_DEKU_STICK_BURN_OUT, + VB_DEKU_UPDATE_BURNING_DEKU_STICK, + + /*** Quick Boss Deaths ***/ + // Vanilla condition: true + VB_PHANTOM_GANON_DEATH_SCENE, + VB_NABOORU_KNUCKLE_DEATH_SCENE, + + /*** Fishsanity ***/ + // Vanilla condition: Actor is ACTOR_EN_ELF, ACTOR_EN_FISH, ACTOR_EN_ICE_HONO, or ACTOR_EN_INSECT + // Opt: *Actor + VB_BOTTLE_ACTOR, +} GIVanillaBehavior; + #ifdef __cplusplus extern "C" { #endif @@ -97,26 +511,75 @@ void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state); #ifdef __cplusplus +#include #include +#include #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 #include #endif -#define DEFINE_HOOK(name, type) \ - struct name { \ - typedef std::function fn; \ - } +typedef uint32_t HOOK_ID; + +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, va_list _originalArgs) { \ + va_list args; \ + va_copy(args, _originalArgs); \ + body; \ + va_end(args); \ + }) class GameInteractor { public: static GameInteractor* Instance; - // Gsme State + // Game State class State { public: static bool NoUIActive; @@ -163,10 +626,35 @@ class GameInteractor { static GameInteractionEffectQueryResult RemoveEffect(RemovableGameInteractionEffect* effect); // Game Hooks - uint32_t nextHookId = 1; - template struct RegisteredGameHooks { inline static std::unordered_map functions; }; - template struct HooksToUnregister { inline static std::vector hooks; }; - template uint32_t RegisterGameHook(typename H::fn h) { + HOOK_ID nextHookId = 1; + template struct RegisteredGameHooks { + inline static std::unordered_map functions; + 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; + inline static std::vector hooksForPtr; + inline static std::vector hooksForFilter; + }; + + template std::unordered_map GetHookData() { + return RegisteredGameHooks::hookData; + } + + // General Hooks + 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()) { @@ -174,73 +662,174 @@ class GameInteractor { } RegisteredGameHooks::functions[this->nextHookId] = h; + RegisteredGameHooks::hookData[this->nextHookId] = HookInfo{GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_NORMAL)}; return this->nextHookId++; } - template void UnregisterGameHook(uint32_t id) { - HooksToUnregister::hooks.push_back(id); + + 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 +#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++; } - DEFINE_HOOK(OnLoadGame, void(int32_t fileNum)); - DEFINE_HOOK(OnExitGame, void(int32_t fileNum)); - DEFINE_HOOK(OnGameFrameUpdate, void()); - DEFINE_HOOK(OnItemReceive, void(GetItemEntry itemEntry)); - DEFINE_HOOK(OnSaleEnd, void(GetItemEntry itemEntry)); - DEFINE_HOOK(OnTransitionEnd, void(int16_t sceneNum)); - DEFINE_HOOK(OnSceneInit, void(int16_t sceneNum)); - DEFINE_HOOK(OnSceneFlagSet, void(int16_t sceneNum, int16_t flagType, int16_t flag)); - DEFINE_HOOK(OnSceneFlagUnset, void(int16_t sceneNum, int16_t flagType, int16_t flag)); - DEFINE_HOOK(OnFlagSet, void(int16_t flagType, int16_t flag)); - DEFINE_HOOK(OnFlagUnset, void(int16_t flagType, int16_t flag)); - DEFINE_HOOK(OnSceneSpawnActors, void()); - DEFINE_HOOK(OnPlayerUpdate, void()); - DEFINE_HOOK(OnOcarinaSongAction, void()); - DEFINE_HOOK(OnShopSlotChange, void(uint8_t cursorIndex, int16_t price)); - DEFINE_HOOK(OnActorInit, void(void* actor)); - DEFINE_HOOK(OnActorUpdate, void(void* actor)); - DEFINE_HOOK(OnActorKill, void(void* actor)); - DEFINE_HOOK(OnEnemyDefeat, void(void* actor)); - DEFINE_HOOK(OnPlayerBonk, void()); - DEFINE_HOOK(OnPlayDestroy, void()); - DEFINE_HOOK(OnPlayDrawEnd, void()); - - DEFINE_HOOK(OnSaveFile, void(int32_t fileNum)); - DEFINE_HOOK(OnLoadFile, void(int32_t fileNum)); - DEFINE_HOOK(OnDeleteFile, void(int32_t fileNum)); - - DEFINE_HOOK(OnDialogMessage, void()); - DEFINE_HOOK(OnPresentTitleCard, void()); - DEFINE_HOOK(OnInterfaceUpdate, void()); - DEFINE_HOOK(OnKaleidoscopeUpdate, void(int16_t inDungeonScene)); - - DEFINE_HOOK(OnPresentFileSelect, void()); - DEFINE_HOOK(OnUpdateFileSelectSelection, void(uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileSelectConfirmationSelection, void(uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileCopySelection, void(uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileCopyConfirmationSelection, void(uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileEraseSelection, void(uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileEraseConfirmationSelection, void(uint16_t optionIndex)); - DEFINE_HOOK(OnUpdateFileAudioSelection, void(uint8_t optionIndex)); - DEFINE_HOOK(OnUpdateFileTargetSelection, void(uint8_t optionIndex)); - DEFINE_HOOK(OnUpdateFileLanguageSelection, void(uint8_t optionIndex)); - DEFINE_HOOK(OnUpdateFileQuestSelection, void(uint8_t questIndex)); - DEFINE_HOOK(OnUpdateFileBossRushOptionSelection, void(uint8_t optionIndex, uint8_t optionValue)); - DEFINE_HOOK(OnUpdateFileNameSelection, void(int16_t charCode)); - - DEFINE_HOOK(OnSetGameLanguage, void()); - - DEFINE_HOOK(OnFileDropped, void(std::string filePath)); - DEFINE_HOOK(OnAssetAltChange, void()); - DEFINE_HOOK(OnKaleidoUpdate, void()); + 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; + } + } + } + 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 +#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; + } + } + } + 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 +#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; + } + } + } + + class HookFilter { + public: + static auto ActorNotPlayer(Actor* actor) { + return actor->id != ACTOR_PLAYER; + } + // For use with Should hooks + static auto SActorNotPlayer(Actor* actor, bool* result) { + return actor->id != ACTOR_PLAYER; + } + static auto ActorMatchIdAndParams(int16_t id, int16_t params) { + return [id, params](Actor* actor) { + return actor->id == id && actor->params == params; + }; + } + // For use with Should hooks + static auto SActorMatchIdAndParams(int16_t id, int16_t params) { + return [id, params](Actor* actor, bool* result) { + return actor->id == id && actor->params == params; + }; + } + }; + +#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); @@ -252,6 +841,7 @@ class GameInteractor { public: static void SetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag); static void UnsetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag); + static bool CheckFlag(int16_t flagType, int16_t flag); static void SetFlag(int16_t flagType, int16_t chestNum); static void UnsetFlag(int16_t flagType, int16_t chestNum); static void AddOrRemoveHealthContainers(int16_t amount); @@ -301,5 +891,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..46f306a3c83 --- /dev/null +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -0,0 +1,58 @@ +/** + * 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(OnBossDefeat, (void* actor)); +DEFINE_HOOK(OnPlayerBonk, ()); +DEFINE_HOOK(OnPlayDestroy, ()); +DEFINE_HOOK(OnPlayDrawEnd, ()); +DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, va_list originalArgs)); +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, ()); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 911c47a71c4..24efb40c151 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -16,34 +16,44 @@ void GameInteractor_ExecuteOnGameFrameUpdate() { void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry) { GameInteractor::Instance->ExecuteHooks(itemEntry); + GameInteractor::Instance->ExecuteHooksForFilter(itemEntry); } void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry) { GameInteractor::Instance->ExecuteHooks(itemEntry); + GameInteractor::Instance->ExecuteHooksForFilter(itemEntry); } void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum) { GameInteractor::Instance->ExecuteHooks(sceneNum); + GameInteractor::Instance->ExecuteHooksForID(sceneNum, sceneNum); + GameInteractor::Instance->ExecuteHooksForFilter(sceneNum); } void GameInteractor_ExecuteOnSceneInitHooks(int16_t sceneNum) { GameInteractor::Instance->ExecuteHooks(sceneNum); + GameInteractor::Instance->ExecuteHooksForID(sceneNum, sceneNum); + GameInteractor::Instance->ExecuteHooksForFilter(sceneNum); } void GameInteractor_ExecuteOnSceneFlagSet(int16_t sceneNum, int16_t flagType, int16_t flag) { GameInteractor::Instance->ExecuteHooks(sceneNum, flagType, flag); + GameInteractor::Instance->ExecuteHooksForFilter(sceneNum, flagType, flag); } void GameInteractor_ExecuteOnSceneFlagUnset(int16_t sceneNum, int16_t flagType, int16_t flag) { GameInteractor::Instance->ExecuteHooks(sceneNum, flagType, flag); + GameInteractor::Instance->ExecuteHooksForFilter(sceneNum, flagType, flag); } void GameInteractor_ExecuteOnFlagSet(int16_t flagType, int16_t flag) { GameInteractor::Instance->ExecuteHooks(flagType, flag); + GameInteractor::Instance->ExecuteHooksForFilter(flagType, flag); } void GameInteractor_ExecuteOnFlagUnset(int16_t flagType, int16_t flag) { GameInteractor::Instance->ExecuteHooks(flagType, flag); + GameInteractor::Instance->ExecuteHooksForFilter(flagType, flag); } void GameInteractor_ExecuteOnSceneSpawnActors() { @@ -64,18 +74,37 @@ void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t pr void GameInteractor_ExecuteOnActorInit(void* actor) { GameInteractor::Instance->ExecuteHooks(actor); + GameInteractor::Instance->ExecuteHooksForID(((Actor*)actor)->id, actor); + GameInteractor::Instance->ExecuteHooksForPtr((uintptr_t)actor, actor); + GameInteractor::Instance->ExecuteHooksForFilter(actor); } void GameInteractor_ExecuteOnActorUpdate(void* actor) { GameInteractor::Instance->ExecuteHooks(actor); + GameInteractor::Instance->ExecuteHooksForID(((Actor*)actor)->id, actor); + GameInteractor::Instance->ExecuteHooksForPtr((uintptr_t)actor, actor); + GameInteractor::Instance->ExecuteHooksForFilter(actor); } void GameInteractor_ExecuteOnActorKill(void* actor) { GameInteractor::Instance->ExecuteHooks(actor); + GameInteractor::Instance->ExecuteHooksForID(((Actor*)actor)->id, actor); + GameInteractor::Instance->ExecuteHooksForPtr((uintptr_t)actor, actor); + GameInteractor::Instance->ExecuteHooksForFilter(actor); } void GameInteractor_ExecuteOnEnemyDefeat(void* actor) { GameInteractor::Instance->ExecuteHooks(actor); + GameInteractor::Instance->ExecuteHooksForID(((Actor*)actor)->id, actor); + GameInteractor::Instance->ExecuteHooksForPtr((uintptr_t)actor, actor); + GameInteractor::Instance->ExecuteHooksForFilter(actor); +} + +void GameInteractor_ExecuteOnBossDefeat(void* actor) { + GameInteractor::Instance->ExecuteHooks(actor); + GameInteractor::Instance->ExecuteHooksForID(((Actor*)actor)->id, actor); + GameInteractor::Instance->ExecuteHooksForPtr((uintptr_t)actor, actor); + GameInteractor::Instance->ExecuteHooksForFilter(actor); } void GameInteractor_ExecuteOnPlayerBonk() { @@ -90,6 +119,27 @@ void GameInteractor_ExecuteOnPlayDrawEnd() { GameInteractor::Instance->ExecuteHooks(); } +bool GameInteractor_Should(GIVanillaBehavior flag, u32 result, ...) { + // Only the external function can use the Variadic Function syntax + // To pass the va args to the next caller must be done using va_list and reading the args into it + // Because there can be N subscribers registered to each template call, the subscribers will be responsible for + // creating a copy of this va_list to avoid incrementing the original pointer between calls + va_list args; + va_start(args, result); + + // Because of default argument promotion, even though our incoming "result" is just a bool, it needs to be typed as + // an int to be permitted to be used in `va_start`, otherwise it is undefined behavior. + // Here we downcast back to a bool for our actual hook handlers + bool boolResult = static_cast(result); + + GameInteractor::Instance->ExecuteHooks(flag, &boolResult, args); + GameInteractor::Instance->ExecuteHooksForID(flag, flag, &boolResult, args); + GameInteractor::Instance->ExecuteHooksForFilter(flag, &boolResult, args); + + va_end(args); + return boolResult; +} + // MARK: - Save Files void GameInteractor_ExecuteOnSaveFile(int32_t fileNum) { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 5c86cb39b52..dccc9930ae2 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -1,4 +1,5 @@ #include "GameInteractor.h" +#include #ifdef __cplusplus extern "C" { @@ -22,11 +23,13 @@ void GameInteractor_ExecuteOnActorInit(void* actor); void GameInteractor_ExecuteOnActorUpdate(void* actor); void GameInteractor_ExecuteOnActorKill(void* actor); void GameInteractor_ExecuteOnEnemyDefeat(void* actor); +void GameInteractor_ExecuteOnBossDefeat(void* actor); void GameInteractor_ExecuteOnPlayerBonk(); void GameInteractor_ExecuteOnOcarinaSongAction(); void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price); void GameInteractor_ExecuteOnPlayDestroy(); void GameInteractor_ExecuteOnPlayDrawEnd(); +bool GameInteractor_Should(GIVanillaBehavior flag, uint32_t result, ...); // MARK: - Save Files void GameInteractor_ExecuteOnSaveFile(int32_t fileNum); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp index 5e61f704ded..fb428d1aec2 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp @@ -205,6 +205,23 @@ void GameInteractor::RawAction::UnsetSceneFlag(int16_t sceneNum, int16_t flagTyp } }; +bool GameInteractor::RawAction::CheckFlag(int16_t flagType, int16_t flag) { + switch (flagType) { + case FlagType::FLAG_EVENT_CHECK_INF: + return Flags_GetEventChkInf(flag); + case FlagType::FLAG_ITEM_GET_INF: + return Flags_GetItemGetInf(flag); + case FlagType::FLAG_INF_TABLE: + return Flags_GetInfTable(flag); + case FlagType::FLAG_EVENT_INF: + return Flags_GetEventInf(flag); + case FlagType::FLAG_RANDOMIZER_INF: + return Flags_GetRandomizerInf(static_cast(flag)); + case FlagType::FLAG_GS_TOKEN: + return GET_GS_FLAGS((flag & 0x1F00) >> 8); + } +} + void GameInteractor::RawAction::SetFlag(int16_t flagType, int16_t flag) { switch (flagType) { case FlagType::FLAG_EVENT_CHECK_INF: diff --git a/soh/soh/Enhancements/item-tables/ItemTableTypes.h b/soh/soh/Enhancements/item-tables/ItemTableTypes.h index 28e70dc959e..44ceb214309 100644 --- a/soh/soh/Enhancements/item-tables/ItemTableTypes.h +++ b/soh/soh/Enhancements/item-tables/ItemTableTypes.h @@ -3,8 +3,8 @@ #include #endif -#define CHEST_ANIM_SHORT 0 -#define CHEST_ANIM_LONG 1 +#define CHEST_ANIM_SHORT (int16_t)0 +#define CHEST_ANIM_LONG (int16_t)1 /** * Flag to indicate which type of Actor has given the player an item. ITEM_FROM_NPC by default, @@ -30,10 +30,10 @@ typedef enum GetItemCategory { } GetItemCategory; #define GET_ITEM(itemId, objectId, drawId, textId, field, chestAnim, itemCategory, modIndex, getItemId) \ - { itemId, field, (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId, modIndex, modIndex, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, NULL } + { itemId, field, (int16_t)((chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1)), textId, objectId, modIndex, modIndex, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, NULL } #define GET_ITEM_CUSTOM_TABLE(itemId, objectId, drawId, textId, field, chestAnim, itemCategory, modIndex, tableId, getItemId) \ - { itemId, field, (chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1), textId, objectId, modIndex, tableId, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, NULL } + { itemId, field, (int16_t)((chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1)), textId, objectId, modIndex, tableId, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, NULL } #define GET_ITEM_NONE \ { ITEM_NONE, 0, 0, 0, 0, 0, 0, 0, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, NULL } @@ -41,7 +41,7 @@ typedef enum GetItemCategory { typedef struct PlayState PlayState; typedef struct GetItemEntry GetItemEntry; -typedef void (*CustomDrawFunc)(PlayState* play, GetItemEntry* getItemEntry); +typedef void (*CustomDrawFunc)(PlayState*, GetItemEntry*); typedef struct GetItemEntry { /* 0x00 */ uint16_t itemId; diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp new file mode 100644 index 00000000000..6d66a05780b --- /dev/null +++ b/soh/soh/Enhancements/kaleido.cpp @@ -0,0 +1,465 @@ +#include "kaleido.h" + +#include "soh/frame_interpolation.h" + +extern "C" { +#include "z64.h" +#include "functions.h" +#include "macros.h" +#include "variables.h" +#include +#include +extern PlayState* gPlayState; +} +#include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh_assets.h" +#include "textures/icon_item_static/icon_item_static.h" +#include "consolevariablebridge.h" +#include "soh/Enhancements/cosmetics/cosmeticsTypes.h" + +#include + +extern "C" { +void KaleidoScope_MoveCursorToSpecialPos(PlayState* play, u16 specialPos); +} + +namespace Rando { + + void KaleidoEntryIcon::LoadIconTex(std::vector* mEntryDl) { + if (mIconFormat == G_IM_FMT_IA) { + if (mIconSize == G_IM_SIZ_8b) { + Gfx iconTexture[] = { gsDPLoadTextureBlock(mIconResourceName, G_IM_FMT_IA, G_IM_SIZ_8b, mIconWidth, mIconHeight, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(iconTexture), std::end(iconTexture)); + } + } else if (mIconFormat == G_IM_FMT_RGBA) { + if (mIconSize == G_IM_SIZ_32b) { + Gfx iconTexture[] = { gsDPLoadTextureBlock(mIconResourceName, G_IM_FMT_RGBA, G_IM_SIZ_32b, mIconWidth, mIconHeight, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(iconTexture), std::end(iconTexture)); + } + } + } + + KaleidoEntry::KaleidoEntry(int16_t x, int16_t y, std::string text) : mX(x), mY(y), mText(std::move(text)) { + mHeight = 0; + mWidth = 0; + vtx = nullptr; + } + + void KaleidoEntry::SetYOffset(int yOffset) { + mY = yOffset; + } + + void KaleidoEntryIcon::Draw(PlayState* play, std::vector* mEntryDl) { + if (vtx == nullptr) { + return; + } + size_t numChar = mText.length(); + if (numChar == 0) { + return; + } + + Color_RGBA8 textColor = { 255, 255, 255, 255 }; + if (mAchieved) { + textColor = { 0x98, 0xFF, 0x44, 255 }; + } + + Matrix_Translate(mX, mY, 0.0f, MTXMODE_APPLY); + + mEntryDl->push_back(gsSPMatrix(Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW)); + + // icon + if (!mAchieved) { + mEntryDl->push_back(gsDPSetGrayscaleColor(109, 109, 109, 255)); + mEntryDl->push_back(gsSPGrayscale(true)); + } + mEntryDl->push_back(gsDPSetPrimColor(0, 0, mIconColor.r, mIconColor.g, mIconColor.b, mIconColor.a)); + mEntryDl->push_back(gsSPVertex(vtx, 4, 0)); + LoadIconTex(mEntryDl); + mEntryDl->push_back(gsSP1Quadrangle(0, 2, 3, 1, 0)); + mEntryDl->push_back(gsSPGrayscale(false)); + + // text + mEntryDl->push_back(gsDPSetPrimColor(0, 0, textColor.r, textColor.g, textColor.b, textColor.a)); + for (size_t i = 0, vtxGroup = 0; i < numChar; i++) { + uint16_t texIndex = mText[i] - 32; + + // A maximum of 64 Vtx can be loaded at once by gSPVertex, or basically 16 characters + // handle loading groups of 16 chars at a time until there are no more left to load. + // By this point 4 vertices have already been loaded for the preceding icon. + if (i % 16 == 0) { + size_t numVtxToLoad = std::min(numChar - i, 16) * 4; + mEntryDl->push_back(gsSPVertex(&vtx[4 + (vtxGroup * 16 * 4)], numVtxToLoad, 0)); + vtxGroup++; + } + + if (texIndex != 0) { + auto texture = reinterpret_cast(Font_FetchCharTexture(texIndex)); + auto vertexStart = static_cast(4 * (i % 16)); + + Gfx charTexture[] = {gsDPLoadTextureBlock_4b(texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, + FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD)}; + mEntryDl->insert(mEntryDl->end(), std::begin(charTexture), std::end(charTexture)); + mEntryDl->push_back( + gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); + } + } + mEntryDl->push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); + } + + Kaleido::Kaleido() { + const auto ctx = Rando::Context::GetInstance(); + int yOffset = 2; + mEntries.push_back(std::make_shared(gRupeeCounterIconTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, + Color_RGBA8{ 0xC8, 0xFF, 0x64, 255 }, FlagType::FLAG_RANDOMIZER_INF, + static_cast(RAND_INF_GREG_FOUND), 0, yOffset, "Greg")); + yOffset += 18; + if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { + mEntries.push_back( + std::make_shared( + gTriforcePieceTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255,255,255,255 }, 0, + yOffset, reinterpret_cast(&gSaveContext.triforcePiecesCollected), + ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).GetSelectedOptionIndex() + 1, + ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).GetSelectedOptionIndex() + 1)); + yOffset += 18; + } + if (ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS)) { + mEntries.push_back(std::make_shared(0, yOffset)); + yOffset += 18; + } + if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).IsNot(RO_BOSS_SOULS_OFF)) { + static const char* bossSoulNames[] = { + "Gohma's Soul", + "King Dodongo's Soul", + "Barinade's Soul", + "Phantom Ganon's Soul", + "Volvagia's Soul", + "Morpha's Soul", + "Bongo Bongo's Soul", + "Twinrova's Soul", + }; + for (int i = RAND_INF_GOHMA_SOUL; i < RAND_INF_GANON_SOUL; i++) { + mEntries.push_back( + std::make_shared( + gBossSoulTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, i, 0, yOffset, bossSoulNames[i - RAND_INF_GOHMA_SOUL] + ) + ); + yOffset += 18; + } + } + if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) { + mEntries.push_back( + std::make_shared( + gBossSoulTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, RAND_INF_GANON_SOUL, 0, yOffset, "Ganon's Soul" + ) + ); + yOffset += 18; + } + } + + extern "C" { + void FrameInterpolation_RecordCloseChild(void); + void FrameInterpolation_RecordOpenChild(const void* a, int b); + } + + void Kaleido::Draw(PlayState* play) { + if (play == nullptr || mEntries.empty()) { + return; + } + PauseContext* pauseCtx = &play->pauseCtx; + Input* input = &play->state.input[0]; + mEntryDl.clear(); + OPEN_DISPS(play->state.gfxCtx); + mEntryDl.push_back(gsDPPipeSync()); + Gfx_SetupDL_42Opa(play->state.gfxCtx); + mEntryDl.push_back(gsDPSetCombineMode(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM)); + + // Move the matrix origin to the top-left corner of the kaleido page + Matrix_Translate(-108.f, 58.f, 0.0f, MTXMODE_APPLY); + // Invert the matrix to render vertices with positive going down + Matrix_Scale(1.0f, -1.0f, 1.0f, MTXMODE_APPLY); + // The scrolling logic is in here because the built in kaleido input throttling happens + // in its Draw functions, which get called after their update functions. I hate it but fixing + // it would be a much larger Kaleido change. + bool shouldScroll = false; + bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0); + if ((!pauseCtx->unk_1E4 || (pauseCtx->unk_1E4 == 5) || (pauseCtx->unk_1E4 == 8)) && + (pauseCtx->pageIndex == PAUSE_QUEST)) { + if (pauseCtx->cursorSpecialPos == 0) { + if ((pauseCtx->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { + if (mTopIndex > 0) { + mTopIndex--; + shouldScroll = true; + } + } else if ((pauseCtx->stickRelY < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) { + if (mTopIndex + mNumVisible < mEntries.size()) { + mTopIndex++; + shouldScroll = true; + } + } + if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_LEFT); + pauseCtx->unk_1E4 = 0; + } else if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT); + pauseCtx->unk_1E4 = 0; + } + } else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT) { + if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { + pauseCtx->cursorSpecialPos = 0; + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } + } else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_RIGHT) { + if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { + pauseCtx->cursorSpecialPos = 0; + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } + } + } + int yOffset = 2; + for (int i = mTopIndex; i < (mTopIndex + mNumVisible) && i < mEntries.size(); i++) { + auto& entry = mEntries[i]; + if (shouldScroll) { + entry->SetYOffset(yOffset); + yOffset += 18; + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } + Matrix_Push(); + entry->Draw(play, &mEntryDl); + Matrix_Pop(); + } + + mEntryDl.push_back(gsSPEndDisplayList()); + gSPDisplayList(POLY_KAL_DISP++, mEntryDl.data()); + CLOSE_DISPS(play->state.gfxCtx); + } + + void Kaleido::Update(PlayState *play) { + for(int i = mTopIndex; i < (mTopIndex + mNumVisible) && i < mEntries.size(); i++) { + const auto& entry = mEntries[i]; + entry->Update(play); + } + } + + extern "C" void RandoKaleido_DrawMiscCollectibles(PlayState* play) { + OTRGlobals::Instance->gRandoContext->GetKaleido()->Draw(play); + } + + extern "C" void RandoKaleido_UpdateMiscCollectibles(int16_t inDungeonScene) { + PauseContext* pauseCtx = &gPlayState->pauseCtx; + if (pauseCtx->randoQuestMode && pauseCtx->pageIndex == PAUSE_QUEST) { + OTRGlobals::Instance->gRandoContext->GetKaleido()->Update(gPlayState); + } + } + + KaleidoEntryIconFlag::KaleidoEntryIconFlag(const char *iconResourceName, int iconFormat, int iconSize, int iconWidth, + int iconHeight, Color_RGBA8 iconColor, FlagType flagType, int flag, + int16_t x, int16_t y, std::string name) : + mFlagType(flagType), mFlag(flag), + KaleidoEntryIcon(iconResourceName, iconFormat, iconSize, iconWidth, iconHeight, iconColor, x, y, std::move(name)) { + BuildVertices(); + } + + void KaleidoEntryIconFlag::Update(PlayState* play) { + mAchieved = GameInteractor::RawAction::CheckFlag(mFlagType, static_cast(mFlag)); + } + + KaleidoEntryIconCountRequired::KaleidoEntryIconCountRequired(const char *iconResourceName, int iconFormat, + int iconSize, int iconWidth, int iconHeight, Color_RGBA8 iconColor, int16_t x, int16_t y, int* watch, + int required, int total) : mWatch(watch), mRequired(required), mTotal(total), + KaleidoEntryIcon(iconResourceName, iconFormat, iconSize, iconWidth, iconHeight, iconColor, x, y) { + mCount = *mWatch; + BuildText(); + BuildVertices(); + } + + void KaleidoEntryIconCountRequired::BuildText() { + std::ostringstream totals; + totals << mCount; + if (mRequired != 0 && mCount < mRequired) { + totals << '/' << mRequired; + } + if (mTotal >= mRequired && mCount >= mRequired) { + totals << '/' << mTotal; + } + mText = totals.str(); + } + + void KaleidoEntryIcon::BuildVertices() { + int offsetY = 0; + int offsetX = 0; + // 4 vertices per character, plus one for the preceding icon. + Vtx* vertices = (Vtx*)calloc(sizeof(Vtx[4]), mText.length() + 1); + // Vertex for the preceding icon. + Interface_CreateQuadVertexGroup(vertices, offsetX, offsetY, mIconWidth, mIconHeight, 0); + offsetX += 18; + for (size_t i = 0; i < mText.length(); i++) { + auto charIndex = static_cast(mText[i] - 32); + int charWidth = 0; + if (charIndex >= 0) { + charWidth = static_cast(Message_GetCharacterWidth(charIndex) * (100.0f / R_TEXT_CHAR_SCALE)); + } + Interface_CreateQuadVertexGroup(&(vertices)[(i + 1) * 4], offsetX, offsetY, charWidth, 16, 0); + offsetX += charWidth; + } + offsetY += FONT_CHAR_TEX_HEIGHT; + mWidth = static_cast(offsetX); + mHeight = static_cast(offsetY); + + vertices[1].v.ob[0] = 16; + vertices[2].v.ob[1] = 16; + vertices[3].v.ob[0] = 16; + vertices[3].v.ob[1] = 16; + vtx = vertices; + } + + KaleidoEntryIcon::KaleidoEntryIcon(const char *iconResourceName, int iconFormat, int iconSize, int iconWidth, + int iconHeight, Color_RGBA8 iconColor, int16_t x, int16_t y, std::string text) + : mIconResourceName(iconResourceName), mIconFormat(iconFormat), mIconSize(iconSize), + mIconWidth(iconWidth), mIconHeight(iconHeight), mIconColor(iconColor), + KaleidoEntry(x, y, std::move(text)) {} + + void KaleidoEntryIcon::RebuildVertices() { + free(vtx); + vtx = nullptr; + BuildVertices(); + } + + void KaleidoEntryIconCountRequired::Update(PlayState *play) { + if (mCount != *mWatch) { + mCount = *mWatch; + BuildText(); + RebuildVertices(); + mAchieved = mCount >= mRequired; + } + + } + + KaleidoEntryOcarinaButtons::KaleidoEntryOcarinaButtons(int16_t x, int16_t y) : + KaleidoEntryIcon(gItemIconOcarinaOfTimeTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, + Color_RGBA8{ 255, 255, 255, 255 }, x, y, "\x9F\xA5\xA6\xA7\xA8") { + CalculateColors(); + BuildVertices(); + } + + void KaleidoEntryOcarinaButtons::CalculateColors() { + Color_RGB8 aButtonColor = { 80, 150, 255 }; + if (CVarGetInteger(CVAR_COSMETIC("HUD.AButton.Changed"), 0)) { + aButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.AButton.Value"), aButtonColor); + } else if (CVarGetInteger(CVAR_COSMETIC("DefaultColorScheme"), COLORSCHEME_N64) == COLORSCHEME_GAMECUBE) { + aButtonColor = { 80, 255, 150}; + } + mButtonColors[0] = { aButtonColor.r, aButtonColor.g, aButtonColor.b, 255 }; + Color_RGB8 cButtonsColor = { 255, 255, 50 }; + Color_RGB8 cUpButtonColor = cButtonsColor; + Color_RGB8 cDownButtonColor = cButtonsColor; + Color_RGB8 cLeftButtonColor = cButtonsColor; + Color_RGB8 cRightButtonColor = cButtonsColor; + if (CVarGetInteger(CVAR_COSMETIC("HUD.CButtons.Changed"), 0)) { + cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); + cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); + cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); + cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); + } + if (CVarGetInteger(CVAR_COSMETIC("HUD.CUpButton.Changed"), 0)) { + cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CUpButton.Value"), cUpButtonColor); + } + if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.Changed"), 0)) { + cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CDownButton.Value"), cDownButtonColor); + } + if (CVarGetInteger(CVAR_COSMETIC("HUD.CLeftButton.Changed"), 0)) { + cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CLeftButton.Value"), cLeftButtonColor); + } + if (CVarGetInteger(CVAR_COSMETIC("HUD.CRightButton.Changed"), 0)) { + cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CRightButton.Value"), cRightButtonColor); + } + mButtonColors[1] = { cUpButtonColor.r, cUpButtonColor.g, cUpButtonColor.b, 255 }; + mButtonColors[2] = { cDownButtonColor.r, cDownButtonColor.g, cDownButtonColor.b, 255 }; + mButtonColors[3] = { cLeftButtonColor.r, cLeftButtonColor.g, cLeftButtonColor.b, 255 }; + mButtonColors[4] = { cRightButtonColor.r, cRightButtonColor.g, cRightButtonColor.b, 255 }; + } + + void KaleidoEntryOcarinaButtons::Update(PlayState *play) { + mButtonCollected[0] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_A) > 0; + mButtonCollected[1] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_UP) > 0; + mButtonCollected[2] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_DOWN) > 0; + mButtonCollected[3] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_LEFT) > 0; + mButtonCollected[4] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_RIGHT) > 0; + CalculateColors(); + mAchieved = false; + for (int i = 0; i < mButtonCollected.size(); i++) { + if (!mButtonCollected[i]) { + mButtonColors[i] = Color_RGBA8{ 109, 109, 109, 255 }; + } else { + mAchieved = true; + } + } + } + + void KaleidoEntryOcarinaButtons::Draw(PlayState *play, std::vector* mEntryDl) { + if (vtx == nullptr) { + return; + } + size_t numChar = mText.length(); + if (numChar == 0) { + return; + } + + Matrix_Translate(mX, mY, 0.0f, MTXMODE_APPLY); +// Matrix_Scale(0.75f, 0.75f, 0.75f, MTXMODE_APPLY); + + mEntryDl->push_back(gsSPMatrix(Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW)); + + // icon + if (!mAchieved) { + mEntryDl->push_back(gsDPSetGrayscaleColor(109, 109, 109, 255)); + mEntryDl->push_back(gsSPGrayscale(true)); + } + mEntryDl->push_back(gsDPSetPrimColor(0, 0, mIconColor.r, mIconColor.g, mIconColor.b, mIconColor.a)); + mEntryDl->push_back(gsSPVertex(vtx, 4, 0)); + LoadIconTex(mEntryDl); + mEntryDl->push_back(gsSP1Quadrangle(0, 2, 3, 1, 0)); + mEntryDl->push_back(gsSPGrayscale(false)); + + // text + for (size_t i = 0, vtxGroup = 0; i < numChar; i++) { + mEntryDl->push_back(gsDPSetPrimColor(0, 0, mButtonColors[i].r, mButtonColors[i].g, mButtonColors[i].b, mButtonColors[i].a)); + uint16_t texIndex = mText[i] - 32; + + // A maximum of 64 Vtx can be loaded at once by gSPVertex, or basically 16 characters + // handle loading groups of 16 chars at a time until there are no more left to load. + // By this point 4 vertices have already been loaded for the preceding icon. + if (i % 16 == 0) { + size_t numVtxToLoad = std::min(numChar - i, 16) * 4; + mEntryDl->push_back(gsSPVertex(&vtx[4 + (vtxGroup * 16 * 4)], numVtxToLoad, 0)); + vtxGroup++; + } + + if (texIndex != 0) { + auto texture = reinterpret_cast(Font_FetchCharTexture(texIndex)); + auto vertexStart = static_cast(4 * (i % 16)); + + Gfx charTexture[] = {gsDPLoadTextureBlock_4b(texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, + FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD)}; + mEntryDl->insert(mEntryDl->end(), std::begin(charTexture), std::end(charTexture)); + mEntryDl->push_back( + gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); + } + } + mEntryDl->push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); + } +} // Rando + +void RandoKaleido_RegisterHooks() { + GameInteractor::Instance->RegisterGameHook(RandoKaleido_UpdateMiscCollectibles); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/kaleido.h b/soh/soh/Enhancements/kaleido.h new file mode 100644 index 00000000000..db86a817e90 --- /dev/null +++ b/soh/soh/Enhancements/kaleido.h @@ -0,0 +1,176 @@ +#ifndef KALEIDO_H +#define KALEIDO_H +#include + + +#ifdef __cplusplus +#include +#include +#include + +namespace Rando { + +/** + * Base class for all Kaleido Entries in our Rando Collectibles list. + * Stores the common aspects such as the line of text, positioning, + * vertices, and whether or not the goal has been achieved (subclasses + * can use this to change their rendering). Also sets an interface for + * subclasses to declare their Draw and Update functions. + */ +class KaleidoEntry { +public: + /** + * @brief Constructor for Base KaleidoEntry class. Sets the position and + * initial value of the line of text. + * @param x x coordinate relative to the current matrix origin. + * @param y y coordinate relative to the current matrix origin. + * @param text the initial value of the line of text. Can be omitted for an + * empty string. + */ + KaleidoEntry(int16_t x, int16_t y, std::string text = ""); + virtual void Draw(PlayState* play, std::vector* mEntryDl) = 0; + virtual void Update(PlayState* play) = 0; + void SetYOffset(int yOffset); +protected: + int16_t mX; + int16_t mY; + int16_t mHeight; + int16_t mWidth; + Vtx* vtx; + std::string mText; + bool mAchieved = false; + +}; + +/** + * Subclass of KaleidoEntry intended to be a parent class for any KaleidoEntry subclasses + * that wish to render an Icon at the start of their line. + */ +class KaleidoEntryIcon : public KaleidoEntry { +public: + /** + * @param iconResourceName resource name of the icon to draw + * @param iconFormat flag representing the format of the icon (i.e. G_IM_FMT_IA) + * @param iconSize flag representing the size of the icon in bytes (i.e. G_IM_SIZ_8b) + * @param iconWidth pixel width of the source icon image + * @param iconHeight pixel height of the source icon image + * @param iconColor Color to shade the icon with. This may be ignored for certain icon formats + * @param x x coordinate of the location to draw this relative to the parent matrix's origin. + * @param y y coordinate of the location to draw this relative to the parent matrix's origin. + * @param text text to draw to the right of the icon. + */ + KaleidoEntryIcon(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, int iconHeight, + Color_RGBA8 iconColor, int16_t x, int16_t y, std::string text = ""); + void Draw(PlayState* play, std::vector* mEntryDl) override; + void RebuildVertices(); +protected: + const char* mIconResourceName; + int mIconFormat; + int mIconSize; + int mIconWidth; + int mIconHeight; + Color_RGBA8 mIconColor; + + void BuildVertices(); + void LoadIconTex(std::vector* mEntryDl); +}; + +/** + * Class representing a Kaleido Entry that can be represented with an icon + * that is either colored in or Grayscale according to a flag + */ +class KaleidoEntryIconFlag : public KaleidoEntryIcon { +public : + /** + * @param iconResourceName resource name of the icon to draw + * @param iconFormat flag representing the format of the icon (i.e. G_IM_FMT_IA) + * @param iconSize flag representing the size of the icon in bytes (i.e. G_IM_SIZ_8b) + * @param iconWidth pixel width of the source icon image + * @param iconHeight pixel height of the source icon image + * @param iconColor Color to shade the icon with. This may be ignored for certain icon formats + * @param flagType FlagType of the flag to check for (i.e. FlagType::FLAG_RANDOMIZER_INF + * @param flag flag to check for. An integer can be provided but enum values should be preferred + * @param x x coordinate of the location to draw this relative to the parent matrix's origin. + * @param y y coordinate of the location to draw this relative to the parent matrix's origin. + * @param mName name to draw to the right of the icon. Leave blank to omit. + */ + KaleidoEntryIconFlag(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, int iconHeight, + Color_RGBA8 iconColor, FlagType flagType, int flag, int16_t x, int16_t y, + std::string name = ""); + void Update(PlayState* play) override; +private: + FlagType mFlagType; + int mFlag; +}; + +/** + * KaleidoEntryIcon subclass to render a count of how many collectibles have been collected. + * The `required` and `total` values can be omitted from the constructor or set to 0 to only + * render the count and not show progress towards a required amount or a total. + */ +class KaleidoEntryIconCountRequired : public KaleidoEntryIcon { +public: + /** + * @param iconResourceName resource name of the icon to draw + * @param iconFormat flag representing the format of the icon (i.e. G_IM_FMT_IA) + * @param iconSize flag representing the size of the icon in bytes (i.e. G_IM_SIZ_8b) + * @param iconWidth pixel width of the source icon image + * @param iconHeight pixel height of the source icon image + * @param iconColor Color to shade the icon with. This may be ignored for certain icon formats + * @param flagType FlagType of the flag to check for (i.e. FlagType::FLAG_RANDOMIZER_INF + * @param flag flag to check for. An integer can be provided but enum values should be preferred + * @param x x coordinate of the location to draw this relative to the parent matrix's origin. + * @param y y coordinate of the location to draw this relative to the parent matrix's origin. + * @param watch a pointer to an integer value to watch. Update will check this value to update + * a local count variable. + * @param required The amount of this collectible required to beat the seed. Set to 0 to not render. + * @param total The amount of this collectible available in the seed. Set to 0 to not render. + */ + KaleidoEntryIconCountRequired(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, int iconHeight, + Color_RGBA8 iconColor, int16_t x, int16_t y, int* watch, int required = 0, int total = 0); + void Update(PlayState* play) override; +private: + int* mWatch; + int mRequired; + int mTotal; + int mCount; + + void BuildText(); +}; + +class KaleidoEntryOcarinaButtons : public KaleidoEntryIcon { +public: + KaleidoEntryOcarinaButtons(int16_t x, int16_t y); + void Update(PlayState* play) override; + void Draw(PlayState* play, std::vector* mEntryDl) override; +private: + void CalculateColors(); + + std::array mButtonColors = {}; + std::array mButtonCollected = {}; +}; + +class Kaleido { +public: + Kaleido(); + void Draw(PlayState* play); + void Update(PlayState* play); +private: + std::vector> mEntries; + std::vector mEntryDl; + int mTopIndex = 0; + int mNumVisible = 7; +}; +} // Rando + +extern "C" { +#endif +void RandoKaleido_DrawMiscCollectibles(PlayState* play); +void RandoKaleido_UpdateMiscCollectibles(int16_t inDungeonScene); +#ifdef __cplusplus +} +#endif +void RandoKaleido_RegisterHooks(); + + +#endif //KALEIDO_H diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 9a3988e39a5..adac0d96812 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -3,12 +3,17 @@ #include "game-interactor/GameInteractor.h" #include "tts/tts.h" #include "soh/OTRGlobals.h" -#include "soh/Enhancements/boss-rush/BossRushTypes.h" +#include "soh/Enhancements/boss-rush/BossRush.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/randomizer/3drando/random.hpp" #include "soh/Enhancements/cosmetics/authenticGfxPatches.h" #include #include "soh/Enhancements/nametag.h" +#include "soh/Enhancements/timesaver_hook_handlers.h" +#include "soh/Enhancements/TimeSavers/TimeSavers.h" +#include "soh/Enhancements/cheat_hook_handlers.h" +#include "soh/Enhancements/randomizer/hook_handlers.h" +#include "objects/object_gi_compass/object_gi_compass.h" #include "src/overlays/actors/ovl_En_Bb/z_en_bb.h" #include "src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.h" @@ -23,9 +28,14 @@ #include "src/overlays/actors/ovl_En_Tp/z_en_tp.h" #include "src/overlays/actors/ovl_En_Firefly/z_en_firefly.h" #include "src/overlays/actors/ovl_En_Xc/z_en_xc.h" +#include "src/overlays/actors/ovl_Fishing/z_fishing.h" #include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h" +#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" +#include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h" +#include "src/overlays/actors/ovl_En_Door/z_en_door.h" #include "objects/object_link_boy/object_link_boy.h" #include "objects/object_link_child/object_link_child.h" +#include "kaleido.h" extern "C" { #include @@ -66,7 +76,7 @@ void ReloadSceneTogglingLinkAge() { void RegisterInfiniteMoney() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; - if (CVarGetInteger(CVAR_CHEAT("InfiniteMoney"), 0) != 0) { + if (CVarGetInteger(CVAR_CHEAT("InfiniteMoney"), 0) != 0 && (!IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_WALLET))) { if (gSaveContext.rupees < CUR_CAPACITY(UPG_WALLET)) { gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET); } @@ -335,7 +345,7 @@ void AutoSave(GetItemEntry itemEntry) { case ITEM_BOMBCHU: case ITEM_BOMBCHUS_5: case ITEM_BOMBCHUS_20: - if (!CVarGetInteger(CVAR_ENHANCEMENT("BombchuDrops"), 0)) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("EnableBombchuDrops"), 0)) { performSave = true; } break; @@ -428,7 +438,7 @@ void UpdatePermanentHeartLossState() { if (!CVarGetInteger(CVAR_ENHANCEMENT("PermanentHeartLoss"), 0) && hasAffectedHealth) { uint8_t heartContainers = gSaveContext.sohStats.heartContainers; // each worth 16 health uint8_t heartPieces = gSaveContext.sohStats.heartPieces; // each worth 4 health, but only in groups of 4 - uint8_t startingHealth = 16 * 3; + uint8_t startingHealth = 16 * (IS_RANDO ? (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_HEARTS) + 1) : 3); uint8_t newCapacity = startingHealth + (heartContainers * 16) + ((heartPieces - (heartPieces % 4)) * 4); @@ -683,7 +693,8 @@ void UpdateMirrorModeState(int32_t sceneNum) { (sceneNum == SCENE_GANON_BOSS); if (mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) { - uint32_t seed = sceneNum + (IS_RANDO ? gSaveContext.finalSeed : gSaveContext.sohStats.fileCreatedAt); + uint32_t seed = sceneNum + (IS_RANDO ? Rando::Context::GetInstance()->GetSettings()->GetSeed() + : gSaveContext.sohStats.fileCreatedAt); Random_Init(seed); } @@ -773,48 +784,6 @@ void RegisterResetNaviTimer() { }); } -f32 triforcePieceScale; - -void RegisterTriforceHunt() { - GameInteractor::Instance->RegisterGameHook([]() { - if (!GameInteractor::IsGameplayPaused() && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) { - - // Warp to credits - if (GameInteractor::State::TriforceHuntCreditsWarpActive) { - gPlayState->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; - gSaveContext.nextCutsceneIndex = 0xFFF2; - gPlayState->transitionTrigger = TRANS_TRIGGER_START; - gPlayState->transitionType = TRANS_TYPE_FADE_WHITE; - GameInteractor::State::TriforceHuntCreditsWarpActive = 0; - } - - // Reset Triforce Piece scale for GI animation. Triforce Hunt allows for multiple triforce models, - // and cycles through them based on the amount of triforce pieces collected. It takes a little while - // for the count to increase during the GI animation, so the model is entirely hidden until that piece - // has been added. That scale has to be reset after the textbox is closed, and this is the best way - // to ensure it's done at that point in time specifically. - if (GameInteractor::State::TriforceHuntPieceGiven) { - triforcePieceScale = 0.0f; - GameInteractor::State::TriforceHuntPieceGiven = 0; - } - } - }); -} - -void RegisterGrantGanonsBossKey() { - GameInteractor::Instance->RegisterGameHook([]() { - // Triforce Hunt needs the check if the player isn't being teleported to the credits scene. - if (!GameInteractor::IsGameplayPaused() && IS_RANDO && - Flags_GetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY) && gPlayState->transitionTrigger != TRANS_TRIGGER_START && - (1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0) { - GetItemEntry getItemEntry = - ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY); - GiveItemEntryWithoutActor(gPlayState, getItemEntry); - } - }); -} - //this map is used for enemies that can be uniquely identified by their id //and that are always counted //enemies that can't be uniquely identified by their id @@ -862,7 +831,7 @@ static std::unordered_map uniqueEnemyIdToStatCount = { void RegisterEnemyDefeatCounts() { GameInteractor::Instance->RegisterGameHook([](void* refActor) { - Actor* actor = (Actor*)refActor; + Actor* actor = static_cast(refActor); if (uniqueEnemyIdToStatCount.contains(actor->id)) { gSaveContext.sohStats.count[uniqueEnemyIdToStatCount[actor->id]]++; } else { @@ -1006,6 +975,45 @@ void RegisterEnemyDefeatCounts() { }); } +void RegisterBossDefeatTimestamps() { + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + Actor* actor = static_cast(refActor); + switch (actor->id) { + case ACTOR_BOSS_DODONGO: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_KING_DODONGO] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_FD2: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_VOLVAGIA] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_GANON: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANONDORF] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_GANON2: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + gSaveContext.sohStats.gameComplete = true; + break; + case ACTOR_BOSS_GANONDROF: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_PHANTOM_GANON] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_GOMA: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GOHMA] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_MO: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_MORPHA] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_SST: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BONGO_BONGO] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_TW: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_TWINROVA] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case ACTOR_BOSS_VA: + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_BARINADE] = GAMEPLAYSTAT_TOTAL_TIME; + break; + } + }); +} + typedef enum { ADD_ICE_TRAP, ADD_BURN_TRAP, @@ -1154,28 +1162,6 @@ void RegisterAltTrapTypes() { }); } -void RegisterRandomizerSheikSpawn() { - GameInteractor::Instance->RegisterGameHook([]() { - if (!gPlayState) return; - bool canSheik = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIAL_COUNT) != RO_GANONS_TRIALS_SKIP && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LIGHT_ARROWS_HINT)); - if (!IS_RANDO || !LINK_IS_ADULT || !canSheik) return; - switch (gPlayState->sceneNum) { - case SCENE_TEMPLE_OF_TIME: - if (gPlayState->roomCtx.curRoom.num == 1) { - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, -104, -40, 2382, 0, 0x8000, 0, SHEIK_TYPE_RANDO, false); - } - break; - case SCENE_INSIDE_GANONS_CASTLE: - if (gPlayState->roomCtx.curRoom.num == 1){ - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, 101, 150, 137, 0, 0, 0, SHEIK_TYPE_RANDO, false); - } - break; - default: break; - } - }); -} - void UpdateHurtContainerModeState(bool newState) { static bool hurtEnabled = false; if (hurtEnabled == newState) { @@ -1394,7 +1380,32 @@ void RegisterPauseMenuHooks() { }); } +extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); + +void PatchCompasses() { + s8 compassesCanBeOutsideDungeon = IS_RANDO && DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_SHUFFLE_MAPANDCOMPASS); + s8 isColoredCompassesEnabled = compassesCanBeOutsideDungeon && CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MatchCompassColors"), 1); + if (isColoredCompassesEnabled) { + ResourceMgr_PatchGfxByName(gGiCompassDL, "Compass_PrimColor", 5, gsDPNoOp()); + ResourceMgr_PatchGfxByName(gGiCompassDL, "Compass_EnvColor", 6, gsDPNoOp()); + } else { + ResourceMgr_UnpatchGfxByName(gGiCompassDL, "Compass_PrimColor"); + ResourceMgr_UnpatchGfxByName(gGiCompassDL, "Compass_EnvColor"); + } +} + +void RegisterRandomizerCompasses() { + GameInteractor::Instance->RegisterGameHook([](int32_t _unused) { + PatchCompasses(); + }); +} + void InitMods() { + BossRush_RegisterHooks(); + RandomizerRegisterHooks(); + TimeSaverRegisterHooks(); + CheatsRegisterHooks(); + TimeSavers_Register(); RegisterTTS(); RegisterInfiniteMoney(); RegisterInfiniteHealth(); @@ -1420,17 +1431,17 @@ void InitMods() { RegisterMenuPathFix(); RegisterMirrorModeHandler(); RegisterResetNaviTimer(); - RegisterTriforceHunt(); - RegisterGrantGanonsBossKey(); RegisterEnemyDefeatCounts(); + RegisterBossDefeatTimestamps(); RegisterAltTrapTypes(); - RegisterRandomizerSheikSpawn(); RegisterRandomizedEnemySizes(); RegisterOpenAllHours(); RegisterToTMedallions(); + RegisterRandomizerCompasses(); NameTag_RegisterHooks(); RegisterFloorSwitchesHook(); RegisterPatchHandHandler(); RegisterHurtContainerModeHandler(); RegisterPauseMenuHooks(); + RandoKaleido_RegisterHooks(); } diff --git a/soh/soh/Enhancements/mods.h b/soh/soh/Enhancements/mods.h index 2755924f20c..b70cda286d0 100644 --- a/soh/soh/Enhancements/mods.h +++ b/soh/soh/Enhancements/mods.h @@ -11,6 +11,7 @@ void UpdateDirtPathFixState(int32_t sceneNum); void UpdateMirrorModeState(int32_t sceneNum); void UpdateHurtContainerModeState(bool newState); void PatchToTMedallions(); +void PatchCompasses(); void UpdatePermanentHeartLossState(); void UpdateHyperEnemiesState(); void UpdateHyperBossesState(); diff --git a/soh/soh/Enhancements/presets.cpp b/soh/soh/Enhancements/presets.cpp index 57bfd689cad..0a2582c4afa 100644 --- a/soh/soh/Enhancements/presets.cpp +++ b/soh/soh/Enhancements/presets.cpp @@ -42,7 +42,10 @@ void applyPreset(std::vector entries) { void DrawPresetSelector(PresetType presetTypeId) { const std::string presetTypeCvar = CVAR_GENERAL("SelectedPresets.") + std::to_string(presetTypeId); const PresetTypeDefinition presetTypeDef = presetTypes.at(presetTypeId); - const uint16_t selectedPresetId = CVarGetInteger(presetTypeCvar.c_str(), 0); + uint16_t selectedPresetId = CVarGetInteger(presetTypeCvar.c_str(), 0); + if(selectedPresetId >= presetTypeDef.presets.size()){ + selectedPresetId = 0; + } const PresetDefinition selectedPresetDef = presetTypeDef.presets.at(selectedPresetId); std::string comboboxTooltip = ""; for ( auto iter = presetTypeDef.presets.begin(); iter != presetTypeDef.presets.end(); ++iter ) { diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index 450eca919e7..98c5eead1d9 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 { @@ -82,7 +83,7 @@ const std::vector enhancementsCvars = { CVAR_ENHANCEMENT("NoForcedNavi"), CVAR_ENHANCEMENT("SkulltulaFreeze"), CVAR_ENHANCEMENT("MMBunnyHood"), - CVAR_ENHANCEMENT("AdultBunnyHood"), + CVAR_ENHANCEMENT("AdultMasks"), CVAR_ENHANCEMENT("FastChests"), CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CVAR_ENHANCEMENT("FastDrops"), @@ -99,7 +100,7 @@ const std::vector enhancementsCvars = { CVAR_ENHANCEMENT("BonkDamageMult"), CVAR_ENHANCEMENT("NoRandomDrops"), CVAR_ENHANCEMENT("NoHeartDrops"), - CVAR_ENHANCEMENT("BombchuDrops"), + CVAR_ENHANCEMENT("EnableBombchuDrops"), CVAR_ENHANCEMENT("GoronPot"), CVAR_ENHANCEMENT("FullHealthSpawn"), CVAR_ENHANCEMENT("DampeWin"), @@ -218,6 +219,7 @@ const std::vector enhancementsCvars = { CVAR_ENHANCEMENT("BowSlingshotAmmoFix"), CVAR_ENHANCEMENT("BetterFarore"), CVAR_ENHANCEMENT("DisableFirstPersonChus"), + CVAR_ENHANCEMENT("BetterBombchuShopping"), CVAR_ENHANCEMENT("HyperBosses"), CVAR_ENHANCEMENT("RupeeDash"), CVAR_ENHANCEMENT("RupeeDashInterval"), @@ -284,6 +286,20 @@ const std::vector enhancementsCvars = { CVAR_ENHANCEMENT("PermanentHeartLoss"), CVAR_ENHANCEMENT("RemoveExplosiveLimit"), CVAR_ENHANCEMENT("ToggleStrength"), + CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), + CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), + CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), + CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), + CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"), + CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), + CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), + CVAR_ENHANCEMENT("TimeSavers.NoForcedDialog"), + CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), + CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), + CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), + CVAR_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), + CVAR_ENHANCEMENT("TimeSavers.SkipChildStealth"), + CVAR_ENHANCEMENT("TimeSavers.SkipTowerEscape"), }; const std::vector cheatCvars = { @@ -383,6 +399,10 @@ const std::vector randomizerCvars = { CVAR_RANDOMIZER_SETTING("ExcludedLocations"), CVAR_RANDOMIZER_SETTING("Forest"), CVAR_RANDOMIZER_SETTING("FullWallets"), + CVAR_RANDOMIZER_SETTING("FishingPoleHint"), + CVAR_RANDOMIZER_SETTING("Fishsanity"), + CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), + CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), CVAR_RANDOMIZER_SETTING("GanonTrial"), CVAR_RANDOMIZER_SETTING("GanonTrialCount"), CVAR_RANDOMIZER_SETTING("GerudoFortress"), @@ -401,6 +421,7 @@ const std::vector randomizerCvars = { CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), CVAR_RANDOMIZER_SETTING("LacsStoneCount"), CVAR_RANDOMIZER_SETTING("LacsTokenCount"), + CVAR_RANDOMIZER_SETTING("GanondorfHint"), CVAR_RANDOMIZER_SETTING("LAHint"), CVAR_RANDOMIZER_SETTING("LinksPocket"), CVAR_RANDOMIZER_SETTING("LogicRules"), @@ -416,14 +437,23 @@ const std::vector randomizerCvars = { CVAR_RANDOMIZER_SETTING("RewardCount"), CVAR_RANDOMIZER_SETTING("ScrubText"), CVAR_RANDOMIZER_SETTING("Shopsanity"), + CVAR_RANDOMIZER_SETTING("ShopsanityCount"), CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), + CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"), + CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), + CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), + CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"), + CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"), + CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"), + CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), + CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), - CVAR_RANDOMIZER_SETTING("ShuffleBeans"), CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), CVAR_RANDOMIZER_SETTING("ShuffleCows"), CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), + CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), @@ -442,11 +472,29 @@ const std::vector randomizerCvars = { CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsWaterTemple"), CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), + CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"), + CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"), + CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"), + CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"), + CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"), + CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"), + CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), + CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), + CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"), CVAR_RANDOMIZER_SETTING("ShuffleOwlDrops"), CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), + CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), + CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"), + CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"), + CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"), + CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"), + CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"), + CVAR_RANDOMIZER_SETTING("ScrubstGiantWalletWeight"), + CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"), + CVAR_RANDOMIZER_SETTING("ScrubsPricesAffordable"), CVAR_RANDOMIZER_SETTING("ShuffleSongs"), CVAR_RANDOMIZER_SETTING("ShuffleTokens"), CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"), @@ -490,6 +538,7 @@ const std::vector randomizerCvars = { CVAR_RANDOMIZER_SETTING("SariaHint"), CVAR_RANDOMIZER_ENHANCEMENT("RandomizeRupeeNames"), CVAR_RANDOMIZER_SETTING("FrogsHint"), + CVAR_RANDOMIZER_SETTING("OoTHint"), CVAR_RANDOMIZER_ENHANCEMENT("RandoRelevantNavi"), CVAR_RANDOMIZER_ENHANCEMENT("QuestItemFanfares"), }; @@ -649,7 +698,7 @@ const std::vector enhancedPresetEntries = { // MM Bunny Hood PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST_AND_JUMP), // Adult Bunny Hood - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1), // Fast Chests PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), // Fast Drops @@ -692,6 +741,9 @@ const std::vector enhancedPresetEntries = { // Autosave PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_LOCATION_AND_MAJOR_ITEMS), + + // Bombchu shop doesn't sell out, and 10 bombchus cost 99 instead of 100 + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterBombchuShopping"), 1), }; const std::vector randomizerPresetEntries = { @@ -773,7 +825,7 @@ const std::vector randomizerPresetEntries = { // MM Bunny Hood PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST_AND_JUMP), // Adult Bunny Hood - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1), // Fast Chests PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), // Fast Drops @@ -879,7 +931,7 @@ const std::vector spockRacePresetEntries = { PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MarketSneak"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastBoomerang"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SeparateArrows"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1), @@ -929,12 +981,16 @@ const std::vector spockRacePresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsRewardCount"), 5), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubText"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_RANDOM), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_BALANCED), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_COUNT), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_AFFORDABLE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_ALL), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsPrice"), RO_PRICE_FIXED), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), 10), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildStealth"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1), @@ -947,7 +1003,7 @@ const std::vector spockRacePresetEntries = { }; const std::vector spockRaceNoLogicPresetEntries = { - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 6), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1), PRESET_ENTRY_S32(CVAR_CHEAT("EasyPauseBuffer"), 1), @@ -1011,9 +1067,12 @@ const std::vector spockRaceNoLogicPresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_NO_LOGIC), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubText"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_RANDOM), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_BALANCED), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 0), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeans"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_BEANS_ONLY), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchantPrices"), RO_PRICE_VANILLA), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_COUNT), @@ -1040,7 +1099,7 @@ const std::vector s6PresetEntries = { PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_BOTH), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 4), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_OPEN), @@ -1074,7 +1133,7 @@ const std::vector hellModePresetEntries = { PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_BOTH), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultBunnyHood"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE), @@ -1095,10 +1154,15 @@ const std::vector hellModePresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_NOTHING), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_RANDOM_NUMBER), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_DUNGEON_REWARDS), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_FOUR_ITEMS), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_SHOPSANITY_PRICE_TYCOON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_SPECIFIC_COUNT), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), RO_SHOPSANITY_COUNT_FOUR_ITEMS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_RANGE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), 0), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), 999), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeans"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_BEANS_ONLY), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchantPrices"), RO_PRICE_VANILLA), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleCows"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_ANYWHERE), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), 1), @@ -1108,7 +1172,8 @@ const std::vector hellModePresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_RANDOM), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_ALL), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsPrice"), RO_PRICE_CHEAP_BALANCED), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_ALL), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), 1), @@ -1122,6 +1187,123 @@ 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_SPECIFIC_COUNT), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), RO_SHOPSANITY_COUNT_FOUR_ITEMS), + //RANDOTODO add refactored price/scrub/merchant settings + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleCows"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSwim"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), RO_BOSS_SOULS_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_FISHSANITY_BOTH), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_ANYWHERE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_MEDALLIONS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), 6), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 4), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GossipStoneHints"), RO_GOSSIP_STONES_NEED_NOTHING), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("HintClarity"), RO_HINT_CLARITY_CLEAR), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("HintDistribution"), RO_HINT_DIST_STRONG), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("AltarHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanondorfHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SheikLAHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DampeHint"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GregHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SariaHint"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FrogsHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("OoTHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BiggoronHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoesHint"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ChickensHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MalonHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("HBAHint"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("WarpSongText"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubText"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("10GSHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("20GSHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("30GSHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("40GSHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("50GSHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MaskShopHint"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("InfiniteUpgrades"), RO_INF_UPGRADES_PROGRESSIVE), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkeletonKey"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ItemPool"), RO_ITEM_POOL_BALANCED), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IceTraps"), RO_ICE_TRAPS_NORMAL), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingOcarina"), RO_STARTING_OCARINA_FAIRY), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingDekuShield"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingKokiriSword"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMasterSword"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingConsumables"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FullWallets"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingEponasSong"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSariasSong"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSunsSong"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSongOfTime"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSongOfStorms"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMinuetOfForest"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingBoleroOfFire"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSerenadeOfWater"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingRequiemOfSpirit"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingNocturneOfShadow"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingPreludeOfLight"), RO_GENERIC_OFF), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingSkulltulaToken"), 0), + PRESET_ENTRY_S32("gRandomizeStartingHearts", 2), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), RO_GENERIC_ON), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), RO_GENERIC_ON), +}; + typedef struct PresetDefinition { const char* label; const char* description; @@ -1195,5 +1377,10 @@ const std::map presetTypes = { "All settings maxed but still using glitchless logic. Expect pain.", hellModePresetEntries } }, + { RANDOMIZER_PRESET_BENCHMARK, { + "Benchmark", + "Used for benchmarking the logic.", + BenchmarkPresetEntries + } }, } } } }; diff --git a/soh/soh/Enhancements/randomizer/3drando/category.hpp b/soh/soh/Enhancements/randomizer/3drando/category.hpp index f43b3ccbafe..fc230b43538 100644 --- a/soh/soh/Enhancements/randomizer/3drando/category.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/category.hpp @@ -1,24 +1,5 @@ #pragma once -enum class Category { - cNull, - cChestMinigame, - cDekuScrub, - cDekuScrubUpgrades, - cSkulltula, - cSong, - cSongDungeonReward, - cCow, - cShop, - cMerchant, - cVanillaSmallKey, - cVanillaGFSmallKey, - cVanillaBossKey, - cVanillaMap, - cVanillaCompass, - cAdultTrade, -}; - enum class OptionCategory { Setting, Toggle, diff --git a/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp b/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp index b7dd96ca7fc..64b75b67058 100644 --- a/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp @@ -1,5 +1,5 @@ #include "custom_messages.hpp" -#include "shops.hpp" +#include "../../custom-message/CustomMessageManager.h" #include "z64item.h" #include @@ -158,7 +158,7 @@ constexpr std::array DungeonColors = { CreateMessage(textId, unk_04, textBoxType, textBoxPosition, text.GetEnglish(), text.GetFrench(), text.GetSpanish()); } - Text AddColorsAndFormat(Text text, const std::vector& colors /*= {}*/) { + Text AddColorsAndFormat(Text text, const std::vector& colors /*= {}*/) { //for each language for (std::string* textStr : {&text.english, &text.french, &text.spanish}) { @@ -280,12 +280,12 @@ constexpr std::array DungeonColors = { std::string SET_SPEED(uint8_t x) { return "\x7F\x10"s + char(x); } - std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; } + std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; } //RANDOTODO just refernce the versions in CustomMessage std::string CURRENT_TIME() { return "\x7F\x17"s; } std::string UNSKIPPABLE() { return "\x7F\x19"s; } - std::string TWO_WAY_CHOICE() { return "\x7F\x1A\xFF\xFF\xFF\xFF"s; } + std::string TWO_WAY_CHOICE() { return "\x1B"s; } std::string NEWLINE() { return "\x7F\x1C"s; } - std::string COLOR(uint8_t x) { return "\x7F\x1D"s + char(x); } + std::string COLOR(std::string x) { return "\x7F\x1D"s + x; } std::string CENTER_TEXT() { return "\x7F\x1E"s; } std::string IF_NOT_MQ() { return "\x7F\x29"s; } std::string MQ_ELSE() { return "\x7F\x2A"s; } diff --git a/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp b/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp index c8029dc66cd..b9d2a08c63d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp @@ -7,15 +7,6 @@ #include "text.hpp" -#define QM_WHITE 0x00 -#define QM_RED 0x41 -#define QM_GREEN 0x42 -#define QM_BLUE 0x43 -#define QM_LBLUE 0x44 -#define QM_PINK 0x45 -#define QM_YELLOW 0x46 -#define QM_BLACK 0x47 - namespace CustomMessages { typedef struct { // In the true file format, offset is the offset into the QM file. @@ -73,7 +64,7 @@ typedef struct { std::string UNSKIPPABLE(); std::string TWO_WAY_CHOICE(); std::string NEWLINE(); - std::string COLOR(uint8_t x); + std::string COLOR(std::string x); std::string CENTER_TEXT(); std::string IF_NOT_MQ(); std::string MQ_ELSE(); diff --git a/soh/soh/Enhancements/randomizer/3drando/dungeon.cpp b/soh/soh/Enhancements/randomizer/3drando/dungeon.cpp deleted file mode 100644 index dd7ba681ddd..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/dungeon.cpp +++ /dev/null @@ -1,641 +0,0 @@ -#include "dungeon.hpp" - -#include "category.hpp" -#include "item_location.hpp" -#include "pool_functions.hpp" -#include "keys.hpp" - -namespace Dungeon { - -DungeonInfo::DungeonInfo(std::string name_, uint32_t hintKey_, uint32_t map_, uint32_t compass_, uint32_t smallKey_, - uint32_t keyRing_, uint32_t bossKey_, uint8_t vanillaKeyCount_, uint8_t mqKeyCount_, - std::vector vanillaLocations_, - std::vector mqLocations_, - std::vector sharedLocations_, - std::vector bossRoomLocations_) - : name(std::move(name_)), - hintKey(hintKey_), - map(map_), - compass(compass_), - smallKey(smallKey_), - keyRing(keyRing_), - bossKey(bossKey_), - vanillaKeyCount(vanillaKeyCount_), - mqKeyCount(mqKeyCount_), - vanillaLocations(std::move(vanillaLocations_)), - mqLocations(std::move(mqLocations_)), - sharedLocations(std::move(sharedLocations_)), - bossRoomLocations(std::move(bossRoomLocations_)) {} - -DungeonInfo::~DungeonInfo() = default; - -uint32_t DungeonInfo::GetHintKey() const { - return hintKey; -} - -uint32_t DungeonInfo::GetSmallKey() const { - return smallKey; -} - -uint32_t DungeonInfo::GetKeyRing() const { - return keyRing; -} - -uint32_t DungeonInfo::GetMap() const { - return map; -} - -uint32_t DungeonInfo::GetCompass() const { - return compass; -} - -uint32_t DungeonInfo::GetBossKey() const { - return bossKey; -} - -void DungeonInfo::PlaceVanillaMap() { - if (map == NONE) { - return; - } - - auto dungeonLocations = GetDungeonLocations(); - auto mapLocation = FilterFromPool(dungeonLocations, [](const uint32_t loc){ return Location(loc)->IsCategory(Category::cVanillaMap); })[0]; - PlaceItemInLocation(mapLocation, map); -} - -void DungeonInfo::PlaceVanillaCompass() { - if (compass == NONE) { - return; - } - - auto dungeonLocations = GetDungeonLocations(); - auto compassLocation = FilterFromPool(dungeonLocations, [](const uint32_t loc){ return Location(loc)->IsCategory(Category::cVanillaCompass); })[0]; - PlaceItemInLocation(compassLocation, compass); -} - -void DungeonInfo::PlaceVanillaBossKey() { - if (bossKey == NONE || bossKey == GANONS_CASTLE_BOSS_KEY) { - return; - } - - auto dungeonLocations = GetDungeonLocations(); - auto bossKeyLocation = FilterFromPool(dungeonLocations, [](const uint32_t loc){ return Location(loc)->IsCategory(Category::cVanillaBossKey); })[0]; - PlaceItemInLocation(bossKeyLocation, bossKey); -} - -void DungeonInfo::PlaceVanillaSmallKeys() { - if (smallKey == NONE) { - return; - } - - auto dungeonLocations = GetDungeonLocations(); - auto smallKeyLocations = FilterFromPool(dungeonLocations, [](const uint32_t loc){ return Location(loc)->IsCategory(Category::cVanillaSmallKey); }); - for (auto location : smallKeyLocations) { - PlaceItemInLocation(location, smallKey); - } -} - -//Gets the chosen dungeon locations for a playthrough (so either MQ or Vanilla) -std::vector DungeonInfo::GetDungeonLocations() const { - auto locations = masterQuest ? mqLocations : vanillaLocations; - AddElementsToPool(locations, sharedLocations); - AddElementsToPool(locations, bossRoomLocations); - return locations; -} - -//Gets all dungeon locations (MQ + Vanilla) -std::vector DungeonInfo::GetEveryLocation() const { - auto locations = vanillaLocations; - AddElementsToPool(locations, mqLocations); - AddElementsToPool(locations, sharedLocations); - AddElementsToPool(locations, bossRoomLocations); - return locations; -} - - DungeonInfo DekuTree = DungeonInfo("Deku Tree", DEKU_TREE, DEKU_TREE_MAP, DEKU_TREE_COMPASS, NONE, NONE, NONE, 0, 0, { - //Vanilla Locations - DEKU_TREE_MAP_CHEST, - DEKU_TREE_COMPASS_CHEST, - DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, - DEKU_TREE_BASEMENT_CHEST, - DEKU_TREE_SLINGSHOT_CHEST, - DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, - DEKU_TREE_GS_BASEMENT_BACK_ROOM, - DEKU_TREE_GS_BASEMENT_GATE, - DEKU_TREE_GS_BASEMENT_VINES, - DEKU_TREE_GS_COMPASS_ROOM, - }, { - //MQ Locations - DEKU_TREE_MQ_MAP_CHEST, - DEKU_TREE_MQ_COMPASS_CHEST, - DEKU_TREE_MQ_SLINGSHOT_CHEST, - DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, - DEKU_TREE_MQ_BASEMENT_CHEST, - DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, - DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, - DEKU_TREE_MQ_DEKU_SCRUB, - DEKU_TREE_MQ_GS_LOBBY, - DEKU_TREE_MQ_GS_COMPASS_ROOM, - DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, - DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, - }, - {}, - { - // Boss Room Locations - DEKU_TREE_QUEEN_GOHMA_HEART, - QUEEN_GOHMA, - }); - - DungeonInfo DodongosCavern = DungeonInfo("Dodongo's Cavern", DODONGOS_CAVERN, DODONGOS_CAVERN_MAP, DODONGOS_CAVERN_COMPASS, NONE, NONE, NONE, 0, 0, { - //Vanilla Locations - DODONGOS_CAVERN_MAP_CHEST, - DODONGOS_CAVERN_COMPASS_CHEST, - DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, - DODONGOS_CAVERN_BOMB_BAG_CHEST, - DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, - DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, - DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, - DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, - DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, - DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, - DODONGOS_CAVERN_GS_SCARECROW, - DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, - DODONGOS_CAVERN_GS_BACK_ROOM, - DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, - }, { - //MQ Locations - DODONGOS_CAVERN_MQ_MAP_CHEST, - DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, - DODONGOS_CAVERN_MQ_COMPASS_CHEST, - DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, - DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, - DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, - DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, - DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, - DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, - DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, - DODONGOS_CAVERN_MQ_GS_BACK_AREA, - }, - {}, - { - // Boss Room Locations - DODONGOS_CAVERN_BOSS_ROOM_CHEST, - DODONGOS_CAVERN_KING_DODONGO_HEART, - KING_DODONGO, - }); - - DungeonInfo JabuJabusBelly = DungeonInfo("Jabu Jabu's Belly", JABU_JABUS_BELLY, JABU_JABUS_BELLY_MAP, JABU_JABUS_BELLY_COMPASS, NONE, NONE, NONE, 0, 0, { - //Vanilla Locations - JABU_JABUS_BELLY_MAP_CHEST, - JABU_JABUS_BELLY_COMPASS_CHEST, - JABU_JABUS_BELLY_BOOMERANG_CHEST, - JABU_JABUS_BELLY_DEKU_SCRUB, - JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, - JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, - JABU_JABUS_BELLY_GS_NEAR_BOSS, - JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, - }, { - //MQ Locations - JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, - JABU_JABUS_BELLY_MQ_MAP_CHEST, - JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, - JABU_JABUS_BELLY_MQ_COMPASS_CHEST, - JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, - JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, - JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, - JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, - JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, - JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, - JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, - JABU_JABUS_BELLY_MQ_COW, - JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, - JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, - JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, - JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, - }, - {}, - { - // Boss Room Locations - JABU_JABUS_BELLY_BARINADE_HEART, - BARINADE, - }); - - DungeonInfo ForestTemple = DungeonInfo("Forest Temple", FOREST_TEMPLE, FOREST_TEMPLE_MAP, FOREST_TEMPLE_COMPASS, FOREST_TEMPLE_SMALL_KEY, FOREST_TEMPLE_KEY_RING, FOREST_TEMPLE_BOSS_KEY, 5, 6, { - //Vanilla Locations - FOREST_TEMPLE_FIRST_ROOM_CHEST, - FOREST_TEMPLE_FIRST_STALFOS_CHEST, - FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, - FOREST_TEMPLE_MAP_CHEST, - FOREST_TEMPLE_WELL_CHEST, - FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, - FOREST_TEMPLE_EYE_SWITCH_CHEST, - FOREST_TEMPLE_BOSS_KEY_CHEST, - FOREST_TEMPLE_FLOORMASTER_CHEST, - FOREST_TEMPLE_BOW_CHEST, - FOREST_TEMPLE_RED_POE_CHEST, - FOREST_TEMPLE_BLUE_POE_CHEST, - FOREST_TEMPLE_BASEMENT_CHEST, - FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, - FOREST_TEMPLE_GS_FIRST_ROOM, - FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, - FOREST_TEMPLE_GS_LOBBY, - FOREST_TEMPLE_GS_BASEMENT, - }, { - //MQ Locations - FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, - FOREST_TEMPLE_MQ_WOLFOS_CHEST, - FOREST_TEMPLE_MQ_BOW_CHEST, - FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, - FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, - FOREST_TEMPLE_MQ_WELL_CHEST, - FOREST_TEMPLE_MQ_MAP_CHEST, - FOREST_TEMPLE_MQ_COMPASS_CHEST, - FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, - FOREST_TEMPLE_MQ_BASEMENT_CHEST, - FOREST_TEMPLE_MQ_REDEAD_CHEST, - FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, - FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, - FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, - FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, - FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, - FOREST_TEMPLE_MQ_GS_WELL, - }, - {}, - { - // Boss Room Locations - FOREST_TEMPLE_PHANTOM_GANON_HEART, - PHANTOM_GANON, - }); - - DungeonInfo FireTemple = DungeonInfo("Fire Temple", FIRE_TEMPLE, FIRE_TEMPLE_MAP, FIRE_TEMPLE_COMPASS, FIRE_TEMPLE_SMALL_KEY, FIRE_TEMPLE_KEY_RING, FIRE_TEMPLE_BOSS_KEY, 8, 5, { - //Vanilla Locations - FIRE_TEMPLE_NEAR_BOSS_CHEST, - FIRE_TEMPLE_FLARE_DANCER_CHEST, - FIRE_TEMPLE_BOSS_KEY_CHEST, - FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, - FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, - FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, - FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, - FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, - FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, - FIRE_TEMPLE_SCARECROW_CHEST, - FIRE_TEMPLE_MAP_CHEST, - FIRE_TEMPLE_COMPASS_CHEST, - FIRE_TEMPLE_HIGHEST_GORON_CHEST, - FIRE_TEMPLE_MEGATON_HAMMER_CHEST, - FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, - FIRE_TEMPLE_GS_BOSS_KEY_LOOP, - FIRE_TEMPLE_GS_BOULDER_MAZE, - FIRE_TEMPLE_GS_SCARECROW_TOP, - FIRE_TEMPLE_GS_SCARECROW_CLIMB, - }, { - //MQ Locations - FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, - FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, - FIRE_TEMPLE_MQ_COMPASS_CHEST, - FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, - FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, - FIRE_TEMPLE_MQ_CHEST_ON_FIRE, - FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, - FIRE_TEMPLE_MQ_MAP_CHEST, - FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, - FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, - FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, - FIRE_TEMPLE_MQ_FREESTANDING_KEY, - FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, - FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, - FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, - FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, - FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, - }, - {}, - { - // Boos Room Locations - FIRE_TEMPLE_VOLVAGIA_HEART, - VOLVAGIA, - }); - - DungeonInfo WaterTemple = DungeonInfo("Water Temple", WATER_TEMPLE, WATER_TEMPLE_MAP, WATER_TEMPLE_COMPASS, WATER_TEMPLE_SMALL_KEY, WATER_TEMPLE_KEY_RING, WATER_TEMPLE_BOSS_KEY, 6, 2, { - //Vanilla Locations - WATER_TEMPLE_MAP_CHEST, - WATER_TEMPLE_COMPASS_CHEST, - WATER_TEMPLE_TORCHES_CHEST, - WATER_TEMPLE_DRAGON_CHEST, - WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, - WATER_TEMPLE_CENTRAL_PILLAR_CHEST, - WATER_TEMPLE_CRACKED_WALL_CHEST, - WATER_TEMPLE_BOSS_KEY_CHEST, - WATER_TEMPLE_LONGSHOT_CHEST, - WATER_TEMPLE_RIVER_CHEST, - WATER_TEMPLE_GS_BEHIND_GATE, - WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, - WATER_TEMPLE_GS_CENTRAL_PILLAR, - WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, - WATER_TEMPLE_GS_RIVER, - }, { - //MQ Locations - WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, - WATER_TEMPLE_MQ_BOSS_KEY_CHEST, - WATER_TEMPLE_MQ_LONGSHOT_CHEST, - WATER_TEMPLE_MQ_COMPASS_CHEST, - WATER_TEMPLE_MQ_MAP_CHEST, - WATER_TEMPLE_MQ_FREESTANDING_KEY, - WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, - WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, - WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, - WATER_TEMPLE_MQ_GS_RIVER, - WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, - }, - {}, - { - // Boss Room Locations - WATER_TEMPLE_MORPHA_HEART, - MORPHA, - }); - - DungeonInfo SpiritTemple = DungeonInfo("Spirit Temple", SPIRIT_TEMPLE, SPIRIT_TEMPLE_MAP, SPIRIT_TEMPLE_COMPASS, SPIRIT_TEMPLE_SMALL_KEY, SPIRIT_TEMPLE_KEY_RING, SPIRIT_TEMPLE_BOSS_KEY, 5, 7, { - //Vanilla Locations - SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, - SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, - SPIRIT_TEMPLE_COMPASS_CHEST, - SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, - SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, - SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, - SPIRIT_TEMPLE_MAP_CHEST, - SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, - SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, - SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, - SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, - SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, - SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, - SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, - SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, - SPIRIT_TEMPLE_BOSS_KEY_CHEST, - SPIRIT_TEMPLE_TOPMOST_CHEST, - SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, - SPIRIT_TEMPLE_GS_BOULDER_ROOM, - SPIRIT_TEMPLE_GS_LOBBY, - SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, - SPIRIT_TEMPLE_GS_METAL_FENCE, - }, { - //MQ Locations - SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, - SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, - SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, - SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, - SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, - SPIRIT_TEMPLE_MQ_MAP_CHEST, - SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, - SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, - SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, - SPIRIT_TEMPLE_MQ_COMPASS_CHEST, - SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, - SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, - SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, - SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, - SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, - SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, - SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, - SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, - SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, - SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, - SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, - SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, - SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, - SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, - SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, - }, { - //Shared Locations - SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, - SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, - }, { - // Boss Room Locations - SPIRIT_TEMPLE_TWINROVA_HEART, - TWINROVA, - }); - - DungeonInfo ShadowTemple = DungeonInfo("Shadow Temple", SHADOW_TEMPLE, SHADOW_TEMPLE_MAP, SHADOW_TEMPLE_COMPASS, SHADOW_TEMPLE_SMALL_KEY, SHADOW_TEMPLE_KEY_RING, SHADOW_TEMPLE_BOSS_KEY, 5, 6, { - //Vanilla Locations - SHADOW_TEMPLE_MAP_CHEST, - SHADOW_TEMPLE_HOVER_BOOTS_CHEST, - SHADOW_TEMPLE_COMPASS_CHEST, - SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, - SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, - SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, - SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, - SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, - SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, - SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, - SHADOW_TEMPLE_WIND_HINT_CHEST, - SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, - SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, - SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, - SHADOW_TEMPLE_BOSS_KEY_CHEST, - SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, - SHADOW_TEMPLE_FREESTANDING_KEY, - SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, - SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, - SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, - SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, - SHADOW_TEMPLE_GS_NEAR_SHIP, - }, { - //MQ Locations - SHADOW_TEMPLE_MQ_COMPASS_CHEST, - SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, - SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, - SHADOW_TEMPLE_MQ_MAP_CHEST, - SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, - SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, - SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, - SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, - SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, - SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, - SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, - SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, - SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, - SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, - SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, - SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, - SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, - SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, - SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, - SHADOW_TEMPLE_MQ_FREESTANDING_KEY, - SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, - SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, - SHADOW_TEMPLE_MQ_GS_AFTER_WIND, - SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, - SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, - }, - {}, - { - // Boss Room Locations - SHADOW_TEMPLE_BONGO_BONGO_HEART, - BONGO_BONGO, - }); - - DungeonInfo BottomOfTheWell = DungeonInfo("Bottom of the Well", BOTTOM_OF_THE_WELL, BOTTOM_OF_THE_WELL_MAP, BOTTOM_OF_THE_WELL_COMPASS, BOTTOM_OF_THE_WELL_SMALL_KEY, BOTTOM_OF_THE_WELL_KEY_RING, NONE, 3, 2, { - //Vanilla Locations - BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, - BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, - BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, - BOTTOM_OF_THE_WELL_COMPASS_CHEST, - BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, - BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, - BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, - BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, - BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, - BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, - BOTTOM_OF_THE_WELL_MAP_CHEST, - BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, - BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, - BOTTOM_OF_THE_WELL_FREESTANDING_KEY, - BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, - BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, - BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, - }, { - //MQ Locations - BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, - BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, - BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, - BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, - BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, - BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, - BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, - BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, - }, {}, {}); - - DungeonInfo IceCavern = DungeonInfo("Ice Cavern", ICE_CAVERN, ICE_CAVERN_MAP, ICE_CAVERN_COMPASS, NONE, NONE, NONE, 0, 0, { - //Vanilla Locations - ICE_CAVERN_MAP_CHEST, - ICE_CAVERN_COMPASS_CHEST, - ICE_CAVERN_IRON_BOOTS_CHEST, - ICE_CAVERN_FREESTANDING_POH, - ICE_CAVERN_GS_PUSH_BLOCK_ROOM, - ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, - ICE_CAVERN_GS_HEART_PIECE_ROOM, - }, { - //MQ Locations - ICE_CAVERN_MQ_IRON_BOOTS_CHEST, - ICE_CAVERN_MQ_COMPASS_CHEST, - ICE_CAVERN_MQ_MAP_CHEST, - ICE_CAVERN_MQ_FREESTANDING_POH, - ICE_CAVERN_MQ_GS_SCARECROW, - ICE_CAVERN_MQ_GS_ICE_BLOCK, - ICE_CAVERN_MQ_GS_RED_ICE, - }, { - //Shared Locations - SHEIK_IN_ICE_CAVERN, - }, {}); - - DungeonInfo GerudoTrainingGrounds = DungeonInfo("Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, NONE, NONE, GERUDO_TRAINING_GROUNDS_SMALL_KEY, GERUDO_TRAINING_GROUNDS_KEY_RING, NONE, 9, 3, { - //Vanilla Locations - GERUDO_TRAINING_GROUNDS_LOBBY_LEFT_CHEST, - GERUDO_TRAINING_GROUNDS_LOBBY_RIGHT_CHEST, - GERUDO_TRAINING_GROUNDS_STALFOS_CHEST, - GERUDO_TRAINING_GROUNDS_BEAMOS_CHEST, - GERUDO_TRAINING_GROUNDS_HIDDEN_CEILING_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_PATH_FIRST_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_PATH_SECOND_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_PATH_THIRD_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_PATH_FINAL_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_CENTRAL_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_SIDE_CHEST, - GERUDO_TRAINING_GROUNDS_UNDERWATER_SILVER_RUPEE_CHEST, - GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_CLEAR_CHEST, - GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_SWITCH_CHEST, - GERUDO_TRAINING_GROUNDS_EYE_STATUE_CHEST, - GERUDO_TRAINING_GROUNDS_NEAR_SCARECROW_CHEST, - GERUDO_TRAINING_GROUNDS_BEFORE_HEAVY_BLOCK_CHEST, - GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FIRST_CHEST, - GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_SECOND_CHEST, - GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_THIRD_CHEST, - GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FOURTH_CHEST, - GERUDO_TRAINING_GROUNDS_FREESTANDING_KEY, - }, { - //MQ Locations - GERUDO_TRAINING_GROUNDS_MQ_LOBBY_RIGHT_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_LOBBY_LEFT_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_FIRST_IRON_KNUCKLE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_BEFORE_HEAVY_BLOCK_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_EYE_STATUE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_FLAME_CIRCLE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_SECOND_IRON_KNUCKLE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_DINOLFOS_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_ICE_ARROWS_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_CENTRAL_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_FIRST_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_SIDE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_THIRD_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_SECOND_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_HIDDEN_CEILING_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER_SILVER_RUPEE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_HEAVY_BLOCK_CHEST, - }, {}, {}); - - DungeonInfo GanonsCastle = DungeonInfo("Ganon's Castle", GANONS_CASTLE, NONE, NONE, GANONS_CASTLE_SMALL_KEY, GANONS_CASTLE_KEY_RING, GANONS_CASTLE_BOSS_KEY, 2, 3, { - //Vanilla Locations - GANONS_CASTLE_FOREST_TRIAL_CHEST, - GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, - GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, - GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, - GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, - GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, - GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, - GANONS_CASTLE_DEKU_SCRUB_LEFT, - GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, - GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, - GANONS_CASTLE_DEKU_SCRUB_RIGHT, - }, { - //MQ Locations - GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, - GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, - GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, - GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, - GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, - GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, - GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, - GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, - GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, - GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, - GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, - GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, - }, { - //Shared Locations - GANONS_TOWER_BOSS_KEY_CHEST, - GANON, - }, {}); - - const DungeonArray dungeonList = { - &DekuTree, - &DodongosCavern, - &JabuJabusBelly, - &ForestTemple, - &FireTemple, - &WaterTemple, - &SpiritTemple, - &ShadowTemple, - &BottomOfTheWell, - &IceCavern, - &GerudoTrainingGrounds, - &GanonsCastle, - }; - -} //namespace Dungeon diff --git a/soh/soh/Enhancements/randomizer/3drando/dungeon.hpp b/soh/soh/Enhancements/randomizer/3drando/dungeon.hpp deleted file mode 100644 index 91644e128c2..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/dungeon.hpp +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "keys.hpp" - -namespace Dungeon { -class DungeonInfo { -public: - DungeonInfo(std::string name_, uint32_t hintKey_, uint32_t map_, uint32_t compass_, uint32_t smallKey_, uint32_t keyRing_, uint32_t bossKey_, - uint8_t vanillaKeyCount_, uint8_t mqKeyCount_, - std::vector vanillaLocations_, - std::vector mqLocations_, - std::vector sharedLocations_, - std::vector bossRoomLocations_); - ~DungeonInfo(); - - const std::string& GetName() const { - return name; - } - - void SetMQ() { - masterQuest = true; - } - - void ClearMQ() { - masterQuest = false; - } - - bool IsMQ() const { - return masterQuest; - } - - void SetKeyRing() { - hasKeyRing = true; - } - - void ClearKeyRing() { - hasKeyRing = false; - } - - bool HasKeyRing() const { - return hasKeyRing; - } - - bool IsVanilla() const { - return !masterQuest; - } - - uint8_t GetSmallKeyCount() const { - return (masterQuest) ? mqKeyCount : vanillaKeyCount; - } - - uint32_t GetHintKey() const; - uint32_t GetSmallKey() const; - uint32_t GetKeyRing() const; - uint32_t GetMap() const; - uint32_t GetCompass() const; - uint32_t GetBossKey() const; - - void PlaceVanillaMap(); - void PlaceVanillaCompass(); - void PlaceVanillaBossKey(); - void PlaceVanillaSmallKeys(); - - // Gets the chosen dungeon locations for a playthrough (so either MQ or Vanilla) - std::vector GetDungeonLocations() const; - - // Gets all dungeon locations (MQ + Vanilla) - std::vector GetEveryLocation() const; - -private: - std::string name; - uint32_t hintKey; - uint32_t map; - uint32_t compass; - uint32_t smallKey; - uint32_t keyRing; - uint32_t bossKey; - uint8_t vanillaKeyCount; - uint8_t mqKeyCount; - bool masterQuest = false; - bool hasKeyRing = false; - std::vector vanillaLocations; - std::vector mqLocations; - std::vector sharedLocations; - std::vector bossRoomLocations; -}; - -extern DungeonInfo DekuTree; -extern DungeonInfo DodongosCavern; -extern DungeonInfo JabuJabusBelly; -extern DungeonInfo ForestTemple; -extern DungeonInfo FireTemple; -extern DungeonInfo WaterTemple; -extern DungeonInfo SpiritTemple; -extern DungeonInfo ShadowTemple; -extern DungeonInfo BottomOfTheWell; -extern DungeonInfo IceCavern; -extern DungeonInfo GerudoTrainingGrounds; -extern DungeonInfo GanonsCastle; - -using DungeonArray = std::array; - -extern const DungeonArray dungeonList; -} // namespace Dungeon diff --git a/soh/soh/Enhancements/randomizer/3drando/entrance.cpp b/soh/soh/Enhancements/randomizer/3drando/entrance.cpp index 8dd8b4c6379..e69de29bb2d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/entrance.cpp @@ -1,1403 +0,0 @@ -#include "entrance.hpp" - -#include "fill.hpp" -#include "settings.hpp" -#include "item_list.hpp" -#include "item_pool.hpp" -#include "item_location.hpp" -#include "spoiler_log.hpp" -#include "hints.hpp" -#include "location_access.hpp" - -#include -#include -#include -#include -#include - -std::list entranceOverrides = {}; -bool noRandomEntrances = false; -static bool entranceShuffleFailure = false; -static int totalRandomizableEntrances = 0; -static int curNumRandomizedEntrances = 0; - -typedef struct { - EntranceType type; - AreaKey parentRegion; - AreaKey connectedRegion; - int16_t index; -} EntranceLinkInfo; - -EntranceLinkInfo NO_RETURN_ENTRANCE = {EntranceType::None, NONE, NONE, -1}; - -typedef struct { - std::list targetRegions; - std::list allowedTypes; -} PriorityEntrance; - //primary, secondary -using EntranceInfoPair = std::pair; -using EntrancePair = std::pair; -using EntrancePools = std::map>; - -// Construct entrance name from parent and connected region keys -std::string EntranceNameByRegions(uint32_t parentRegion, uint32_t connectedRegion) { - return AreaTable(parentRegion)->regionName + " -> " + AreaTable(connectedRegion)->regionName; -} - -//The entrance randomization algorithm used here is a direct copy of -//the algorithm used in the original N64 randomizer (except now in C++ instead -//of python). It may be easier to understand the algorithm by looking at the -//base randomizer's code instead: -// https://github.com/TestRunnerSRL/OoT-Randomizer/blob/Dev/EntranceShuffle.py - -// Updates the user on how many entrances are currently shuffled -static void DisplayEntranceProgress() { - std::string dots = "."; - float progress = (float)curNumRandomizedEntrances / (float)totalRandomizableEntrances; - if (progress > 0.33) { - dots += "."; - } else { - dots += " "; - } - if (progress > 0.66) { - dots += "."; - } else { - dots += " "; - } - printf("\x1b[7;29H%s", dots.c_str()); - #ifdef ENABLE_DEBUG - if (curNumRandomizedEntrances == totalRandomizableEntrances) { - Areas::DumpWorldGraph("Finish Validation"); - } - #endif -} - -void SetAllEntrancesData(std::vector& entranceShuffleTable) { - for (auto& entrancePair: entranceShuffleTable) { - - auto& forwardEntry = entrancePair.first; - auto& returnEntry = entrancePair.second; - - //set data - Entrance* forwardEntrance = AreaTable(forwardEntry.parentRegion)->GetExit(forwardEntry.connectedRegion); - forwardEntrance->SetIndex(forwardEntry.index); - forwardEntrance->SetType(forwardEntry.type); - forwardEntrance->SetAsPrimary(); - - // When decouple entrances is on, mark the forward entrance - if (Settings::DecoupleEntrances) { - forwardEntrance->SetDecoupled(); - } - - if (returnEntry.parentRegion != NONE) { - Entrance* returnEntrance = AreaTable(returnEntry.parentRegion)->GetExit(returnEntry.connectedRegion); - returnEntrance->SetIndex(returnEntry.index); - returnEntrance->SetType(returnEntry.type); - forwardEntrance->BindTwoWay(returnEntrance); - - // Mark reverse entrance as decoupled - if (Settings::DecoupleEntrances) { - returnEntrance->SetDecoupled(); - } - } - } -} - -static std::vector AssumeEntrancePool(std::vector& entrancePool) { - std::vector assumedPool = {}; - for (Entrance* entrance : entrancePool) { - totalRandomizableEntrances++; - Entrance* assumedForward = entrance->AssumeReachable(); - if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) { - Entrance* assumedReturn = entrance->GetReverse()->AssumeReachable(); - if (!(Settings::MixedEntrancePools && (Settings::ShuffleOverworldEntrances || Settings::ShuffleInteriorEntrances.Is(SHUFFLEINTERIORS_ALL)))) { - auto type = entrance->GetType(); - if (((type == EntranceType::Dungeon || type == EntranceType::GrottoGrave) && entrance->GetReverse()->GetName() != "Spirit Temple Entryway -> Desert Colossus From Spirit Entryway") || - (type == EntranceType::Interior && Settings::ShuffleInteriorEntrances.Is(SHUFFLEINTERIORS_ALL))) { - // In most cases, Dungeon, Grotto/Grave and Simple Interior exits shouldn't be assumed able to give access to their parent region - assumedReturn->SetCondition([]{return false;}); - } - } - assumedForward->BindTwoWay(assumedReturn); - } - assumedPool.push_back(assumedForward); - } - return assumedPool; -} - -static std::vector BuildOneWayTargets(std::vector typesToInclude, std::vector> exclude = {}/*, target_region_names*/) { - std::vector oneWayEntrances = {}; - // Get all entrances of the specified type - for (EntranceType poolType : typesToInclude) { - AddElementsToPool(oneWayEntrances, GetShuffleableEntrances(poolType, false)); - } - // Filter out any that are passed in the exclusion list - FilterAndEraseFromPool(oneWayEntrances, [&exclude](Entrance* entrance){ - std::pair entranceBeingChecked (entrance->GetParentRegionKey(), entrance->GetConnectedRegionKey()); - return ElementInContainer(entranceBeingChecked, exclude); - }); - - // The code below is part of the function in ootr, but no use of the function ever provides target_region_names - // if target_region_names: - // return [entrance.get_new_target() for entrance in valid_one_way_entrances - // if entrance.connected_region.name in target_region_names] - - std::vector newTargets = {}; - for (Entrance* entrance : oneWayEntrances) { - newTargets.push_back(entrance->GetNewTarget()); - } - return newTargets; -} - -//returns restrictive entrances and soft entrances in an array of size 2 (restrictive vector is index 0, soft is index 1) -static std::array, 2> SplitEntrancesByRequirements(std::vector& entrancesToSplit, std::vector& assumedEntrances) { - //First, disconnect all root assumed entrances and save which regions they were originally connected to, so we can reconnect them later - std::map originalConnectedRegions = {}; - std::set entrancesToDisconnect = {}; - for (Entrance* entrance : assumedEntrances) { - entrancesToDisconnect.insert(entrance); - if (entrance->GetReverse() != nullptr) { - entrancesToDisconnect.insert(entrance->GetReverse()); - } - } - - //disconnect each entrance temporarily to find restrictive vs soft entrances - //soft entrances are ones that can be accessed by both ages (child/adult) at both times of day (day/night) - //restrictive entrances are ones that do not meet this criteria - for (Entrance* entrance : entrancesToDisconnect) { - if (entrance->GetConnectedRegionKey() != NONE) { - originalConnectedRegions[entrance] = entrance->Disconnect(); - } - } - - std::vector restrictiveEntrances = {}; - std::vector softEntrances = {}; - - Logic::LogicReset(); - // Apply the effects of all advancement items to search for entrance accessibility - std::vector items = FilterFromPool(ItemPool, [](const ItemKey i){ return ItemTable(i).IsAdvancement();}); - for (ItemKey unplacedItem : items) { - ItemTable(unplacedItem).ApplyEffect(); - } - // run a search to see what's accessible - GetAccessibleLocations({}); - - 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 - if (entrance->ConditionsMet(true)) { - softEntrances.push_back(entrance); - } else { - restrictiveEntrances.push_back(entrance); - } - } - - //Reconnect all disconnected entrances - for (Entrance* entrance : entrancesToDisconnect) { - entrance->Connect(originalConnectedRegions[entrance]); - } - - return {restrictiveEntrances, softEntrances}; -} - -static bool AreEntrancesCompatible(Entrance* entrance, Entrance* target, std::vector& rollbacks) { - - //Entrances shouldn't connect to their own scene, fail in this situation - if (entrance->GetParentRegion()->scene != "" && entrance->GetParentRegion()->scene == target->GetConnectedRegion()->scene) { - auto message = "Entrance " + entrance->GetName() + " attempted to connect with own scene target " + target->to_string() + ". Connection failed.\n"; - SPDLOG_DEBUG(message); - return false; - } - - // One way entrances shouldn't lead to the same scene as other already chosen one way entrances - auto type = entrance->GetType(); - const std::vector oneWayTypes = {EntranceType::OwlDrop, EntranceType::Spawn, EntranceType::WarpSong}; - if (ElementInContainer(type, oneWayTypes)) { - for (auto& rollback : rollbacks) { - if (rollback.first->GetConnectedRegion()->scene == target->GetConnectedRegion()->scene) { - auto message = "A one way entrance already leads to " + target->to_string() + ". Connection failed.\n"; - SPDLOG_DEBUG(message); - return false; - } - } - } - - return true; -} - -//Change connections between an entrance and a target assumed entrance, in order to test the connections afterwards if necessary -static void ChangeConnections(Entrance* entrance, Entrance* targetEntrance) { - auto message = "Attempting to connect " + entrance->GetName() + " to " + targetEntrance->to_string() + "\n"; - SPDLOG_DEBUG(message); - entrance->Connect(targetEntrance->Disconnect()); - entrance->SetReplacement(targetEntrance->GetReplacement()); - if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) { - targetEntrance->GetReplacement()->GetReverse()->Connect(entrance->GetReverse()->GetAssumed()->Disconnect()); - targetEntrance->GetReplacement()->GetReverse()->SetReplacement(entrance->GetReverse()); - } -} - -// In the event that we need to retry shuffling an entire group we can restore the -// original connections to reset the entrance and target entrance. -static void RestoreConnections(Entrance* entrance, Entrance* targetEntrance) { - targetEntrance->Connect(entrance->Disconnect()); - entrance->SetReplacement(nullptr); - if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) { - entrance->GetReverse()->GetAssumed()->Connect(targetEntrance->GetReplacement()->GetReverse()->Disconnect()); - targetEntrance->GetReplacement()->GetReverse()->SetReplacement(nullptr); - } -} - -static void DeleteTargetEntrance(Entrance* targetEntrance) { - if (targetEntrance->GetConnectedRegionKey() != NONE) { - targetEntrance->Disconnect(); - } - if (targetEntrance->GetParentRegionKey() != NONE) { - targetEntrance->GetParentRegion()->RemoveExit(targetEntrance); - targetEntrance->SetParentRegion(NONE); - } -} - -static void ConfirmReplacement(Entrance* entrance, Entrance* targetEntrance) { - DeleteTargetEntrance(targetEntrance); - if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) { - auto replacedReverse = targetEntrance->GetReplacement()->GetReverse(); - DeleteTargetEntrance(replacedReverse->GetReverse()->GetAssumed()); - } -} - -// Returns whether or not we can affirm the entrance can never be accessed as the given age -static bool EntranceUnreachableAs(Entrance* entrance, uint8_t age, std::vector& alreadyChecked) { - - if (entrance == nullptr) { - SPDLOG_DEBUG("Entrance is nullptr in EntranceUnreachableAs()"); - return true; - } - - alreadyChecked.push_back(entrance); - auto type = entrance->GetType(); - - // The following cases determine when we say an entrance is not safe to affirm unreachable as the given age - if (type == EntranceType::WarpSong || type == EntranceType::Overworld) { - // Note that we consider all overworld entrances as potentially accessible as both ages, to be completely safe - return false; - } else if (type == EntranceType::OwlDrop) { - return age == AGE_ADULT; - } else if (type == EntranceType::Spawn && entrance->GetConnectedRegionKey() == KF_LINKS_HOUSE) { - return age == AGE_ADULT; - } else if (type == EntranceType::Spawn && entrance->GetConnectedRegionKey() == TEMPLE_OF_TIME) { - return age == AGE_CHILD; - } - - // Other entrances such as Interior, Dungeon or Grotto are fine unless they have a parent which is one of the above cases - // Recursively check parent entrances to verify that they are also not reachable as the wrong age - auto& parentEntrances = entrance->GetParentRegion()->entrances; - for (Entrance* parentEntrance : parentEntrances) { - - //if parentEntrance is in alreadyChecked, then continue - if (ElementInContainer(parentEntrance, alreadyChecked)) { - continue; - } - - bool unreachable = EntranceUnreachableAs(parentEntrance, age, alreadyChecked); - if (!unreachable) { - return false; - } - } - - return true; -} - -static bool ValidateWorld(Entrance* entrancePlaced) { - SPDLOG_DEBUG("Validating world\n"); - - //check certain conditions when certain types of ER are enabled - EntranceType type = EntranceType::None; - if (entrancePlaced != nullptr) { - type = entrancePlaced->GetType(); - } - - bool checkPoeCollectorAccess = (Settings::ShuffleOverworldEntrances || Settings::ShuffleInteriorEntrances.Is(SHUFFLEINTERIORS_ALL)) && (entrancePlaced == nullptr || Settings::MixedEntrancePools || - type == EntranceType::Interior || type == EntranceType::SpecialInterior || type == EntranceType::Overworld || type == EntranceType::Spawn || type == EntranceType::WarpSong || type == EntranceType::OwlDrop); - bool checkOtherEntranceAccess = (Settings::ShuffleOverworldEntrances || Settings::ShuffleInteriorEntrances.Is(SHUFFLEINTERIORS_ALL) || Settings::ShuffleOverworldSpawns) && (entrancePlaced == nullptr || Settings::MixedEntrancePools || - type == EntranceType::SpecialInterior || type == EntranceType::Overworld || type == EntranceType::Spawn || type == EntranceType::WarpSong || type == EntranceType::OwlDrop); - - // Search the world to verify that all necessary conditions are still being held - // Conditions will be checked during the search and any that fail will be figured out - // afterwards - Logic::LogicReset(); - GetAccessibleLocations({}, SearchMode::ValidateWorld, "", checkPoeCollectorAccess, checkOtherEntranceAccess); - - if (!Settings::DecoupleEntrances) { - // Unless entrances are decoupled, we don't want the player to end up through certain entrances as the wrong age - // This means we need to hard check that none of the relevant entrances are ever reachable as that age - // This is mostly relevant when mixing entrance pools or shuffling special interiors (such as windmill or kak potion shop) - // Warp Songs and Overworld Spawns can also end up inside certain indoors so those need to be handled as well - std::array childForbidden = {"OGC Great Fairy Fountain -> Castle Grounds", "GV Carpenter Tent -> GV Fortress Side", "Ganon's Castle Entryway -> Castle Grounds From Ganon's Castle"}; - std::array adultForbidden = {"HC Great Fairy Fountain -> Castle Grounds", "HC Storms Grotto -> Castle Grounds"}; - - auto allShuffleableEntrances = GetShuffleableEntrances(EntranceType::All, false); - for (auto& entrance: allShuffleableEntrances) { - - std::vector alreadyChecked = {}; - - if (entrance->IsShuffled()) { - if (entrance->GetReplacement() != nullptr) { - - auto replacementName = entrance->GetReplacement()->GetName(); - alreadyChecked.push_back(entrance->GetReplacement()->GetReverse()); - - if (ElementInContainer(replacementName, childForbidden) && !EntranceUnreachableAs(entrance, AGE_CHILD, alreadyChecked)) { - auto message = replacementName + " is replaced by an entrance with a potential child access\n"; - SPDLOG_DEBUG(message); - return false; - } else if (ElementInContainer(replacementName, adultForbidden) && !EntranceUnreachableAs(entrance, AGE_ADULT, alreadyChecked)) { - auto message = replacementName + " is replaced by an entrance with a potential adult access\n"; - SPDLOG_DEBUG(message); - return false; - } - } - } else { - auto name = entrance->GetName(); - alreadyChecked.push_back(entrance->GetReverse()); - - if (ElementInContainer(name, childForbidden) && !EntranceUnreachableAs(entrance, AGE_CHILD, alreadyChecked)) { - auto message = name + " is potentially accessible as child\n"; - SPDLOG_DEBUG(message); - return false; - } else if (ElementInContainer(name, adultForbidden) && !EntranceUnreachableAs(entrance, AGE_ADULT, alreadyChecked)) { - auto message = name + " is potentially accessible as adult\n"; - SPDLOG_DEBUG(message); - return false; - } - } - } - } - - if (Settings::ShuffleInteriorEntrances.IsNot(SHUFFLEINTERIORS_OFF) && Settings::GossipStoneHints.IsNot(HINTS_NO_HINTS) && - (entrancePlaced == nullptr || type == EntranceType::Interior || type == EntranceType::SpecialInterior)) { - //When cows are shuffled, ensure both Impa's House entrances are in the same hint area because the cow is reachable from both sides - if (Settings::ShuffleCows) { - auto impasHouseFrontHintRegion = GetHintRegionHintKey(KAK_IMPAS_HOUSE); - auto impasHouseBackHintRegion = GetHintRegionHintKey(KAK_IMPAS_HOUSE_BACK); - if (impasHouseFrontHintRegion != NONE && impasHouseBackHintRegion != NONE && impasHouseBackHintRegion != LINKS_POCKET && impasHouseFrontHintRegion != LINKS_POCKET && impasHouseBackHintRegion != impasHouseFrontHintRegion) { - auto message = "Kak Impas House entrances are not in the same hint area\n"; - SPDLOG_DEBUG(message); - return false; - } - } - } - - // If all locations aren't reachable, that means that one of the conditions failed when searching - if (!allLocationsReachable) { - 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(KOKIRI_FOREST)->HasAccess() && !AreaTable(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(AGE_CHILD) || !Areas::HasTimePassAccess(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 (Settings::ResolvedStartingAge == AGE_CHILD && !AreaTable(TEMPLE_OF_TIME)->Adult()) { - SPDLOG_DEBUG("Path to Temple of Time as adult is not guaranteed\n"); - return false; - } else if (Settings::ResolvedStartingAge == AGE_ADULT && !AreaTable(TEMPLE_OF_TIME)->Child()) { - SPDLOG_DEBUG("Path to Temple of Time as child is not guaranteed\n"); - return false; - } - } - - // The Big Poe shop should always be accessible as adult without the need to use any bottles - // 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(MARKET_GUARD_HOUSE)->Adult()) { - SPDLOG_DEBUG("Big Poe Shop access is not guarenteed as adult\n"); - return false; - } - } - SPDLOG_DEBUG("All Locations NOT REACHABLE\n"); - return false; - } - return true; -} - -static bool ReplaceEntrance(Entrance* entrance, Entrance* target, std::vector& rollbacks) { - - if (!AreEntrancesCompatible(entrance, target, rollbacks)) { - return false; - } - ChangeConnections(entrance, target); - if (ValidateWorld(entrance)) { - #ifdef ENABLE_DEBUG - std::string ticks = std::to_string(svcGetSystemTick()); - auto message = "Dumping World Graph at " + ticks + "\n"; - //SPDLOG_DEBUG(message); - //Areas::DumpWorldGraph(ticks); - #endif - rollbacks.push_back(EntrancePair{entrance, target}); - curNumRandomizedEntrances++; - DisplayEntranceProgress(); - return true; - } else { - #ifdef ENABLE_DEBUG - std::string ticks = std::to_string(svcGetSystemTick()); - auto message = "Dumping World Graph at " + ticks + "\n"; - //SPDLOG_DEBUG(message); - //Areas::DumpWorldGraph(ticks); - #endif - if (entrance->GetConnectedRegionKey() != NONE) { - RestoreConnections(entrance, target); - } - } - DisplayEntranceProgress(); - return false; -} - -// Connect one random entrance from entrance pools to one random target in the respective target pool. -// Entrance chosen will have one of the allowed types. -// Target chosen will lead to one of the allowed regions. -static bool PlaceOneWayPriorityEntrance(std::string priorityName, std::list& allowedRegions, std::list& allowedTypes, std::vector& rollbacks, EntrancePools oneWayEntrancePools, EntrancePools oneWayTargetEntrancePools) { - // Combine the entrances for allowed types in one list. - // Shuffle this list. - // Pick the first one not already set, not adult spawn, that has a valid target entrance. - // Assemble then clear entrances from the pool and target pools as appropriate. - std::vector availPool = {}; - for (auto& pool : oneWayEntrancePools) { - auto entranceType = pool.first; - if (ElementInContainer(entranceType, allowedTypes)) { - AddElementsToPool(availPool, pool.second); - } - } - Shuffle(availPool); - - for (Entrance* entrance : availPool) { - if (entrance->GetReplacement() != nullptr) { - continue; - } - // Only allow Adult Spawn as sole Nocturne access if hints != mask. - // Otherwise, child access is required here (adult access assumed or guaranteed later). - if (entrance->GetParentRegionKey() == ADULT_SPAWN) { - if (priorityName != "Nocturne" || Settings::GossipStoneHints.Is(HINTS_MASK_OF_TRUTH)) { - continue; - } - } - // If not shuffling dungeons, Nocturne requires adult access - if (!Settings::ShuffleDungeonEntrances && priorityName == "Nocturne") { - if (entrance->GetType() != EntranceType::WarpSong && entrance->GetParentRegionKey() != ADULT_SPAWN) { - continue; - } - } - for (Entrance* target : oneWayTargetEntrancePools[entrance->GetType()]) { - AreaKey targetRegionKey = target->GetConnectedRegionKey(); - if (targetRegionKey != NONE && ElementInContainer(targetRegionKey, allowedRegions)) { - if (ReplaceEntrance(entrance, target, rollbacks)) { - // Return once the entrance has been replaced - return true; - } - } - } - } - #ifdef ENABLE_DEBUG - auto message = "ERROR: Unable to place priority one-way entrance for " + priorityName + "\n"; - SPDLOG_DEBUG(message); - PlacementLog_Write(); - #endif - return false; -} - -// Once the first entrance to Impas House has been placed, try to place the next one immediately to reduce chances of failure. -static bool PlaceOtherImpasHouseEntrance(std::vector entrances, std::vector targetEntrances, std::vector& rollbacks) { - // Get the other impas house entrance - auto otherImpaTargets = FilterFromPool(targetEntrances, [](const Entrance* target){return (target->GetConnectedRegionKey() == KAK_IMPAS_HOUSE || target->GetConnectedRegionKey() == KAK_IMPAS_HOUSE_BACK);}); - if (otherImpaTargets.empty()) { - return true; - } - - Entrance* otherImpaTarget = otherImpaTargets[0]; - auto m = "Now Placing Other Impa Target: " + otherImpaTarget->GetName() + "\n"; - SPDLOG_DEBUG(m); - AreaKey otherImpaRegion = otherImpaTarget->GetConnectedRegionKey() != KAK_IMPAS_HOUSE_BACK ? KAK_IMPAS_HOUSE_BACK : KAK_IMPAS_HOUSE; - for (Entrance* entrance : entrances) { - // If the entrance is already connected or it doesn't have the same hint region as the already placed impas house entrance, then don't try to use it - if (entrance->GetConnectedRegionKey() != NONE || (GetHintRegionHintKey(otherImpaRegion) != GetHintRegionHintKey(entrance->GetParentRegionKey()))) { - continue; - } - // If the placement succeeds, we return true - if (ReplaceEntrance(entrance, otherImpaTarget, rollbacks)) { - return true; - } - } - SPDLOG_DEBUG("No available entrances for placing other impa region.\n"); - return false; -} - -// Shuffle entrances by placing them instead of entrances in the provided target entrances list -static bool ShuffleEntrances(std::vector& entrances, std::vector& targetEntrances, std::vector& rollbacks) { - - Shuffle(entrances); - - //place all entrances in the pool, validating after every placement - for (Entrance* entrance : entrances) { - if (entrance->GetConnectedRegionKey() != NONE) { - continue; - } - - Shuffle(targetEntrances); - for (Entrance* target : targetEntrances) { - if (target->GetConnectedRegionKey() == NONE) { - continue; - } - - // Store whether or not we're about to attempt placing an entrance to Impas House - bool attemptedImpasHousePlacement = (target->GetConnectedRegionKey() == KAK_IMPAS_HOUSE || target->GetConnectedRegionKey() == KAK_IMPAS_HOUSE_BACK); - - if (ReplaceEntrance(entrance, target, rollbacks)) { - // If shuffle cows is enabled and the last entrance was one to Impas House, - // then immediately attempt to place the other entrance to Impas House - if (Settings::ShuffleCows && attemptedImpasHousePlacement) { - if (!PlaceOtherImpasHouseEntrance(entrances, targetEntrances, rollbacks)) { - return false; - } - } - break; - } - } - - if (entrance->GetConnectedRegionKey() == NONE) { - return false; - } - } - - //all entrances were validly connected - return true; -} - -static bool ShuffleOneWayPriorityEntrances(std::map& oneWayPriorities, EntrancePools oneWayEntrancePools, EntrancePools oneWayTargetEntrancePools, int retryCount = 2) { - while (retryCount > 0) { - retryCount--; - std::vector rollbacks = {}; - - bool success = true; - for (auto& priority : oneWayPriorities) { - std::string key = priority.first; - auto& regions = priority.second.targetRegions; - auto& types = priority.second.allowedTypes; - success = PlaceOneWayPriorityEntrance(key, regions, types, rollbacks, oneWayEntrancePools, oneWayTargetEntrancePools); - if (!success) { - for (auto& pair : rollbacks) { - RestoreConnections(pair.first, pair.second); - } - break; - } - } - if (!success) { - continue; - } - // If there are no issues, log the connections and continue - for (auto& pair : rollbacks) { - ConfirmReplacement(pair.first, pair.second); - } - break; - } - - if (retryCount <= 0) { - SPDLOG_DEBUG("Entrance placement attempt count for one way priorities exceeded. Restarting randomization completely\n"); - entranceShuffleFailure = true; - return false; - } - return true; -} - -static void ShuffleEntrancePool(std::vector& entrancePool, std::vector& targetEntrances, int retryCount = 20) { - noRandomEntrances = false; - - auto splitEntrances = SplitEntrancesByRequirements(entrancePool, targetEntrances); - - auto& restrictiveEntrances = splitEntrances[0]; - auto& softEntrances = splitEntrances[1]; - - int retries = retryCount; - while (retries > 0) { - if (retries != retryCount) { - #ifdef ENABLE_DEBUG - std::string ticks = std::to_string(svcGetSystemTick()); - 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); - #endif - } - retries--; - - std::vector rollbacks = {}; - - //Shuffle Restrictive Entrances first while more regions are available in - //order to heavily reduce the chances of the placement failing - bool success = ShuffleEntrances(restrictiveEntrances, targetEntrances, rollbacks); - if (success) { - success = ShuffleEntrances(softEntrances, targetEntrances, rollbacks); - if(!success) { - for (auto& pair : rollbacks) { - RestoreConnections(pair.first, pair.second); - curNumRandomizedEntrances--; - } - continue; - } - } else { - for (auto& pair : rollbacks) { - RestoreConnections(pair.first, pair.second); - curNumRandomizedEntrances--; - } - continue; - } - - //If there are no issues, log the connections and continue - for (auto& pair : rollbacks) { - ConfirmReplacement(pair.first, pair.second); - } - break; - } - - if (retries <= 0) { - SPDLOG_DEBUG("Entrance placement attempt count exceeded. Restarting randomization completely"); - entranceShuffleFailure = true; - } -} - -static void SetShuffledEntrances(EntrancePools entrancePools) { - for (auto& pool : entrancePools) { - for (Entrance* entrance : pool.second) { - entrance->SetAsShuffled(); - if (entrance->GetReverse() != nullptr) { - entrance->GetReverse()->SetAsShuffled(); - } - } - } -} - -//Process for setting up the shuffling of all entrances to be shuffled -int ShuffleAllEntrances() { - - totalRandomizableEntrances = 0; - curNumRandomizedEntrances = 0; - - std::vector entranceShuffleTable = { - //Parent Region Connected Region index - {{EntranceType::Dungeon, KF_OUTSIDE_DEKU_TREE, DEKU_TREE_ENTRYWAY, 0x0000}, - {EntranceType::Dungeon, DEKU_TREE_ENTRYWAY, KF_OUTSIDE_DEKU_TREE, 0x0209}}, - {{EntranceType::Dungeon, DEATH_MOUNTAIN_TRAIL, DODONGOS_CAVERN_ENTRYWAY, 0x0004}, - {EntranceType::Dungeon, DODONGOS_CAVERN_ENTRYWAY, DEATH_MOUNTAIN_TRAIL, 0x0242}}, - {{EntranceType::Dungeon, ZORAS_FOUNTAIN, JABU_JABUS_BELLY_ENTRYWAY, 0x0028}, - {EntranceType::Dungeon, JABU_JABUS_BELLY_ENTRYWAY, ZORAS_FOUNTAIN, 0x0221}}, - {{EntranceType::Dungeon, SACRED_FOREST_MEADOW, FOREST_TEMPLE_ENTRYWAY, 0x0169}, - {EntranceType::Dungeon, FOREST_TEMPLE_ENTRYWAY, SACRED_FOREST_MEADOW, 0x0215}}, - {{EntranceType::Dungeon, DMC_CENTRAL_LOCAL, FIRE_TEMPLE_ENTRYWAY, 0x0165}, - {EntranceType::Dungeon, FIRE_TEMPLE_ENTRYWAY, DMC_CENTRAL_LOCAL, 0x024A}}, - {{EntranceType::Dungeon, LAKE_HYLIA, WATER_TEMPLE_ENTRYWAY, 0x0010}, - {EntranceType::Dungeon, WATER_TEMPLE_ENTRYWAY, LAKE_HYLIA, 0x021D}}, - {{EntranceType::Dungeon, DESERT_COLOSSUS, SPIRIT_TEMPLE_ENTRYWAY, 0x0082}, - {EntranceType::Dungeon, SPIRIT_TEMPLE_ENTRYWAY, DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY, 0x01E1}}, - {{EntranceType::Dungeon, GRAVEYARD_WARP_PAD_REGION, SHADOW_TEMPLE_ENTRYWAY, 0x0037}, - {EntranceType::Dungeon, SHADOW_TEMPLE_ENTRYWAY, GRAVEYARD_WARP_PAD_REGION, 0x0205}}, - {{EntranceType::Dungeon, KAKARIKO_VILLAGE, BOTTOM_OF_THE_WELL_ENTRYWAY, 0x0098}, - {EntranceType::Dungeon, BOTTOM_OF_THE_WELL_ENTRYWAY, KAKARIKO_VILLAGE, 0x02A6}}, - {{EntranceType::Dungeon, ZORAS_FOUNTAIN, ICE_CAVERN_ENTRYWAY, 0x0088}, - {EntranceType::Dungeon, ICE_CAVERN_ENTRYWAY, ZORAS_FOUNTAIN, 0x03D4}}, - {{EntranceType::Dungeon, GERUDO_FORTRESS, GERUDO_TRAINING_GROUNDS_ENTRYWAY, 0x0008}, - {EntranceType::Dungeon, GERUDO_TRAINING_GROUNDS_ENTRYWAY, GERUDO_FORTRESS, 0x03A8}}, - {{EntranceType::GanonDungeon, GANONS_CASTLE_LEDGE, GANONS_CASTLE_ENTRYWAY, 0x0467}, - {EntranceType::GanonDungeon, GANONS_CASTLE_ENTRYWAY, CASTLE_GROUNDS_FROM_GANONS_CASTLE, 0x023D}}, - - {{EntranceType::Interior, KOKIRI_FOREST, KF_MIDOS_HOUSE, 0x0433}, - {EntranceType::Interior, KF_MIDOS_HOUSE, KOKIRI_FOREST, 0x0443}}, - {{EntranceType::Interior, KOKIRI_FOREST, KF_SARIAS_HOUSE, 0x0437}, - {EntranceType::Interior, KF_SARIAS_HOUSE, KOKIRI_FOREST, 0x0447}}, - {{EntranceType::Interior, KOKIRI_FOREST, KF_HOUSE_OF_TWINS, 0x009C}, - {EntranceType::Interior, KF_HOUSE_OF_TWINS, KOKIRI_FOREST, 0x033C}}, - {{EntranceType::Interior, KOKIRI_FOREST, KF_KNOW_IT_ALL_HOUSE, 0x00C9}, - {EntranceType::Interior, KF_KNOW_IT_ALL_HOUSE, KOKIRI_FOREST, 0x026A}}, - {{EntranceType::Interior, KOKIRI_FOREST, KF_KOKIRI_SHOP, 0x00C1}, - {EntranceType::Interior, KF_KOKIRI_SHOP, KOKIRI_FOREST, 0x0266}}, - {{EntranceType::Interior, LAKE_HYLIA, LH_LAB, 0x0043}, - {EntranceType::Interior, LH_LAB, LAKE_HYLIA, 0x03CC}}, - {{EntranceType::Interior, LH_FISHING_ISLAND, LH_FISHING_HOLE, 0x045F}, - {EntranceType::Interior, LH_FISHING_HOLE, LH_FISHING_ISLAND, 0x0309}}, - {{EntranceType::Interior, GV_FORTRESS_SIDE, GV_CARPENTER_TENT, 0x03A0}, - {EntranceType::Interior, GV_CARPENTER_TENT, GV_FORTRESS_SIDE, 0x03D0}}, - {{EntranceType::Interior, MARKET_ENTRANCE, MARKET_GUARD_HOUSE, 0x007E}, - {EntranceType::Interior, MARKET_GUARD_HOUSE, MARKET_ENTRANCE, 0x026E}}, - {{EntranceType::Interior, THE_MARKET, MARKET_MASK_SHOP, 0x0530}, - {EntranceType::Interior, MARKET_MASK_SHOP, THE_MARKET, 0x01D1}}, - {{EntranceType::Interior, THE_MARKET, MARKET_BOMBCHU_BOWLING, 0x0507}, - {EntranceType::Interior, MARKET_BOMBCHU_BOWLING, THE_MARKET, 0x03BC}}, - {{EntranceType::Interior, THE_MARKET, MARKET_POTION_SHOP, 0x0388}, - {EntranceType::Interior, MARKET_POTION_SHOP, THE_MARKET, 0x02A2}}, - {{EntranceType::Interior, THE_MARKET, MARKET_TREASURE_CHEST_GAME, 0x0063}, - {EntranceType::Interior, MARKET_TREASURE_CHEST_GAME, THE_MARKET, 0x01D5}}, - {{EntranceType::Interior, MARKET_BACK_ALLEY, MARKET_BOMBCHU_SHOP, 0x0528}, - {EntranceType::Interior, MARKET_BOMBCHU_SHOP, MARKET_BACK_ALLEY, 0x03C0}}, - {{EntranceType::Interior, MARKET_BACK_ALLEY, MARKET_MAN_IN_GREEN_HOUSE, 0x043B}, - {EntranceType::Interior, MARKET_MAN_IN_GREEN_HOUSE, MARKET_BACK_ALLEY, 0x0067}}, - {{EntranceType::Interior, KAKARIKO_VILLAGE, KAK_CARPENTER_BOSS_HOUSE, 0x02FD}, - {EntranceType::Interior, KAK_CARPENTER_BOSS_HOUSE, KAKARIKO_VILLAGE, 0x0349}}, - {{EntranceType::Interior, KAKARIKO_VILLAGE, KAK_HOUSE_OF_SKULLTULA, 0x0550}, - {EntranceType::Interior, KAK_HOUSE_OF_SKULLTULA, KAKARIKO_VILLAGE, 0x04EE}}, - {{EntranceType::Interior, KAKARIKO_VILLAGE, KAK_IMPAS_HOUSE, 0x039C}, - {EntranceType::Interior, KAK_IMPAS_HOUSE, KAKARIKO_VILLAGE, 0x0345}}, - {{EntranceType::Interior, KAK_IMPAS_LEDGE, KAK_IMPAS_HOUSE_BACK, 0x05C8}, - {EntranceType::Interior, KAK_IMPAS_HOUSE_BACK, KAK_IMPAS_LEDGE, 0x05DC}}, - {{EntranceType::Interior, KAK_BACKYARD, KAK_ODD_POTION_BUILDING, 0x0072}, - {EntranceType::Interior, KAK_ODD_POTION_BUILDING, KAK_BACKYARD, 0x034D}}, - {{EntranceType::Interior, THE_GRAVEYARD, GRAVEYARD_DAMPES_HOUSE, 0x030D}, - {EntranceType::Interior, GRAVEYARD_DAMPES_HOUSE, THE_GRAVEYARD, 0x0355}}, - {{EntranceType::Interior, GORON_CITY, GC_SHOP, 0x037C}, - {EntranceType::Interior, GC_SHOP, GORON_CITY, 0x03FC}}, - {{EntranceType::Interior, ZORAS_DOMAIN, ZD_SHOP, 0x0380}, - {EntranceType::Interior, ZD_SHOP, ZORAS_DOMAIN, 0x03C4}}, - {{EntranceType::Interior, LON_LON_RANCH, LLR_TALONS_HOUSE, 0x004F}, - {EntranceType::Interior, LLR_TALONS_HOUSE, LON_LON_RANCH, 0x0378}}, - {{EntranceType::Interior, LON_LON_RANCH, LLR_STABLES, 0x02F9}, - {EntranceType::Interior, LLR_STABLES, LON_LON_RANCH, 0x042F}}, - {{EntranceType::Interior, LON_LON_RANCH, LLR_TOWER, 0x05D0}, - {EntranceType::Interior, LLR_TOWER, LON_LON_RANCH, 0x05D4}}, - {{EntranceType::Interior, THE_MARKET, MARKET_BAZAAR, 0x052C}, - {EntranceType::Interior, MARKET_BAZAAR, THE_MARKET, 0x03B8}}, - {{EntranceType::Interior, THE_MARKET, MARKET_SHOOTING_GALLERY, 0x016D}, - {EntranceType::Interior, MARKET_SHOOTING_GALLERY, THE_MARKET, 0x01CD}}, - {{EntranceType::Interior, KAKARIKO_VILLAGE, KAK_BAZAAR, 0x00B7}, - {EntranceType::Interior, KAK_BAZAAR, KAKARIKO_VILLAGE, 0x0201}}, - {{EntranceType::Interior, KAKARIKO_VILLAGE, KAK_SHOOTING_GALLERY, 0x003B}, - {EntranceType::Interior, KAK_SHOOTING_GALLERY, KAKARIKO_VILLAGE, 0x0463}}, - {{EntranceType::Interior, DESERT_COLOSSUS, COLOSSUS_GREAT_FAIRY_FOUNTAIN, 0x0588}, - {EntranceType::Interior, COLOSSUS_GREAT_FAIRY_FOUNTAIN, DESERT_COLOSSUS, 0x057C}}, - {{EntranceType::Interior, HYRULE_CASTLE_GROUNDS, HC_GREAT_FAIRY_FOUNTAIN, 0x0578}, - {EntranceType::Interior, HC_GREAT_FAIRY_FOUNTAIN, CASTLE_GROUNDS, 0x0340}}, - {{EntranceType::Interior, GANONS_CASTLE_GROUNDS, OGC_GREAT_FAIRY_FOUNTAIN, 0x04C2}, - {EntranceType::Interior, OGC_GREAT_FAIRY_FOUNTAIN, CASTLE_GROUNDS, 0x03E8}}, //0x3E8 is an unused entrance index repruposed to differentiate between the HC and OGC fairy fountain exits (normally they both use 0x340) - {{EntranceType::Interior, DMC_LOWER_NEARBY, DMC_GREAT_FAIRY_FOUNTAIN, 0x04BE}, - {EntranceType::Interior, DMC_GREAT_FAIRY_FOUNTAIN, DMC_LOWER_LOCAL, 0x0482}}, - {{EntranceType::Interior, DEATH_MOUNTAIN_SUMMIT, DMT_GREAT_FAIRY_FOUNTAIN, 0x0315}, - {EntranceType::Interior, DMT_GREAT_FAIRY_FOUNTAIN, DEATH_MOUNTAIN_SUMMIT, 0x045B}}, - {{EntranceType::Interior, ZORAS_FOUNTAIN, ZF_GREAT_FAIRY_FOUNTAIN, 0x0371}, - {EntranceType::Interior, ZF_GREAT_FAIRY_FOUNTAIN, ZORAS_FOUNTAIN, 0x0394}}, - - {{EntranceType::SpecialInterior, KOKIRI_FOREST, KF_LINKS_HOUSE, 0x0272}, - {EntranceType::SpecialInterior, KF_LINKS_HOUSE, KOKIRI_FOREST, 0x0211}}, - {{EntranceType::SpecialInterior, TOT_ENTRANCE, TEMPLE_OF_TIME, 0x0053}, - {EntranceType::SpecialInterior, TEMPLE_OF_TIME, TOT_ENTRANCE, 0x0472}}, - {{EntranceType::SpecialInterior, KAKARIKO_VILLAGE, KAK_WINDMILL, 0x0453}, - {EntranceType::SpecialInterior, KAK_WINDMILL, KAKARIKO_VILLAGE, 0x0351}}, - {{EntranceType::SpecialInterior, KAKARIKO_VILLAGE, KAK_POTION_SHOP_FRONT, 0x0384}, - {EntranceType::SpecialInterior, KAK_POTION_SHOP_FRONT, KAKARIKO_VILLAGE, 0x044B}}, - {{EntranceType::SpecialInterior, KAK_BACKYARD, KAK_POTION_SHOP_BACK, 0x03EC}, - {EntranceType::SpecialInterior, KAK_POTION_SHOP_BACK, KAK_BACKYARD, 0x04FF}}, - - // Grotto Loads use an entrance index of 0x0700 + their grotto id. The id is used as index for the - // grottoLoadTable in soh/soh/Enhancements/randomizer/randomizer_grotto.c - // Grotto Returns use an entrance index of 0x0800 + their grotto id. The id is used as index for the - // grottoReturnTable in soh/soh/Enhancements/randomizer/randomizer_grotto.c - {{EntranceType::GrottoGrave, DESERT_COLOSSUS, COLOSSUS_GROTTO, 0x0700}, - {EntranceType::GrottoGrave, COLOSSUS_GROTTO, DESERT_COLOSSUS, 0x0800}}, - {{EntranceType::GrottoGrave, LAKE_HYLIA, LH_GROTTO, 0x0701}, - {EntranceType::GrottoGrave, LH_GROTTO, LAKE_HYLIA, 0x0801}}, - {{EntranceType::GrottoGrave, ZORAS_RIVER, ZR_STORMS_GROTTO, 0x0702}, - {EntranceType::GrottoGrave, ZR_STORMS_GROTTO, ZORAS_RIVER, 0x0802}}, - {{EntranceType::GrottoGrave, ZORAS_RIVER, ZR_FAIRY_GROTTO, 0x0703}, - {EntranceType::GrottoGrave, ZR_FAIRY_GROTTO, ZORAS_RIVER, 0x0803}}, - {{EntranceType::GrottoGrave, ZORAS_RIVER, ZR_OPEN_GROTTO, 0x0704}, - {EntranceType::GrottoGrave, ZR_OPEN_GROTTO, ZORAS_RIVER, 0x0804}}, - {{EntranceType::GrottoGrave, DMC_LOWER_NEARBY, DMC_HAMMER_GROTTO, 0x0705}, - {EntranceType::GrottoGrave, DMC_HAMMER_GROTTO, DMC_LOWER_LOCAL, 0x0805}}, - {{EntranceType::GrottoGrave, DMC_UPPER_NEARBY, DMC_UPPER_GROTTO, 0x0706}, - {EntranceType::GrottoGrave, DMC_UPPER_GROTTO, DMC_UPPER_LOCAL, 0x0806}}, - {{EntranceType::GrottoGrave, GC_GROTTO_PLATFORM, GC_GROTTO, 0x0707}, - {EntranceType::GrottoGrave, GC_GROTTO, GC_GROTTO_PLATFORM, 0x0807}}, - {{EntranceType::GrottoGrave, DEATH_MOUNTAIN_TRAIL, DMT_STORMS_GROTTO, 0x0708}, - {EntranceType::GrottoGrave, DMT_STORMS_GROTTO, DEATH_MOUNTAIN_TRAIL, 0x0808}}, - {{EntranceType::GrottoGrave, DEATH_MOUNTAIN_SUMMIT, DMT_COW_GROTTO, 0x0709}, - {EntranceType::GrottoGrave, DMT_COW_GROTTO, DEATH_MOUNTAIN_SUMMIT, 0x0809}}, - {{EntranceType::GrottoGrave, KAK_BACKYARD, KAK_OPEN_GROTTO, 0x070A}, - {EntranceType::GrottoGrave, KAK_OPEN_GROTTO, KAK_BACKYARD, 0x080A}}, - {{EntranceType::GrottoGrave, KAKARIKO_VILLAGE, KAK_REDEAD_GROTTO, 0x070B}, - {EntranceType::GrottoGrave, KAK_REDEAD_GROTTO, KAKARIKO_VILLAGE, 0x080B}}, - {{EntranceType::GrottoGrave, HYRULE_CASTLE_GROUNDS, HC_STORMS_GROTTO, 0x070C}, - {EntranceType::GrottoGrave, HC_STORMS_GROTTO, CASTLE_GROUNDS, 0x080C}}, - {{EntranceType::GrottoGrave, HYRULE_FIELD, HF_TEKTITE_GROTTO, 0x070D}, - {EntranceType::GrottoGrave, HF_TEKTITE_GROTTO, HYRULE_FIELD, 0x080D}}, - {{EntranceType::GrottoGrave, HYRULE_FIELD, HF_NEAR_KAK_GROTTO, 0x070E}, - {EntranceType::GrottoGrave, HF_NEAR_KAK_GROTTO, HYRULE_FIELD, 0x080E}}, - {{EntranceType::GrottoGrave, HYRULE_FIELD, HF_FAIRY_GROTTO, 0x070F}, - {EntranceType::GrottoGrave, HF_FAIRY_GROTTO, HYRULE_FIELD, 0x080F}}, - {{EntranceType::GrottoGrave, HYRULE_FIELD, HF_NEAR_MARKET_GROTTO, 0x0710}, - {EntranceType::GrottoGrave, HF_NEAR_MARKET_GROTTO, HYRULE_FIELD, 0x0810}}, - {{EntranceType::GrottoGrave, HYRULE_FIELD, HF_COW_GROTTO, 0x0711}, - {EntranceType::GrottoGrave, HF_COW_GROTTO, HYRULE_FIELD, 0x0811}}, - {{EntranceType::GrottoGrave, HYRULE_FIELD, HF_INSIDE_FENCE_GROTTO, 0x0712}, - {EntranceType::GrottoGrave, HF_INSIDE_FENCE_GROTTO, HYRULE_FIELD, 0x0812}}, - {{EntranceType::GrottoGrave, HYRULE_FIELD, HF_OPEN_GROTTO, 0x0713}, - {EntranceType::GrottoGrave, HF_OPEN_GROTTO, HYRULE_FIELD, 0x0813}}, - {{EntranceType::GrottoGrave, HYRULE_FIELD, HF_SOUTHEAST_GROTTO, 0x0714}, - {EntranceType::GrottoGrave, HF_SOUTHEAST_GROTTO, HYRULE_FIELD, 0x0814}}, - {{EntranceType::GrottoGrave, LON_LON_RANCH, LLR_GROTTO, 0x0715}, - {EntranceType::GrottoGrave, LLR_GROTTO, LON_LON_RANCH, 0x0815}}, - {{EntranceType::GrottoGrave, SFM_ENTRYWAY, SFM_WOLFOS_GROTTO, 0x0716}, - {EntranceType::GrottoGrave, SFM_WOLFOS_GROTTO, SFM_ENTRYWAY, 0x0816}}, - {{EntranceType::GrottoGrave, SACRED_FOREST_MEADOW, SFM_STORMS_GROTTO, 0x0717}, - {EntranceType::GrottoGrave, SFM_STORMS_GROTTO, SACRED_FOREST_MEADOW, 0x0817}}, - {{EntranceType::GrottoGrave, SACRED_FOREST_MEADOW, SFM_FAIRY_GROTTO, 0x0718}, - {EntranceType::GrottoGrave, SFM_FAIRY_GROTTO, SACRED_FOREST_MEADOW, 0x0818}}, - {{EntranceType::GrottoGrave, LW_BEYOND_MIDO, LW_SCRUBS_GROTTO, 0x0719}, - {EntranceType::GrottoGrave, LW_SCRUBS_GROTTO, LW_BEYOND_MIDO, 0x0819}}, - {{EntranceType::GrottoGrave, THE_LOST_WOODS, LW_NEAR_SHORTCUTS_GROTTO, 0x071A}, - {EntranceType::GrottoGrave, LW_NEAR_SHORTCUTS_GROTTO, THE_LOST_WOODS, 0x081A}}, - {{EntranceType::GrottoGrave, KOKIRI_FOREST, KF_STORMS_GROTTO, 0x071B}, - {EntranceType::GrottoGrave, KF_STORMS_GROTTO, KOKIRI_FOREST, 0x081B}}, - {{EntranceType::GrottoGrave, ZORAS_DOMAIN, ZD_STORMS_GROTTO, 0x071C}, - {EntranceType::GrottoGrave, ZD_STORMS_GROTTO, ZORAS_DOMAIN, 0x081C}}, - {{EntranceType::GrottoGrave, GERUDO_FORTRESS, GF_STORMS_GROTTO, 0x071D}, - {EntranceType::GrottoGrave, GF_STORMS_GROTTO, GERUDO_FORTRESS, 0x081D}}, - {{EntranceType::GrottoGrave, GV_FORTRESS_SIDE, GV_STORMS_GROTTO, 0x071E}, - {EntranceType::GrottoGrave, GV_STORMS_GROTTO, GV_FORTRESS_SIDE, 0x081E}}, - {{EntranceType::GrottoGrave, GV_GROTTO_LEDGE, GV_OCTOROK_GROTTO, 0x071F}, - {EntranceType::GrottoGrave, GV_OCTOROK_GROTTO, GV_GROTTO_LEDGE, 0x081F}}, - {{EntranceType::GrottoGrave, LW_BEYOND_MIDO, DEKU_THEATER, 0x0720}, - {EntranceType::GrottoGrave, DEKU_THEATER, LW_BEYOND_MIDO, 0x0820}}, - - // Graves have their own specified entrance indices - {{EntranceType::GrottoGrave, THE_GRAVEYARD, GRAVEYARD_SHIELD_GRAVE, 0x004B}, - {EntranceType::GrottoGrave, GRAVEYARD_SHIELD_GRAVE, THE_GRAVEYARD, 0x035D}}, - {{EntranceType::GrottoGrave, THE_GRAVEYARD, GRAVEYARD_HEART_PIECE_GRAVE, 0x031C}, - {EntranceType::GrottoGrave, GRAVEYARD_HEART_PIECE_GRAVE, THE_GRAVEYARD, 0x0361}}, - {{EntranceType::GrottoGrave, THE_GRAVEYARD, GRAVEYARD_COMPOSERS_GRAVE, 0x002D}, - {EntranceType::GrottoGrave, GRAVEYARD_COMPOSERS_GRAVE, THE_GRAVEYARD, 0x050B}}, - {{EntranceType::GrottoGrave, THE_GRAVEYARD, GRAVEYARD_DAMPES_GRAVE, 0x044F}, - {EntranceType::GrottoGrave, GRAVEYARD_DAMPES_GRAVE, THE_GRAVEYARD, 0x0359}}, - - {{EntranceType::Overworld, KOKIRI_FOREST, LW_BRIDGE_FROM_FOREST, 0x05E0}, - {EntranceType::Overworld, LW_BRIDGE, KOKIRI_FOREST, 0x020D}}, - {{EntranceType::Overworld, KOKIRI_FOREST, THE_LOST_WOODS, 0x011E}, - {EntranceType::Overworld, LW_FOREST_EXIT, KOKIRI_FOREST, 0x0286}}, - {{EntranceType::Overworld, THE_LOST_WOODS, GC_WOODS_WARP, 0x04E2}, - {EntranceType::Overworld, GC_WOODS_WARP, THE_LOST_WOODS, 0x04D6}}, - {{EntranceType::Overworld, THE_LOST_WOODS, ZORAS_RIVER, 0x01DD}, - {EntranceType::Overworld, ZORAS_RIVER, THE_LOST_WOODS, 0x04DA}}, - {{EntranceType::Overworld, LW_BEYOND_MIDO, SFM_ENTRYWAY, 0x00FC}, - {EntranceType::Overworld, SFM_ENTRYWAY, LW_BEYOND_MIDO, 0x01A9}}, - {{EntranceType::Overworld, LW_BRIDGE, HYRULE_FIELD, 0x0185}, - {EntranceType::Overworld, HYRULE_FIELD, LW_BRIDGE, 0x04DE}}, - {{EntranceType::Overworld, HYRULE_FIELD, LAKE_HYLIA, 0x0102}, - {EntranceType::Overworld, LAKE_HYLIA, HYRULE_FIELD, 0x0189}}, - {{EntranceType::Overworld, HYRULE_FIELD, GERUDO_VALLEY, 0x0117}, - {EntranceType::Overworld, GERUDO_VALLEY, HYRULE_FIELD, 0x018D}}, - {{EntranceType::Overworld, HYRULE_FIELD, MARKET_ENTRANCE, 0x0276}, - {EntranceType::Overworld, MARKET_ENTRANCE, HYRULE_FIELD, 0x01FD}}, - {{EntranceType::Overworld, HYRULE_FIELD, KAKARIKO_VILLAGE, 0x00DB}, - {EntranceType::Overworld, KAKARIKO_VILLAGE, HYRULE_FIELD, 0x017D}}, - {{EntranceType::Overworld, HYRULE_FIELD, ZR_FRONT, 0x00EA}, - {EntranceType::Overworld, ZR_FRONT, HYRULE_FIELD, 0x0181}}, - {{EntranceType::Overworld, HYRULE_FIELD, LON_LON_RANCH, 0x0157}, - {EntranceType::Overworld, LON_LON_RANCH, HYRULE_FIELD, 0x01F9}}, - {{EntranceType::Overworld, LAKE_HYLIA, ZORAS_DOMAIN, 0x0328}, - {EntranceType::Overworld, ZORAS_DOMAIN, LAKE_HYLIA, 0x0560}}, - {{EntranceType::Overworld, GV_FORTRESS_SIDE, GERUDO_FORTRESS, 0x0129}, - {EntranceType::Overworld, GERUDO_FORTRESS, GV_FORTRESS_SIDE, 0x022D}}, - {{EntranceType::Overworld, GF_OUTSIDE_GATE, WASTELAND_NEAR_FORTRESS, 0x0130}, - {EntranceType::Overworld, WASTELAND_NEAR_FORTRESS, GF_OUTSIDE_GATE, 0x03AC}}, - {{EntranceType::Overworld, WASTELAND_NEAR_COLOSSUS, DESERT_COLOSSUS, 0x0123}, - {EntranceType::Overworld, DESERT_COLOSSUS, WASTELAND_NEAR_COLOSSUS, 0x0365}}, - {{EntranceType::Overworld, MARKET_ENTRANCE, THE_MARKET, 0x00B1}, - {EntranceType::Overworld, THE_MARKET, MARKET_ENTRANCE, 0x0033}}, - {{EntranceType::Overworld, THE_MARKET, CASTLE_GROUNDS, 0x0138}, - {EntranceType::Overworld, CASTLE_GROUNDS, THE_MARKET, 0x025A}}, - {{EntranceType::Overworld, THE_MARKET, TOT_ENTRANCE, 0x0171}, - {EntranceType::Overworld, TOT_ENTRANCE, THE_MARKET, 0x025E}}, - {{EntranceType::Overworld, KAKARIKO_VILLAGE, THE_GRAVEYARD, 0x00E4}, - {EntranceType::Overworld, THE_GRAVEYARD, KAKARIKO_VILLAGE, 0x0195}}, - {{EntranceType::Overworld, KAK_BEHIND_GATE, DEATH_MOUNTAIN_TRAIL, 0x013D}, - {EntranceType::Overworld, DEATH_MOUNTAIN_TRAIL, KAK_BEHIND_GATE, 0x0191}}, - {{EntranceType::Overworld, DEATH_MOUNTAIN_TRAIL, GORON_CITY, 0x014D}, - {EntranceType::Overworld, GORON_CITY, DEATH_MOUNTAIN_TRAIL, 0x01B9}}, - {{EntranceType::Overworld, GC_DARUNIAS_CHAMBER, DMC_LOWER_LOCAL, 0x0246}, - {EntranceType::Overworld, DMC_LOWER_NEARBY, GC_DARUNIAS_CHAMBER, 0x01C1}}, - {{EntranceType::Overworld, DEATH_MOUNTAIN_SUMMIT, DMC_UPPER_LOCAL, 0x0147}, - {EntranceType::Overworld, DMC_UPPER_NEARBY, DEATH_MOUNTAIN_SUMMIT, 0x01BD}}, - {{EntranceType::Overworld, ZR_BEHIND_WATERFALL, ZORAS_DOMAIN, 0x0108}, - {EntranceType::Overworld, ZORAS_DOMAIN, ZR_BEHIND_WATERFALL, 0x019D}}, - {{EntranceType::Overworld, ZD_BEHIND_KING_ZORA, ZORAS_FOUNTAIN, 0x0225}, - {EntranceType::Overworld, ZORAS_FOUNTAIN, ZD_BEHIND_KING_ZORA, 0x01A1}}, - - {{EntranceType::Overworld, GV_LOWER_STREAM, LAKE_HYLIA, 0x0219}, NO_RETURN_ENTRANCE}, - - {{EntranceType::OwlDrop, LH_OWL_FLIGHT, HYRULE_FIELD, 0x027E}, NO_RETURN_ENTRANCE}, - {{EntranceType::OwlDrop, DMT_OWL_FLIGHT, KAK_IMPAS_ROOFTOP, 0x0554}, NO_RETURN_ENTRANCE}, - - {{EntranceType::Spawn, CHILD_SPAWN, KF_LINKS_HOUSE, 0x00BB}, NO_RETURN_ENTRANCE}, - {{EntranceType::Spawn, ADULT_SPAWN, TEMPLE_OF_TIME, 0x0282}, NO_RETURN_ENTRANCE}, // 0x282 is an unused entrance index repurposed to differentiate between - // Adult Spawn and prelude of light (normally they both use 0x5F4) - {{EntranceType::WarpSong, MINUET_OF_FOREST_WARP, SACRED_FOREST_MEADOW, 0x0600}, NO_RETURN_ENTRANCE}, - {{EntranceType::WarpSong, BOLERO_OF_FIRE_WARP, DMC_CENTRAL_LOCAL, 0x04F6}, NO_RETURN_ENTRANCE}, - {{EntranceType::WarpSong, SERENADE_OF_WATER_WARP, LAKE_HYLIA, 0x0604}, NO_RETURN_ENTRANCE}, - {{EntranceType::WarpSong, REQUIEM_OF_SPIRIT_WARP, DESERT_COLOSSUS, 0x01F1}, NO_RETURN_ENTRANCE}, - {{EntranceType::WarpSong, NOCTURNE_OF_SHADOW_WARP, GRAVEYARD_WARP_PAD_REGION, 0x0568}, NO_RETURN_ENTRANCE}, - {{EntranceType::WarpSong, PRELUDE_OF_LIGHT_WARP, TEMPLE_OF_TIME, 0x05F4}, NO_RETURN_ENTRANCE}, - - {{EntranceType::ChildBoss, DEKU_TREE_BOSS_ENTRYWAY, DEKU_TREE_BOSS_ROOM, 0x040F}, - {EntranceType::ChildBoss, DEKU_TREE_BOSS_ROOM, DEKU_TREE_BOSS_ENTRYWAY, 0x0252}}, - {{EntranceType::ChildBoss, DODONGOS_CAVERN_BOSS_ENTRYWAY, DODONGOS_CAVERN_BOSS_ROOM, 0x040B}, - {EntranceType::ChildBoss, DODONGOS_CAVERN_BOSS_ROOM, DODONGOS_CAVERN_BOSS_ENTRYWAY, 0x00C5}}, - {{EntranceType::ChildBoss, JABU_JABUS_BELLY_BOSS_ENTRYWAY, JABU_JABUS_BELLY_BOSS_ROOM, 0x0301}, - {EntranceType::ChildBoss, JABU_JABUS_BELLY_BOSS_ROOM, JABU_JABUS_BELLY_BOSS_ENTRYWAY, 0x0407}}, - {{EntranceType::AdultBoss, FOREST_TEMPLE_BOSS_ENTRYWAY, FOREST_TEMPLE_BOSS_ROOM, 0x000C}, - {EntranceType::AdultBoss, FOREST_TEMPLE_BOSS_ROOM, FOREST_TEMPLE_BOSS_ENTRYWAY, 0x024E}}, - {{EntranceType::AdultBoss, FIRE_TEMPLE_BOSS_ENTRYWAY, FIRE_TEMPLE_BOSS_ROOM, 0x0305}, - {EntranceType::AdultBoss, FIRE_TEMPLE_BOSS_ROOM, FIRE_TEMPLE_BOSS_ENTRYWAY, 0x0175}}, - {{EntranceType::AdultBoss, WATER_TEMPLE_BOSS_ENTRYWAY, WATER_TEMPLE_BOSS_ROOM, 0x0417}, - {EntranceType::AdultBoss, WATER_TEMPLE_BOSS_ROOM, WATER_TEMPLE_BOSS_ENTRYWAY, 0x0423}}, - {{EntranceType::AdultBoss, SPIRIT_TEMPLE_BOSS_ENTRYWAY, SPIRIT_TEMPLE_BOSS_ROOM, 0x008D}, - {EntranceType::AdultBoss, SPIRIT_TEMPLE_BOSS_ROOM, SPIRIT_TEMPLE_BOSS_ENTRYWAY, 0x02F5}}, - {{EntranceType::AdultBoss, SHADOW_TEMPLE_BOSS_ENTRYWAY, SHADOW_TEMPLE_BOSS_ROOM, 0x0413}, - {EntranceType::AdultBoss, SHADOW_TEMPLE_BOSS_ROOM, SHADOW_TEMPLE_BOSS_ENTRYWAY, 0x02B2}}, - - {{EntranceType::BlueWarp, DEKU_TREE_BOSS_ROOM, KF_OUTSIDE_DEKU_TREE, 0x0457}, NO_RETURN_ENTRANCE}, - {{EntranceType::BlueWarp, DODONGOS_CAVERN_BOSS_ROOM, DEATH_MOUNTAIN_TRAIL, 0x047A}, NO_RETURN_ENTRANCE}, - {{EntranceType::BlueWarp, JABU_JABUS_BELLY_BOSS_ROOM, ZORAS_FOUNTAIN, 0x010E}, NO_RETURN_ENTRANCE}, - {{EntranceType::BlueWarp, FOREST_TEMPLE_BOSS_ROOM, SACRED_FOREST_MEADOW, 0x0608}, NO_RETURN_ENTRANCE}, - {{EntranceType::BlueWarp, FIRE_TEMPLE_BOSS_ROOM, DMC_CENTRAL_LOCAL, 0x0564}, NO_RETURN_ENTRANCE}, - {{EntranceType::BlueWarp, WATER_TEMPLE_BOSS_ROOM, LAKE_HYLIA, 0x060C}, NO_RETURN_ENTRANCE}, - {{EntranceType::BlueWarp, SPIRIT_TEMPLE_BOSS_ROOM, DESERT_COLOSSUS, 0x0610}, NO_RETURN_ENTRANCE}, - {{EntranceType::BlueWarp, SHADOW_TEMPLE_BOSS_ROOM, GRAVEYARD_WARP_PAD_REGION, 0x0580}, NO_RETURN_ENTRANCE}, - }; - - std::map priorityEntranceTable = { - {"Bolero", {{DMC_CENTRAL_LOCAL}, {EntranceType::OwlDrop, EntranceType::WarpSong}}}, - {"Nocturne", {{GRAVEYARD_WARP_PAD_REGION}, {EntranceType::OwlDrop, EntranceType::Spawn, EntranceType::WarpSong}}}, - {"Requiem", {{DESERT_COLOSSUS, DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY}, {EntranceType::OwlDrop, EntranceType::Spawn, EntranceType::WarpSong}}}, - }; - - entranceShuffleFailure = false; - SetAllEntrancesData(entranceShuffleTable); - - EntrancePools oneWayEntrancePools = {}; - EntrancePools entrancePools = {}; - std::map oneWayPriorities = {}; - - // Owl Drops - if (Settings::ShuffleOwlDrops) { - oneWayEntrancePools[EntranceType::OwlDrop] = GetShuffleableEntrances(EntranceType::OwlDrop); - } - - // Spawns - if (Settings::ShuffleOverworldSpawns) { - oneWayEntrancePools[EntranceType::Spawn] = GetShuffleableEntrances(EntranceType::Spawn); - } - - // Warpsongs - if (Settings::ShuffleWarpSongs) { - oneWayEntrancePools[EntranceType::WarpSong] = GetShuffleableEntrances(EntranceType::WarpSong); - // In Glitchless, there aren't any other ways to access these areas - if (Settings::Logic.Is(LOGIC_GLITCHLESS)) { - oneWayPriorities["Bolero"] = priorityEntranceTable["Bolero"]; - oneWayPriorities["Nocturne"] = priorityEntranceTable["Nocturne"]; - if (!Settings::ShuffleDungeonEntrances && !Settings::ShuffleOverworldEntrances) { - oneWayPriorities["Requiem"] = priorityEntranceTable["Requiem"]; - } - } - } - - // Shuffle Bosses - if (Settings::ShuffleBossEntrances.IsNot(SHUFFLEBOSSES_OFF)) { - if (Settings::ShuffleBossEntrances.Is(SHUFFLEBOSSES_FULL)) { - entrancePools[EntranceType::Boss] = GetShuffleableEntrances(EntranceType::ChildBoss); - AddElementsToPool(entrancePools[EntranceType::Boss], GetShuffleableEntrances(EntranceType::AdultBoss)); - // If forest is closed, ensure Ghoma is inside the Deku tree - // Deku tree being in its vanilla location is handled below - if (Settings::OpenForest.Is(OPENFOREST_CLOSED) && !(Settings::ShuffleOverworldEntrances || Settings::ShuffleInteriorEntrances)) { - FilterAndEraseFromPool(entrancePools[EntranceType::Boss], [](const Entrance* entrance){return entrance->GetParentRegionKey() == DEKU_TREE_BOSS_ENTRYWAY && - entrance->GetConnectedRegionKey() == DEKU_TREE_BOSS_ROOM;}); - } - if (Settings::DecoupleEntrances) { - for (Entrance* entrance : entrancePools[EntranceType::Boss]) { - entrancePools[EntranceType::BossReverse].push_back(entrance->GetReverse()); - } - } - } else { - entrancePools[EntranceType::ChildBoss] = GetShuffleableEntrances(EntranceType::ChildBoss); - entrancePools[EntranceType::AdultBoss] = GetShuffleableEntrances(EntranceType::AdultBoss); - // If forest is closed, ensure Ghoma is inside the Deku tree - if (Settings::OpenForest.Is(OPENFOREST_CLOSED) && !(Settings::ShuffleOverworldEntrances || Settings::ShuffleInteriorEntrances)) { - FilterAndEraseFromPool(entrancePools[EntranceType::ChildBoss], [](const Entrance* entrance){return entrance->GetParentRegionKey() == DEKU_TREE_BOSS_ENTRYWAY && - entrance->GetConnectedRegionKey() == DEKU_TREE_BOSS_ROOM;}); - } - if (Settings::DecoupleEntrances) { - for (Entrance* entrance : entrancePools[EntranceType::ChildBoss]) { - entrancePools[EntranceType::ChildBossReverse].push_back(entrance->GetReverse()); - } - for (Entrance* entrance : entrancePools[EntranceType::AdultBoss]) { - entrancePools[EntranceType::AdultBossReverse].push_back(entrance->GetReverse()); - } - } - } - } - - //Shuffle Dungeon Entrances - if (Settings::ShuffleDungeonEntrances.IsNot(SHUFFLEDUNGEONS_OFF)) { - entrancePools[EntranceType::Dungeon] = GetShuffleableEntrances(EntranceType::Dungeon); - //Add Ganon's Castle, if set to On + Ganon - if (Settings::ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_GANON)) { - AddElementsToPool(entrancePools[EntranceType::Dungeon], GetShuffleableEntrances(EntranceType::GanonDungeon)); - } - //If forest is closed don't allow a forest escape via spirit temple hands - if (Settings::OpenForest.Is(OPENFOREST_CLOSED) && !(Settings::ShuffleOverworldEntrances || Settings::ShuffleInteriorEntrances)) { - FilterAndEraseFromPool(entrancePools[EntranceType::Dungeon], [](const Entrance* entrance){return entrance->GetParentRegionKey() == KF_OUTSIDE_DEKU_TREE && - entrance->GetConnectedRegionKey() == DEKU_TREE_ENTRYWAY;}); - } - if (Settings::DecoupleEntrances) { - for (Entrance* entrance : entrancePools[EntranceType::Dungeon]) { - entrancePools[EntranceType::DungeonReverse].push_back(entrance->GetReverse()); - } - } - } - - // Interior entrances - if (Settings::ShuffleInteriorEntrances.IsNot(SHUFFLEINTERIORS_OFF)) { - entrancePools[EntranceType::Interior] = GetShuffleableEntrances(EntranceType::Interior); - // Special interiors - if (Settings::ShuffleInteriorEntrances.Is(SHUFFLEINTERIORS_ALL)) { - AddElementsToPool(entrancePools[EntranceType::Interior], GetShuffleableEntrances(EntranceType::SpecialInterior)); - } - if (Settings::DecoupleEntrances) { - for (Entrance* entrance : entrancePools[EntranceType::Interior]) { - entrancePools[EntranceType::InteriorReverse].push_back(entrance->GetReverse()); - } - } - } - - //grotto entrances - if (Settings::ShuffleGrottoEntrances) { - entrancePools[EntranceType::GrottoGrave] = GetShuffleableEntrances(EntranceType::GrottoGrave); - - if (Settings::DecoupleEntrances) { - for (Entrance* entrance : entrancePools[EntranceType::GrottoGrave]) { - entrancePools[EntranceType::GrottoGraveReverse].push_back(entrance->GetReverse()); - } - } - } - - //overworld entrances - if (Settings::ShuffleOverworldEntrances) { - bool excludeOverworldReverse = Settings::MixOverworld && !Settings::DecoupleEntrances; - entrancePools[EntranceType::Overworld] = GetShuffleableEntrances(EntranceType::Overworld, excludeOverworldReverse); - // Only shuffle GV Lower Stream -> Lake Hylia if decoupled entrances are on - if (!Settings::DecoupleEntrances) { - FilterAndEraseFromPool(entrancePools[EntranceType::Overworld], [](const Entrance* entrance){return entrance->GetParentRegionKey() == GV_LOWER_STREAM && - entrance->GetConnectedRegionKey() == LAKE_HYLIA;}); - } - } - - // Set shuffled entrances as such - SetShuffledEntrances(entrancePools); - SetShuffledEntrances(oneWayEntrancePools); - - //combine entrance pools if mixing pools. Only continue if more than one pool is selected. - int totalMixedPools = (Settings::MixDungeons ? 1 : 0) + (Settings::MixBosses ? 1 : 0) + - (Settings::MixOverworld ? 1 : 0) + (Settings::MixInteriors ? 1 : 0) + - (Settings::MixGrottos ? 1 : 0); - if (totalMixedPools < 2) { - Settings::MixedEntrancePools.SetSelectedIndex(OFF); - Settings::MixDungeons.SetSelectedIndex(OFF); - Settings::MixBosses.SetSelectedIndex(OFF); - Settings::MixOverworld.SetSelectedIndex(OFF); - Settings::MixInteriors.SetSelectedIndex(OFF); - Settings::MixGrottos.SetSelectedIndex(OFF); - } - if (Settings::MixedEntrancePools) { - std::set poolsToMix = {}; - if (Settings::MixDungeons) { - poolsToMix.insert(EntranceType::Dungeon); - // Insert reverse entrances when decoupled entrances is on - if (Settings::DecoupleEntrances) { - poolsToMix.insert(EntranceType::DungeonReverse); - } - } - if (Settings::MixBosses) { - poolsToMix.insert(EntranceType::Boss); - if (Settings::DecoupleEntrances) { - poolsToMix.insert(EntranceType::BossReverse); - } - } - if (Settings::MixOverworld) { - poolsToMix.insert(EntranceType::Overworld); - } - if (Settings::MixInteriors) { - poolsToMix.insert(EntranceType::Interior); - if (Settings::DecoupleEntrances) { - poolsToMix.insert(EntranceType::InteriorReverse); - } - } - if (Settings::MixGrottos) { - poolsToMix.insert(EntranceType::GrottoGrave); - if (Settings::DecoupleEntrances) { - poolsToMix.insert(EntranceType::GrottoGraveReverse); - } - } - - for (auto& pool : entrancePools) { - - auto type = pool.first; - - if (poolsToMix.count(type) > 0) { - AddElementsToPool(entrancePools[EntranceType::Mixed], pool.second); - entrancePools[type].clear(); - } - } - } - - // Build target entrance pools and set the assumption for entrances being reachable - EntrancePools oneWayTargetEntrancePools = {}; - for (auto& pool : oneWayEntrancePools) { - - std::vector validTargetTypes = {}; - EntranceType poolType = pool.first; - - if (poolType == EntranceType::OwlDrop) { - validTargetTypes = {EntranceType::WarpSong, EntranceType::OwlDrop, EntranceType::Overworld, EntranceType::Extra}; - oneWayTargetEntrancePools[poolType] = BuildOneWayTargets(validTargetTypes, {std::make_pair(PRELUDE_OF_LIGHT_WARP, TEMPLE_OF_TIME)}); - // Owl Drops are only accessible as child, so targets should reflect that - for (Entrance* target : oneWayTargetEntrancePools[poolType]) { - target->SetCondition([]{return Logic::IsChild;}); - } - - } else if (poolType == EntranceType::Spawn) { - validTargetTypes = {EntranceType::Spawn, EntranceType::WarpSong, EntranceType::OwlDrop, EntranceType::Overworld, EntranceType::Interior, EntranceType::SpecialInterior, EntranceType::GrottoGrave, EntranceType::Extra}; - oneWayTargetEntrancePools[poolType] = BuildOneWayTargets(validTargetTypes); - - } else if (poolType == EntranceType::WarpSong) { - validTargetTypes = {EntranceType::Spawn, EntranceType::WarpSong, EntranceType::OwlDrop, EntranceType::Overworld, EntranceType::Interior, EntranceType::SpecialInterior, EntranceType::GrottoGrave, EntranceType::Extra}; - oneWayTargetEntrancePools[poolType] = BuildOneWayTargets(validTargetTypes); - } - // for target in one_way_target_entrance_pools[pool_type]: - // target.add_rule((lambda entrances=entrance_pool: (lambda state, **kwargs: any(entrance.connected_region == None for entrance in entrances)))()) - } - - // Disconnect all one way entrances at this point (they need to be connected during all of the above process) - for (auto& pool : oneWayEntrancePools) { - for (Entrance* entrance : pool.second) { - totalRandomizableEntrances++; - entrance->Disconnect(); - } - } - - // Assume entrance pools for each type - EntrancePools targetEntrancePools = {}; - for (auto& pool : entrancePools) { - targetEntrancePools[pool.first] = AssumeEntrancePool(pool.second); - } - - //distribution stuff - - //check placed on-way entrances - //remove replaced entrances so we don't place two in one target - //remvoe priority targets if any placed entrances point at their regions - - // Place priority entrances - ShuffleOneWayPriorityEntrances(oneWayPriorities, oneWayEntrancePools, oneWayTargetEntrancePools); - if (entranceShuffleFailure) { - return ENTRANCE_SHUFFLE_FAILURE; - } - - // Delete all targets that we just placed from one way target pools so - // multiple one way entrances don't use the same target - std::vector replacedEntrances = {}; - for (auto& pool : oneWayEntrancePools) { - for (Entrance* entrance : pool.second) { - if (entrance->GetReplacement() != nullptr) { - replacedEntrances.push_back(entrance); - } - } - } - for (auto& pool : oneWayTargetEntrancePools) { - for (Entrance* remainingTarget : pool.second) { - auto replacement = remainingTarget->GetReplacement(); - if (ElementInContainer(replacement, replacedEntrances)) { - DeleteTargetEntrance(remainingTarget); - } - } - } - - // Shuffle all one way entrances among pools to shuffle - for (auto& pool : oneWayEntrancePools) { - ShuffleEntrancePool(pool.second, oneWayTargetEntrancePools[pool.first], 5); - if (entranceShuffleFailure) { - return ENTRANCE_SHUFFLE_FAILURE; - } - // Delete all targets that we just placed from other one way target pools so - // multiple one way entrances don't use the same target - replacedEntrances = FilterFromPool(pool.second, [](Entrance* entrance){ - return entrance->GetReplacement() != nullptr; - }); - for (auto& targetPool : oneWayTargetEntrancePools) { - for (Entrance* remainingTarget : targetPool.second) { - auto replacement = remainingTarget->GetReplacement(); - if (ElementInContainer(replacement, replacedEntrances)) { - DeleteTargetEntrance(remainingTarget); - } - } - } - // Delete all unused extra targets after placing a one way pool, since the - // unused targets won't ever be replaced - for (Entrance* unusedTarget : oneWayTargetEntrancePools[pool.first]) { - DeleteTargetEntrance(unusedTarget); - } - } - - //shuffle all entrances among pools to shuffle - for (auto& pool : entrancePools) { - ShuffleEntrancePool(pool.second, targetEntrancePools[pool.first]); - if (entranceShuffleFailure) { - return ENTRANCE_SHUFFLE_FAILURE; - } - } - - // Determine blue warp targets - if (true /* Settings.BlueWarps.Is(BLUEWARPS_DUNGEON) */) { // RANDOTODO: add bluewarp shuffle - // If a boss room is inside a boss door, make the blue warp go outside the dungeon's entrance - std::map bossExits = { - { EntranceNameByRegions(DEKU_TREE_BOSS_ROOM, DEKU_TREE_BOSS_ENTRYWAY), - GetEntrance(EntranceNameByRegions(DEKU_TREE_ENTRYWAY, KF_OUTSIDE_DEKU_TREE)) }, - { EntranceNameByRegions(DODONGOS_CAVERN_BOSS_ROOM, DODONGOS_CAVERN_BOSS_ENTRYWAY), - GetEntrance(EntranceNameByRegions(DODONGOS_CAVERN_ENTRYWAY, DEATH_MOUNTAIN_TRAIL)) }, - { EntranceNameByRegions(JABU_JABUS_BELLY_BOSS_ROOM, JABU_JABUS_BELLY_BOSS_ENTRYWAY), - GetEntrance(EntranceNameByRegions(JABU_JABUS_BELLY_ENTRYWAY, ZORAS_FOUNTAIN)) }, - { EntranceNameByRegions(FOREST_TEMPLE_BOSS_ROOM, FOREST_TEMPLE_BOSS_ENTRYWAY), - GetEntrance(EntranceNameByRegions(FOREST_TEMPLE_ENTRYWAY, SACRED_FOREST_MEADOW)) }, - { EntranceNameByRegions(FIRE_TEMPLE_BOSS_ROOM, FIRE_TEMPLE_BOSS_ENTRYWAY), - GetEntrance(EntranceNameByRegions(FIRE_TEMPLE_ENTRYWAY, DMC_CENTRAL_LOCAL)) }, - { EntranceNameByRegions(WATER_TEMPLE_BOSS_ROOM, WATER_TEMPLE_BOSS_ENTRYWAY), - GetEntrance(EntranceNameByRegions(WATER_TEMPLE_ENTRYWAY, LAKE_HYLIA)) }, - { EntranceNameByRegions(SPIRIT_TEMPLE_BOSS_ROOM, SPIRIT_TEMPLE_BOSS_ENTRYWAY), - GetEntrance(EntranceNameByRegions(SPIRIT_TEMPLE_ENTRYWAY, DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY)) }, - { EntranceNameByRegions(SHADOW_TEMPLE_BOSS_ROOM, SHADOW_TEMPLE_BOSS_ENTRYWAY), - GetEntrance(EntranceNameByRegions(SHADOW_TEMPLE_ENTRYWAY, GRAVEYARD_WARP_PAD_REGION)) }, - }; - - // If a boss room is inside a dungeon entrance (or inside a dungeon which is inside a dungeon entrance), make the blue warp go to that dungeon's blue warp target - std::map dungeonExits = { - { EntranceNameByRegions(DEKU_TREE_ENTRYWAY, KF_OUTSIDE_DEKU_TREE), - GetEntrance(EntranceNameByRegions(DEKU_TREE_BOSS_ROOM, KF_OUTSIDE_DEKU_TREE)) }, - { EntranceNameByRegions(DODONGOS_CAVERN_ENTRYWAY, DEATH_MOUNTAIN_TRAIL), - GetEntrance(EntranceNameByRegions(DODONGOS_CAVERN_BOSS_ROOM, DEATH_MOUNTAIN_TRAIL)) }, - { EntranceNameByRegions(JABU_JABUS_BELLY_ENTRYWAY, ZORAS_FOUNTAIN), - GetEntrance(EntranceNameByRegions(JABU_JABUS_BELLY_BOSS_ROOM, ZORAS_FOUNTAIN)) }, - { EntranceNameByRegions(FOREST_TEMPLE_ENTRYWAY, SACRED_FOREST_MEADOW), - GetEntrance(EntranceNameByRegions(FOREST_TEMPLE_BOSS_ROOM, SACRED_FOREST_MEADOW)) }, - { EntranceNameByRegions(FIRE_TEMPLE_ENTRYWAY, DMC_CENTRAL_LOCAL), - GetEntrance(EntranceNameByRegions(FIRE_TEMPLE_BOSS_ROOM, DMC_CENTRAL_LOCAL)) }, - { EntranceNameByRegions(WATER_TEMPLE_ENTRYWAY, LAKE_HYLIA), - GetEntrance(EntranceNameByRegions(WATER_TEMPLE_BOSS_ROOM, LAKE_HYLIA)) }, - { EntranceNameByRegions(SPIRIT_TEMPLE_ENTRYWAY, DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY), - GetEntrance(EntranceNameByRegions(SPIRIT_TEMPLE_BOSS_ROOM, DESERT_COLOSSUS)) }, - { EntranceNameByRegions(SHADOW_TEMPLE_ENTRYWAY, GRAVEYARD_WARP_PAD_REGION), - GetEntrance(EntranceNameByRegions(SHADOW_TEMPLE_BOSS_ROOM, GRAVEYARD_WARP_PAD_REGION)) }, - }; - - // Pair - std::vector bossRoomExitPairs = { - { GetEntrance(EntranceNameByRegions(DEKU_TREE_BOSS_ROOM, KF_OUTSIDE_DEKU_TREE)), - GetEntrance(EntranceNameByRegions(DEKU_TREE_BOSS_ROOM, DEKU_TREE_BOSS_ENTRYWAY)) }, - { GetEntrance(EntranceNameByRegions(DODONGOS_CAVERN_BOSS_ROOM, DEATH_MOUNTAIN_TRAIL)), - GetEntrance(EntranceNameByRegions(DODONGOS_CAVERN_BOSS_ROOM, DODONGOS_CAVERN_BOSS_ENTRYWAY)) }, - { GetEntrance(EntranceNameByRegions(JABU_JABUS_BELLY_BOSS_ROOM, ZORAS_FOUNTAIN)), - GetEntrance(EntranceNameByRegions(JABU_JABUS_BELLY_BOSS_ROOM, JABU_JABUS_BELLY_BOSS_ENTRYWAY)) }, - { GetEntrance(EntranceNameByRegions(FOREST_TEMPLE_BOSS_ROOM, SACRED_FOREST_MEADOW)), - GetEntrance(EntranceNameByRegions(FOREST_TEMPLE_BOSS_ROOM, FOREST_TEMPLE_BOSS_ENTRYWAY)) }, - { GetEntrance(EntranceNameByRegions(FIRE_TEMPLE_BOSS_ROOM, DMC_CENTRAL_LOCAL)), - GetEntrance(EntranceNameByRegions(FIRE_TEMPLE_BOSS_ROOM, FIRE_TEMPLE_BOSS_ENTRYWAY)) }, - { GetEntrance(EntranceNameByRegions(WATER_TEMPLE_BOSS_ROOM, LAKE_HYLIA)), - GetEntrance(EntranceNameByRegions(WATER_TEMPLE_BOSS_ROOM, WATER_TEMPLE_BOSS_ENTRYWAY)) }, - { GetEntrance(EntranceNameByRegions(SPIRIT_TEMPLE_BOSS_ROOM, DESERT_COLOSSUS)), - GetEntrance(EntranceNameByRegions(SPIRIT_TEMPLE_BOSS_ROOM, SPIRIT_TEMPLE_BOSS_ENTRYWAY)) }, - { GetEntrance(EntranceNameByRegions(SHADOW_TEMPLE_BOSS_ROOM, GRAVEYARD_WARP_PAD_REGION)), - GetEntrance(EntranceNameByRegions(SHADOW_TEMPLE_BOSS_ROOM, SHADOW_TEMPLE_BOSS_ENTRYWAY)) }, - }; - - for (EntrancePair pair : bossRoomExitPairs) { - Entrance* target = pair.second->GetReplacement() != nullptr ? pair.second->GetReplacement() : pair.second; - - if (!Settings::DecoupleEntrances) { - while (bossExits.find(target->GetName()) != bossExits.end()) { - Entrance* next = bossExits.at(target->GetName()); - target = next->GetReplacement() != nullptr ? next->GetReplacement() : next; - } - - if (dungeonExits.find(target->GetName()) != dungeonExits.end()) { - target = dungeonExits.at(target->GetName()); - } - } - - pair.first->Connect(target->GetOriginalConnectedRegionKey()); - pair.first->SetReplacement(target); - } - } - - // Validate the world one last time to ensure all special conditions are still valid - if (!ValidateWorld(nullptr)) { - return ENTRANCE_SHUFFLE_FAILURE; - } - - return ENTRANCE_SHUFFLE_SUCCESS; -} - -// Save the set of shuffled entrances that will be sent to the patch -void CreateEntranceOverrides() { - entranceOverrides.clear(); - if (noRandomEntrances) { - return; - } - SPDLOG_DEBUG("\nCREATING ENTRANCE OVERRIDES\n"); - auto allShuffleableEntrances = GetShuffleableEntrances(EntranceType::All, false); - - for (Entrance* entrance : allShuffleableEntrances) { - - //Double-check to make sure the entrance is actually shuffled - if (!entrance->IsShuffled()) { - continue; - } - - auto message = "Setting " + entrance->to_string() + "\n"; - SPDLOG_DEBUG(message); - - uint8_t type = (uint8_t)entrance->GetType(); - int16_t originalIndex = entrance->GetIndex(); - int16_t replacementIndex = entrance->GetReplacement()->GetIndex(); - - int16_t destinationIndex = -1; - int16_t replacementDestinationIndex = -1; - - // Only set destination indices for two way entrances and when decouple entrances - // is off - if (entrance->GetReverse() != nullptr && !Settings::DecoupleEntrances) { - replacementDestinationIndex = entrance->GetReplacement()->GetReverse()->GetIndex(); - destinationIndex = entrance->GetReverse()->GetIndex(); - } - - entranceOverrides.push_back({ - .type = type, - .index = originalIndex, - .destination = destinationIndex, - .override = replacementIndex, - .overrideDestination = replacementDestinationIndex, - }); - - message = "\tOriginal: " + std::to_string(originalIndex) + "\n"; - SPDLOG_DEBUG(message); - message = "\tReplacement " + std::to_string(replacementIndex) + "\n"; - SPDLOG_DEBUG(message); - } -} - -std::vector> playthroughEntrances; diff --git a/soh/soh/Enhancements/randomizer/3drando/entrance.hpp b/soh/soh/Enhancements/randomizer/3drando/entrance.hpp deleted file mode 100644 index e99b418d8dd..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/entrance.hpp +++ /dev/null @@ -1,292 +0,0 @@ -#pragma once - -#include "keys.hpp" -#include "location_access.hpp" - -#include -#include - -#include "../randomizer_entrance.h" - -#define ENTRANCE_SHUFFLE_SUCCESS 0 -#define ENTRANCE_SHUFFLE_FAILURE 1 - -extern std::list entranceOverrides; - -enum class EntranceType { - None, - OwlDrop, - Spawn, - WarpSong, - BlueWarp, - Dungeon, - GanonDungeon, - DungeonReverse, - Boss, - BossReverse, - ChildBoss, - ChildBossReverse, - AdultBoss, - AdultBossReverse, - Interior, - InteriorReverse, - SpecialInterior, - GrottoGrave, - GrottoGraveReverse, - Overworld, - Extra, - Mixed, - All, -}; - -class Entrance { -public: - - Entrance(uint32_t connectedRegion_, std::vector conditions_met_) - : connectedRegion(connectedRegion_) { - originalConnectedRegion = connectedRegion_; - conditions_met.resize(2); - for (size_t i = 0; i < conditions_met_.size(); i++) { - conditions_met[i] = conditions_met_[i]; - } - } - - // Resets the glitchless condition for the entrance - void SetCondition(ConditionFn newCondition) { - conditions_met[0] = newCondition; - } - - bool GetConditionsMet() const { - if (Settings::Logic.Is(LOGIC_NONE) || Settings::Logic.Is(LOGIC_VANILLA)) { - return true; - } else if (Settings::Logic.Is(LOGIC_GLITCHLESS)) { - return conditions_met[0](); - } else if (Settings::Logic.Is(LOGIC_GLITCHED)) { - if (conditions_met[0]()) { - return true; - } else if (conditions_met[1] != NULL) { - return conditions_met[1](); - } - } - return false; - } - - std::string to_string() const { - return AreaTable(parentRegion)->regionName + " -> " + AreaTable(connectedRegion)->regionName; - } - - void SetName(std::string name_ = "") { - if (name_ == "") { - name = AreaTable(parentRegion)->regionName + " -> " + AreaTable(connectedRegion)->regionName; - } else { - name = std::move(name_); - } - - } - - std::string GetName() const { - return name; - } - - void printAgeTimeAccess() { - //CitraPrint("Name: "); - //CitraPrint(name); - auto message = "Child Day: " + std::to_string(CheckConditionAtAgeTime(Logic::IsChild, Logic::AtDay)) + "\t" - "Child Night: " + std::to_string(CheckConditionAtAgeTime(Logic::IsChild, Logic::AtNight)) + "\t" - "Adult Day: " + std::to_string(CheckConditionAtAgeTime(Logic::IsAdult, Logic::AtDay)) + "\t" - "Adult Night: " + std::to_string(CheckConditionAtAgeTime(Logic::IsAdult, Logic::AtNight)); - //CitraPrint(message); - } - - bool ConditionsMet(bool allAgeTimes = false) 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); - } - - uint32_t Getuint32_t() const { - return connectedRegion; - } - - //set the logic to be a specific age and time of day and see if the condition still holds - bool CheckConditionAtAgeTime(bool& age, bool& time, bool passAnyway = false) const { - - Logic::IsChild = false; - Logic::IsAdult = false; - Logic::AtDay = false; - Logic::AtNight = false; - - time = true; - age = true; - - Logic::UpdateHelpers(); - return GetConditionsMet() && (connectedRegion != NONE || passAnyway); - } - - uint32_t GetConnectedRegionKey() const { - return connectedRegion; - } - - uint32_t GetOriginalConnectedRegionKey() const { - return originalConnectedRegion; - } - - Area* GetConnectedRegion() const { - return AreaTable(connectedRegion); - } - - void SetParentRegion(uint32_t newParent) { - parentRegion = newParent; - } - - uint32_t GetParentRegionKey() const { - return parentRegion; - } - - Area* GetParentRegion() const { - return AreaTable(parentRegion); - } - - void SetNewEntrance(uint32_t newRegion) { - connectedRegion = newRegion; - } - - void SetAsShuffled() { - shuffled = true; - } - - bool IsShuffled() const { - return shuffled; - } - - bool IsAddedToPool() const { - return addedToPool; - } - - void AddToPool() { - addedToPool = true; - } - - void RemoveFromPool() { - addedToPool = false; - } - - void SetAsPrimary() { - primary = true; - } - - bool IsPrimary() const { - return primary; - } - - bool IsDecoupled() const { - return decoupled; - } - - void SetDecoupled() { - decoupled = true; - } - - int16_t GetIndex() const { - return index; - } - - void SetIndex(int16_t newIndex) { - index = newIndex; - } - - Entrance* GetAssumed() const { - return assumed; - } - - void SetReplacement(Entrance* newReplacement) { - replacement = newReplacement; - } - - Entrance* GetReplacement() const { - return replacement; - } - - EntranceType GetType() const { - return type; - } - - void SetType(EntranceType newType) { - type = newType; - } - - Entrance* GetReverse() const { - return reverse; - } - - void Connect(uint32_t newConnectedRegion) { - connectedRegion = newConnectedRegion; - AreaTable(newConnectedRegion)->entrances.push_front(this); - } - - uint32_t Disconnect() { - AreaTable(connectedRegion)->entrances.remove_if([this](const auto entrance){return this == entrance;}); - uint32_t previouslyConnected = connectedRegion; - connectedRegion = NONE; - return previouslyConnected; - } - - void BindTwoWay(Entrance* otherEntrance) { - reverse = otherEntrance; - otherEntrance->reverse = this; - } - - Entrance* GetNewTarget() { - AreaTable(ROOT)->AddExit(ROOT, connectedRegion, []{return true;}); - Entrance* targetEntrance = AreaTable(ROOT)->GetExit(connectedRegion); - targetEntrance->SetReplacement(this); - targetEntrance->SetName(AreaTable(ROOT)->regionName + " -> " + GetConnectedRegion()->regionName); - return targetEntrance; - } - - Entrance* AssumeReachable() { - if (assumed == nullptr) { - assumed = GetNewTarget(); - Disconnect(); - } - return assumed; - } - -private: - uint32_t parentRegion; - uint32_t connectedRegion; - uint32_t originalConnectedRegion; - std::vector conditions_met; - - //Entrance Randomizer stuff - EntranceType type = EntranceType::None; - Entrance* target = nullptr; - Entrance* reverse = nullptr; - Entrance* assumed = nullptr; - Entrance* replacement = nullptr; - int16_t index = 0xFFFF; - bool shuffled = false; - bool primary = false; - bool addedToPool = false; - bool decoupled = false; - std::string name = ""; -}; - -int ShuffleAllEntrances(); -void CreateEntranceOverrides(); -std::string EntranceNameByRegions(uint32_t parentRegion, uint32_t connectedRegion); - -extern std::vector> playthroughEntrances; -extern bool noRandomEntrances; diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index ca683143efe..ff128a13942 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -1,40 +1,77 @@ #include "fill.hpp" #include "custom_messages.hpp" -#include "dungeon.hpp" -#include "item_location.hpp" +#include "../dungeon.h" +#include "../context.h" #include "item_pool.hpp" -#include "location_access.hpp" -#include "logic.hpp" #include "random.hpp" #include "spoiler_log.hpp" #include "starting_inventory.hpp" #include "hints.hpp" -#include "hint_list.hpp" -#include "entrance.hpp" #include "shops.hpp" +#include "pool_functions.hpp" +//#include "debug.hpp" +#include "soh/Enhancements/randomizer/static_data.h" +#include "soh/Enhancements/debugger/performanceTimer.h" #include #include +#include #include using namespace CustomMessages; -using namespace Logic; -using namespace Settings; +using namespace Rando; + static bool placementFailure = false; + +PriceSettingsStruct shopsanityPrices = {RSK_SHOPSANITY_PRICES, + RSK_SHOPSANITY_PRICES_FIXED_PRICE, + RSK_SHOPSANITY_PRICES_RANGE_1, + RSK_SHOPSANITY_PRICES_RANGE_2, + RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT, + RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT, + RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT, + RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT, + RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT, + RSK_SHOPSANITY_PRICES_AFFORDABLE}; + +PriceSettingsStruct scrubPrices = {RSK_SCRUBS_PRICES, + RSK_SCRUBS_PRICES_FIXED_PRICE, + RSK_SCRUBS_PRICES_RANGE_1, + RSK_SCRUBS_PRICES_RANGE_2, + RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT, + RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT, + RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT, + RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT, + RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT, + RSK_SCRUBS_PRICES_AFFORDABLE}; + +PriceSettingsStruct merchantPrices = {RSK_MERCHANT_PRICES, + RSK_MERCHANT_PRICES_FIXED_PRICE, + RSK_MERCHANT_PRICES_RANGE_1, + RSK_MERCHANT_PRICES_RANGE_2, + RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT, + RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT, + RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT, + RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT, + RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT, + RSK_MERCHANT_PRICES_AFFORDABLE}; + static void RemoveStartingItemsFromPool() { - for (uint32_t startingItem : StartingInventory) { + for (RandomizerGet startingItem : StartingInventory) { for (size_t i = 0; i < ItemPool.size(); i++) { - if (startingItem == BIGGORON_SWORD) { - if (ItemPool[i] == GIANTS_KNIFE || ItemPool[i] == BIGGORON_SWORD) { + if (startingItem == RG_BIGGORON_SWORD) { + if (ItemPool[i] == RG_GIANTS_KNIFE || ItemPool[i] == RG_BIGGORON_SWORD) { ItemPool[i] = GetJunkItem(); } continue; - } else if (startingItem == ItemPool[i] || (ItemTable(startingItem).IsBottleItem() && ItemTable(ItemPool[i]).IsBottleItem())) { - if (AdditionalHeartContainers > 0 && (startingItem == PIECE_OF_HEART || startingItem == TREASURE_GAME_HEART)) { - ItemPool[i] = HEART_CONTAINER; + } else if (startingItem == ItemPool[i] || (Rando::StaticData::RetrieveItem(startingItem).IsBottleItem() && + Rando::StaticData::RetrieveItem(ItemPool[i]).IsBottleItem())) { + if (AdditionalHeartContainers > 0 && + (startingItem == RG_PIECE_OF_HEART || startingItem == RG_TREASURE_GAME_HEART)) { + ItemPool[i] = RG_HEART_CONTAINER; AdditionalHeartContainers--; } else { ItemPool[i] = GetJunkItem(); @@ -45,128 +82,191 @@ static void RemoveStartingItemsFromPool() { } } -//This function will propogate Time of Day access through the entrance -static bool UpdateToDAccess(Entrance* entrance, SearchMode mode) { +static void PropagateTimeTravel(GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, + bool stopOnBeatable = false, bool addToPlaythrough = false){ + //special check for temple of time + if(gals.haveTimeAccess && gals.foundTempleOfTime && gals.validatedStartingRegion){ + if (!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; + ProcessRegion(RegionTable(RR_ROOT), gals, ignore, stopOnBeatable, addToPlaythrough); + } else if (!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; + ProcessRegion(RegionTable(RR_ROOT), gals, ignore, stopOnBeatable, addToPlaythrough); + } + } +} + +//This function will propagate Time of Day access through the entrance +static bool UpdateToDAccess(Entrance* entrance, Region* connection) { + StartPerformanceTimer(PT_TOD_ACCESS); bool ageTimePropogated = false; + Region* parent = entrance->GetParentRegion(); - //propogate childDay, childNight, adultDay, and adultNight separately - Area* parent = entrance->GetParentRegion(); - Area* connection = entrance->GetConnectedRegion(); - - if (!connection->childDay && parent->childDay && entrance->CheckConditionAtAgeTime(Logic::IsChild, AtDay)) { + if (!connection->childDay && parent->childDay && entrance->CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) { connection->childDay = true; ageTimePropogated = true; } - if (!connection->childNight && parent->childNight && entrance->CheckConditionAtAgeTime(Logic::IsChild, AtNight)) { + if (!connection->childNight && parent->childNight && entrance->CheckConditionAtAgeTime(logic->IsChild, logic->AtNight)) { connection->childNight = true; ageTimePropogated = true; } - if (!connection->adultDay && parent->adultDay && entrance->CheckConditionAtAgeTime(IsAdult, AtDay)) { + if (!connection->adultDay && parent->adultDay && entrance->CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay)) { connection->adultDay = true; ageTimePropogated = true; } - if (!connection->adultNight && parent->adultNight && entrance->CheckConditionAtAgeTime(IsAdult, AtNight)) { + if (!connection->adultNight && parent->adultNight && entrance->CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight)) { connection->adultNight = true; ageTimePropogated = true; } - //special check for temple of time - bool propogateTimeTravel = mode != SearchMode::TimePassAccess && mode != SearchMode::TempleOfTimeAccess; - if (!AreaTable(ROOT)->Adult() && AreaTable(TOT_BEYOND_DOOR_OF_TIME)->Child() && propogateTimeTravel) { - AreaTable(ROOT)->adultDay = AreaTable(TOT_BEYOND_DOOR_OF_TIME)->childDay; - AreaTable(ROOT)->adultNight = AreaTable(TOT_BEYOND_DOOR_OF_TIME)->childNight; - } else if (!AreaTable(ROOT)->Child() && AreaTable(TOT_BEYOND_DOOR_OF_TIME)->Adult() && propogateTimeTravel){ - AreaTable(ROOT)->childDay = AreaTable(TOT_BEYOND_DOOR_OF_TIME)->adultDay; - AreaTable(ROOT)->childNight = AreaTable(TOT_BEYOND_DOOR_OF_TIME)->adultNight; - } - + StopPerformanceTimer(PT_TOD_ACCESS); return ageTimePropogated; } -// Various checks that need to pass for the world to be validated as completable -static void ValidateWorldChecks(SearchMode& mode, bool checkPoeCollectorAccess, bool checkOtherEntranceAccess, std::vector& areaPool) { +// Check if key locations in the overworld are accessable +static void ValidateOtherEntrance(GetAccessibleLocationsStruct& gals) { + auto ctx = Rando::Context::GetInstance(); // Condition for validating Temple of Time Access - if (mode == SearchMode::TempleOfTimeAccess && ((Settings::ResolvedStartingAge == AGE_CHILD && AreaTable(TEMPLE_OF_TIME)->Adult()) || (Settings::ResolvedStartingAge == AGE_ADULT && AreaTable(TEMPLE_OF_TIME)->Child()) || !checkOtherEntranceAccess)) { - mode = SearchMode::ValidStartingRegion; + if (!gals.foundTempleOfTime && ((ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD && RegionTable(RR_TEMPLE_OF_TIME)->Adult()) || + (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT && RegionTable(RR_TEMPLE_OF_TIME)->Child()))) { + gals.foundTempleOfTime = true; } // Condition for validating a valid starting region - if (mode == SearchMode::ValidStartingRegion) { - bool childAccess = Settings::ResolvedStartingAge == AGE_CHILD || AreaTable(TOT_BEYOND_DOOR_OF_TIME)->Child(); - bool adultAccess = Settings::ResolvedStartingAge == AGE_ADULT || AreaTable(TOT_BEYOND_DOOR_OF_TIME)->Adult(); - - Area* kokiri = AreaTable(KOKIRI_FOREST); - Area* kakariko = AreaTable(KAKARIKO_VILLAGE); - - if ((childAccess && (kokiri->Child() || kakariko->Child())) || - (adultAccess && (kokiri->Adult() || kakariko->Adult())) || - !checkOtherEntranceAccess) { - mode = SearchMode::PoeCollectorAccess; - ApplyStartingInventory(); - Logic::NoBottles = true; + if (!gals.validatedStartingRegion) { + bool childAccess = ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child(); + bool adultAccess = ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_ADULT || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult(); + + Region* kokiri = RegionTable(RR_KOKIRI_FOREST); + Region* kakariko = RegionTable(RR_KAKARIKO_VILLAGE); + + if ((childAccess && (kokiri->Child() || kakariko->Child())) ||// RANDOTODO when proper ammo logic is done, this could probably be made optional + (adultAccess && (kokiri->Adult() || kakariko->Adult()))) { + gals.validatedStartingRegion = true; + ApplyStartingInventory(); // RANDOTODO when proper ammo logic is done, this could be moved to the start } } - // Condition for validating Poe Collector Access - if (mode == SearchMode::PoeCollectorAccess && (AreaTable(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 entrance rando seed that needs to be avalible without items, is, +// and if so allow obtaining items in logic +static void ValidateSphereZero(GetAccessibleLocationsStruct& 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 ItemTable(i).IsAdvancement(); }); - for (uint32_t unplacedItem : itemsToPlace) { - ItemTable(unplacedItem).ApplyEffect(); - } + ApplyAllAdvancmentItems(); // Reset access as the non-starting age - if (Settings::ResolvedStartingAge == AGE_CHILD) { - for (uint32_t areaKey : areaPool) { - AreaTable(areaKey)->adultDay = false; - AreaTable(areaKey)->adultNight = false; + if (ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { + for (RandomizerRegion regionKey : gals.regionPool) { + RegionTable(regionKey)->adultDay = false; + RegionTable(regionKey)->adultNight = false; } } else { - for (uint32_t areaKey : areaPool) { - AreaTable(areaKey)->childDay = false; - AreaTable(areaKey)->childNight = false; + for (RandomizerRegion regionKey : gals.regionPool) { + RegionTable(regionKey)->childDay = false; + RegionTable(regionKey)->childNight = false; + } + } + //RANDOTODO do we want to keep the region pool after this reset? + //It's a lot of potential looping over regions we have no access to + gals.sphereZeroComplete = true; + } +} + +//This function handles each possible exit +void ProcessExits(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, + bool stopOnBeatable = false, bool addToPlaythrough = false){ + auto ctx = Rando::Context::GetInstance(); + for (auto& exit : region->exits) { + Region* exitRegion = exit.GetConnectedRegion(); + //Update Time of Day Access for the exit + if (UpdateToDAccess(&exit, exitRegion)) { + gals.logicUpdated = true; + if (!gals.sphereZeroComplete){ + if (!gals.foundTempleOfTime || !gals.validatedStartingRegion){ + ValidateOtherEntrance(gals); + } + ValidateSphereZero(gals); + } + //process the region we just expanded to, to reduce looping + ProcessRegion(exitRegion, gals, ignore, stopOnBeatable, addToPlaythrough); + } + + //If the exit is accessible and hasn't been added yet, add it to the pool + //RANDOTODO do we want to add the region after the loop now, considering we + //are processing the new region immediately. Maybe a reverse for loop in ProcessRegion? + if (!exitRegion->addedToPool && exit.ConditionsMet()) { + exitRegion->addedToPool = true; + gals.regionPool.push_back(exit.GetConnectedRegionKey()); + } + + if (addToPlaythrough){ + // RANDOTODO Should this match the regular spheres? + // 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(); + } } } - mode = SearchMode::AllLocationsReachable; - } else { - Logic::NoBottles = false; } } + //Get the max number of tokens that can possibly be useful static int GetMaxGSCount() { + auto ctx = Rando::Context::GetInstance(); //If bridge or LACS is set to tokens, get how many are required int maxBridge = 0; int maxLACS = 0; - if (Settings::Bridge.Is(RAINBOWBRIDGE_TOKENS)) { - maxBridge = Settings::BridgeTokenCount.Value(); + if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) { + maxBridge = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Value(); } - if (Settings::GanonsBossKey.Is(GANONSBOSSKEY_LACS_TOKENS)) { - maxLACS = Settings::LACSTokenCount.Value(); + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) { + maxLACS = ctx->GetOption(RSK_LACS_TOKEN_COUNT).Value(); } maxBridge = std::max(maxBridge, maxLACS); //Get the max amount of GS which could be useful from token reward locations int maxUseful = 0; //If the highest advancement item is a token, we know it is useless since it won't lead to an otherwise useful item - if (Location(KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && Location(KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + if (ctx->GetItemLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && ctx->GetItemLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { maxUseful = 100; - } - else if (Location(KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && Location(KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 50; - } - else if (Location(KAK_40_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && Location(KAK_40_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 40; - } - else if (Location(KAK_30_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && Location(KAK_30_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 30; - } - else if (Location(KAK_20_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && Location(KAK_20_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 20; - } - else if (Location(KAK_10_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && Location(KAK_10_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 10; + } else if (ctx->GetItemLocation(RC_KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 50; + } else if (ctx->GetItemLocation(RC_KAK_40_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_40_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 40; + } else if (ctx->GetItemLocation(RC_KAK_30_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_30_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 30; + } else if (ctx->GetItemLocation(RC_KAK_20_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_20_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 20; + } else if (ctx->GetItemLocation(RC_KAK_10_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_10_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 10; } //Return max of the two possible reasons tokens could be important, minus the tokens in the starting inventory - return std::max(maxUseful, maxBridge) - StartingSkulltulaToken.Value(); + return std::max(maxUseful, maxBridge) - ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Value(); } std::string GetShopItemBaseName(std::string itemName) { @@ -182,383 +282,499 @@ std::string GetShopItemBaseName(std::string itemName) { return baseName; } -std::vector GetEmptyLocations(std::vector allowedLocations) { - return FilterFromPool(allowedLocations, [](const auto loc){ return Location(loc)->GetPlaceduint32_t() == NONE;}); +std::vector GetEmptyLocations(std::vector targetLocations) { + auto ctx = Rando::Context::GetInstance(); + return FilterFromPool(targetLocations, [ctx](const auto loc) { + return ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == RG_NONE; + }); } -std::vector GetAllEmptyLocations() { - return FilterFromPool(allLocations, [](const auto loc) { return Location(loc)->GetPlaceduint32_t() == NONE; }); +std::vector GetAllEmptyLocations() { + auto ctx = Rando::Context::GetInstance(); + return FilterFromPool(ctx->allLocations, [ctx](const auto loc) { + return ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == RG_NONE; + }); } -//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*/, std::string ignore /*= ""*/, bool checkPoeCollectorAccess /*= false*/, bool checkOtherEntranceAccess /*= false*/) { - std::vector accessibleLocations; - // Reset all access to begin a new search - if (mode < SearchMode::ValidateWorld) { - ApplyStartingInventory(); - } - Areas::AccessReset(); - LocationReset(); - std::vector areaPool = {ROOT}; - - if (mode == SearchMode::ValidateWorld) { - mode = SearchMode::TimePassAccess; - AreaTable(ROOT)->childNight = true; - AreaTable(ROOT)->adultNight = true; - AreaTable(ROOT)->childDay = true; - AreaTable(ROOT)->adultDay = true; - allLocationsReachable = false; - } +bool IsBombchus(RandomizerGet item, bool includeShops = false){ + return (item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS || + (includeShops && (item == RG_BUY_BOMBCHUS_10 || item == RG_BUY_BOMBCHUS_20)); +} - //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 - bool bombchusFound = false; - std::vector buyIgnores; +bool IsBeatableWithout(RandomizerCheck excludedCheck, bool replaceItem, RandomizerGet ignore = RG_NONE){ //RANDOTODO make excludCheck an ItemLocation + auto ctx = Rando::Context::GetInstance(); + RandomizerGet copy = ctx->GetItemLocation(excludedCheck)->GetPlacedRandomizerGet(); //Copy out item + ctx->GetItemLocation(excludedCheck)->SetPlacedItem(RG_NONE); //Write in empty item + ctx->playthroughBeatable = false; + logic->Reset(); + CheckBeatable(ignore); + if (replaceItem){ + ctx->GetItemLocation(excludedCheck)->SetPlacedItem(copy); //Immediately put item back + } + return ctx->playthroughBeatable; +} - //Variables for search - std::vector newItemLocations; - bool updatedEvents = false; - bool ageTimePropogated = false; - bool firstIteration = true; - - //Variables for Time Pass access - bool timePassChildDay = false; - bool timePassChildNight = false; - bool timePassAdultDay = false; - bool timePassAdultNight = false; - - // Main access checking loop - while (newItemLocations.size() > 0 || updatedEvents || ageTimePropogated || firstIteration) { - firstIteration = false; - ageTimePropogated = false; - updatedEvents = false; - - for (ItemLocation* location : newItemLocations) { - location->ApplyPlacedItemEffect(); +// Reset non-Logic-class logic, and optionally apply the initial inventory +void ResetLogic(std::shared_ptr& ctx, GetAccessibleLocationsStruct& gals, bool applyInventory = false){ + gals.timePassChildDay = true; + gals.timePassChildNight = true; + gals.timePassAdultDay = true; + gals.timePassAdultNight = true; + gals.haveTimeAccess = true; + gals.foundTempleOfTime = true; + gals.validatedStartingRegion = true; + gals.sphereZeroComplete = true; + if (applyInventory){ + ApplyStartingInventory(); + } + Regions::AccessReset(); + ctx->LocationReset(); +} + +//Generate the playthrough, so we want to add advancement items, unless we know to ignore them +void AddToPlaythrough(LocationAccess& locPair, GetAccessibleLocationsStruct& 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; } - newItemLocations.clear(); - - std::vector itemSphere; - std::list entranceSphere; - - for (size_t i = 0; i < areaPool.size(); i++) { - Area* area = AreaTable(areaPool[i]); - - if (area->UpdateEvents(mode)){ - updatedEvents = true; + //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; + } +} - // 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 - // 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) { - timePassChildDay = true; - } - if (area->childNight) { - timePassChildNight = true; - } - if (area->adultDay) { - timePassAdultDay = true; - } - if (area->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; - } - } +void ApplyOrStoreItem(Rando::ItemLocation* loc, GetAccessibleLocationsStruct& gals, bool addToPlaythrough){ + if (addToPlaythrough){ + gals.newItemLocations.push_back(loc); + } else { + loc->ApplyPlacedItemEffect(); + } + gals.logicUpdated = true; +} - //for each exit in this area - for (auto& exit : area->exits) { +// Adds the contents of a location to the current progression and optionally playthrough +bool AddCheckToLogic(LocationAccess& locPair, GetAccessibleLocationsStruct& 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(); - //Update Time of Day Access for the exit - if (UpdateToDAccess(&exit, mode)) { - ageTimePropogated = true; - ValidateWorldChecks(mode, checkPoeCollectorAccess, checkOtherEntranceAccess, areaPool); - } + if (!location->IsAddedToPool() && locPair.ConditionsMet()) { + location->AddToPool(); - //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.Getuint32_t()); + 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) { + ApplyOrStoreItem(location, gals, addToPlaythrough); } - - // 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() == EntranceType::BlueWarp && - (Settings::ShuffleDungeonEntrances.IsNot(SHUFFLEDUNGEONS_OFF) || - Settings::ShuffleBossEntrances.IsNot(SHUFFLEBOSSES_OFF)))) && - !exit.IsAddedToPool() && !noRandomEntrances) { - entranceSphere.push_back(&exit); - exit.AddToPool(); - // Don't list a two-way coupled entrance from both directions - if (exit.GetReverse() != nullptr && exit.GetReplacement()->GetReverse() != nullptr && !exit.IsDecoupled()) { - exit.GetReplacement()->GetReverse()->AddToPool(); + //If we want to ignore bombchus, only add if bombchu is not in the name + else if (IsBombchus(ignore) && IsBombchus(locItem, true)) { + ApplyOrStoreItem(location, gals, addToPlaythrough); + } + //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) { + ApplyOrStoreItem(location, gals, addToPlaythrough); } } } + //If it doesn't, we can just add the location + else { + ApplyOrStoreItem(location, gals, addToPlaythrough); //Add item to cache to be considered in logic next iteration + } + } + if (addToPlaythrough){ + AddToPlaythrough(locPair, gals); + } + //All we care about is if the game is beatable, used to pare down playthrough + if (location->GetPlacedRandomizerGet() == RG_TRIFORCE && stopOnBeatable) { + StopPerformanceTimer(PT_LOCATION_LOGIC); + return true; //Return early for efficiency + } + } + StopPerformanceTimer(PT_LOCATION_LOGIC); + return false; +} - //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]; - uint32_t loc = locPair.GetLocation(); - ItemLocation* location = Location(loc); - - if (!location->IsAddedToPool() && locPair.ConditionsMet()) { - - location->AddToPool(); - - if (location->GetPlaceduint32_t() == 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 != "") { - ItemType type = location->GetPlacedItem().GetItemType(); - std::string itemName(location->GetPlacedItemName().GetEnglish()); - //If we want to ignore tokens, only add if not a token - if (ignore == "Tokens" && type != ITEMTYPE_TOKEN) { - newItemLocations.push_back(location); - } - //If we want to ignore bombchus, only add if bombchu is not in the name - else if (ignore == "Bombchus" && itemName.find("Bombchu") == std::string::npos) { - newItemLocations.push_back(location); - } - //We want to ignore a specific Buy item name - else if (ignore != "Tokens" && ignore != "Bombchus") { - if ((type == ITEMTYPE_SHOP && ignore != GetShopItemBaseName(itemName)) || 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 - } - } +void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore, + bool stopOnBeatable, bool addToPlaythrough){ + + if (gals.haveTimeAccess) { + region->ApplyTimePass(); + } else { + // 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 region. + //RANDOTODO can probably be removed after a ToD rework that accounts for having Dampe time access + if (region->timePass) { + if (region->childDay) { + gals.timePassChildDay = true; + } + if (region->childNight) { + gals.timePassChildNight = true; + } + if (region->adultDay) { + gals.timePassAdultDay = true; + } + if (region->adultNight) { + gals.timePassAdultNight = true; + } + } + // Condition for validating that all startring AgeTimes have timepass access + if (gals.timePassChildDay && gals.timePassChildNight && + gals.timePassAdultDay && gals.timePassAdultNight) { + gals.haveTimeAccess = true; + region->ApplyTimePass(); + } + } - //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 (!playthroughBeatable && location->GetPlacedItem().IsAdvancement()) { - ItemType type = location->GetPlacedItem().GetItemType(); - std::string itemName(location->GetPlacedItemName().GetEnglish()); - bool bombchus = itemName.find("Bombchu") != std::string::npos; //Is a bombchu location - - //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) Bombchus after the first (including buy bombchus) - //3) 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; - } - //Only print first bombchu location found - else if (bombchus && !bombchusFound) { - bombchusFound = true; - exclude = false; - } - //Handle buy items - //If ammo drops are off, don't do this step, since buyable ammo becomes logically important - else if (AmmoDrops.IsNot(AMMODROPS_NONE) && !(bombchus && bombchusFound) && type == ITEMTYPE_SHOP) { - //Only check each buy item once - std::string buyItem = GetShopItemBaseName(itemName); - //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 (!bombchus && 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->GetPlaceduint32_t() == TRIFORCE) { - itemSphere.clear(); - itemSphere.push_back(loc); - playthroughBeatable = true; - } - } - //All we care about is if the game is beatable, used to pare down playthrough - else if (location->GetPlaceduint32_t() == TRIFORCE && mode == SearchMode::CheckBeatable) { - playthroughBeatable = true; - return {}; //Return early for efficiency - } - } - } + if (region->UpdateEvents()){ + gals.logicUpdated = true; + //if we are working in spheres, reset the sphere on an event being enabled to avoid sphere skipping + if (addToPlaythrough){ + gals.resetSphere = true; + } + } + + ProcessExits(region, gals, ignore, stopOnBeatable, addToPlaythrough); + + PropagateTimeTravel(gals, ignore, stopOnBeatable, addToPlaythrough); + for (size_t k = 0; k < region->locations.size(); k++) { + if(AddCheckToLogic(region->locations[k], gals, ignore, stopOnBeatable, addToPlaythrough)){ + Rando::Context::GetInstance()->playthroughBeatable = true; + return; + } + } +} + +// 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(); + GetAccessibleLocationsStruct gals(0); + ResetLogic(ctx, gals, true); + do { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + ProcessRegion(RegionTable(gals.regionPool[i]), gals, ignore); + } + } while (gals.logicUpdated); + 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; +} - if (mode == SearchMode::GeneratePlaythrough && itemSphere.size() > 0) { - playthroughLocations.push_back(itemSphere); +// Create the playthrough for the seed +void GeneratePlaythrough() { + auto ctx = Rando::Context::GetInstance(); + ctx->playthroughBeatable = false; + logic->Reset(); + GetAccessibleLocationsStruct gals(GetMaxGSCount()); + ResetLogic(ctx, gals, true); + do { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + ProcessRegion(RegionTable(gals.regionPool[i]), gals, RG_NONE, false, true); + if (gals.resetSphere){ + gals.resetSphere = false; + i = -1; + } + } + if (gals.itemSphere.size() > 0) { + ctx->playthroughLocations.push_back(gals.itemSphere); } - if (mode == SearchMode::GeneratePlaythrough && entranceSphere.size() > 0 && !noRandomEntrances) { - playthroughEntrances.push_back(entranceSphere); + if (gals.entranceSphere.size() > 0 && !ctx->GetEntranceShuffler()->HasNoRandomEntrances()) { + ctx->GetEntranceShuffler()->playthroughEntrances.push_back(gals.entranceSphere); } + } while (gals.logicUpdated); +} + +// return if the seed is currently beatable or not +bool CheckBeatable(RandomizerGet ignore /* = RG_NONE*/) { + auto ctx = Rando::Context::GetInstance(); + GetAccessibleLocationsStruct gals(0); + ResetLogic(ctx, gals, true); + do { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + ProcessRegion(RegionTable(gals.regionPool[i]), gals, ignore, true); + if (ctx->playthroughBeatable == true){ + return true; + } + } + } while (gals.logicUpdated); + return false; +} + +// Check if the currently randomised set of entrances is a valid game map. +void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess) { + auto ctx = Rando::Context::GetInstance(); + GetAccessibleLocationsStruct gals(0); + ResetLogic(ctx, gals, !checkOtherEntranceAccess); + + ctx->allLocationsReachable = false; + if (checkPoeCollectorAccess){ + logic->CanEmptyBigPoes = false; } - //Check to see if all locations were reached - if (mode == SearchMode::AllLocationsReachable) { - allLocationsReachable = true; - for (const uint32_t loc : allLocations) { - if (!Location(loc)->IsAddedToPool()) { - allLocationsReachable = false; - auto message = "Location " + Location(loc)->GetName() + " not reachable\n"; - SPDLOG_DEBUG(message); + if (checkOtherEntranceAccess){ + gals.foundTempleOfTime = false; + gals.validatedStartingRegion = false; + //Variables for Time Pass access + gals.timePassChildDay = false; + gals.timePassChildNight = false; + gals.timePassAdultDay = false; + gals.timePassAdultNight = false; + gals.haveTimeAccess = false; + gals.sphereZeroComplete = false; + RegionTable(RR_ROOT)->childNight = true; + RegionTable(RR_ROOT)->adultNight = true; + RegionTable(RR_ROOT)->childDay = true; + RegionTable(RR_ROOT)->adultDay = true; + } else { + ApplyAllAdvancmentItems(); + } + + do { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + ProcessRegion(RegionTable(gals.regionPool[i]), gals); + } + } while (gals.logicUpdated); + if (gals.sphereZeroComplete) { + ctx->allLocationsReachable = true; + //RANDOTODO a size check here before getting the exact fails would be a minor optimization + //and a full list of location failures would be useful for logging when it does fail + for (const RandomizerCheck loc : ctx->allLocations) { + if (!ctx->GetItemLocation(loc)->IsAddedToPool()) { + ctx->allLocationsReachable = false; + auto message = "Location " + + Rando::StaticData::GetLocation(ctx->GetItemLocation(loc)->GetRandomizerCheck())->GetName() + + " not reachable\n"; + SPDLOG_DEBUG(message); #ifndef ENABLE_DEBUG break; #endif } } - return {}; } +} - erase_if(accessibleLocations, [&allowedLocations](uint32_t loc){ - for (uint32_t allowedLocation : allowedLocations) { - if (loc == allowedLocation || Location(loc)->GetPlaceduint32_t() != NONE) { - return false; +void LookForExternalArea(Region* currentRegion, std::set &alreadyChecked, std::set &areas, bool LowPriorityMode=false){ + for (const auto& entrance : currentRegion->entrances) { + //if this entrance does not pass areas, only process it if we are in low priority mode + if (LowPriorityMode || entrance->DoesSpreadAreas()){ + std::set otherAreas = entrance->GetParentRegion()->GetAllAreas(); + //if the region is arealess and hasn't already been checked, recursivly check what connects to it + if (otherAreas.size() == 0 && !alreadyChecked.contains(currentRegion)) { + alreadyChecked.insert(entrance->GetParentRegion()); + LookForExternalArea(entrance->GetParentRegion(), alreadyChecked, areas, LowPriorityMode); + //if we find an area and it's not links pocket, we should try and add it. + //If it's Links Pocket or RA_NONE, do not propagate those, they are not real areas. + //This check is likely to fail if a region somehow is both in Link's Pocket and elsewhere, but this should never happen + } else if (*otherAreas.begin() > RA_LINKS_POCKET){ + areas.merge(otherAreas); } } - return true; - }); - return accessibleLocations; + } } -static void GeneratePlaythrough() { - playthroughBeatable = false; - LogicReset(); - GetAccessibleLocations(allLocations, SearchMode::GeneratePlaythrough); +void SetAreas(){ + auto ctx = Rando::Context::GetInstance(); +//RANDOTODO give entrances an enum like RandomizerCheck, the give them all areas here, +//then use those areas to not need to recursivly find ItemLocation areas when an identifying entrance's area + for (int regionType = 0; regionType < RR_MARKER_AREAS_END; regionType++) { + Region region = areaTable[regionType]; + std::set areas = region.GetAllAreas(); + std::set regionsToSet = {®ion}; + if (areas.empty()) { + LookForExternalArea(®ion, regionsToSet, areas); + //If we found nothing, try again in low priority mode to try every entrance + if (areas.empty()) { + LookForExternalArea(®ion, regionsToSet, areas, true); + //If we still found nothing, we're disconnected, use RA_NONE to represent that + if (areas.empty()){ + areas.insert(RA_NONE); + } + } + } + for (auto regionToSet : regionsToSet) { + regionToSet->ReplaceAreas(areas); + for (auto& loc : regionToSet->locations){ + ctx->GetItemLocation(loc.GetLocation())->MergeAreas(areas); + } + } + } } //Remove unnecessary items from playthrough by removing their location, and checking if game is still beatable //To reduce searches, some preprocessing is done in playthrough generation to avoid adding obviously unnecessary items static void PareDownPlaythrough() { - std::vector toAddBackItem; + auto ctx = Rando::Context::GetInstance(); + std::vector toAddBackItem; //Start at sphere before Ganon's and count down - for (int i = playthroughLocations.size() - 2; i >= 0; i--) { + for (int i = ctx->playthroughLocations.size() - 2; i >= 0; i--) { //Check each item location in sphere std::vector erasableIndices; - std::vector sphere = playthroughLocations.at(i); + std::vector sphere = ctx->playthroughLocations.at(i); for (int j = sphere.size() - 1; j >= 0; j--) { - uint32_t loc = sphere.at(j); - uint32_t copy = Location(loc)->GetPlaceduint32_t(); //Copy out item - Location(loc)->SetPlacedItem(NONE); //Write in empty item - playthroughBeatable = false; - LogicReset(); - - std::string ignore = ""; - if (ItemTable(copy).GetItemType() == ITEMTYPE_TOKEN) { - ignore = "Tokens"; - } - else if (ItemTable(copy).GetName().GetEnglish().find("Bombchu") != std::string::npos) { - ignore = "Bombchus"; - } - else if (ItemTable(copy).GetItemType() == ITEMTYPE_SHOP) { - ignore = GetShopItemBaseName(ItemTable(copy).GetName().GetEnglish()); - } + RandomizerCheck loc = sphere.at(j); + RandomizerGet locGet = ctx->GetItemLocation(loc)->GetPlacedRandomizerGet(); //Copy out item - GetAccessibleLocations(allLocations, SearchMode::CheckBeatable, ignore); //Check if game is still beatable + RandomizerGet ignore = RG_NONE; + if (locGet == RG_GOLD_SKULLTULA_TOKEN || IsBombchus(locGet, true) + || Rando::StaticData::RetrieveItem(locGet).GetItemType() == ITEMTYPE_SHOP) { + ignore = locGet; + } //Playthrough is still beatable without this item, therefore it can be removed from playthrough section. - if (playthroughBeatable) { - //Uncomment to print playthrough deletion log in citra - // std::string itemname(ItemTable(copy).GetName().GetEnglish()); - // std::string locationname(Location(loc)->GetName()); - // std::string removallog = itemname + " at " + locationname + " removed from playthrough"; - // CitraPrint(removallog); - playthroughLocations[i].erase(playthroughLocations[i].begin() + j); - Location(loc)->SetDelayedItem(copy); //Game is still beatable, don't add back until later + if (IsBeatableWithout(loc, false, ignore)) { + ctx->playthroughLocations[i].erase(ctx->playthroughLocations[i].begin() + j); + ctx->GetItemLocation(loc)->SetDelayedItem(locGet); //Game is still beatable, don't add back until later toAddBackItem.push_back(loc); } else { - Location(loc)->SetPlacedItem(copy); //Immediately put item back so game is beatable again + ctx->GetItemLocation(loc)->SetPlacedItem(locGet); //Immediately put item back so game is beatable again } } } //Some spheres may now be empty, remove these - for (int i = playthroughLocations.size() - 2; i >= 0; i--) { - if (playthroughLocations.at(i).size() == 0) { - playthroughLocations.erase(playthroughLocations.begin() + i); + for (int i = ctx->playthroughLocations.size() - 2; i >= 0; i--) { + if (ctx->playthroughLocations.at(i).size() == 0) { + ctx->playthroughLocations.erase(ctx->playthroughLocations.begin() + i); } } //Now we can add back items which were removed previously - for (uint32_t loc : toAddBackItem) { - Location(loc)->SaveDelayedItem(); + for (RandomizerCheck loc : toAddBackItem) { + ctx->GetItemLocation(loc)->SaveDelayedItem(); } } -//Very similar to PareDownPlaythrough except it creates the list of Way of the Hero items +//Very similar to PareDownPlaythrough except it sets WotH candidacy of Way of the Hero items //Way of the Hero items are more specific than playthrough items in that they are items which *must* // be obtained to logically be able to complete the seed, rather than playthrough items which // are just possible items you *can* collect to complete the seed. static void CalculateWotH() { - //First copy locations from the 2-dimensional playthroughLocations into the 1-dimensional wothLocations + auto ctx = Rando::Context::GetInstance(); //size - 1 so Triforce is not counted - for (size_t i = 0; i < playthroughLocations.size() - 1; i++) { - for (size_t j = 0; j < playthroughLocations[i].size(); j++) { - if (Location(playthroughLocations[i][j])->IsHintable()) { - wothLocations.push_back(playthroughLocations[i][j]); + for (size_t i = 0; i < ctx->playthroughLocations.size() - 1; i++) { + for (size_t j = 0; j < ctx->playthroughLocations[i].size(); j++) { + //If removing this item and no other item caused the game to become unbeatable, then it is strictly necessary, + //so add it unless it is in Links Pocket or an isolated place. + auto itemLoc = ctx->GetItemLocation(ctx->playthroughLocations[i][j]); + if (itemLoc->IsHintable() && *itemLoc->GetAreas().begin() > RA_LINKS_POCKET && + !(IsBeatableWithout(ctx->playthroughLocations[i][j], true))) { + itemLoc->SetWothCandidate(); } } } + ctx->playthroughBeatable = true; + logic->Reset(); + ReachabilitySearch(ctx->allLocations); +} - //Now go through and check each location, seeing if it is strictly necessary for game completion - for (int i = wothLocations.size() - 1; i >= 0; i--) { - uint32_t loc = wothLocations[i]; - uint32_t copy = Location(loc)->GetPlaceduint32_t(); //Copy out item - Location(loc)->SetPlacedItem(NONE); //Write in empty item - playthroughBeatable = false; - LogicReset(); - GetAccessibleLocations(allLocations, SearchMode::CheckBeatable); //Check if game is still beatable - Location(loc)->SetPlacedItem(copy); //Immediately put item back - //If removing this item and no other item caused the game to become unbeatable, then it is strictly necessary, so keep it - //Else, delete from wothLocations - if (playthroughBeatable) { - wothLocations.erase(wothLocations.begin() + i); +static bool FindIfBarren(Rando::ItemLocation* itemLoc, std::array NotBarren){ + std::set locAreas = itemLoc->GetAreas(); + for (auto locArea: locAreas){ + if (NotBarren[locArea]){ + return false; } } + return true; +} - playthroughBeatable = true; - LogicReset(); - GetAccessibleLocations(allLocations); +//Calculate barren locations and assign Barren Candidacy to all locations inside those areas +static void CalculateBarren() { + auto ctx = Rando::Context::GetInstance(); + std::array NotBarren = {}; //I would invert this but the "initialise all as true" syntax wasn't working + //Isolated Areas and Link's Pocket are never Hinted Barren + NotBarren[RA_NONE] = true; + NotBarren[RA_LINKS_POCKET] = true; + + for (RandomizerCheck loc : ctx->allLocations) { + Rando::ItemLocation* itemLoc = ctx->GetItemLocation(loc); + std::set locAreas = itemLoc->GetAreas(); + for (auto locArea: locAreas){ + // If a location has a major item or is a way of the hero location, it is not barren + if (NotBarren[locArea] == false && (itemLoc->GetPlacedItem().IsMajorItem() || itemLoc->IsWothCandidate())) { + NotBarren[locArea] = true; + } + } + } + + for (RandomizerCheck loc : ctx->allLocations) { + Rando::ItemLocation* itemLoc = ctx->GetItemLocation(loc); + if (FindIfBarren(itemLoc, NotBarren)){ + itemLoc->SetBarrenCandidate(); + } + } } //Will place things completely randomly, no logic checks are performed -static void FastFill(std::vector items, std::vector locations, bool endOnItemsEmpty = false) { +static void FastFill(std::vector items, std::vector locations, bool endOnItemsEmpty = false) { + auto ctx = Rando::Context::GetInstance(); //Loop until locations are empty, or also end if items are empty and the parameters specify to end then while (!locations.empty() && (!endOnItemsEmpty || !items.empty())) { if (items.empty() && !endOnItemsEmpty) { items.push_back(GetJunkItem()); } - uint32_t loc = RandomElement(locations, true); - Location(loc)->SetAsHintable(); - PlaceItemInLocation(loc, RandomElement(items, true)); + RandomizerCheck loc = RandomElement(locations, true); + ctx->GetItemLocation(loc)->SetAsHintable(); + ctx->PlaceItemInLocation(loc, RandomElement(items, true)); } } @@ -569,28 +785,30 @@ static void FastFill(std::vector items, std::vector location | This method helps distribution of items locked behind many requirements. | - OoT Randomizer */ -static void AssumedFill(const std::vector& items, const std::vector& allowedLocations, +static void AssumedFill(const std::vector& items, const std::vector& allowedLocations, bool setLocationsAsHintable = false) { - + auto ctx = Rando::Context::GetInstance(); if (items.size() > allowedLocations.size()) { - printf("\x1b[2;2HERROR: MORE ITEMS THAN LOCATIONS IN GIVEN LISTS"); + SPDLOG_ERROR("ERROR: MORE ITEMS THAN LOCATIONS IN GIVEN LISTS"); SPDLOG_DEBUG("Items:\n"); - for (const uint32_t item : items) { + // NOLINTNEXTLINE(clang-diagnostic-unused-variable) + for (const RandomizerGet item : items) { SPDLOG_DEBUG("\t"); - SPDLOG_DEBUG(ItemTable(item).GetName().GetEnglish()); + SPDLOG_DEBUG(Rando::StaticData::RetrieveItem(item).GetName().GetEnglish()); SPDLOG_DEBUG("\n"); } SPDLOG_DEBUG("\nAllowed Locations:\n"); - for (const uint32_t loc : allowedLocations) { + // NOLINTNEXTLINE(clang-diagnostic-unused-variable) + for (const RandomizerCheck loc : allowedLocations) { SPDLOG_DEBUG("\t"); - SPDLOG_DEBUG(Location(loc)->GetName()); + SPDLOG_DEBUG(Rando::StaticData::GetLocation(loc)->GetName()); SPDLOG_DEBUG("\n"); } placementFailure = true; return; } - if (Settings::Logic.Is(LOGIC_NONE)) { + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC)) { FastFill(items, GetEmptyLocations(allowedLocations), true); return; } @@ -598,7 +816,7 @@ static void AssumedFill(const std::vector& items, const std::vector attemptedLocations; + std::vector attemptedLocations; do { retries--; if (retries <= 0) { @@ -606,47 +824,47 @@ static void AssumedFill(const std::vector& items, const std::vector itemsToPlace = items; + std::vector itemsToPlace = items; // copy all not yet placed advancement items so that we can apply their effects for the fill algorithm - std::vector itemsToNotPlace = - FilterFromPool(ItemPool, [](const auto i) { return ItemTable(i).IsAdvancement(); }); + std::vector itemsToNotPlace = + FilterFromPool(ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).IsAdvancement(); }); // shuffle the order of items to place Shuffle(itemsToPlace); while (!itemsToPlace.empty()) { - uint32_t item = std::move(itemsToPlace.back()); - ItemTable(item).SetAsPlaythrough(); + RandomizerGet item = std::move(itemsToPlace.back()); + Rando::StaticData::RetrieveItem(item).SetAsPlaythrough(); itemsToPlace.pop_back(); // assume we have all unplaced items - LogicReset(); - for (uint32_t unplacedItem : itemsToPlace) { - ItemTable(unplacedItem).ApplyEffect(); + logic->Reset(); + for (RandomizerGet unplacedItem : itemsToPlace) { + Rando::StaticData::RetrieveItem(unplacedItem).ApplyEffect(); } - for (uint32_t unplacedItem : itemsToNotPlace) { - ItemTable(unplacedItem).ApplyEffect(); + for (RandomizerGet unplacedItem : itemsToNotPlace) { + Rando::StaticData::RetrieveItem(unplacedItem).ApplyEffect(); } // 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()) { SPDLOG_DEBUG("\nCANNOT PLACE "); - SPDLOG_DEBUG(ItemTable(item).GetName().GetEnglish()); + SPDLOG_DEBUG(Rando::StaticData::RetrieveItem(item).GetName().GetEnglish()); SPDLOG_DEBUG(". TRYING AGAIN...\n"); #ifdef ENABLE_DEBUG - Areas::DumpWorldGraph(ItemTable(item).GetName().GetEnglish()); + Regions::DumpWorldGraph(Rando::StaticData::RetrieveItem(item).GetName().GetEnglish()); PlacementLog_Write(); #endif // reset any locations that got an item - for (uint32_t loc : attemptedLocations) { - Location(loc)->SetPlacedItem(NONE); - itemsPlaced--; + for (RandomizerCheck loc : attemptedLocations) { + ctx->GetItemLocation(loc)->SetPlacedItem(RG_NONE); + //itemsPlaced--; } attemptedLocations.clear(); @@ -655,24 +873,24 @@ static void AssumedFill(const std::vector& items, const std::vectorPlaceItemInLocation(selectedLocation, item); attemptedLocations.push_back(selectedLocation); // This tells us the location went through the randomization algorithm // to distinguish it from locations which did not or that the player already // knows if (setLocationsAsHintable) { - Location(selectedLocation)->SetAsHintable(); + ctx->GetItemLocation(selectedLocation)->SetAsHintable(); } // If ALR is off, then we check beatability after placing the item. // If the game is beatable, then we can stop placing items with logic. - if (!LocationsReachable) { - playthroughBeatable = false; - LogicReset(); - GetAccessibleLocations(allLocations, SearchMode::CheckBeatable); - if (playthroughBeatable) { + if (!ctx->GetOption(RSK_ALL_LOCATIONS_REACHABLE)) { + ctx->playthroughBeatable = false; + logic->Reset(); + CheckBeatable(); + if (ctx->playthroughBeatable) { SPDLOG_DEBUG("Game beatable, now placing items randomly. " + std::to_string(itemsToPlace.size()) + " major items remaining.\n\n"); FastFill(itemsToPlace, GetEmptyLocations(allowedLocations), true); @@ -686,112 +904,118 @@ static void AssumedFill(const std::vector& items, const std::vector rDungeonRewardOverrides{}; //quest item bit mask of each stone/medallion for the savefile - static constexpr std::array bitMaskTable = { - 0x00040000, //Kokiri Emerald - 0x00080000, //Goron Ruby - 0x00100000, //Zora Sapphire - 0x00000001, //Forest Medallion - 0x00000002, //Fire Medallion - 0x00000004, //Water Medallion - 0x00000008, //Spirit Medallion - 0x00000010, //Shadow Medallion - 0x00000020, //Light Medallion - }; - int baseOffset = ItemTable(KOKIRI_EMERALD).GetItemID(); + // static constexpr std::array bitMaskTable = { + // 0x00040000, //Kokiri Emerald + // 0x00080000, //Goron Ruby + // 0x00100000, //Zora Sapphire + // 0x00000001, //Forest Medallion + // 0x00000002, //Fire Medallion + // 0x00000004, //Water Medallion + // 0x00000008, //Spirit Medallion + // 0x00000010, //Shadow Medallion + // 0x00000020, //Light Medallion + // }; + int baseOffset = Rando::StaticData::RetrieveItem(RG_KOKIRI_EMERALD).GetItemID(); //End of Dungeons includes Link's Pocket - if (ShuffleRewards.Is(REWARDSHUFFLE_END_OF_DUNGEON)) { + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { //get stones and medallions - std::vector rewards = FilterAndEraseFromPool(ItemPool, [](const auto i) {return ItemTable(i).GetItemType() == ITEMTYPE_DUNGEONREWARD;}); + std::vector rewards = FilterAndEraseFromPool(ItemPool, [](const auto i) {return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD;}); // If there are less than 9 dungeon rewards, prioritize the actual dungeons // for placement instead of Link's Pocket if (rewards.size() < 9) { - PlaceItemInLocation(LINKS_POCKET, GREEN_RUPEE); + ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); } - if (Settings::Logic.Is(LOGIC_VANILLA)) { //Place dungeon rewards in vanilla locations - for (uint32_t loc : dungeonRewardLocations) { - Location(loc)->PlaceVanillaItem(); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) { //Place dungeon rewards in vanilla locations + for (RandomizerCheck loc : Rando::StaticData::dungeonRewardLocations) { + ctx->GetItemLocation(loc)->PlaceVanillaItem(); } } else { //Randomize dungeon rewards with assumed fill - AssumedFill(rewards, dungeonRewardLocations); + AssumedFill(rewards, Rando::StaticData::dungeonRewardLocations); } - for (size_t i = 0; i < dungeonRewardLocations.size(); i++) { - const auto index = Location(dungeonRewardLocations[i])->GetPlacedItem().GetItemID() - baseOffset; + for (size_t i = 0; i < Rando::StaticData::dungeonRewardLocations.size(); i++) { + const auto index = ctx->GetItemLocation(Rando::StaticData::dungeonRewardLocations[i])->GetPlacedItem().GetItemID() - baseOffset; rDungeonRewardOverrides[i] = index; //set the player's dungeon reward on file creation instead of pushing it to them at the start. //This is done mainly because players are already familiar with seeing their dungeon reward //before opening up their file - if (i == dungeonRewardLocations.size()-1) { - LinksPocketRewardBitMask = bitMaskTable[index]; - } + // if (i == Rando::StaticData::dungeonRewardLocations.size()-1) { + // LinksPocketRewardBitMask = bitMaskTable[index]; + // } } - } else if (LinksPocketItem.Is(LINKSPOCKETITEM_DUNGEON_REWARD)) { + } else if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_DUNGEON_REWARD)) { //get 1 stone/medallion - std::vector rewards = FilterFromPool(ItemPool, [](const auto i) {return ItemTable(i).GetItemType() == ITEMTYPE_DUNGEONREWARD;}); + std::vector rewards = FilterFromPool( + ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; }); // If there are no remaining stones/medallions, then Link's pocket won't get one if (rewards.empty()) { - PlaceItemInLocation(LINKS_POCKET, GREEN_RUPEE); + ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); return; } - uint32_t startingReward = RandomElement(rewards, true); + RandomizerGet startingReward = RandomElement(rewards, true); - LinksPocketRewardBitMask = bitMaskTable[ItemTable(startingReward).GetItemID() - baseOffset]; - PlaceItemInLocation(LINKS_POCKET, startingReward); + //LinksPocketRewardBitMask = bitMaskTable[Rando::StaticData::RetrieveItem(startingReward).GetItemID() - baseOffset]; + ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingReward); //erase the stone/medallion from the Item Pool - FilterAndEraseFromPool(ItemPool, [startingReward](const uint32_t i) {return i == startingReward;}); + FilterAndEraseFromPool(ItemPool, [startingReward](const RandomizerGet i) {return i == startingReward;}); } } //Fills any locations excluded by the player with junk items so that advancement items //can't be placed there. static void FillExcludedLocations() { + auto ctx = Rando::Context::GetInstance(); //Only fill in excluded locations that don't already have something and are forbidden - std::vector excludedLocations = FilterFromPool(allLocations, [](const auto loc){ - return Location(loc)->IsExcluded(); + std::vector excludedLocations = FilterFromPool(ctx->allLocations, [ctx](const auto loc){ + return ctx->GetItemLocation(loc)->IsExcluded(); }); - for (uint32_t loc : excludedLocations) { + for (RandomizerCheck loc : excludedLocations) { PlaceJunkInExcludedLocation(loc); } } //Function to handle the Own Dungeon setting -static void RandomizeOwnDungeon(const Dungeon::DungeonInfo* dungeon) { - std::vector dungeonItems; +static void RandomizeOwnDungeon(const Rando::DungeonInfo* dungeon) { + auto ctx = Rando::Context::GetInstance(); + std::vector dungeonItems; // Search and filter for locations that match the hint region of the dungeon // This accounts for boss room shuffle so that own dungeon items can be placed // in the shuffled boss room - std::vector dungeonLocations = FilterFromPool(allLocations, [dungeon](const auto loc) { - return GetHintRegionHintKey(Location(loc)->GetParentRegionKey()) == dungeon->GetHintKey(); + std::vector dungeonLocations = FilterFromPool(ctx->allLocations, [dungeon, ctx](const auto loc) { + return ctx->GetItemLocation(loc)->GetAreas().contains(dungeon->GetArea()); }); //filter out locations that may be required to have songs placed at them - dungeonLocations = FilterFromPool(dungeonLocations, [](const auto loc){ - if (ShuffleSongs.Is(SONGSHUFFLE_SONG_LOCATIONS)) { - return !(Location(loc)->IsCategory(Category::cSong)); + dungeonLocations = FilterFromPool(dungeonLocations, [ctx](const auto loc) { + if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_SONG_LOCATIONS)) { + return !(Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION); } - if (ShuffleSongs.Is(SONGSHUFFLE_DUNGEON_REWARDS)) { - return !(Location(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; }); //Add specific items that need be randomized within this dungeon - if (Keysanity.Is(KEYSANITY_OWN_DUNGEON) && dungeon->GetSmallKey() != NONE) { - std::vector dungeonSmallKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const uint32_t i){ return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());}); + if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) && dungeon->GetSmallKey() != RG_NONE) { + std::vector dungeonSmallKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){ return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());}); AddElementsToPool(dungeonItems, dungeonSmallKeys); } - if ((BossKeysanity.Is(BOSSKEYSANITY_OWN_DUNGEON) && dungeon->GetBossKey() != GANONS_CASTLE_BOSS_KEY) || - (GanonsBossKey.Is(GANONSBOSSKEY_OWN_DUNGEON) && dungeon->GetBossKey() == GANONS_CASTLE_BOSS_KEY)) { - auto dungeonBossKey = FilterAndEraseFromPool(ItemPool, [dungeon](const uint32_t i){ return i == dungeon->GetBossKey();}); + if ((ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) && dungeon->GetBossKey() != RG_GANONS_CASTLE_BOSS_KEY) || + (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OWN_DUNGEON) && dungeon->GetBossKey() == RG_GANONS_CASTLE_BOSS_KEY)) { + auto dungeonBossKey = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){ return i == dungeon->GetBossKey();}); AddElementsToPool(dungeonItems, dungeonBossKey); } @@ -799,8 +1023,8 @@ static void RandomizeOwnDungeon(const Dungeon::DungeonInfo* dungeon) { AssumedFill(dungeonItems, dungeonLocations); //randomize map and compass separately since they're not progressive - if (MapsAndCompasses.Is(MAPSANDCOMPASSES_OWN_DUNGEON) && dungeon->GetMap() != NONE && dungeon->GetCompass() != NONE) { - auto dungeonMapAndCompass = FilterAndEraseFromPool(ItemPool, [dungeon](const uint32_t i){ return i == dungeon->GetMap() || i == dungeon->GetCompass();}); + if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) && dungeon->GetMap() != RG_NONE && dungeon->GetCompass() != RG_NONE) { + auto dungeonMapAndCompass = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){ return i == dungeon->GetMap() || i == dungeon->GetCompass();}); AssumedFill(dungeonMapAndCompass, dungeonLocations); } } @@ -814,138 +1038,136 @@ static void RandomizeOwnDungeon(const Dungeon::DungeonInfo* dungeon) { will be randomized together if they have the same setting. Maps and Compasses are randomized separately once the dungeon advancement items have all been placed.*/ static void RandomizeDungeonItems() { - using namespace Dungeon; + auto ctx = Rando::Context::GetInstance(); //Get Any Dungeon and Overworld group locations - std::vector anyDungeonLocations = FilterFromPool(allLocations, [](const auto loc){return Location(loc)->IsDungeon();}); - //overworldLocations defined in item_location.cpp + std::vector anyDungeonLocations = Rando::StaticData::GetDungeonLocations(); + //Rando::StaticData::GetOverworldLocations() defined in item_location.cpp //Create Any Dungeon and Overworld item pools - std::vector anyDungeonItems; - std::vector overworldItems; + std::vector anyDungeonItems; + std::vector overworldItems; - for (auto dungeon : dungeonList) { - if (Keysanity.Is(KEYSANITY_ANY_DUNGEON)) { - auto dungeonKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const uint32_t i){return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());}); + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON)) { + auto dungeonKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());}); AddElementsToPool(anyDungeonItems, dungeonKeys); - } else if (Keysanity.Is(KEYSANITY_OVERWORLD)) { - auto dungeonKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const uint32_t i){return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());}); + } else if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { + auto dungeonKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());}); AddElementsToPool(overworldItems, dungeonKeys); } - if (BossKeysanity.Is(BOSSKEYSANITY_ANY_DUNGEON) && dungeon->GetBossKey() != GANONS_CASTLE_BOSS_KEY) { - auto bossKey = FilterAndEraseFromPool(ItemPool, [dungeon](const uint32_t i){return i == dungeon->GetBossKey();}); + if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON) && dungeon->GetBossKey() != RG_GANONS_CASTLE_BOSS_KEY) { + auto bossKey = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return i == dungeon->GetBossKey();}); AddElementsToPool(anyDungeonItems, bossKey); - } else if (BossKeysanity.Is(BOSSKEYSANITY_OVERWORLD) && dungeon->GetBossKey() != GANONS_CASTLE_BOSS_KEY) { - auto bossKey = FilterAndEraseFromPool(ItemPool, [dungeon](const uint32_t i){return i == dungeon->GetBossKey();}); + } else if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD) && dungeon->GetBossKey() != RG_GANONS_CASTLE_BOSS_KEY) { + auto bossKey = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return i == dungeon->GetBossKey();}); AddElementsToPool(overworldItems, bossKey); } - if (GanonsBossKey.Is(GANONSBOSSKEY_ANY_DUNGEON)) { - auto ganonBossKey = FilterAndEraseFromPool(ItemPool, [](const auto i){return i == GANONS_CASTLE_BOSS_KEY;}); + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANY_DUNGEON)) { + auto ganonBossKey = FilterAndEraseFromPool(ItemPool, [](const auto i){return i == RG_GANONS_CASTLE_BOSS_KEY;}); AddElementsToPool(anyDungeonItems, ganonBossKey); - } else if (GanonsBossKey.Is(GANONSBOSSKEY_OVERWORLD)) { - auto ganonBossKey = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == GANONS_CASTLE_BOSS_KEY; }); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OVERWORLD)) { + auto ganonBossKey = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GANONS_CASTLE_BOSS_KEY; }); AddElementsToPool(overworldItems, ganonBossKey); } } - if (GerudoKeys.Is(GERUDOKEYS_ANY_DUNGEON)) { - auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == GERUDO_FORTRESS_SMALL_KEY || i == GERUDO_FORTRESS_KEY_RING; }); + if (ctx->GetOption(RSK_GERUDO_KEYS).Is(RO_GERUDO_KEYS_ANY_DUNGEON)) { + auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GERUDO_FORTRESS_SMALL_KEY || i == RG_GERUDO_FORTRESS_KEY_RING; }); AddElementsToPool(anyDungeonItems, gerudoKeys); - } else if (GerudoKeys.Is(GERUDOKEYS_OVERWORLD)) { - auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == GERUDO_FORTRESS_SMALL_KEY || i == GERUDO_FORTRESS_KEY_RING; }); + } else if (ctx->GetOption(RSK_GERUDO_KEYS).Is(RO_GERUDO_KEYS_OVERWORLD)) { + auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GERUDO_FORTRESS_SMALL_KEY || i == RG_GERUDO_FORTRESS_KEY_RING; }); AddElementsToPool(overworldItems, gerudoKeys); } - if (ShuffleRewards.Is(REWARDSHUFFLE_ANY_DUNGEON)) { + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_ANY_DUNGEON)) { auto rewards = FilterAndEraseFromPool( - ItemPool, [](const auto i) { return ItemTable(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; }); + ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; }); AddElementsToPool(anyDungeonItems, rewards); - } else if (ShuffleRewards.Is(REWARDSHUFFLE_OVERWORLD)) { + } else if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_OVERWORLD)) { auto rewards = FilterAndEraseFromPool( - ItemPool, [](const auto i) { return ItemTable(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; }); + ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; }); AddElementsToPool(overworldItems, rewards); } //Randomize Any Dungeon and Overworld pools AssumedFill(anyDungeonItems, anyDungeonLocations, true); - AssumedFill(overworldItems, overworldLocations, true); + AssumedFill(overworldItems, Rando::StaticData::GetOverworldLocations(), true); //Randomize maps and compasses after since they're not advancement items - for (auto dungeon : dungeonList) { - if (MapsAndCompasses.Is(MAPSANDCOMPASSES_ANY_DUNGEON)) { - auto mapAndCompassItems = FilterAndEraseFromPool(ItemPool, [dungeon](const uint32_t i){return i == dungeon->GetMap() || i == dungeon->GetCompass();}); + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON)) { + auto mapAndCompassItems = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return i == dungeon->GetMap() || i == dungeon->GetCompass();}); AssumedFill(mapAndCompassItems, anyDungeonLocations, true); - } else if (MapsAndCompasses.Is(MAPSANDCOMPASSES_OVERWORLD)) { - auto mapAndCompassItems = FilterAndEraseFromPool(ItemPool, [dungeon](const uint32_t i){return i == dungeon->GetMap() || i == dungeon->GetCompass();}); - AssumedFill(mapAndCompassItems, overworldLocations, 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::GetOverworldLocations(), true); } } } static void RandomizeLinksPocket() { - if (LinksPocketItem.Is(LINKSPOCKETITEM_ADVANCEMENT)) { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_ADVANCEMENT)) { //Get all the advancement items don't include tokens - std::vector advancementItems = FilterAndEraseFromPool(ItemPool, [](const auto i) { - return ItemTable(i).IsAdvancement() && ItemTable(i).GetItemType() != ITEMTYPE_TOKEN; + std::vector advancementItems = FilterAndEraseFromPool(ItemPool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).IsAdvancement() && Rando::StaticData::RetrieveItem(i).GetItemType() != ITEMTYPE_TOKEN; }); //select a random one - uint32_t startingItem = RandomElement(advancementItems, true); + RandomizerGet startingItem = RandomElement(advancementItems, true); //add the others back AddElementsToPool(ItemPool, advancementItems); - PlaceItemInLocation(LINKS_POCKET, startingItem); - } else if (LinksPocketItem.Is(LINKSPOCKETITEM_NOTHING)) { - PlaceItemInLocation(LINKS_POCKET, GREEN_RUPEE); + ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingItem); + } else if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_NOTHING)) { + ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); } } void VanillaFill() { + auto ctx = Rando::Context::GetInstance(); //Perform minimum needed initialization - AreaTable_Init(); - GenerateLocationPool(); + RegionTable_Init(); + ctx->GenerateLocationPool(); GenerateItemPool(); GenerateStartingInventory(); //Place vanilla item in each location RandomizeDungeonRewards(); - for (uint32_t loc : allLocations) { - Location(loc)->PlaceVanillaItem(); + for (RandomizerCheck loc : ctx->allLocations) { + ctx->GetItemLocation(loc)->PlaceVanillaItem(); } //If necessary, handle ER stuff - if (ShuffleEntrances) { - printf("\x1b[7;10HShuffling Entrances..."); - ShuffleAllEntrances(); - printf("\x1b[7;32HDone"); + if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) { + SPDLOG_INFO("Shuffling Entrances..."); + ctx->GetEntranceShuffler()->ShuffleAllEntrances(); + SPDLOG_INFO("Shuffling Entrances Done"); } // Populate the playthrough for entrances so they are placed in the spoiler log GeneratePlaythrough(); //Finish up - CreateItemOverrides(); - CreateEntranceOverrides(); + ctx->CreateItemOverrides(); + ctx->GetEntranceShuffler()->CreateEntranceOverrides(); CreateWarpSongTexts(); } void ClearProgress() { - printf("\x1b[7;32H "); // Done - printf("\x1b[8;10H "); // Placing Items...Done - printf("\x1b[9;10H "); // Calculating Playthrough...Done - printf("\x1b[10;10H "); // Creating Hints...Done - printf("\x1b[11;10H "); // Writing Spoiler Log...Done } int Fill() { - + auto ctx = Rando::Context::GetInstance(); int retries = 0; + SPDLOG_INFO("Starting seed generation..."); while(retries < 5) { + SPDLOG_INFO("Attempt {}...", retries + 1); placementFailure = false; - showItemProgress = false; - playthroughLocations.clear(); - playthroughEntrances.clear(); - wothLocations.clear(); - AreaTable_Init(); //Reset the world graph to intialize the proper locations - ItemReset(); //Reset shops incase of shopsanity random - GenerateLocationPool(); + //showItemProgress = false; + ctx->playthroughLocations.clear(); + ctx->GetEntranceShuffler()->playthroughEntrances.clear(); + RegionTable_Init(); //Reset the world graph to intialize the proper locations + ctx->ItemReset(); //Reset shops incase of shopsanity random + ctx->GenerateLocationPool(); GenerateItemPool(); GenerateStartingInventory(); RemoveStartingItemsFromPool(); @@ -953,89 +1175,146 @@ int Fill() { //Temporarily add shop items to the ItemPool so that entrance randomization //can validate the world using deku/hylian shields - AddElementsToPool(ItemPool, GetMinVanillaShopItems(32)); //assume worst case shopsanity 4 - if (ShuffleEntrances) { - printf("\x1b[7;10HShuffling Entrances"); - if (ShuffleAllEntrances() == ENTRANCE_SHUFFLE_FAILURE) { + StartPerformanceTimer(PT_ENTRANCE_SHUFFLE); + AddElementsToPool(ItemPool, GetMinVanillaShopItems(8)); //assume worst case shopsanity 7 + if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) { + SPDLOG_INFO("Shuffling Entrances..."); + if (ctx->GetEntranceShuffler()->ShuffleAllEntrances() == ENTRANCE_SHUFFLE_FAILURE) { retries++; ClearProgress(); continue; } - printf("\x1b[7;32HDone"); + SPDLOG_INFO("Shuffling Entrances Done"); } + SetAreas(); //erase temporary shop items - FilterAndEraseFromPool(ItemPool, [](const auto item) { return ItemTable(item).GetItemType() == ITEMTYPE_SHOP; }); + FilterAndEraseFromPool(ItemPool, [](const auto item) { return Rando::StaticData::RetrieveItem(item).GetItemType() == ITEMTYPE_SHOP; }); + StopPerformanceTimer(PT_ENTRANCE_SHUFFLE); - showItemProgress = true; + //ctx->showItemProgress = true; //Place shop items first, since a buy shield is needed to place a dungeon reward on Gohma due to access - NonShopItems = {}; - if (Shopsanity.Is(SHOPSANITY_OFF)) { + + StartPerformanceTimer(PT_SHOPSANITY); + if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { + SPDLOG_INFO("Placing Vanilla Shop Items..."); PlaceVanillaShopItems(); //Place vanilla shop items in vanilla location } else { + SPDLOG_INFO("Shuffling Shop Items"); int total_replaced = 0; - if (Shopsanity.IsNot(SHOPSANITY_ZERO)) { //Shopsanity 1-4, random - //Initialize NonShopItems - ItemAndPrice init; - init.Name = Text{"No Item", "Sin objeto", "Pas d'objet"}; - init.Price = -1; - init.Repurchaseable = false; - NonShopItems.assign(32, init); - //Indices from OoTR. So shopsanity one will overwrite 7, three will overwrite 7, 5, 8, etc. - const std::array indices = {7, 5, 8, 6}; + if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_RANDOM) || ctx->GetOption(RSK_SHOPSANITY_COUNT).IsNot(RO_SHOPSANITY_COUNT_ZERO_ITEMS)) { //Shopsanity 1-7, random + /* + Indices from OoTR. So shopsanity one will overwrite 7, three will overwrite 7, 5, 8, etc. + 8 6 2 4 + 7 5 1 3 + */ + const std::array indices = { 7, 5, 8, 6, 3, 1, 4, 2 }; //Overwrite appropriate number of shop items - for (size_t i = 0; i < ShopLocationLists.size(); i++) { - int num_to_replace = GetShopsanityReplaceAmount(); //1-4 shop items will be overwritten, depending on settings + #define LOCATIONS_PER_SHOP 8 + for (size_t i = 0; i < Rando::StaticData::GetShopLocations().size() / LOCATIONS_PER_SHOP; i++) { + int num_to_replace = GetShopsanityReplaceAmount(); //1-7 shop items will be overwritten, depending on settings total_replaced += num_to_replace; for (int j = 0; j < num_to_replace; j++) { int itemindex = indices[j]; - int shopsanityPrice = GetRandomShopPrice(); - NonShopItems[TransformShopIndex(i*8+itemindex-1)].Price = shopsanityPrice; //Set price to be retrieved by the patch and textboxes - Location(ShopLocationLists[i][itemindex - 1])->SetShopsanityPrice(shopsanityPrice); + RandomizerCheck rc = Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1]; + Rando::ItemLocation* itemLoc = ctx->GetItemLocation(rc); + uint16_t shopsanityPrice = GetRandomPrice(Rando::StaticData::GetLocation(rc), shopsanityPrices); + itemLoc->SetCustomPrice(shopsanityPrice); } } + #undef LOCATIONS_PER_SHOP } //Get all locations and items that don't have a shopsanity price attached - std::vector shopLocations = {}; + std::vector shopLocations = {}; //Get as many vanilla shop items as the total number of shop items minus the number of replaced items //So shopsanity 0 will get all 64 vanilla items, shopsanity 4 will get 32, etc. - std::vector shopItems = GetMinVanillaShopItems(total_replaced); + std::vector shopItems = GetMinVanillaShopItems(total_replaced); - for (size_t i = 0; i < ShopLocationLists.size(); i++) { - for (size_t j = 0; j < ShopLocationLists[i].size(); j++) { - uint32_t loc = ShopLocationLists[i][j]; - if (!(Location(loc)->HasShopsanityPrice())) { - shopLocations.push_back(loc); - } + for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetShopLocations()) { + if (!(ctx->GetItemLocation(randomizerCheck)->HasCustomPrice())) { + shopLocations.push_back(randomizerCheck); } } //Place the shop items which will still be at shop locations AssumedFill(shopItems, shopLocations); } + //Add prices to scrubs + auto scrubLoc = Rando::StaticData::GetScrubLocations(); + if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) { + for (size_t i = 0; i < scrubLoc.size(); i++) { + ctx->GetItemLocation(scrubLoc[i])->SetCustomPrice( + GetRandomPrice(Rando::StaticData::GetLocation(scrubLoc[i]), scrubPrices) + ); + } + } else { + for (size_t i = 0; i < scrubLoc.size(); i++) { + ctx->GetItemLocation(scrubLoc[i])->SetCustomPrice( + Rando::StaticData::GetLocation(scrubLoc[i])->GetVanillaPrice() + ); + } + } + + //set merchant prices + if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)){ + ctx->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->SetCustomPrice( + GetRandomPrice(Rando::StaticData::GetLocation(RC_ZR_MAGIC_BEAN_SALESMAN), merchantPrices) + ); + } else { + ctx->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->SetCustomPrice( + Rando::StaticData::GetLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetVanillaPrice() + ); + } + + auto merchantLoc = Rando::StaticData::GetMerchantLocations(); + + if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)){ + for (size_t i = 0; i < merchantLoc.size(); i++) { + ctx->GetItemLocation(merchantLoc[i])->SetCustomPrice( + GetRandomPrice(Rando::StaticData::GetLocation(merchantLoc[i]), merchantPrices) + ); + } + } else { + for (size_t i = 0; i < merchantLoc.size(); i++) { + ctx->GetItemLocation(merchantLoc[i])->SetCustomPrice( + Rando::StaticData::GetLocation(merchantLoc[i])->GetVanillaPrice() + ); + } + } + StopPerformanceTimer(PT_SHOPSANITY); + + StartPerformanceTimer(PT_OWN_DUNGEON); //Place dungeon rewards + SPDLOG_INFO("Shuffling and Placing Dungeon Items..."); RandomizeDungeonRewards(); //Place dungeon items restricted to their Own Dungeon - for (auto dungeon : Dungeon::dungeonList) { + 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 (ShuffleSongs.IsNot(SONGSHUFFLE_ANYWHERE)) { + if (ctx->GetOption(RSK_SHUFFLE_SONGS).IsNot(RO_SONG_SHUFFLE_ANYWHERE)) { //Get each song - std::vector songs = - FilterAndEraseFromPool(ItemPool, [](const auto i) { return ItemTable(i).GetItemType() == ITEMTYPE_SONG; }); + std::vector songs = FilterAndEraseFromPool( + ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_SONG; }); //Get each song location - std::vector songLocations; - if (ShuffleSongs.Is(SONGSHUFFLE_SONG_LOCATIONS)) { - songLocations = - FilterFromPool(allLocations, [](const auto loc) { return Location(loc)->IsCategory(Category::cSong); }); - - } else if (ShuffleSongs.Is(SONGSHUFFLE_DUNGEON_REWARDS)) { + std::vector songLocations; + if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_SONG_LOCATIONS)) { songLocations = FilterFromPool( - allLocations, [](const auto loc) { return Location(loc)->IsCategory(Category::cSongDungeonReward); }); + 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)->GetRCType() == RCTYPE_BOSS_HEART_OR_OTHER_REWARD || + loc == RC_SHEIK_IN_ICE_CAVERN || + loc == RC_SONG_FROM_IMPA; + }); } AssumedFill(songs, songLocations, true); @@ -1043,63 +1322,66 @@ int Fill() { //Then place dungeon items that are assigned to restrictive location pools RandomizeDungeonItems(); + SPDLOG_INFO("Dungeon Items Done"); //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 ItemTable(i).IsAdvancement(); }); - AssumedFill(remainingAdvancementItems, allLocations, true); + 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 - std::vector remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; }); + SPDLOG_INFO("Shuffling Remaining Items"); + std::vector remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; }); FastFill(remainingPool, GetAllEmptyLocations(), false); + StopPerformanceTimer(PT_REMAINING_ITEMS); - //Add prices for scrubsanity, this is unique to SoH because we write/read scrub prices to/from the spoilerfile. - if (Scrubsanity.Is(SCRUBSANITY_AFFORDABLE)) { - for (size_t i = 0; i < ScrubLocations.size(); i++) { - Location(ScrubLocations[i])->SetScrubsanityPrice(10); - } - } else if (Scrubsanity.Is(SCRUBSANITY_RANDOM_PRICES)) { - for (size_t i = 0; i < ScrubLocations.size(); i++) { - int randomPrice = GetRandomScrubPrice(); - Location(ScrubLocations[i])->SetScrubsanityPrice(randomPrice); - } - } + StartPerformanceTimer(PT_PLAYTHROUGH_GENERATION); GeneratePlaythrough(); + StopPerformanceTimer(PT_PLAYTHROUGH_GENERATION); //Successful placement, produced beatable result - if(playthroughBeatable && !placementFailure) { - printf("Done"); - printf("\x1b[9;10HCalculating Playthrough..."); + if(ctx->playthroughBeatable && !placementFailure) { + + SPDLOG_INFO("Calculating Playthrough..."); + StartPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH); PareDownPlaythrough(); + StopPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH); + + StartPerformanceTimer(PT_WOTH); CalculateWotH(); - printf("Done"); - CreateItemOverrides(); - CreateEntranceOverrides(); - if (GossipStoneHints.IsNot(HINTS_NO_HINTS)) { - printf("\x1b[10;10HCreating Hints..."); - CreateAllHints(); - printf("Done"); - } - if (ShuffleMerchants.Is(SHUFFLEMERCHANTS_HINTS)) { - CreateMerchantsHints(); - } - //Always execute ganon hint generation for the funny line - CreateGanonText(); - CreateAltarText(); - CreateDampesDiaryText(); - CreateGregRupeeHint(); - CreateSheikText(); - CreateSariaText(); + 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); + SPDLOG_DEBUG("Number of retries {}", retries); return 1; } //Unsuccessful placement if(retries < 4) { - SPDLOG_DEBUG("\nGOT STUCK. RETRYING...\n"); - Areas::ResetAllLocations(); - LogicReset(); + SPDLOG_DEBUG("Failed to generate a beatable seed. Retrying..."); + Regions::ResetAllLocations(); + logic->Reset(); ClearProgress(); } retries++; diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.hpp b/soh/soh/Enhancements/randomizer/3drando/fill.hpp index 427668985ba..94cba70c7b0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.hpp @@ -1,27 +1,71 @@ #pragma once -#include "keys.hpp" +#include "../randomizerTypes.h" +#include "location_access.hpp" +#include "../entrance.h" #include #include -enum class SearchMode { - ReachabilitySearch, - GeneratePlaythrough, - CheckBeatable, - AllLocationsReachable, - ValidateWorld, - TimePassAccess, - TempleOfTimeAccess, - ValidStartingRegion, - PoeCollectorAccess, +//RANDOTODO merge into Logic once Logic is a class passed to logic funtions +struct GetAccessibleLocationsStruct { + std::vector accessibleLocations; + std::vector regionPool; + //Variables for playthrough + int gsCount; + int maxGsCount; + std::vector buyIgnores; + + //Variables for search + std::vector newItemLocations; + bool logicUpdated; + bool resetSphere; + + //Variables For Validating Entrences + bool haveTimeAccess; + bool foundTempleOfTime; + bool validatedStartingRegion; + bool sphereZeroComplete; + bool timePassChildDay; + bool timePassChildNight; + bool timePassAdultDay; + bool timePassAdultNight; + + std::vector itemSphere; + std::list entranceSphere; + + GetAccessibleLocationsStruct(int _maxGsCount){ + regionPool = {RR_ROOT}; + gsCount = 0; + maxGsCount = _maxGsCount; + logicUpdated = false; + resetSphere = false; + } + + void InitLoop(){ + logicUpdated = false; + for (Rando::ItemLocation* location : newItemLocations) { + location->ApplyPlacedItemEffect(); + } + newItemLocations.clear(); + itemSphere.clear(); + entranceSphere.clear(); + } }; void ClearProgress(); void VanillaFill(); int Fill(); -std::vector GetAccessibleLocations(const std::vector& allowedLocations, - SearchMode mode = SearchMode::ReachabilitySearch, std::string ignore = "", - bool checkPoeCollectorAccess = false, - bool checkOtherEntranceAccess = false); +std::vector GetEmptyLocations(std::vector allowedLocations); + +void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, + bool stopOnBeatable = false, bool addToPlaythrough = false); + +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/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index a50de65022a..1b2870ed650 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -1,9 +1,11 @@ -#include "hint_list.hpp" #include "custom_messages.hpp" -#include +#include "../randomizerTypes.h" +#include "../context.h" +#include "../static_data.h" using namespace CustomMessages; +using namespace std::literals::string_literals; // Big thanks to Lioncache, Gabyelnuevo, Danius88, and Charade for their translations! @@ -16,2065 +18,1826 @@ using namespace CustomMessages; // surrounding text with '#' will make it a different color // - OoT Randomizer -// '%d' indicates a number will be placed there. +// '[[d]]' indicates a number will be placed there, numbers in [[]] will be replaced by other text in hints +namespace Rando { -std::array hintTable; - -void HintTable_Init() { +void StaticData::HintTable_Init() { /*-------------------------- - | GENERAL TEXT | + | GENERAL TEXT | ---------------------------*/ - hintTable[NONE] = HintText::Exclude({ Text{ "No Hint", "Pas d'Indice", "" } }); - hintTable[PREFIX] = - HintText::Exclude({ Text{ "They say that ", /*french*/ "Selon moi, ", /*spanish*/ "Según dicen, " } }); - hintTable[WAY_OF_THE_HERO] = - HintText::Exclude({ Text{ " is on %cthe way of the hero%w.", /*french*/ " est sur %cla voie du héros%w.", - /*spanish*/ " conduce a la senda del héroe." } }); - hintTable[PLUNDERING] = - HintText::Exclude({ Text{ "plundering ", /*french*/ "explorer ", /*spanish*/ "inspeccionar " } }); - hintTable[FOOLISH] = HintText::Exclude( - { Text{ " is %pa foolish choice%w.", /*french*/ " est %pfutile%w.", /*spanish*/ " no es una sabia decisión." } }); - hintTable[CAN_BE_FOUND_AT] = - HintText::Exclude({ Text{ "can be found at", /*french*/ "se trouve dans", /*spanish*/ "aguarda en" } }); - hintTable[HOARDS] = HintText::Exclude({ Text{ "hoards", /*french*/ "recèle", /*spanish*/ "acapara" } }); + hintTextTable[RHT_NONE] = HintText(CustomMessage("No Hint", "Kein Hinweis", "Pas d'Indice" )); + hintTextTable[RHT_WAY_OF_THE_HERO] = + HintText(CustomMessage( "They say that #[[1]]# is on #the way of the hero#.", + "Man erzählt sich, daß #[[1]]# auf #dem Weg des Helden# sei.", + /*french*/ "Selon moi, #[[1]]# est sur #la voie du héros#.", {QM_RED, QM_LBLUE})); + // /*spanish*/ "Según dicen, #[[1]]# conduce a la senda del héroe." + hintTextTable[RHT_FOOLISH] = + HintText(CustomMessage( "They say that plundering #[[1]]# is #a foolish choice#.", + "Man erzählt sich, daß das Plündern von #[[1]]# #eine törichte Entscheidung# sei.", + /*french*/ "Selon moi, explorer #[[1]]# est #futile#.", {QM_RED, QM_PINK})); + // /*spanish*/ "Según dicen, inspeccionar #[[1]]# #no es una sabia decisión#." + hintTextTable[RHT_CAN_BE_FOUND_AT] = + HintText(CustomMessage( "They say that #[[1]]# can be found at #[[2]]#.", + "Man erzählt sich, daß #[[1]]# bei #[[2]]# gefunden werden könne.", + /*french*/ "Selon moi, #[[1]]# se trouve dans #[[2]]#.", {QM_GREEN, QM_RED})); + // /*spanish*/ "Según dicen, #[[1]]# aguarda en #[[2]]#." + hintTextTable[RHT_HOARDS] = + HintText(CustomMessage( "They say that #[[2]]# hoards #[[1]]#.", + "Man erzählt sich, daß #[[2]]# #[[1]]# horte.", + /*french*/ "Selon moi, #[[2]]# recèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ "Según dicen, #[[2]]# acapara #[[1]]#." HintTable_Init_Item(); HintTable_Init_Exclude_Overworld(); HintTable_Init_Exclude_Dungeon(); - /*-------------------------- - | ALWAYS HINT TEXT | - ---------------------------*/ - - hintTable[ZR_FROGS_OCARINA_GAME] = HintText::Always( - { - // obscure text - Text{ "an #amphibian feast# yields", /*french*/ "un #festin d'amphibiens# donne", - /*spanish*/ "una #fiesta anfibia# brinda" }, - Text{ "the #croaking choir's magnum opus# awards", /*french*/ "la #chorale coassante# donne", - /*spanish*/ "un #coro maestro de ancas# premia" }, - Text{ "the #froggy finale# yields", /*french*/ "la #finale amphibienne# donne", - /*spanish*/ "el #gran final batracio# brinda" }, - }, - {}, - // clear text - Text{ "the final reward from the #Frogs of Zora's River# is", - /*french*/ "la dernière récompense des #grenouilles de la Rivière Zora# est", - /*spanish*/ "la recompensa final de las #ranas del Río Zora# premia" }); - - hintTable[KF_LINKS_HOUSE_COW] = HintText::Always( - { - // obscure text - Text{ "the #bovine bounty of a horseback hustle# gifts", - /*french*/ "le cadeau #qui découle d'une réussite équestre# est", - /*spanish*/ "la #recompensa bovina de un paseo a caballo# brinda" }, - }, - {}, - // clear text - Text{ "#Malon's obstacle course# leads to", /*french*/ "la #course à obstacle de Malon# amène à", - /*spanish*/ "la #carrera de obstáculos de Malon# brinda" }); - - hintTable[KAK_100_GOLD_SKULLTULA_REWARD] = HintText::Always( - { - // obscure text - Text{ "#100 bug badges# rewards", - /*french*/ "#100 écussons# donnent", - /*spanish*/ "#100 medallas de insectos# otorgan" }, - Text{ "#100 spider souls# yields", - /*french*/ "#100 âmes d'arachnide# donnent", - /*spanish*/ "#100 almas de araña# otorgan" }, - Text{ "#100 auriferous arachnids# lead to", - /*french*/ "#100 arachnides aurifères# donnent", - /*spanish*/ "#100 arácnidos auríferos# otorgan" }, - }, - {}, - // clear text - Text{ "slaying #100 Gold Skulltulas# reveals", - /*french*/ "détruire #100 Skulltulas d'or# donne", - /*spanish*/ "exterminar #100 skulltulas doradas# revela" }); /*-------------------------- | SOMETIMES HINT TEXT | ---------------------------*/ - hintTable[SONG_FROM_OCARINA_OF_TIME] = HintText::Sometimes({ - // obscure text - Text{ "the #Ocarina of Time# teaches", /*french*/ "l'#Ocarina du Temps# est accompagné par", - /*spanish*/ "la #Ocarina del Tiempo# enseña" }, - }); - - hintTable[SONG_FROM_COMPOSERS_GRAVE] = HintText::Sometimes({ - // obscure text - Text{ "#ReDead in the Composers' Grave# guard", - /*french*/ "les #Éffrois du tombeau des compositeurs# protègent", - /*spanish*/ "los #ReDeads del Panteón Real# guardan" }, - Text{ "the #Composer Brothers wrote#", /*french*/ "le #trésor des compositeurs# est", - /*spanish*/ "los #hermanos compositores escribieron#" }, - }); - - hintTable[SHEIK_IN_FOREST] = HintText::Sometimes({ - // obscure text - Text{ "#in a meadow# Sheik teaches", /*french*/ "Sheik confiera, #dans un bosquet#,", - /*spanish*/ "#en la pradera sagrada# Sheik enseña" }, - }); - - hintTable[SHEIK_AT_TEMPLE] = HintText::Sometimes({ - // obscure text - Text{ "Sheik waits at a #monument to time# to teach", - /*french*/ "Sheik confiera, #au pied de l'épée légendaire#,", - /*spanish*/ "Sheik espera en el #momumento del tiempo# para enseñar" }, - }); - - hintTable[SHEIK_IN_CRATER] = HintText::Sometimes({ - // obscure text - Text{ "the #crater's melody# is", /*french*/ "Sheik confiera, #entouré de lave#,", - /*spanish*/ "la #melodía del cráter# otorga" }, - }); - - hintTable[SHEIK_IN_ICE_CAVERN] = HintText::Sometimes({ - // obscure text - Text{ "the #frozen cavern# echoes with", /*french*/ "Sheik confiera, #dans une caverne enneigée#,", - /*spanish*/ "en la #caverna de hielo# retumban los ecos de" }, - }); - - hintTable[SHEIK_IN_KAKARIKO] = HintText::Sometimes({ - // obscure text - Text{ "a #ravaged village# mourns with", /*french*/ "Sheik confirera, #au coeur d'un village ravagé#,", - /*spanish*/ "un #arrasado pueblo# llora" }, - }); - - hintTable[SHEIK_AT_COLOSSUS] = HintText::Sometimes({ - // obscure text - Text{ "a hero ventures #beyond the wasteland# to learn", - /*french*/ "Sheik confiera, #au bout d'un chemin sableux#,", - /*spanish*/ "el héroe que se adentre #más allá del desierto# aprenderá" }, - }); - - hintTable[MARKET_10_BIG_POES] = HintText::Sometimes( - { - // obscure text - Text{ "#ghost hunters# will be rewarded with", - /*french*/ "#les chasseurs de fantômes# sont récompensés avec", - /*spanish*/ "los #cazafantasmas# son premiados con" }, - }, - {}, - // clear text - Text{ "catching #Big Poes# leads to", /*french*/ "#d'attraper des Àmes# donne", - /*spanish*/ "hacerte con #Grandes Poes# conduce a" }); - - hintTable[DEKU_THEATER_SKULL_MASK] = HintText::Sometimes({ - // obscure text - Text{ "the #Skull Mask# yields", /*french*/ "le #Masque de Mort# donne", - /*spanish*/ "la #máscara de calavera# otorga" }, - }); - - hintTable[DEKU_THEATER_MASK_OF_TRUTH] = HintText::Sometimes( - { - // obscure text - Text{ "showing a #truthful eye to the crowd# rewards", - /*french*/ "montrer #l'oeil de vérité à la foule# donne", - /*spanish*/ "#mostrarle el ojo verdadero# a una multitud brinda" }, - }, - {}, - // clear text - Text{ "the #Mask of Truth# yields", /*french*/ "le #Masque de Vérité# donne", - /*spanish*/ "la #máscara de la verdad# premia" }); - - hintTable[HF_OCARINA_OF_TIME_ITEM] = HintText::Sometimes({ - // obscure text - Text{ "the #treasure thrown by Princess Zelda# is", /*french*/ "le trésor #laissé par la princesse# est", - /*spanish*/ "el #tesoro arrojado por la Princesa Zelda# se trata de" }, - }); - - hintTable[DMT_TRADE_BROKEN_SWORD] = HintText::Sometimes({ - // obscure text - Text{ "a #blinded Biggoron# entrusts", /*french*/ "un #Grogoron aveuglé# confie", - /*spanish*/ "un #miope Biggoron# otorga" }, - }); - - hintTable[DMT_TRADE_EYEDROPS] = HintText::Sometimes({ - // obscure text - Text{ "while you wait, #Biggoron# gives", /*french*/ "pendant que tu attends, #Biggoron# donne", - /*spanish*/ "#Biggoron# está a la espera de otorgar" }, - }); - - hintTable[DMT_TRADE_CLAIM_CHECK] = HintText::Sometimes({ - // obscure text - Text{ "#Biggoron# crafts", /*french*/ "#Biggoron# fabrique", /*spanish*/ "#Biggoron# forja" }, - }); - - hintTable[KAK_50_GOLD_SKULLTULA_REWARD] = HintText::Sometimes( - { - // obscure text - Text{ "#50 bug badges# rewards", /*french*/ "#50 écussons# donnent", - /*spanish*/ "#50 medallas de insectos# otorgan" }, - Text{ "#50 spider souls# yields", /*french*/ "#50 âmes d'arachnide# donnent", - /*spanish*/ "#50 almas de araña# otorgan" }, - Text{ "#50 auriferous arachnids# lead to", /*french*/ "#50 arachnides aurifères# donnent", - /*spanish*/ "#50 arácnidos auríferos# otorgan" }, - }, - {}, - // clear text - Text{ "slaying #50 Gold Skulltulas# reveals", /*french*/ "détruire #50 Skulltulas d'or# donne", - /*spanish*/ "exterminar #50 skulltulas doradas# revela" }); - - hintTable[KAK_40_GOLD_SKULLTULA_REWARD] = HintText::Sometimes( - { - // obscure text - Text{ "#40 bug badges# rewards", /*french*/ "#40 écussons# donnent", - /*spanish*/ "#40 medallas de insectos# otorgan" }, - Text{ "#40 spider souls# yields", /*french*/ "#40 âmes d'arachnide# donnent", - /*spanish*/ "#40 almas de araña# otorgan" }, - Text{ "#40 auriferous arachnids# lead to", /*french*/ "#40 arachnides aurifères# donnent", - /*spanish*/ "#40 arácnidos auríferos# otorgan" }, - }, - {}, - // clear text - Text{ "slaying #40 Gold Skulltulas# reveals", /*french*/ "détruire #40 Skulltulas d'or# donne", - /*spanish*/ "exterminar #40 skulltulas doradas# revela" }); - - hintTable[KAK_30_GOLD_SKULLTULA_REWARD] = HintText::Sometimes( - { - // obscure text - Text{ "#30 bug badges# rewards", /*french*/ "#30 écussons# donnent", - /*spanish*/ "#30 medallas de insectos# otorgan" }, - Text{ "#30 spider souls# yields", /*french*/ "#30 âmes d'arachnide# donnent", - /*spanish*/ "#30 almas de araña# otorgan" }, - Text{ "#30 auriferous arachnids# lead to", /*french*/ "#30 arachnides aurifères# donnent", - /*spanish*/ "#30 arácnidos auríferos# otorgan" }, - }, - {}, - // clear text - Text{ "slaying #30 Gold Skulltulas# reveals", /*french*/ "détruire #30 Skulltulas d'or# donne", - /*spanish*/ "exterminar #30 skulltulas doradas# revela" }); - - hintTable[KAK_20_GOLD_SKULLTULA_REWARD] = HintText::Sometimes( - { - // obscure text - Text{ "#20 bug badges# rewards", /*french*/ "#20 écussons# donnent", - /*spanish*/ "#20 medallas de insectos# otorgan" }, - Text{ "#20 spider souls# yields", /*french*/ "#20 âmes d'arachnide# donnent", - /*spanish*/ "#20 almas de araña# otorgan" }, - Text{ "#20 auriferous arachnids# lead to", /*french*/ "#20 arachnides aurifères# donnent", - /*spanish*/ "#20 arácnidos auríferos# otorgan" }, - }, - {}, - // clear text - Text{ "slaying #20 Gold Skulltulas# reveals", /*french*/ "détruire #20 Skulltulas d'or# donne", - /*spanish*/ "exterminar #20 skulltulas doradas# revela" }); - - hintTable[KAK_ANJU_AS_CHILD] = HintText::Sometimes( - { - // obscure text - Text{ "#wrangling roosters# rewards", /*french*/ "#plumer des poulets# donne", - /*spanish*/ "#atrapar a las gallinas# premia" }, - Text{ "#chucking chickens# gifts", /*french*/ "#lancer des poulets# donne", - /*spanish*/ "#reunir a unos emplumados# premia" }, - }, - {}, - // clear text - Text{ "#collecting cuccos# rewards", /*french*/ "#rapporter les Cocottes# donne", - /*spanish*/ "#hacerte con todos los cucos# premia" }); - - hintTable[KAK_TRADE_POCKET_CUCCO] = HintText::Sometimes({ - // obscure text - Text{ "an adult's #happy Cucco# awards", /*french*/ "un adulte avec une #poulette joyeuse# obtient", - /*spanish*/ "un #alegre cuco# en la madurez otorga" }, - }); - - hintTable[KAK_TRADE_ODD_MUSHROOM] = HintText::Sometimes({ - // obscure text - Text{ "the #potion shop lady# entrusts", /*french*/ "la #gribiche du magasin de potion# confie", - /*spanish*/ "la #señora de la tienda de pociones# otorga" }, - }); - - hintTable[GC_DARUNIAS_JOY] = HintText::Sometimes( - { - // obscure text - Text{ "a #groovin' goron# gifts", /*french*/ "#le Goron joyeux# donne", - /*spanish*/ "#un goron marchoso# otorga" }, - }, - {}, - // clear text - Text{ "#Darunia's dance# leads to", /*french*/ "#la dance de Darunia# donne", - /*spanish*/ "#el baile de Darunia# conduce a" }); - - hintTable[LW_SKULL_KID] = HintText::Sometimes({ - // obscure text - Text{ "the #Skull Kid# grants", /*french*/ "le #Skull Kid# donne", /*spanish*/ "#Skull Kid# otorga" }, - }); - - hintTable[LW_TRADE_COJIRO] = HintText::Sometimes({ - // obscure text - Text{ "returning a #special Cucco# awards", /*french*/ "ramener une #poulette précieuse# donne", - /*spanish*/ "quien devuelva un #cuco especial# encontrará" }, - }); - - hintTable[LW_TRADE_ODD_POTION] = HintText::Sometimes({ - // obscure text - Text{ "a #Kokiri girl in the woods# leaves", /*french*/ "la #fillette Kokiri dans les bois# laisse", - /*spanish*/ "una #chica kokiri del bosque# otorga" }, - }); - - hintTable[LH_SUN] = HintText::Sometimes( - { - // obscure text - Text{ "staring into #the sun# grants", /*french*/ "regarder #le soleil# donne", - /*spanish*/ "#mirar al sol# revela" }, - }, - {}, - // clear text - Text{ "shooting #the sun# grants", /*french*/ "tirer une flèche dans #sur le soleil# donne", - /*spanish*/ "#disparar al sol# revela" }); - - hintTable[LH_TRADE_FROG] = HintText::Sometimes({ - // obscure text - Text{ "#Lake Hylia's scientist# hurriedly entrusts", /*french*/ "le #scientifique du lac# confie rapidement", - /*spanish*/ "el #científico del Lago Hylia# otorga con prisa" }, - }); - - hintTable[MARKET_TREASURE_CHEST_GAME_REWARD] = HintText::Sometimes( - { - // obscure text - Text{ "#gambling# grants", /*french*/ "#parier# donne", /*spanish*/ "#los juegos de azar# revelan" }, - Text{ "there is a #1/32 chance# to win", /*french*/ "être #le gagnant parmi 32# donne", - /*spanish*/ "hay una #probabilidad de 1/32# de ganar" }, - }, - {}, - // clear text - Text{ "the #treasure chest game# grants", /*french*/ "la #Chasse-aux-Trésors# donne", - /*spanish*/ "#el Cofre del Tesoro# premia" }); - - hintTable[MARKET_TREASURE_CHEST_GAME_ITEM_1] = HintText::Sometimes( - { - // obscure text - Text{ "#gambling once# grants", /*french*/ "#parier une fois# donne", - /*spanish*/ "#apostar solo una vez# revelará" }, - Text{ "the #first or second game chest# contains", - /*french*/ "le #premier ou deuxième coffre à jeu# contient", - /*spanish*/ "#el primer o segundo cofre del azar# revela" }, - }, - {}, - // clear text - Text{ "the #first locked room# in the chest game contains", - /*french*/ "la #première salle# de la Chasse-aux-Trésors contient", - /*spanish*/ "#en la primera sala del Cofre del Tesoro# aguarda" }); - - hintTable[MARKET_TREASURE_CHEST_GAME_ITEM_2] = HintText::Sometimes( - { - // obscure text - Text{ "#gambling twice# grants", /*french*/ "#parier deux fois# donne", - /*spanish*/ "#apostar dos veces# revelará" }, - Text{ "the #third or fourth game chest# contains", - /*french*/ "le #troisième ou quatrième coffre à jeu# contient", - /*spanish*/ "#el tercer o cuarto cofre del azar# revela" }, - }, - {}, - // clear text - Text{ "the #second locked room# in the chest game contains", - /*french*/ "la #deuxième salle# de la Chasse-aux-Trésors contient", - /*spanish*/ "#en la segunda sala del Cofre del Tesoro# aguarda" }); - - hintTable[MARKET_TREASURE_CHEST_GAME_ITEM_3] = HintText::Sometimes( - { - // obscure text - Text{ "#gambling 3 times# grants", /*french*/ "#parier trois fois# donne", - /*spanish*/ "#apostar tres veces# revelará" }, - Text{ "the #fifth or sixth game chest# contains", - /*french*/ "le #cinquième ou sixième coffre à jeu# contient", - /*spanish*/ "#el quinto o sexto cofre del azar# revela" }, - }, - {}, - // clear text - Text{ "the #third locked room# in the chest game contains", - /*french*/ "la #troisième salle# de la Chasse-aux-Trésors contient", - /*spanish*/ "#en la tercera sala del Cofre del Tesoro# aguarda" }); - - hintTable[MARKET_TREASURE_CHEST_GAME_ITEM_4] = HintText::Sometimes( - { - // obscure text - Text{ "#gambling 4 times# grants", /*french*/ "#parier quatre fois# donne", - /*spanish*/ "#apostar cuatro veces# revelará" }, - Text{ "the #seventh or eighth game chest# contains", - /*french*/ "le #septième ou huitième coffre à jeu# contient", - /*spanish*/ "#el séptimo u octavo cofre del azar# revela" }, - }, - {}, - // clear text - Text{ "the #fourth locked room# in the chest game contains", - /*french*/ "la #quatrième salle# de la Chasse-aux-Trésors contient", - /*spanish*/ "#en la cuarta sala del Cofre del Tesoro# aguarda" }); - - hintTable[MARKET_TREASURE_CHEST_GAME_ITEM_5] = HintText::Sometimes( - { - // obscure text - Text{ "#gambling 5 times# grants", /*french*/ "#parier cinq fois# donne", - /*spanish*/ "#apostar cinco veces# revelará" }, - Text{ "the #ninth or tenth game chest# contains", - /*french*/ "le #neuvième ou dixième coffre à jeu# contient", - /*spanish*/ "#el noveno o décimo cofre del azar# revela" }, - }, - {}, - // clear text - Text{ "the #fifth locked room# in the chest game contains", - /*french*/ "la #cinquième salle# de la Chasse-aux-Trésors contient", - /*spanish*/ "#en la quinta sala del Cofre del Tesoro# aguarda" }); - - hintTable[GF_HBA_1500_POINTS] = HintText::Sometimes( - { - // obscure text - Text{ "mastery of #horseback archery# grants", /*french*/ "maîtriser l'#archerie équestre# donne", - /*spanish*/ "dominar el #tiro con arco a caballo# premia con" }, - }, - {}, - // clear text - Text{ "scoring 1500 in #horseback archery# grants", - /*french*/ "obtenir 1500 points dans l'#archerie équestre# donne", - /*spanish*/ "conseguir 1500 puntos en el #tiro con arco a caballo# premia" }); - - hintTable[GRAVEYARD_HEART_PIECE_GRAVE_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "playing #Sun's Song# in a grave spawns", /*french*/ "jouer le #chant du soleil# dans un tombeau donne", - /*spanish*/ "#tocar la Canción del Sol# en una cripta conduce a" }, - }); - - hintTable[GC_MAZE_LEFT_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "in #Goron City# the hammer unlocks", /*french*/ "dans le #village Goron#, le marteau donne accès à", - /*spanish*/ "en la #Ciudad Goron# el martillo desbloquea" }, - }); - - hintTable[GV_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "in #Gerudo Valley# the hammer unlocks", /*french*/ "dans la #Vallée Gerudo#, le marteau donne accès à", - /*spanish*/ "en el #Valle Gerudo# el martillo desbloquea" }, - }); - - hintTable[GV_TRADE_SAW] = HintText::Sometimes({ - // obscure text - Text{ "the #boss of the carpenters# leaves", /*french*/ "le #patron des ouvriers# laisse", - /*spanish*/ "el #capataz de los carpinteros# otorga" }, - }); - - hintTable[GV_COW] = HintText::Sometimes({ - // obscure text - Text{ "a #cow in Gerudo Valley# gifts", /*french*/ "la #vache de la Vallée Gerudo# donne", - /*spanish*/ "una #vaca del Valle Gerudo# brinda" }, - }); - - hintTable[HC_GS_STORMS_GROTTO] = HintText::Sometimes({ - // obscure text - Text{ "a #spider behind a muddy wall# in a grotto holds", - /*french*/ "l'#araignée derrière un mur de boue# dans une grotte donne", - /*spanish*/ "una #Skulltula tras la agrietada pared# de una cueva otorga" }, - }); - - hintTable[HF_GS_COW_GROTTO] = HintText::Sometimes({ - // obscure text - Text{ "a #spider behind webs# in a grotto holds", - /*french*/ "l'#araignée derrière une toile# dans une grotte donne", - /*spanish*/ "una #Skulltula tras la telaraña# de una cueva otorga" }, - }); - - hintTable[HF_COW_GROTTO_COW] = HintText::Sometimes( - { - // obscure text - Text{ "the #cobwebbed cow# gifts", /*french*/ "la #vache prisonnière d'araignées# donne", - /*spanish*/ "una #vaca tras una telaraña# brinda" }, - }, - {}, - // clear text - Text{ "a #cow behind webs# in a grotto gifts", /*french*/ "la #vache derrière les toiles# d'une grotte donne", - /*spanish*/ "una #vaca tras la telaraña# de una cueva brinda" }); - - hintTable[ZF_GS_HIDDEN_CAVE] = HintText::Sometimes({ - // obscure text - Text{ "a spider high #above the icy waters# holds", /*french*/ "l'araignée #en haut des eaux glacées# donne", - /*spanish*/ "una Skulltula en lo #alto de las congeladas aguas# otorga" }, - }); - - hintTable[WASTELAND_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "#deep in the wasteland# is", /*french*/ "#loin dans le désert# gît", - /*spanish*/ "en lo #profundo del desierto encantado# yace" }, - Text{ "beneath #the sands#, flames reveal", /*french*/ "#sous le désert#, les flammes font apparaître", - /*spanish*/ "tras las #arenas# unas llamas revelan" }, - }); - - hintTable[WASTELAND_GS] = HintText::Sometimes({ - // obscure text - Text{ "a #spider in the wasteland# holds", /*french*/ "#l'araignée dans le désert# donne", - /*spanish*/ "una #Skulltula del desierto encantado# otorga" }, - }); - - hintTable[GRAVEYARD_COMPOSERS_GRAVE_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "#flames in the Composers' Grave# reveal", - /*french*/ "#les flammes dans le tombeau des compositeurs# cachent", - /*spanish*/ "#las llamas del Panteón Real# revelan" }, - Text{ "the #Composer Brothers hid#", /*french*/ "#les Frères compositeurs on caché#", - /*spanish*/ "los #hermanos compositores esconden#" }, - }); - - hintTable[ZF_BOTTOM_FREESTANDING_POH] = HintText::Sometimes({ - // obscure text - Text{ "#under the icy waters# lies", /*french*/ "#sous les eaux glacées# se cache", - /*spanish*/ "#bajo las congeladas aguas# yace" }, - }); - - hintTable[GC_POT_FREESTANDING_POH] = HintText::Sometimes({ - // obscure text - Text{ "spinning #Goron pottery# contains", /*french*/ "la #potterie Goron# contient", - /*spanish*/ "una #cerámica goron# contiene" }, - }); - - hintTable[ZD_KING_ZORA_THAWED] = HintText::Sometimes( - { - // obscure text - Text{ "a #defrosted dignitary# gifts", /*french*/ "le #monarque libéré# donne", - /*spanish*/ "una #liberación monárquica# brinda" }, - }, - {}, - // clear text - Text{ "unfreezing #King Zora# grants", /*french*/ "dégeler # le Roi Zora# donne", - /*spanish*/ "#descongelar al Rey Zora# conduce a" }); - - hintTable[ZD_TRADE_PRESCRIPTION] = HintText::Sometimes({ - // obscure text - Text{ "#King Zora# hurriedly entrusts", /*french*/ "le #roi Zora# confie rapidement", - /*spanish*/ "el #Rey Zora# otorga con prisa" }, - }); - - hintTable[DMC_DEKU_SCRUB] = HintText::Sometimes({ - // obscure text - Text{ "a single #scrub in the crater# sells", /*french*/ "la #peste Mojo dans le cratère# vend", - /*spanish*/ "un solitario #deku del cráter# vende" }, - }); - - hintTable[DMC_GS_CRATE] = HintText::Sometimes({ - // obscure text - Text{ "a spider under a #crate in the crater# holds", /*french*/ "la Skulltula dans une #boîte volcanique# a", - /*spanish*/ "una Skulltula bajo una #caja del cráter# otorga" }, - }); - - hintTable[DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "a #temporal stone within a tree# contains", /*french*/ "la #pierre bleue dans un arbre# mène à", - /*spanish*/ "un #bloque temporal de un árbol# contiene" }, - }, - {}, - // clear text - Text{ "a #temporal stone within the Deku Tree# contains", - /*french*/ "la #pierre temporelle dans l'Arbre Mojo# cache", - /*spanish*/ "un #bloque temporal del Gran Árbol Deku# contiene" }); - - hintTable[DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM] = HintText::Sometimes( - { - // obscure text - Text{ "a #spider on a ceiling in a tree# holds", /*french*/ "l'#araignée haut-perchée dans un arbre# a", - /*spanish*/ "una #Skulltula en el techo de un árbol# otorga" }, - }, - {}, - // clear text - Text{ "a #spider on a ceiling in the Deku Tree# holds", - /*french*/ "la#Skulltula dans le Cimetière de l'Arbre Mojo# a", - /*spanish*/ "una #Skulltula en el techo del Gran Árbol Deku# otorga" }); - - hintTable[DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM] = HintText::Sometimes( - { - // obscure text - Text{ "a spider under #temporal stones in a cavern# holds", - /*french*/ "l'araignée sous #une pierre bleue dans une caverne# a", - /*spanish*/ "una Skulltula bajo #bloques temporales de una cueva# otorga" }, - }, - {}, - // clear text - Text{ "a spider under #temporal stones in Dodongo's Cavern# holds", - /*french*/ "la Skulltula sous #la pierre temporelle dans la Caverne Dodongo# a", - /*spanish*/ "una Skulltula bajo #bloques temporales de la Cueva de los Dodongos# otorga" }); - - hintTable[JABU_JABUS_BELLY_BOOMERANG_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "a school of #stingers swallowed by a deity# guard", - /*french*/ "les #raies dans un gardien# protègent", - /*spanish*/ "unos de #stingers engullidos por cierta deidad# guardan" }, - }, - {}, - // clear text - Text{ "a school of #stingers swallowed by Jabu-Jabu# guard", /*french*/ "les #raies dans Jabu-Jabu# protègent", - /*spanish*/ "unos #stingers engullidos por Jabu-Jabu# guardan" }); - - hintTable[JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM] = HintText::Sometimes( - { - // obscure text - Text{ "a spider surrounded by #shadows in the belly of a deity# holds", - /*french*/ "l'araignée entourée d'#ombres dans le ventre du gardien# possède", - /*spanish*/ "una Skulltula rodeada de #sombras en la tripa de cierta diedad# otorga" }, - }, - {}, - // clear text - Text{ "a spider surrounded by #shadows in Jabu-Jabu's Belly# holds", - /*french*/ "la Skulltula entourée d'#ombres dans Jabu-Jabu# possède", - /*spanish*/ "una Skulltula rodeada de #sombras en la Tripa de Jabu-Jabu# otorga" }); - - hintTable[JABU_JABUS_BELLY_MQ_COW] = HintText::Sometimes( - { - // obscure text - Text{ "a #cow swallowed by a deity# gifts", /*french*/ "la #vache dans le gardien# donne", - /*spanish*/ "una #vaca engullida por cierta deidad# brinda" }, - }, - {}, - // clear text - Text{ "a #cow swallowed by Jabu-Jabu# gifts", /*french*/ "la #vache avallée par Jabu-Jabu# donne", - /*spanish*/ "una #vaca engullida por Jabu-Jabu# brinda" }); - - hintTable[FIRE_TEMPLE_SCARECROW_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "a #scarecrow atop the volcano# hides", /*french*/ "l'#épouvantail au sommet d'un volcan# donne", - /*spanish*/ "un #espantapájaros en lo alto del volcán# esconde" }, - }, - {}, - // clear text - Text{ "#Pierre atop the Fire Temple# hides", /*french*/ "#Pierre au sommet du Temple du Feu# donne", - /*spanish*/ "#Pierre en lo alto del Templo del Fuego# esconde" }); - - hintTable[FIRE_TEMPLE_MEGATON_HAMMER_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "the #Flare Dancer atop the volcano# guards a chest containing", - /*french*/ "le #danseur au sommet du volcan# protège", - /*spanish*/ "el #Bailafuego en lo alto del volcán# otorga" }, - }, - {}, - // clear text - Text{ "the #Flare Dancer atop the Fire Temple# guards a chest containing", - /*french*/ "le #Danse-Flamme au sommet du Temple du Feu# protège", - /*spanish*/ "el #Bailaguego en lo alto del Templo del Fuego# otorga" }); - - hintTable[FIRE_TEMPLE_MQ_CHEST_ON_FIRE] = HintText::Sometimes( - { - // obscure text - Text{ "the #Flare Dancer atop the volcano# guards a chest containing", - /*french*/ "le #danseur au sommet du volcan# protège", - /*spanish*/ "el #Bailafuego en lo alto del volcán# otorga" }, - }, - {}, - // clear text - Text{ "the #Flare Dancer atop the Fire Temple# guards a chest containing", - /*french*/ "le #Danse-Flamme au sommet du Temple du Feu# protège", - /*spanish*/ "el #Bailafuego en lo alto del Templo del Fuego# otorga" }); - - hintTable[FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE] = HintText::Sometimes( - { - // obscure text - Text{ "a #spider under a block in the volcano# holds", - /*french*/ "l'#araignée sous un bloc dans le volcan# a", - /*spanish*/ "una #Skulltula bajo el bloque de un volcán# otorga" }, - }, - {}, - // clear text - Text{ "a #spider under a block in the Fire Temple# holds", - /*french*/ "une #Skulltula sous un bloc dans le Temple du Feu# a", - /*spanish*/ "una #Skulltula bajo un bloque del Templo del Fuego# otorga" }); - - hintTable[WATER_TEMPLE_RIVER_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "beyond the #river under the lake# waits", /*french*/ "au delà de #la rivière sous le lac# se cache", - /*spanish*/ "tras el #río bajo el lago# yace" }, - }, - {}, - // clear text - Text{ "beyond the #river in the Water Temple# waits", - /*french*/ "au delà de #la rivière dans le Temple de l'Eau# se cache", - /*spanish*/ "tras el #río del Templo del Agua# yace" }); - - hintTable[WATER_TEMPLE_BOSS_KEY_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "dodging #rolling boulders under the lake# leads to", - /*french*/ "éviter des #rochers roulants sous le lac# mène à", - /*spanish*/ "esquivar #rocas rodantes bajo el lago# conduce a" }, - }, - {}, - // clear text - Text{ "dodging #rolling boulders in the Water Temple# leads to", - /*french*/ "éviter des #rochers roulants dans le Temple de l'Eau# mène à", - /*spanish*/ "esquivar #rocas rondantes del Templo del Agua# conduce a" }); - - hintTable[WATER_TEMPLE_GS_BEHIND_GATE] = HintText::Sometimes( - { - // obscure text - Text{ "a spider behind a #gate under the lake# holds", - /*french*/ "l'araignée derrière une #barrière sous le lac# a", - /*spanish*/ "una Skulltula tras #una valla bajo el lago# otorga" }, - }, - {}, - // clear text - Text{ "a spider behind a #gate in the Water Temple# holds", - /*french*/ "la Skulltula derrière une #barrière dans le Temple de l'Eau# a", - /*spanish*/ "una Skulltula tras #una valla del Templo del Agua# otorga" }); - - hintTable[WATER_TEMPLE_MQ_FREESTANDING_KEY] = HintText::Sometimes( - { - // obscure text - Text{ "hidden in a #box under the lake# lies", /*french*/ "dans une #boîte sous le lac# gît", - /*spanish*/ "en una #caja bajo el lago# yace" }, - }, - {}, - // clear text - Text{ "hidden in a #box in the Water Temple# lies", /*french*/ "dans une #boîte dans le Temple de l'Eau# gît", - /*spanish*/ "en una #caja del Templo del Agua# yace" }); - - hintTable[WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA] = HintText::Sometimes( - { - // obscure text - Text{ "the #locked spider under the lake# holds", /*french*/ "l'#araignée emprisonnée sous le lac# a", - /*spanish*/ "la #Skulltula enjaulada bajo el lago# otorga" }, - }, - {}, - // clear text - Text{ "the #locked spider in the Water Temple# holds", - /*french*/ "une #Skulltula emprisonnée dans le Temple de l'Eau# a", - /*spanish*/ "la #Skulltula enjaulada del Templo del Agua# otorga" }); - - hintTable[WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH] = HintText::Sometimes( - { - // obscure text - Text{ "a spider behind a #gate under the lake# holds", - /*french*/ "l'#araignée derrière une barrière sous le lac# a", - /*spanish*/ "una Skulltula tras una #valla bajo el lago# otorga" }, - }, - {}, - // clear text - Text{ "a spider behind a #gate in the Water Temple# holds", - /*french*/ "une #Skulltula derrière une barrière dans le Temple de l'Eau# a", - /*spanish*/ "una Skulltula tras una #valla del Templo del Agua#" }); - - hintTable[GERUDO_TRAINING_GROUNDS_UNDERWATER_SILVER_RUPEE_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "those who seek #sunken silver rupees# will find", - /*french*/ "ceux qui pêchent les #joyaux argentés# trouveront", - /*spanish*/ "aquellos que busquen las #rupias plateadas sumergidas# encontrarán" }, - Text{ "the #thieves' underwater training# rewards", /*french*/ "l'#épreuve de plongée des voleurs# recèle", - /*spanish*/ "la #instrucción submarina de las bandidas# premia" }, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER_SILVER_RUPEE_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "those who seek #sunken silver rupees# will find", - /*french*/ "ceux qui pêchent les #joyaux argentés# trouveront", - /*spanish*/ "aquellos que busquen las #rupias plateadas sumergidas# encontrarán" }, - Text{ "the #thieves' underwater training# rewards", /*french*/ "l'#épreuve de plongée des voleurs# recèle", - /*spanish*/ "la #instrucción submarina de las bandidas# premia" }, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MAZE_PATH_FINAL_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "the final prize of #the thieves' training# is", - /*french*/ "la récompense ultime de #l'épreuve des voleurs# est", - /*spanish*/ "la recompensa final de la #instrucción de las bandida# brinda" }, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_ICE_ARROWS_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "the final prize of #the thieves' training# is", - /*french*/ "la récompense ultime de #l'épreuve des voleurs# est", - /*spanish*/ "el premio final de la #instrucción de las bandidas# brinda" }, - }); - - hintTable[BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "the well's #grasping ghoul# hides", /*french*/ "la #terreur du Puits# cache", - /*spanish*/ "en las #profundidades del pozo# se esconde" }, - Text{ "a #nether dweller in the well# holds", /*french*/ "le #spectre qui réside dans le Puits# a", - /*spanish*/ "el #temido morador del pozo# concede" }, - }, - {}, - // clear text - Text{ "#Dead Hand in the well# holds", /*french*/ "le #Poigneur dans le Puits# cache", - /*spanish*/ "la #Mano Muerta del pozo# concede" }); - - hintTable[BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "the well's #grasping ghoul# hides", /*french*/ "la #terreur du Puits# cache", - /*spanish*/ "en las #profundidades del pozo# se esconde" }, - Text{ "a #nether dweller in the well# holds", /*french*/ "le #spectre qui réside dans le Puits# a", - /*spanish*/ "el #temido morador del pozo# concede" }, - }, - {}, - // clear text - Text{ "#Dead Hand in the well# holds", /*french*/ "le #Poigneur dans le Puits# cache", - /*spanish*/ "la #Mano Muerta del pozo# concede" }); - - hintTable[SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "the treasure #sought by Nabooru# is", /*french*/ "le trésor que #recherche Nabooru# est", - /*spanish*/ "el #ansiado tesoro de Nabooru# brinda" }, - }, - {}, - // clear text - Text{ "upon the #Colossus's right hand# is", /*french*/ "sur la #main droite du colosse# repose", - /*spanish*/ "en la #mano derecha del Coloso# yace" }); - - hintTable[SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "upon the #Colossus's left hand# is", /*french*/ "sur la #main gauche du colosse# repose", - /*spanish*/ "en la #mano izquierda del Coloso# yace" }, - }); - - hintTable[SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "a #temporal paradox in the Colossus# yields", - /*french*/ "un #paradoxe temporel dans le colosse# révèle", - /*spanish*/ "una #paradoja temporal del Coloso# conduce a" }, - }, - {}, - // clear text - Text{ "a #temporal paradox in the Spirit Temple# yields", - /*french*/ "le #paradoxe temporel dans le Temple de l'Esprit# révèle", - /*spanish*/ "una #paradoja temporal del Coloso# conduce a" }); - - hintTable[SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST] = HintText::Sometimes( - { - // obscure text - Text{ "a #symphony in the Colossus# yields", /*french*/ "la #symphonie du colosse# révèle", - /*spanish*/ "una #sinfonía del Coloso# conduce a" }, - }, - {}, - // clear text - Text{ "a #symphony in the Spirit Temple# yields", - /*french*/ "les #cinq chansons du Temple de l'Esprit# révèlent", - /*spanish*/ "una #sinfonía del Coloso# conduce a" }); - - hintTable[SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM] = HintText::Sometimes( - { - // obscure text - Text{ "a #spider's symphony in the Colossus# yields", - /*french*/ "la #mélodie de l'araignée du colosse# révèle", - /*spanish*/ "la #Skulltula de la sinfonía del Coloso# otorga" }, - }, - {}, - // clear text - Text{ "a #spider's symphony in the Spirit Temple# yields", - /*french*/ "la #mélodie de la Skulltula du Temple de l'Esprit# révèle", - /*spanish*/ "la #Skulltula de la sinfonía del Coloso# otorga" }); - - hintTable[SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "shadows in an #invisible maze# guard", /*french*/ "les ombres dans le #labyrinthe invisible# protègent", - /*spanish*/ "las sombras del #laberinto misterioso# esconden" }, - }); - - hintTable[SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST] = HintText::Sometimes({ - // obscure text - Text{ "shadows in an #invisible maze# guard", /*french*/ "les ombres dans le #labyrinthe invisible# protègent", - /*spanish*/ "las sombras del #laberinto invisible# esconden" }, - }); + hintTextTable[RHT_KF_LINKS_HOUSE_COW] = HintText(CustomMessage("They say that #Malon's obstacle course# leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Malons Hinderniskurs# zu #[[1]]# führe.", + /*french*/ "Selon moi, la #course à obstacle de Malon# amène à #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/la #carrera de obstáculos de Malon# brinda #[[1]]#. + {}, + {CustomMessage("They say that the #bovine bounty of a horseback hustle# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #bovine Schatz einer Pferdehast# #[[1]]# sei.", + /*french*/ "Selon moi, le cadeau #qui découle d'une réussite équestre# est #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/la #recompensa bovina de un paseo a caballo# brinda #[[1]]#. + + hintTextTable[RHT_KAK_100_GOLD_SKULLTULA_REWARD] = HintText(CustomMessage("They say that slaying #100 Gold Skulltulas# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Vernichten von #100 Goldenen Skulltulas# #[[1]]# enthülle.", + /*french*/ "Selon moi, détruire #100 Skulltulas d'or# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/exterminar #100 skulltulas doradas# revela #[[1]]#. + {}, + {CustomMessage("They say that #100 bug badges# rewards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #100 Insektenplaketten# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #100 écussons# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#100 medallas de insectos# otorgan #[[1]]#. + CustomMessage("They say that #100 spider souls# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß #100 Spinnenseelen# #[[1]]# einbrächte.", + /*french*/ "Selon moi, #100 âmes d'arachnide# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#100 almas de araña# otorgan #[[1]]#. + CustomMessage("They say that #100 auriferous arachnids# lead to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #100 goldhaltige Arachniden# zu #[[1]]# führen würde.", + /*french*/ "Selon moi, #100 arachnides aurifères# donnent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#100 arácnidos auríferos# otorgan #[[1]]#. + + hintTextTable[RHT_SONG_FROM_OCARINA_OF_TIME] = HintText(CustomMessage("They say that the #Ocarina of Time# teaches #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Okarina der Zeit# #[[1]]# lehre.", + /*french*/ "Selon moi, l'#Ocarina du Temps# est accompagné par #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/la #Ocarina del Tiempo# enseña #[[1]]#. + + hintTextTable[RHT_SONG_FROM_ROYAL_FAMILYS_TOMB] = HintText(CustomMessage("They say that #ReDead in the Composers' Grave# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Zombies im Grab des Komponisten# #[[1]]# bewache.", + /*french*/ "Selon moi, les #Éffrois du tombeau des compositeurs# protègent #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/los #ReDeads del Panteón Real# guardan #[[1]]#. + + hintTextTable[RHT_SHEIK_IN_FOREST] = HintText(CustomMessage("They say that #in a meadow# Sheik teaches #[[1]]#.", + /*german*/ "Man erzählt sich, daß Shiek #auf einer Wiese# #[[1]]# lehre.", + /*french*/ "Selon moi, Sheik confiera, #dans un bosquet#, #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/#en la pradera sagrada# Sheik enseña #[[1]]#. + + hintTextTable[RHT_SHEIK_AT_TEMPLE] = HintText(CustomMessage("They say that Sheik waits at a #monument to time# to teach #[[1]]#.", + /*german*/ "Man erzählt sich, daß Shiek auf einem #Monument der Zeit# warte und #[[1]]# lehre.", + /*french*/ "Selon moi, Sheik confiera, #au pied de l'épée légendaire#, #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/Sheik espera en el #momumento del tiempo# para enseñar #[[1]]#. + + hintTextTable[RHT_SHEIK_IN_CRATER] = HintText(CustomMessage("They say that the #crater's melody# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Melodie eines Kraters# #[[1]]# sei.", + /*french*/ "Selon moi, Sheik confiera, #entouré de lave#, #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/la #melodía del cráter# otorga #[[1]]#. + + hintTextTable[RHT_SHEIK_IN_ICE_CAVERN] = HintText(CustomMessage("They say that the #frozen cavern# echoes with #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #gefrorene Kaverne# mit #[[1]]# echoe.", + /*french*/ "Selon moi, Sheik confiera, #dans une caverne enneigée#, #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/en la #caverna de hielo# retumban los ecos de #[[1]]#. + + hintTextTable[RHT_SHEIK_IN_KAKARIKO] = HintText(CustomMessage("They say that a #ravaged village# mourns with #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #verwüstetes Dorf# mit #[[1]]# trauere.", + /*french*/ "Selon moi, Sheik confirera, #au coeur d'un village ravagé#, #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/un #arrasado pueblo# llora #[[1]]#. + + hintTextTable[RHT_SHEIK_AT_COLOSSUS] = HintText(CustomMessage("They say that a hero ventures #beyond the wasteland# to learn #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein Held sich #jenseits des Ödlands# wage und #[[1]]# lerne.", + /*french*/ "Selon moi, Sheik confiera, #au bout d'un chemin sableux#, #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/el héroe que se adentre #más allá del desierto# aprenderá #[[1]]#. + + hintTextTable[RHT_MARKET_10_BIG_POES] = HintText(CustomMessage("They say that catching #Big Poes# leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Fangen #großer Irrlichter# zu #[[1]]# führe.", + /*french*/ "Selon moi, #d'attraper des Àmes# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/hacerte con #Grandes Poes# conduce a #[[1]]#. + {}, + {CustomMessage("They say that #ghost hunters# will be rewarded with #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Geisterjäger# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #les chasseurs de fantômes# sont récompensés avec #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/los #cazafantasmas# son premiados con #[[1]]#. + + hintTextTable[RHT_DEKU_THEATER_SKULL_MASK] = HintText(CustomMessage("They say that the #Skull Mask# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Schädel-Maske# #[[1]]# einbrächte.", + /*french*/ "Selon moi, le #Masque de Mort# donne #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/la #máscara de calavera# otorga #[[1]]#. + + hintTextTable[RHT_DEKU_THEATER_MASK_OF_TRUTH] = HintText(CustomMessage("They say that the #Mask of Truth# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Maske der Wahrheit# #[[1]]# einbrächte.", + /*french*/ "Selon moi, le #Masque de Vérité# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/la #máscara de la verdad# premia #[[1]]#. + {}, + {CustomMessage("They say that showing a #truthful eye to the crowd# rewards #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Zeigen eines #wahrhaftigen Auges zu der Menge# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, montrer #l'oeil de vérité à la foule# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#mostrarle el ojo verdadero# a una multitud brinda #[[1]]#. + + hintTextTable[RHT_HF_OCARINA_OF_TIME_ITEM] = HintText(CustomMessage("They say that the #treasure thrown by Princess Zelda# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #von Prinzessin Zelda geworfene Schatz# #[[1]]# sei.", + /*french*/ "Selon moi, le trésor #laissé par la princesse# est #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/el #tesoro arrojado por la Princesa Zelda# se trata de #[[1]]#. + + hintTextTable[RHT_DMT_TRADE_BROKEN_SWORD] = HintText(CustomMessage("They say that a #blinded Biggoron# entrusts #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #erblindeter Biggoron# #[[1]]# anvertraue.", + /*french*/ "Selon moi, They say that un #Grogoron aveuglé# confie #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/un #miope Biggoron# otorga #[[1]]#. + + hintTextTable[RHT_DMT_TRADE_EYEDROPS] = HintText(CustomMessage("They say that while you wait, #Biggoron# gives #[[1]]#.", + /*german*/ "Man erzählt sich, daß während man warte, #Biggoron# #[[1]]# gäbe.", + /*french*/ "Selon moi, pendant que tu attends, #Biggoron# donne #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/#Biggoron# está a la espera de otorgar #[[1]]#. + + hintTextTable[RHT_DMT_TRADE_CLAIM_CHECK] = HintText(CustomMessage("They say that #Biggoron# crafts #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Biggoron# #[[1]]# fertige.", + /*french*/ "Selon moi, #Biggoron# fabrique #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/#Biggoron# forja #[[1]]#. + + hintTextTable[RHT_KAK_50_GOLD_SKULLTULA_REWARD] = HintText(CustomMessage("They say that slaying #50 Gold Skulltulas# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Vernichten von #50 Goldenen Skulltulas# #[[1]]# enthülle.", + /*french*/ "Selon moi, détruire #50 Skulltulas d'or# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/exterminar #50 skulltulas doradas# revela #[[1]]#. + {}, + {CustomMessage("They say that #50 bug badges# rewards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #50 Insektenplaketten# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #50 écussons# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#50 medallas de insectos# otorgan #[[1]]#. + CustomMessage("They say that #50 spider souls# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß #50 Spinnenseelen# #[[1]]# einbrächte.", + /*french*/ "Selon moi, #50 âmes d'arachnide# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#50 almas de araña# otorgan #[[1]]#. + CustomMessage("They say that #50 auriferous arachnids# lead to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #50 goldhaltige Arachniden# zu #[[1]]# führen würde.", + /*french*/ "Selon moi, #50 arachnides aurifères# donnent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#50 arácnidos auríferos# otorgan #[[1]]#. + + hintTextTable[RHT_KAK_40_GOLD_SKULLTULA_REWARD] = HintText(CustomMessage("They say that slaying #40 Gold Skulltulas# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Vernichten von #40 Goldenen Skulltulas# #[[1]]# enthülle.", + /*french*/ "Selon moi, détruire #40 Skulltulas d'or# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/exterminar #40 skulltulas doradas# revela #[[1]]#. + {}, + {CustomMessage("They say that #40 bug badges# rewards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #40 Insektenplaketten# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #40 écussons# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#40 medallas de insectos# otorgan #[[1]]#. + CustomMessage("They say that #40 spider souls# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß #40 Spinnenseelen# #[[1]]# einbrächte.", + /*french*/ "Selon moi, #40 âmes d'arachnide# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#40 almas de araña# otorgan #[[1]]#. + CustomMessage("They say that #40 auriferous arachnids# lead to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #40 goldhaltige Arachniden# zu #[[1]]# führen würde.", + /*french*/ "Selon moi, #40 arachnides aurifères# donnent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#40 arácnidos auríferos# otorgan #[[1]]#. + + hintTextTable[RHT_KAK_30_GOLD_SKULLTULA_REWARD] = HintText(CustomMessage("They say that slaying #30 Gold Skulltulas# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Vernichten von #30 Goldenen Skulltulas# #[[1]]# enthülle.", + /*french*/ "Selon moi, détruire #30 Skulltulas d'or# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/exterminar #30 skulltulas doradas# revela #[[1]]#. + {}, + {CustomMessage("They say that #30 bug badges# rewards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #30 Insektenplaketten# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #30 écussons# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#30 medallas de insectos# otorgan #[[1]]#. + CustomMessage("They say that #30 spider souls# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß #30 Spinnenseelen# #[[1]]# einbrächte.", + /*french*/ "Selon moi, #30 âmes d'arachnide# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#30 almas de araña# otorgan #[[1]]#. + CustomMessage("They say that #30 auriferous arachnids# lead to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #30 goldhaltige Arachniden# zu #[[1]]# führen würde.", + /*french*/ "Selon moi, #30 arachnides aurifères# donnent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#30 arácnidos auríferos# otorgan #[[1]]#. + + hintTextTable[RHT_KAK_20_GOLD_SKULLTULA_REWARD] = HintText(CustomMessage("They say that slaying #20 Gold Skulltulas# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Vernichten von #20 Goldenen Skulltulas# #[[1]]# enthülle.", + /*french*/ "Selon moi, détruire #20 Skulltulas d'or# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/exterminar #20 skulltulas doradas# revela #[[1]]#. + {}, + {CustomMessage("They say that #20 bug badges# rewards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #20 Insektenplaketten# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #20 écussons# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#20 medallas de insectos# otorgan #[[1]]#. + CustomMessage("They say that #20 spider souls# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß #20 Spinnenseelen# #[[1]]# einbrächte.", + /*french*/ "Selon moi, #20 âmes d'arachnide# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#20 almas de araña# otorgan #[[1]]#. + CustomMessage("They say that #20 auriferous arachnids# lead to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #20 goldhaltige Arachniden# zu #[[1]]# führen würde.", + /*french*/ "Selon moi, #20 arachnides aurifères# donnent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#20 arácnidos auríferos# otorgan #[[1]]#. + + hintTextTable[RHT_KAK_ANJU_AS_CHILD] = HintText(CustomMessage("They say that #collecting cuccos# rewards #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Sammeln von Hühnern# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #rapporter les Cocottes# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#hacerte con todos los cucos# premia #[[1]]#. + {}, + {CustomMessage("They say that #wrangling roosters# rewards #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Rangeln mit Hähnen# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #plumer des poulets# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#atrapar a las gallinas# premia #[[1]]#. + CustomMessage("They say that #chucking chickens# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Werfen von Hühnchen# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #lancer des poulets# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#reunir a unos emplumados# premia #[[1]]#. + + hintTextTable[RHT_KAK_TRADE_POCKET_CUCCO] = HintText(CustomMessage("They say that an adult's #happy Cucco# awards #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #glückliche Huhn# eines Erwachsenen #[[1]]# verleihe.", + /*french*/ "Selon moi, un adulte avec une #poulette joyeuse# obtient #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/un #alegre cuco# en la madurez otorga #[[1]]#. + + hintTextTable[RHT_KAK_TRADE_ODD_MUSHROOM] = HintText(CustomMessage("They say that the #potion shop lady# entrusts #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Dame des Trankladens# #[[1]]# anvertraue.", + /*french*/ "Selon moi, la #gribiche du magasin de potion# confie #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/la #señora de la tienda de pociones# otorga #[[1]]#. + + hintTextTable[RHT_GC_DARUNIAS_JOY] = HintText(CustomMessage("They say that #Darunia's dance# leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Darunias Tanz# zu #[[1]]# führe.", + /*french*/ "Selon moi, #la dance de Darunia# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#el baile de Darunia# conduce a #[[1]]#. + {}, + {CustomMessage("They say that a #groovin' goron# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #grooviger Gorone# #[[1]]# schenke.", + /*french*/ "Selon moi, #le Goron joyeux# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#un goron marchoso# otorga #[[1]]#. + + hintTextTable[RHT_LW_SKULL_KID] = HintText(CustomMessage("They say that the #Skull Kid# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Horror-Kid# #[[1]]# gewähre.", + /*french*/ "Selon moi, le #Skull Kid# donne #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/#Skull Kid# otorga #[[1]]#. + + hintTextTable[RHT_LW_TRADE_COJIRO] = HintText(CustomMessage("They say that returning a #special Cucco# awards #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Zurückbringen eines #speziellen Huhns# #[[1]]# einbrächte.", + /*french*/ "Selon moi, ramener une #poulette précieuse# donne #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/quien devuelva un #cuco especial# encontrará #[[1]]#. + + hintTextTable[RHT_LW_TRADE_ODD_POTION] = HintText(CustomMessage("They say that a #Kokiri girl in the woods# leaves #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Kokiri-Mädchen in den Wäldern# #[[1]]# überließe.", + /*french*/ "Selon moi, la #fillette Kokiri dans les bois# laisse #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/una #chica kokiri del bosque# otorga #[[1]]#. + + hintTextTable[RHT_LH_SUN] = HintText(CustomMessage("They say that shooting #the sun# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Beschießen #der Sonne# #[[1]]# gewähre.", + /*french*/ "Selon moi, tirer une flèche dans #sur le soleil# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#disparar al sol# revela #[[1]]#. + {}, + {CustomMessage("They say that staring into #the sun# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Starren in #die Sonne# #[[1]]# gewähre.", + /*french*/ "Selon moi, regarder #le soleil# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#mirar al sol# revela #[[1]]#. + + hintTextTable[RHT_LH_TRADE_FROG] = HintText(CustomMessage("They say that #Lake Hylia's scientist# hurriedly entrusts #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Wissenschaftler des Hylia-Sees# #[[1]]# zügig anvertraue.", + /*french*/ "Selon moi, le #scientifique du lac# confie rapidement #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/el #científico del Lago Hylia# otorga con prisa #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_REWARD] = HintText(CustomMessage("They say that the #treasure chest game# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Schatzkisten-Poker# #[[1]]# gewähre.", + /*french*/ "Selon moi, la #Chasse-aux-Trésors# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#el Cofre del Tesoro# premia #[[1]]#. + {}, + {CustomMessage("They say that #gambling# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#los juegos de azar# revelan #[[1]]#. + CustomMessage("They say that there is a #1/32 chance# to win #[[1]]#.", + /*german*/ "Man erzählt sich, daß es eine #Chance von 1 zu 32# gäbe, um #[[1]]# zu gewinnen.", + /*french*/ "Selon moi, être #le gagnant parmi 32# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/hay una #probabilidad de 1/32# de ganar #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1] = HintText(CustomMessage("They say that the #first locked room# in the chest game contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #erste verschlossene Raum# im Schatzkisten-Poker #[[1]]# enthielte.", + /*french*/ "Selon moi, la #première salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#en la primera sala del Cofre del Tesoro# aguarda #[[1]]#. + {}, + {CustomMessage("They say that #gambling once# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #einmaliges Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier une fois# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#apostar solo una vez# revelará #[[1]]#. + CustomMessage("They say that the #first or second game chest# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #erste oder zweite Schatzkiste im Spiel# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #premier ou deuxième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#el primer o segundo cofre del azar# revela #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2] = HintText(CustomMessage("They say that the #second locked room# in the chest game contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #zweite verschlossene Raum# im Schatzkisten-Poker #[[1]]# enthielte.", + /*french*/ "Selon moi, la #deuxième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#en la segunda sala del Cofre del Tesoro# aguarda #[[1]]#. + {}, + {CustomMessage("They say that #gambling twice# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #zweimaliges Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier deux fois# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#apostar dos veces# revelará #[[1]]#. + CustomMessage("They say that the #third or fourth game chest# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #dritte oder vierte Schatzkiste im Spiel# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #troisième ou quatrième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#el tercer o cuarto cofre del azar# revela #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3] = HintText(CustomMessage("They say that the #third locked room# in the chest game contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #dritte verschlossene Raum# im Schatzkisten-Poker #[[1]]# enthielte.", + /*french*/ "Selon moi, la #troisième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#en la tercera sala del Cofre del Tesoro# aguarda #[[1]]#. + {}, + {CustomMessage("They say that #gambling 3 times# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #dreimaliges Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier trois fois# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#apostar tres veces# revelará #[[1]]#. + CustomMessage("They say that the #fifth or sixth game chest# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #fünfte oder sechste Schatzkiste im Spiel# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #cinquième ou sixième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#el quinto o sexto cofre del azar# revela #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4] = HintText(CustomMessage("They say that the #fourth locked room# in the chest game contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #vierte verschlossene Raum# im Schatzkisten-Poker #[[1]]# enthielte.", + /*french*/ "Selon moi, la #quatrième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#en la cuarta sala del Cofre del Tesoro# aguarda #[[1]]#. + {}, + {CustomMessage("They say that #gambling 4 times# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #viermaliges Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier quatre fois# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#apostar cuatro veces# revelará #[[1]]#. + CustomMessage("They say that the #seventh or eighth game chest# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #siebente oder achte Schatzkiste im Spiel# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #septième ou huitième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#el séptimo u octavo cofre del azar# revela #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5] = HintText(CustomMessage("They say that the #fifth locked room# in the chest game contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #fünfte verschlossene Raum# im Schatzkisten-Poker #[[1]]# enthielte.", + /*french*/ "Selon moi, la #cinquième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#en la quinta sala del Cofre del Tesoro# aguarda #[[1]]#. + {}, + {CustomMessage("They say that #gambling 5 times# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #fünfmaliges Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier cinq fois# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#apostar cinco veces# revelará #[[1]]#. + CustomMessage("They say that the #ninth or tenth game chest# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #neunte oder zehnte Schatzkiste im Spiel# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #neuvième ou dixième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#el noveno o décimo cofre del azar# revela #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_1] = HintText(CustomMessage("They say that the #first locked room# in the chest game contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #erste verschlossene Raum# im Schatzkisten-Poker #[[1]]# enthielte.", + /*french*/ "Selon moi, la #première salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#en la primera sala del Cofre del Tesoro# aguarda #[[1]]#. + {}, + {CustomMessage("They say that #gambling once# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #einmaliges Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier une fois# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#apostar solo una vez# revelará #[[1]]#. + CustomMessage("They say that the #first or second game chest# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #erste oder zweite Schatzkiste im Spiel# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #premier ou deuxième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#el primer o segundo cofre del azar# revela #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_2] = HintText(CustomMessage("They say that the #second locked room# in the chest game contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #zweite verschlossene Raum# im Schatzkisten-Poker #[[1]]# enthielte.", + /*french*/ "Selon moi, la #deuxième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#en la segunda sala del Cofre del Tesoro# aguarda #[[1]]#. + {}, + {CustomMessage("They say that #gambling twice# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #zweimaliges Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier deux fois# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#apostar dos veces# revelará #[[1]]#. + CustomMessage("They say that the #third or fourth game chest# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #dritte oder vierte Schatzkiste im Spiel# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #troisième ou quatrième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#el tercer o cuarto cofre del azar# revela #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_3] = HintText(CustomMessage("They say that the #third locked room# in the chest game contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #dritte verschlossene Raum# im Schatzkisten-Poker #[[1]]# enthielte.", + /*french*/ "Selon moi, la #troisième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#en la tercera sala del Cofre del Tesoro# aguarda #[[1]]#. + {}, + {CustomMessage("They say that #gambling 3 times# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #dreimaliges Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier trois fois# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#apostar tres veces# revelará #[[1]]#. + CustomMessage("They say that the #fifth or sixth game chest# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #fünfte oder sechste Schatzkiste im Spiel# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #cinquième ou sixième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#el quinto o sexto cofre del azar# revela #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_4] = HintText(CustomMessage("They say that the #fourth locked room# in the chest game contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #vierte verschlossene Raum# im Schatzkisten-Poker #[[1]]# enthielte.", + /*french*/ "Selon moi, la #quatrième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#en la cuarta sala del Cofre del Tesoro# aguarda #[[1]]#. + {}, + {CustomMessage("They say that #gambling 4 times# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #viermaliges Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier quatre fois# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#apostar cuatro veces# revelará #[[1]]#. + CustomMessage("They say that the #seventh or eighth game chest# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #siebente oder achte Schatzkiste im Spiel# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #septième ou huitième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#el séptimo u octavo cofre del azar# revela #[[1]]#. + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME_KEY_5] = HintText(CustomMessage("They say that the #fifth locked room# in the chest game contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #fünfte verschlossene Raum# im Schatzkisten-Poker #[[1]]# enthielte.", + /*french*/ "Selon moi, la #cinquième salle# de la Chasse-aux-Trésors contient #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#en la quinta sala del Cofre del Tesoro# aguarda #[[1]]#. + {}, + {CustomMessage("They say that #gambling 5 times# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß #fünfmaliges Glücksspiel# #[[1]]# gewähre.", + /*french*/ "Selon moi, #parier cinq fois# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#apostar cinco veces# revelará #[[1]]#. + CustomMessage("They say that the #ninth or tenth game chest# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #neunte oder zehnte Schatzkiste im Spiel# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #neuvième ou dixième coffre à jeu# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/#el noveno o décimo cofre del azar# revela #[[1]]#. + + hintTextTable[RHT_GF_HBA_1500_POINTS] = HintText(CustomMessage("They say that scoring 1500 in #horseback archery# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Erzielen von 1500 Punkten beim #Bogenschießen zu Pferde# #[[1]]# gewähre.", + /*french*/ "Selon moi, obtenir 1500 points dans l'#archerie équestre# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/conseguir 1500 puntos en el #tiro con arco a caballo# premia #[[1]]#. + {}, + {CustomMessage("They say that mastery of #horseback archery# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Meistern des #Bogenschießens zu Pferde# #[[1]]# gewähre.", + /*french*/ "Selon moi, maîtriser l'#archerie équestre# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/dominar el #tiro con arco a caballo# premia con #[[1]]#. + + hintTextTable[RHT_GRAVEYARD_HEART_PIECE_GRAVE_CHEST] = HintText(CustomMessage("They say that playing #Sun's Song# in a grave spawns #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Spielen der #Hymne der Sonne# in einem Grab, #[[1]]# erscheinen ließe.", + /*french*/ "Selon moi, jouer le #chant du soleil# dans un tombeau donne #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/#tocar la Canción del Sol# en una cripta conduce a #[[1]]#. + + hintTextTable[RHT_GC_MAZE_LEFT_CHEST] = HintText(CustomMessage("They say that in #Goron City# the hammer unlocks #[[1]]#.", + /*german*/ "Man erzählt sich, daß der Hammer in #Goronia# #[[1]]# freilege.", + /*french*/ "Selon moi, dans le #village Goron#, le marteau donne accès à #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/en la #Ciudad Goron# el martillo desbloquea #[[1]]#. + + hintTextTable[RHT_GV_CHEST] = HintText(CustomMessage("They say that in #Gerudo Valley# the hammer unlocks #[[1]]#.", + /*german*/ "Man erzählt sich, daß der Hammer im #Gerudotal# #[[1]]# freilege.", + /*french*/ "Selon moi, dans la #Vallée Gerudo#, le marteau donne accès à #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/en el #Valle Gerudo# el martillo desbloquea #[[1]]#. + + hintTextTable[RHT_GV_TRADE_SAW] = HintText(CustomMessage("They say that the #boss of the carpenters# leaves #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Chef der Zimmerleute# #[[1]]# hinterließe.", + /*french*/ "Selon moi, le #patron des ouvriers# laisse #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/el #capataz de los carpinteros# otorga #[[1]]#. + + hintTextTable[RHT_GV_COW] = HintText(CustomMessage("They say that a #cow in Gerudo Valley# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Kuh im Gerudotal# #[[1]]# schenke.", + /*french*/ "Selon moi, la #vache de la Vallée Gerudo# donne #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/una #vaca del Valle Gerudo# brinda #[[1]]#. + + hintTextTable[RHT_HC_GS_STORMS_GROTTO] = HintText(CustomMessage("They say that a #spider behind a muddy wall# in a grotto holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne hinter einer schlammigen Wand# in einer Grotte #[[1]]# hielte.", + /*french*/ "Selon moi, l'#araignée derrière un mur de boue# dans une grotte donne #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/una #Skulltula tras la agrietada pared# de una cueva otorga #[[1]]#. + + hintTextTable[RHT_HF_GS_COW_GROTTO] = HintText(CustomMessage("They say that a #spider behind webs# in a grotto holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne hinter Weben# in einer Grotte #[[1]]# hielte.", + /*french*/ "Selon moi, l'#araignée derrière une toile# dans une grotte donne #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/una #Skulltula tras la telaraña# de una cueva otorga #[[1]]#. + + hintTextTable[RHT_HF_COW_GROTTO_COW] = HintText(CustomMessage("They say that a #cow behind webs# in a grotto gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Kuh hinter Weben# in einer Grotte #[[1]]# hielte.", + /*french*/ "Selon moi, la #vache derrière les toiles# d'une grotte donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una #vaca tras la telaraña# de una cueva brinda #[[1]]#. + {}, + {CustomMessage("They say that the #cobwebbed cow# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #in Spinnweben eingehüllte Kuh# #[[1]]# schenke.", + /*french*/ "Selon moi, la #vache prisonnière d'araignées# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una #vaca tras una telaraña# brinda #[[1]]#. + + hintTextTable[RHT_ZR_FROGS_OCARINA_GAME] = HintText(CustomMessage("They say that the final reward from the #Frogs of Zora's River# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß die letzte Belohnung der #Frösche des Zora-Flußes# #[[1]]# sei.", + /*french*/ "Selon moi, la dernière récompense des #grenouilles de la Rivière Zora# est #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/la recompensa final de las #ranas del Río Zora# premia #[[1]]#. + {}, + {CustomMessage("They say that an #amphibian feast# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #amphibisches Bankett# #[[1]]# einbrächte.", + /*french*/ "Selon moi, un #festin d'amphibiens# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una #fiesta anfibia# brinda #[[1]]#. + CustomMessage("They say that the #croaking choir's magnum opus# awards #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Opus magnum eines quakenden Chors# #[[1]]# verleihe.", + /*french*/ "Selon moi, la #chorale coassante# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/un #coro maestro de ancas# premia #[[1]]#. + CustomMessage("They say that the #froggy finale# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #froschige Finale# #[[1]]# einbrächte.", + /*french*/ "Selon moi, la #finale amphibienne# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/el #gran final batracio# brinda #[[1]]#. + + hintTextTable[RHT_ZF_GS_HIDDEN_CAVE] = HintText(CustomMessage("They say that a spider high #above the icy waters# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne hoch #auf den eisigen Gewässern# #[[1]]# hielte.", + /*french*/ "Selon moi, l'araignée #en haut des eaux glacées# donne #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/una Skulltula en lo #alto de las congeladas aguas# otorga #[[1]]#. + + hintTextTable[RHT_WASTELAND_CHEST] = HintText(CustomMessage("They say that #deep in the wasteland# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #tief im Ödland# #[[1]]# sei.", + /*french*/ "Selon moi, #loin dans le désert# gît #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/en lo #profundo del desierto encantado# yace #[[1]]#. + + hintTextTable[RHT_WASTELAND_GS] = HintText(CustomMessage("They say that a #spider in the wasteland# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne im Ödland# #[[1]]# hielte.", + /*french*/ "Selon moi, #l'araignée dans le désert# donne #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/una #Skulltula del desierto encantado# otorga #[[1]]#. + + hintTextTable[RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST] = HintText(CustomMessage("They say that #flames in the Composers' Grave# reveal #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Flammen im Grab des Komponisten# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, #les flammes dans le tombeau des compositeurs# cachent #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/#las llamas del Panteón Real# revelan #[[1]]#. + + hintTextTable[RHT_ZF_BOTTOM_FREESTANDING_POH] = HintText(CustomMessage("They say that #under the icy waters# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #unter den eisigen Gewässern# #[[1]]# läge.", + /*french*/ "Selon moi, #sous les eaux glacées# se cache #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/#bajo las congeladas aguas# yace #[[1]]#. + + hintTextTable[RHT_GC_POT_FREESTANDING_POH] = HintText(CustomMessage("They say that spinning #Goron pottery# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß die drehende #Goronenkeramik# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #potterie Goron# contient #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/una #cerámica goron# contiene #[[1]]#. + + hintTextTable[RHT_ZD_KING_ZORA_THAWED] = HintText(CustomMessage("They say that unfreezing #King Zora# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Auftauen #König Zoras# #[[1]]# gewähre.", + /*french*/ "Selon moi, dégeler #le Roi Zora# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#descongelar al Rey Zora# conduce a #[[1]]#. + {}, + {CustomMessage("They say that a #defrosted dignitary# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #enteister Würdenträger# #[[1]]# schenke.", + /*french*/ "Selon moi, le #monarque libéré# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una #liberación monárquica# brinda #[[1]]#. + + hintTextTable[RHT_ZD_TRADE_PRESCRIPTION] = HintText(CustomMessage("They say that #King Zora# hurriedly entrusts #[[1]]#.", + /*german*/ "Man erzählt sich, daß #König Zora# #[[1]]# zügig anvertraue.", + /*french*/ "Selon moi, le #roi Zora# confie rapidement #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/el #Rey Zora# otorga con prisa #[[1]]#. + + hintTextTable[RHT_DMC_DEKU_SCRUB] = HintText(CustomMessage("They say that a single #scrub in the crater# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein einzelner #Deku im Krater# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #peste Mojo dans le cratère# vend #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/un solitario #deku del cráter# vende #[[1]]#. + hintTextTable[RHT_DMC_GS_CRATE] = HintText(CustomMessage("They say that a spider under a #crate in the crater# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne unter einer #Kiste im Krater# #[[1]]# hielte.", + /*french*/ "Selon moi, la Skulltula dans une #boîte volcanique# a #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/una Skulltula bajo una #caja del cráter# otorga #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST] = HintText(CustomMessage("They say that a #temporal stone within the Deku Tree# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #zeitlicher Stein innerhalb des Deku-Baums# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #pierre temporelle dans l'Arbre Mojo# cache #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/un #bloque temporal del Gran Árbol Deku# contiene #[[1]]#. + {}, + {CustomMessage("They say that a #temporal stone within a tree# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #zeitlicher Stein innerhalb eines Baums# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #pierre bleue dans un arbre# mène à #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/un #bloque temporal de un árbol# contiene #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM] = HintText(CustomMessage("They say that a #spider on a ceiling in the Deku Tree# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne an einer Decke im Deku-Baum# #[[1]]# hielte.", + /*french*/ "Selon moi, la #Skulltula dans le Cimetière de l'Arbre Mojo# a #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una #Skulltula en el techo del Gran Árbol Deku# otorga #[[1]]#. + {}, + {CustomMessage("They say that a #spider on a ceiling in a tree# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne an einer Decke in einem Baum# #[[1]]# hielte.", + /*french*/ "Selon moi, l'#araignée haut-perchée dans un arbre# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una #Skulltula en el techo de un árbol# otorga #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM] = HintText(CustomMessage("They say that a spider under #temporal stones in Dodongo's Cavern# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne unter #zeitlichen Steinen in Dodongos Höhle# #[[1]]# hielte.", + /*french*/ "Selon moi, la Skulltula sous #la pierre temporelle dans la Caverne Dodongo# a #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una Skulltula bajo #bloques temporales de la Cueva de los Dodongos# otorga #[[1]]#. + {}, + {CustomMessage("They say that a spider under #temporal stones in a cavern# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne unter #zeitlichen Steinen in einer Kaverne# #[[1]]# hielte.", + /*french*/ "Selon moi, l'araignée sous #une pierre bleue dans une caverne# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una Skulltula bajo #bloques temporales de una cueva# otorga #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_BOOMERANG_CHEST] = HintText(CustomMessage("They say that a school of #stingers swallowed by Jabu-Jabu# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #von Jabu-Jabu verschluckter Rochenschwarm# #[[1]]# bewache.", + /*french*/ "Selon moi, les #raies dans Jabu-Jabu# protègent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/unos #stingers engullidos por Jabu-Jabu# guardan #[[1]]#. + {}, + {CustomMessage("They say that a school of #stingers swallowed by a deity# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #von einer Gottheit verschluckter Rochenschwarm# #[[1]]# bewache.", + /*french*/ "Selon moi, les #raies dans un gardien# protègent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/unos de #stingers engullidos por cierta deidad# guardan #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM] = HintText(CustomMessage("They say that a spider surrounded by #shadows in Jabu-Jabu's Belly# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine von #Schatten in Jabu-Jabus Bauch# umgebene Spinne #[[1]]# hielte.", + /*french*/ "Selon moi, la Skulltula entourée d'#ombres dans Jabu-Jabu# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una Skulltula rodeada de #sombras en la Tripa de Jabu-Jabu# otorga #[[1]]#. + {}, + {CustomMessage("They say that a spider surrounded by #shadows in the belly of a deity# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine von #Schatten im Bauch einer Gottheit# umgebene Spinne #[[1]]# hielte.", + /*french*/ "Selon moi, l'araignée entourée d'#ombres dans le ventre du gardien# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una Skulltula rodeada de #sombras en la tripa de cierta diedad# otorga #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_COW] = HintText(CustomMessage("They say that a #cow swallowed by Jabu-Jabu# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von Jabu-Jabu verschluckte Kuh# #[[1]]# schenke.", + /*french*/ "Selon moi, la #vache avallée par Jabu-Jabu# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una #vaca engullida por Jabu-Jabu# brinda #[[1]]#. + {}, + {CustomMessage("They say that a #cow swallowed by a deity# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von einer Gottheit verschluckte Kuh# #[[1]]# schenke.", + /*french*/ "Selon moi, la #vache dans le gardien# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una #vaca engullida por cierta deidad# brinda #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_SCARECROW_CHEST] = HintText(CustomMessage("They say that #Pierre atop the Fire Temple# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Pierre auf der Spitze des Feuertempels# #[[1]]# verstecke.", + /*french*/ "Selon moi, #Pierre au sommet du Temple du Feu# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#Pierre en lo alto del Templo del Fuego# esconde #[[1]]#. + {}, + {CustomMessage("They say that a #scarecrow atop the volcano# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Vogelscheuche auf der Spitze des Vulkans# #[[1]]# verstecke.", + /*french*/ "Selon moi, l'#épouvantail au sommet d'un volcan# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/un #espantapájaros en lo alto del volcán# esconde #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MEGATON_HAMMER_CHEST] = HintText(CustomMessage("They say that the #Flare Dancer atop the Fire Temple# guards a chest containing #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Flammenderwisch auf der Spitze des Feuertempels# eine Truhe bewache, welche #[[1]]# enthielte.", + /*french*/ "Selon moi, le #Danse-Flamme au sommet du Temple du Feu# protège #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/el #Bailaguego en lo alto del Templo del Fuego# otorga #[[1]]#. + {}, + {CustomMessage("They say that the #Flare Dancer atop the volcano# guards a chest containing #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Flammenderwisch auf der Spitze des Vulkans# eine Truhe bewache, welche #[[1]]# enthielte.", + /*french*/ "Selon moi, le #danseur au sommet du volcan# protège #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/el #Bailafuego en lo alto del volcán# otorga #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_CHEST_ON_FIRE] = HintText(CustomMessage("They say that the #Flare Dancer atop the Fire Temple# guards a chest containing #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Flammenderwisch auf der Spitze des Feuertempels# eine Truhe bewache, welche #[[1]]# enthielte.", + /*french*/ "Selon moi, le #Danse-Flamme au sommet du Temple du Feu# protège #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/el #Bailafuego en lo alto del Templo del Fuego# otorga #[[1]]#. + {}, + {CustomMessage("They say that the #Flare Dancer atop the volcano# guards a chest containing #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Flammenderwisch auf der Spitze des Vulkans# eine Truhe bewache, welche #[[1]]# enthielte.", + /*french*/ "Selon moi, le #danseur au sommet du volcan# protège #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/el #Bailafuego en lo alto del volcán# otorga #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE] = HintText(CustomMessage("They say that a #spider under a block in the Fire Temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne unter einem Block im Feuertempel# #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula sous un bloc dans le Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una #Skulltula bajo un bloque del Templo del Fuego# otorga #[[1]]#. + {}, + {CustomMessage("They say that a #spider under a block in the volcano# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne unter einem Block im Vulkan# #[[1]]# hielte.", + /*french*/ "Selon moi, l'#araignée sous un bloc dans le volcan# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una #Skulltula bajo el bloque de un volcán# otorga #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_RIVER_CHEST] = HintText(CustomMessage("They say that beyond the #river in the Water Temple# waits #[[1]]#.", + /*german*/ "Man erzählt sich, daß jenseits des #Flußes im Wassertempel# #[[1]]# warte.", + /*french*/ "Selon moi, au delà de #la rivière dans le Temple de l'Eau# se cache #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/tras el #río del Templo del Agua# yace #[[1]]#. + {}, + {CustomMessage("They say that beyond the #river under the lake# waits #[[1]]#.", + /*german*/ "Man erzählt sich, daß jenseits des #Flußes unter dem See# #[[1]]# warte.", + /*french*/ "Selon moi, au delà de #la rivière sous le lac# se cache #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/tras el #río bajo el lago# yace #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that dodging #rolling boulders in the Water Temple# leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Ausweichen von #rollenden Felsen im Wassertempel# zu #[[1]]# führe.", + /*french*/ "Selon moi, éviter des #rochers roulants dans le Temple de l'Eau# mène à #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/esquivar #rocas rondantes del Templo del Agua# conduce a #[[1]]#. + {}, + {CustomMessage("They say that dodging #rolling boulders under the lake# leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Ausweichen von #rollenden Felsen unter einem See# zu #[[1]]# führe.", + /*french*/ "Selon moi, éviter des #rochers roulants sous le lac# mène à #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/esquivar #rocas rodantes bajo el lago# conduce a #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_GS_BEHIND_GATE] = HintText(CustomMessage("They say that a spider behind a #gate in the Water Temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne hinter einem #Tor im Wassertempel# #[[1]]# hielte.", + /*french*/ "Selon moi, la Skulltula derrière une #barrière dans le Temple de l'Eau# a #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una Skulltula tras #una valla del Templo del Agua# otorga #[[1]]#. + {}, + {CustomMessage("They say that a spider behind a #gate under the lake# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne hinter einem #Tor unter dem See# #[[1]]# hielte.", + /*french*/ "Selon moi, l'araignée derrière une #barrière sous le lac# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una Skulltula tras #una valla bajo el lago# otorga #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_FREESTANDING_KEY] = HintText(CustomMessage("They say that hidden in a #box in the Water Temple# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß versteckt in einem #Kasten im Wassertempel# #[[1]]# läge.", + /*french*/ "Selon moi, dans une #boîte dans le Temple de l'Eau# gît #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/en una #caja del Templo del Agua# yace #[[1]]#. + {}, + {CustomMessage("They say that hidden in a #box under the lake# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß versteckt in einem #Kasten unter dem See# #[[1]]# läge.", + /*french*/ "Selon moi, dans une #boîte sous le lac# gît #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/en una #caja bajo el lago# yace #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA] = HintText(CustomMessage("They say that the #locked spider in the Water Temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #eingeschlossene Spinne im Wassertempel# #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula emprisonnée dans le Temple de l'Eau# a #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/la #Skulltula enjaulada del Templo del Agua# otorga #[[1]]#. + {}, + {CustomMessage("They say that the #locked spider under the lake# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #eingeschlossene Spinne unter dem See# #[[1]]# hielte.", + /*french*/ "Selon moi, l'#araignée emprisonnée sous le lac# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/la #Skulltula enjaulada bajo el lago# otorga #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH] = HintText(CustomMessage("They say that a spider behind a #gate in the Water Temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne hinter einem #Tor im Wassertempel# #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula derrière une barrière dans le Temple de l'Eau# a #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una Skulltula tras una #valla del Templo del Agua# #[[1]]#. + {}, + {CustomMessage("They say that a spider behind a #gate under the lake# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne hinter einem #Tor unter dem See# #[[1]]# hielte.", + /*french*/ "Selon moi, l'#araignée derrière une barrière sous le lac# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una Skulltula tras una #valla bajo el lago# otorga #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST] = HintText(CustomMessage("They say that those who seek #sunken silver rupees# will find #[[1]]#.", + /*german*/ "Man erzählt sich, daß jene, welche #versunkene silberne Rubine# suchen, #[[1]]# finden würden.", + /*french*/ "Selon moi, ceux qui pêchent les #joyaux argentés# trouveront #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/aquellos que busquen las #rupias plateadas sumergidas# encontrarán + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST] = HintText(CustomMessage("They say that those who seek #sunken silver rupees# will find #[[1]]#.", + /*german*/ "Man erzählt sich, daß jene, welche #versunkene silberne Rubine# suchen, #[[1]]# finden würden.", + /*french*/ "Selon moi, ceux qui pêchent les #joyaux argentés# trouveront #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/aquellos que busquen las #rupias plateadas sumergidas# encontrarán #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST] = HintText(CustomMessage("They say that the final prize of #the thieves' training# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der letzte Preis des #Diebestrainings# #[[1]]# sei.", + /*french*/ "Selon moi, la récompense ultime de #l'épreuve des voleurs# est #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/la recompensa final de la #instrucción de las bandida# brinda #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST] = HintText(CustomMessage("They say that the final prize of #the thieves' training# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der letzte Preis des #Diebestrainings# #[[1]]# sei.", + /*french*/ "Selon moi, la récompense ultime de #l'épreuve des voleurs# est #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/el premio final de la #instrucción de las bandidas# brinda #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST] = HintText(CustomMessage("They say that #Dead Hand in the well# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Hirnsauger im Brunnen# #[[1]]# hielte.", + /*french*/ "Selon moi, le #Poigneur dans le Puits# cache #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/la #Mano Muerta del pozo# concede #[[1]]#. + {}, + {CustomMessage("They say that the well's #grasping ghoul# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #habgierige Fledderer des Brunnens# #[[1]]# verstecke.", + /*french*/ "Selon moi, la #terreur du Puits# cache #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/en las #profundidades del pozo# se esconde #[[1]]#. + CustomMessage("They say that a #nether dweller in the well# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Unterweltbewohner im Brunnen# #[[1]]# hielte.", + /*french*/ "Selon moi, le #spectre qui réside dans le Puits# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/el #temido morador del pozo# concede #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST] = HintText(CustomMessage("They say that #Dead Hand in the well# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Hirnsauger im Brunnen# #[[1]]# hielte.", + /*french*/ "Selon moi, le #Poigneur dans le Puits# cache #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/la #Mano Muerta del pozo# concede #[[1]]#. + {}, + {CustomMessage("They say that the well's #grasping ghoul# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #habgierige Fledderer des Brunnens# #[[1]]# verstecke.", + /*french*/ "Selon moi, la #terreur du Puits# cache #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/en las #profundidades del pozo# se esconde #[[1]]#. + CustomMessage("They say that a #nether dweller in the well# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Unterweltbewohner im Brunnen# #[[1]]# hielte.", + /*french*/ "Selon moi, le #spectre qui réside dans le Puits# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/el #temido morador del pozo# concede #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST] = HintText(CustomMessage("They say that upon the #Colossus's right hand# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf der #rechten Hand des Koloßes# #[[1]]# sei.", + /*french*/ "Selon moi, sur la #main droite du colosse# repose #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/en la #mano derecha del Coloso# yace #[[1]]#. + {}, + {CustomMessage("They say that the treasure #sought by Nabooru# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #von Naboru gesuchte Schatz# #[[1]]# sei.", + /*french*/ "Selon moi, le trésor que #recherche Nabooru# est #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/el #ansiado tesoro de Nabooru# brinda #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST] = HintText(CustomMessage("They say that upon the #Colossus's left hand# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf der #linken Hand des Koloßes# #[[1]]# sei.", + /*french*/ "Selon moi, sur la #main gauche du colosse# repose #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/en la #mano izquierda del Coloso# yace #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST] = HintText(CustomMessage("They say that a #temporal paradox in the Spirit Temple# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #zeitliches Paradox im Geistertempel# #[[1]]# einbrächte.", + /*french*/ "Selon moi, le #paradoxe temporel dans le Temple de l'Esprit# révèle #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una #paradoja temporal del Coloso# conduce a #[[1]]#. + {}, + {CustomMessage("They say that a #temporal paradox in the Colossus# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #zeitliches Paradox im Koloß# #[[1]]# einbrächte.", + /*french*/ "Selon moi, un #paradoxe temporel dans le colosse# révèle #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una #paradoja temporal del Coloso# conduce a #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST] = HintText(CustomMessage("They say that a #symphony in the Spirit Temple# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Sinfonie im Geistertempel# #[[1]]# einbrächte.", + /*french*/ "Selon moi, les #cinq chansons du Temple de l'Esprit# révèlent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/una #sinfonía del Coloso# conduce a #[[1]]#. + {}, + {CustomMessage("They say that a #symphony in the Colossus# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Sinfonie im Koloß# #[[1]]# einbrächte.", + /*french*/ "Selon moi, la #symphonie du colosse# révèle #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/una #sinfonía del Coloso# conduce a #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM] = HintText(CustomMessage("They say that a #spider's symphony in the Spirit Temple# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinnensinfonie im Geistertempel# #[[1]]# einbrächte.", + /*french*/ "Selon moi, la #mélodie de la Skulltula du Temple de l'Esprit# révèle #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/la #Skulltula de la sinfonía del Coloso# otorga #[[1]]#. + {}, + {CustomMessage("They say that a #spider's symphony in the Colossus# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinnensinfonie im Koloß# #[[1]]# einbrächte.", + /*french*/ "Selon moi, la #mélodie de l'araignée du colosse# révèle #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/la #Skulltula de la sinfonía del Coloso# otorga #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST] = HintText(CustomMessage("They say that shadows in an #invisible maze# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß Schatten in einem #unsichtbaren Labyrinth# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les ombres dans le #labyrinthe invisible# protègent #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/las sombras del #laberinto misterioso# esconden #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST] = HintText(CustomMessage("They say that shadows in an #invisible maze# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß Schatten in einem #unsichtbaren Labyrinth# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les ombres dans le #labyrinthe invisible# protègent #[[1]]#.", {QM_RED, QM_GREEN})), + // /*spanish*/las sombras del #laberinto invisible# esconden #[[1]]#. /*-------------------------- | ENTRANCE HINT TEXT | ---------------------------*/ - hintTable[DESERT_COLOSSUS_TO_COLOSSUS_GROTTO] = HintText::Entrance({ - // obscure text - Text{ "lifting a #rock in the desert# reveals", /*french*/ "soulever une #roche dans le désert# révèle", - /*spanish*/ "levantar una #roca del desierto# revela" }, - }); - - hintTable[GV_GROTTO_LEDGE_TO_GV_OCTOROK_GROTTO] = HintText::Entrance({ - // obscure text - Text{ "a rock on #a ledge in the valley# hides", /*french*/ "soulever une #roche dans la vallée# révèle", - /*spanish*/ "levantar una #roca al borde del valle# esconde" }, - }); - - hintTable[GC_GROTTO_PLATFORM_TO_GC_GROTTO] = HintText::Entrance({ - // obscure text - Text{ "a #pool of lava# in Goron City blocks the way to", - /*french*/ "l'#étang de lave# dans le village Goron renferme", - /*spanish*/ "un #estanque de lava# en la Ciudad Goron bloquea el paso a" }, - }); - - hintTable[GERUDO_FORTRESS_TO_GF_STORMS_GROTTO] = HintText::Entrance({ - // obscure text - Text{ "a #storm within Gerudo's Fortress# reveals", /*french*/ "la #tempête dans la forteresse# révèle", - /*spanish*/ "una #tormenta en la Fortaleza Gerudo# revela" }, - }); - - hintTable[ZORAS_DOMAIN_TO_ZD_STORMS_GROTTO] = HintText::Entrance({ - // obscure text - Text{ "a #storm within Zora's Domain# reveals", /*french*/ "la #tempête dans le Domaine Zora# révèle", - /*spanish*/ "una #tormenta en la Región de los Zora# revela" }, - }); - - hintTable[HYRULE_CASTLE_GROUNDS_TO_HC_STORMS_GROTTO] = HintText::Entrance({ - // obscure text - Text{ "a #storm near the castle# reveals", /*french*/ "la #tempête près du château# révèle", - /*spanish*/ "una #tormenta junto al castillo# revela" }, - }); - - hintTable[GV_FORTRESS_SIDE_TO_GV_STORMS_GROTTO] = HintText::Entrance({ - // obscure text - Text{ "a #storm in the valley# reveals", /*french*/ "la #tempête dans la vallée# révèle", - /*spanish*/ "una #tormenta en el valle# revela" }, - }); - - hintTable[DESERT_COLOSSUS_TO_COLOSSUS_GREAT_FAIRY_FOUNTAIN] = HintText::Entrance({ - // obscure text - Text{ "a #fractured desert wall# hides", /*french*/ "le #mur fragile du désert# cache", - /*spanish*/ "una #agrietada pared del desierto# esconde" }, - }); - - hintTable[GANONS_CASTLE_GROUNDS_TO_OGC_GREAT_FAIRY_FOUNTAIN] = HintText::Entrance({ - // obscure text - Text{ "a #heavy pillar# outside the castle obstructs", /*french*/ "le #rocher fragile près du château# cache", - /*spanish*/ "una #pesada columna# fuera del castillo obstruye" }, - }); - - hintTable[ZORAS_FOUNTAIN_TO_ZF_GREAT_FAIRY_FOUNTAIN] = HintText::Entrance({ - // obscure text - Text{ "a #fountain wall# hides", /*french*/ "le #mur fragile du réservoir# cache", - /*spanish*/ "una #pared de la fuente# esconde" }, - }); - - hintTable[GV_FORTRESS_SIDE_TO_GV_CARPENTER_TENT] = HintText::Entrance({ - // obscure text - Text{ "a #tent in the valley# covers", /*french*/ "la #tente dans la vallée# recouvre", - /*spanish*/ "una #tienda de campaña del valle# cubre" }, - }); - - hintTable[GRAVEYARD_WARP_PAD_REGION_TO_SHADOW_TEMPLE_ENTRYWAY] = HintText::Entrance({ - // obscure text - Text{ "at the #back of the Graveyard#, there is", /*french*/ "#derrière le Cimetière# gît", - /*spanish*/ "en la #parte trasera del cementerio# se halla" }, - }); - - hintTable[LAKE_HYLIA_TO_WATER_TEMPLE_LOBBY] = HintText::Entrance({ - // obscure text - Text{ "deep #under a vast lake#, one can find", /*french*/ "#sous le lac# gît", - /*spanish*/ "en las #profundidades de un lago inmenso# se halla" }, - }); - - hintTable[GERUDO_FORTRESS_TO_GERUDO_TRAINING_GROUNDS_LOBBY] = HintText::Entrance({ - // obscure text - Text{ "paying a #fee to the Gerudos# grants access to", - /*french*/ "l'#entrée payante des Gerudo# donne accès à", - /*spanish*/ "pagarle una #tasa a las gerudo# da acceso a" }, - }); - - hintTable[ZORAS_FOUNTAIN_TO_JABU_JABUS_BELLY_BEGINNING] = HintText::Entrance({ - // obscure text - Text{ "inside #Jabu-Jabu#, one can find", /*french*/ "#dans Jabu-Jabu# se trouve", - /*spanish*/ "dentro de #Jabu-Jabu# se halla" }, - }); - - hintTable[KAKARIKO_VILLAGE_TO_BOTTOM_OF_THE_WELL] = HintText::Entrance({ - // obscure text - Text{ "a #village well# leads to", /*french*/ "dans le fond du #Puits du village# gît", - /*spanish*/ "el #pozo de un pueblo# conduce a" }, - }); + hintTextTable[RHT_DESERT_COLOSSUS_TO_COLOSSUS_GROTTO] = HintText(CustomMessage("They say that lifting a #rock in the desert# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Heben eines #Felsens in der Wüste# #[[1]]# enthülle.", + /*french*/ "Selon moi, soulever une #roche dans le désert# révèle #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/levantar una #roca del desierto# revela #[[1]]#. + + hintTextTable[RHT_GV_GROTTO_LEDGE_TO_GV_OCTOROK_GROTTO] = HintText(CustomMessage("They say that a rock on #a ledge in the valley# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein Felsen auf #einem Vorsprung im Tal# #[[1]]# verstecke.", + /*french*/ "Selon moi, soulever une #roche dans la vallée# révèle #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/levantar una #roca al borde del valle# esconde #[[1]]#. + + hintTextTable[RHT_GC_GROTTO_PLATFORM_TO_GC_GROTTO] = HintText(CustomMessage("They say that a #pool of lava# in Goron City blocks the way to #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Lavateich# in Goronia den Weg zu #[[1]]# blockiere.", + /*french*/ "Selon moi, l'#étang de lave# dans le village Goron renferme #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/un #estanque de lava# en la Ciudad Goron bloquea el paso a #[[1]]#. + + hintTextTable[RHT_GERUDO_FORTRESS_TO_GF_STORMS_GROTTO] = HintText(CustomMessage("They say that a #storm within Gerudo's Fortress# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Sturm innerhalb der Gerudo-Festung# #[[1]]# enthülle.", + /*french*/ "Selon moi, la #tempête dans la forteresse# révèle #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/una #tormenta en la Fortaleza Gerudo# revela #[[1]]#. + + hintTextTable[RHT_ZORAS_DOMAIN_TO_ZD_STORMS_GROTTO] = HintText(CustomMessage("They say that a #storm within Zora's Domain# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Sturm innerhalb von Zoras Reich# #[[1]]# enthülle.", + /*french*/ "Selon moi, la #tempête dans le Domaine Zora# révèle #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/una #tormenta en la Región de los Zora# revela #[[1]]#. + + hintTextTable[RHT_HYRULE_CASTLE_GROUNDS_TO_HC_STORMS_GROTTO] = HintText(CustomMessage("They say that a #storm near the castle# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Sturm in der Nähe des Schloßes# #[[1]]# enthülle.", + /*french*/ "Selon moi, la #tempête près du château# révèle #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/una #tormenta junto al castillo# revela #[[1]]#. + + hintTextTable[RHT_GV_FORTRESS_SIDE_TO_GV_STORMS_GROTTO] = HintText(CustomMessage("They say that a #storm in the valley# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Sturm im Tal# #[[1]]# enthülle.", + /*french*/ "Selon moi, la #tempête dans la vallée# révèle #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/una #tormenta en el valle# revela #[[1]]#. + + hintTextTable[RHT_DESERT_COLOSSUS_TO_COLOSSUS_GREAT_FAIRY_FOUNTAIN] = HintText(CustomMessage("They say that a #fractured desert wall# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #gebrochene Wüstenmauer# #[[1]]# verstecke.", + /*french*/ "Selon moi, le #mur fragile du désert# cache #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/una #agrietada pared del desierto# esconde #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_GROUNDS_TO_OGC_GREAT_FAIRY_FOUNTAIN] = HintText(CustomMessage("They say that a #heavy pillar# outside the castle obstructs #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #schwere Säule# außerhalb des Schloßes #[[1]]# versperre.", + /*french*/ "Selon moi, le #rocher fragile près du château# cache #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/una #pesada columna# fuera del castillo obstruye #[[1]]#. + + hintTextTable[RHT_ZORAS_FOUNTAIN_TO_ZF_GREAT_FAIRY_FOUNTAIN] = HintText(CustomMessage("They say that a #fountain wall# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Wasserwand# #[[1]]# verstecke.", + /*french*/ "Selon moi, le #mur fragile du réservoir# cache #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/una #pared de la fuente# esconde #[[1]]#. + + hintTextTable[RHT_GV_FORTRESS_SIDE_TO_GV_CARPENTER_TENT] = HintText(CustomMessage("They say that a #tent in the valley# covers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Zelt im Tal# #[[1]]# verdecke.", + /*french*/ "Selon moi, la #tente dans la vallée# recouvre #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/una #tienda de campaña del valle# cubre #[[1]]#. + + hintTextTable[RHT_GRAVEYARD_WARP_PAD_REGION_TO_SHADOW_TEMPLE_ENTRYWAY] = HintText(CustomMessage("They say that at the #back of the Graveyard#, there is #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich #hinter dem Friedhof, #[[1]]# befände.", + /*french*/ "Selon moi, #derrière le Cimetière# gît #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/en la #parte trasera del cementerio# se halla #[[1]]#. + + hintTextTable[RHT_LAKE_HYLIA_TO_WATER_TEMPLE_LOBBY] = HintText(CustomMessage("They say that deep #under a vast lake#, one can find #[[1]]#.", + /*german*/ "Man erzählt sich, daß man tief #unter einem gewaltigen See#, #[[1]]# finden könne.", + /*french*/ "Selon moi, #sous le lac# gît #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/en las #profundidades de un lago inmenso# se halla #[[1]]#. + + hintTextTable[RHT_GERUDO_FORTRESS_TO_GERUDO_TRAINING_GROUNDS_LOBBY] = HintText(CustomMessage("They say that paying a #fee to the Gerudos# grants access to #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Bezahlen einer #Gebühr an die Gerudos#, Zugang zu #[[1]]# gewähre.", + /*french*/ "Selon moi, l'#entrée payante des Gerudo# donne accès à #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/pagarle una #tasa a las gerudo# da acceso a #[[1]]#. + + hintTextTable[RHT_ZORAS_FOUNTAIN_TO_JABU_JABUS_BELLY_BEGINNING] = HintText(CustomMessage("They say that inside #Jabu-Jabu#, one can find #[[1]]#.", + /*german*/ "Man erzählt sich, daß man #in Jabu-Jabu#, #[[1]]# finden könne.", + /*french*/ "Selon moi, #dans Jabu-Jabu# se trouve #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/dentro de #Jabu-Jabu# se halla #[[1]]#. + + hintTextTable[RHT_KAKARIKO_VILLAGE_TO_BOTTOM_OF_THE_WELL] = HintText(CustomMessage("They say that a #village well# leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Dorfbrunnen# zu #[[1]]# führe.", + /*french*/ "Selon moi, dans le fond du #Puits du village# gît #[[1]]#.", {QM_RED, QM_BLUE})), + // /*spanish*/el #pozo de un pueblo# conduce a #[[1]]#. /*-------------------------- | EXIT HINT TEXT | ---------------------------*/ - // maybe make a new type for this? I'm not sure if it really matters - - hintTable[LINKS_POCKET] = HintText::Exclude({ - // obscure text - Text{ "Link's Pocket", /*french*/ "les Poches de @", /*spanish*/ "el bolsillo de @" }, - }); - - hintTable[KOKIRI_FOREST] = HintText::Exclude({ - // obscure text - Text{ "Kokiri Forest", /*french*/ "la Forêt Kokiri", /*spanish*/ "el Bosque Kokiri" }, - }); - - hintTable[THE_LOST_WOODS] = HintText::Exclude({ - // obscure text - Text{ "the Lost Woods", /*french*/ "les Bois Perdus", /*spanish*/ "el Bosque Perdido" }, - }); - - hintTable[SACRED_FOREST_MEADOW] = HintText::Exclude({ - // obscure text - Text{ "Sacred Forest Meadow", /*french*/ "le Bosquet Sacré", /*spanish*/ "la pradera sagrada del bosque" }, - }); - - hintTable[HYRULE_FIELD] = HintText::Exclude({ - // obscure text - Text{ "Hyrule Field", /*french*/ "la Plaine d'Hyrule", /*spanish*/ "la Llanura de Hyrule" }, - }); - - hintTable[LAKE_HYLIA] = HintText::Exclude({ - // obscure text - Text{ "Lake Hylia", /*french*/ "le Lac Hylia", /*spanish*/ "el Lago Hylia" }, - }); - - hintTable[GERUDO_VALLEY] = HintText::Exclude({ - // obscure text - Text{ "Gerudo Valley", /*french*/ "la Vallée Gerudo", /*spanish*/ "el Valle Gerudo" }, - }); - - hintTable[GERUDO_FORTRESS] = HintText::Exclude({ - // obscure text - Text{ "Gerudo's Fortress", /*french*/ "le Repaire des Voleurs", /*spanish*/ "la Fortaleza Gerudo" }, - }); - - hintTable[HAUNTED_WASTELAND] = HintText::Exclude({ - // obscure text - Text{ "Haunted Wasteland", /*french*/ "le Désert Hanté", /*spanish*/ "el desierto encantado" }, - }); - - hintTable[DESERT_COLOSSUS] = HintText::Exclude({ - // obscure text - Text{ "Desert Colossus", /*french*/ "le Colosse du Désert", /*spanish*/ "el Coloso del Desierto" }, - }); - - hintTable[THE_MARKET] = HintText::Exclude({ - // obscure text - Text{ "the Market", /*french*/ "la Place du Marché", /*spanish*/ "la plaza del mercado" }, - }); - - hintTable[TEMPLE_OF_TIME] = HintText::Exclude({ - // obscure text - Text{ "Temple of Time", /*french*/ "le Temple du Temps", /*spanish*/ "el Templo del Tiempo" }, - }); - - hintTable[CASTLE_GROUNDS] = HintText::Exclude({ - // obscure text - Text{ "the Castle Grounds", /*french*/ "le Château d'Hyrule", /*spanish*/ "" }, - }); - - hintTable[HYRULE_CASTLE] = HintText::Exclude({ - // obscure text - Text{ "Hyrule Castle", /*french*/ "le Château d'Hyrule", /*spanish*/ "el Castillo de Hyrule" }, - }); - - hintTable[OUTSIDE_GANONS_CASTLE] = HintText::Exclude({ - // obscure text - Text{ "outside Ganon's Castle", /*french*/ "les alentours du Château&de Ganon", - /*spanish*/ "el exterior del Castillo de Ganon" }, - }); - - hintTable[KAKARIKO_VILLAGE] = HintText::Exclude({ - // obscure text - Text{ "Kakariko Village", /*french*/ "le Village Cocorico", /*spanish*/ "Kakariko" }, - }); - - hintTable[THE_GRAVEYARD] = HintText::Exclude({ - // obscure text - Text{ "the Graveyard", /*french*/ "le Cimetière", /*spanish*/ "el cementerio" }, - }); - - hintTable[DEATH_MOUNTAIN_TRAIL] = HintText::Exclude({ - // obscure text - Text{ "Death Mountain Trail", /*french*/ "le Chemin du Péril", - /*spanish*/ "el sendero de la Montaña de la Muerte" }, - }); - - hintTable[GORON_CITY] = HintText::Exclude({ - // obscure text - Text{ "Goron City", /*french*/ "le Village Goron", /*spanish*/ "la Ciudad Goron" }, - }); - - hintTable[DEATH_MOUNTAIN_CRATER] = HintText::Exclude({ - // obscure text - Text{ "Death Mountain Crater", /*french*/ "le Cratère du Péril", - /*spanish*/ "el cráter de la Montaña de la Muerte" }, - }); - - hintTable[ZORAS_RIVER] = HintText::Exclude({ - // obscure text - Text{ "Zora's River", /*french*/ "la Rivière Zora", /*spanish*/ "el Río Zora" }, - }); - - hintTable[ZORAS_DOMAIN] = HintText::Exclude({ - // obscure text - Text{ "Zora's Domain", /*french*/ "le Domaine Zora", /*spanish*/ "la Región de los Zora" }, - }); - - hintTable[ZORAS_FOUNTAIN] = HintText::Exclude({ - // obscure text - Text{ "Zora's Fountain", /*french*/ "la Fontaine Zora", /*spanish*/ "la Fuente Zora" }, - }); - - hintTable[LON_LON_RANCH] = HintText::Exclude({ - // obscure text - Text{ "Lon Lon Ranch", /*french*/ "le Ranch Lon Lon", /*spanish*/ "el Rancho Lon Lon" }, - }); + + hintTextTable[RHT_LINKS_POCKET] = HintText(CustomMessage("Link's Pocket", + /*german*/ "Links Taschen", + /*french*/ "les Poches de @")); + // /*spanish*/el bolsillo de @ + + hintTextTable[RHT_KOKIRI_FOREST] = HintText(CustomMessage("Kokiri Forest", + /*german*/ "Kokiri-Wald", + /*french*/ "la Forêt Kokiri")); + // /*spanish*/el Bosque Kokiri + + hintTextTable[RHT_THE_LOST_WOODS] = HintText(CustomMessage("the Lost Woods", + /*german*/ "Verlorene Wälder", + /*french*/ "les Bois Perdus")); + // /*spanish*/el Bosque Perdido + + hintTextTable[RHT_SACRED_FOREST_MEADOW] = HintText(CustomMessage("Sacred Forest Meadow", + /*german*/ "Heilige Lichtung", + /*french*/ "le Bosquet Sacré")); + // /*spanish*/la pradera sagrada del bosque + + hintTextTable[RHT_HYRULE_FIELD] = HintText(CustomMessage("Hyrule Field", + /*german*/ "Hylianische Steppe", + /*french*/ "la Plaine d'Hyrule")); + // /*spanish*/la Llanura de Hyrule + + hintTextTable[RHT_LAKE_HYLIA] = HintText(CustomMessage("Lake Hylia", + /*german*/ "Hylia-See", + /*french*/ "le Lac Hylia")); + // /*spanish*/el Lago Hylia + + hintTextTable[RHT_GERUDO_VALLEY] = HintText(CustomMessage("Gerudo Valley", + /*german*/ "Gerudotal", + /*french*/ "la Vallée Gerudo")); + // /*spanish*/el Valle Gerudo + + hintTextTable[RHT_GERUDO_FORTRESS] = HintText(CustomMessage("Gerudo's Fortress", + /*german*/ "Gerudo-Festung", + /*french*/ "le Repaire des Voleurs")); + // /*spanish*/la Fortaleza Gerudo + + hintTextTable[RHT_HAUNTED_WASTELAND] = HintText(CustomMessage("Haunted Wasteland", + /*german*/ "Gespensterwüste", + /*french*/ "le Désert Hanté")); + // /*spanish*/el desierto encantado + + hintTextTable[RHT_DESERT_COLOSSUS] = HintText(CustomMessage("Desert Colossus", + /*german*/ "Wüstenkoloß", + /*french*/ "le Colosse du Désert")); + // /*spanish*/el Coloso del Desierto + + hintTextTable[RHT_THE_MARKET] = HintText(CustomMessage("the Market", + /*german*/ "Markt", + /*french*/ "la Place du Marché")); + // /*spanish*/la plaza del mercado + + hintTextTable[RHT_TEMPLE_OF_TIME] = HintText(CustomMessage("Temple of Time", + /*german*/ "Zitadelle der Zeit", + /*french*/ "le Temple du Temps")); + // /*spanish*/el Templo del Tiempo + + hintTextTable[RHT_CASTLE_GROUNDS] = HintText(CustomMessage("the Castle Grounds", + /*german*/ "Anlage von Schloß Hyrule", + /*french*/ "le Château d'Hyrule")); + // /*spanish*/ + + hintTextTable[RHT_HYRULE_CASTLE] = HintText(CustomMessage("Hyrule Castle", + /*german*/ "Schloß Hyrule", + /*french*/ "le Château d'Hyrule")); + // /*spanish*/el Castillo de Hyrule + + hintTextTable[RHT_OUTSIDE_GANONS_CASTLE] = HintText(CustomMessage("outside Ganon's Castle", + /*german*/ "außerhalb von Ganons Schloß", + /*french*/ "les alentours du Château de Ganon")); + // /*spanish*/el exterior del Castillo de Ganon + + hintTextTable[RHT_CASTLE_GROUNDS] = HintText(CustomMessage("the Castle Grounds", + /*german*/ "Anlage von Schloß Hyrule", + /*french*/ "le Château d'Hyrule")); + // /*spanish*/ + + hintTextTable[RHT_KAKARIKO_VILLAGE] = HintText(CustomMessage("Kakariko Village", + /*german*/ "Kakariko", + /*french*/ "le Village Cocorico")); + // /*spanish*/Kakariko + + hintTextTable[RHT_THE_GRAVEYARD] = HintText(CustomMessage("the Graveyard", + /*german*/ "Friedhof", + /*french*/ "le Cimetière")); + // /*spanish*/el cementerio + + hintTextTable[RHT_DEATH_MOUNTAIN_TRAIL] = HintText(CustomMessage("Death Mountain Trail", + /*german*/ "Gebirgspfad", + /*french*/ "le Chemin du Péril")); + // /*spanish*/el sendero de la Montaña de la Muerte + + hintTextTable[RHT_GORON_CITY] = HintText(CustomMessage("Goron City", + /*german*/ "Goronia", + /*french*/ "le Village Goron")); + // /*spanish*/la Ciudad Goron + + hintTextTable[RHT_DEATH_MOUNTAIN_CRATER] = HintText(CustomMessage("Death Mountain Crater", + /*german*/ "Todeskrater", + /*french*/ "le Cratère du Péril")); + // /*spanish*/el cráter de la Montaña de la Muerte + + hintTextTable[RHT_ZORAS_RIVER] = HintText(CustomMessage("Zora's River", + /*german*/ "Zoras Fluß", + /*french*/ "la Rivière Zora")); + // /*spanish*/el Río Zora + + hintTextTable[RHT_ZORAS_DOMAIN] = HintText(CustomMessage("Zora's Domain", + /*german*/ "Zoras Reich", + /*french*/ "le Domaine Zora")); + // /*spanish*/la Región de los Zora + + hintTextTable[RHT_ZORAS_FOUNTAIN] = HintText(CustomMessage("Zora's Fountain", + /*german*/ "Zoras Quelle", + /*french*/ "la Fontaine Zora")); + // /*spanish*/la Fuente Zora + + hintTextTable[RHT_LON_LON_RANCH] = HintText(CustomMessage("Lon Lon Ranch", + /*german*/ "Lon Lon-Farm", + /*french*/ "le Ranch Lon Lon")); + // /*spanish*/el Rancho Lon Lon /*-------------------------- | REGION HINT TEXT | ---------------------------*/ - hintTable[KF_LINKS_HOUSE] = HintText::Region({ - // obscure text - Text{ "Link's House", /*french*/ "la #maison de @#", /*spanish*/ "la casa de @" }, - }); - - // hintTable[TOT_MAIN] = HintText::Region({ - // //obscure text - // Text{"the #Temple of Time#", /*french*/"le #Temple du Temps#", /*spanish*/"el Templo del - // Tiempo"}, - // }); - - hintTable[KF_MIDOS_HOUSE] = HintText::Region({ - // obscure text - Text{ "Mido's house", /*french*/ "la Cabane du Grand Mido", /*spanish*/ "la casa de Mido" }, - }); - - hintTable[KF_SARIAS_HOUSE] = HintText::Region({ - // obscure text - Text{ "Saria's House", /*french*/ "la Cabane de Saria", /*spanish*/ "la casa de Saria" }, - }); - - hintTable[KF_HOUSE_OF_TWINS] = HintText::Region({ - // obscure text - Text{ "the #House of Twins#", /*french*/ "la Cabane des Jumelles", /*spanish*/ "la casa de las gemelas" }, - }); - - hintTable[KF_KNOW_IT_ALL_HOUSE] = HintText::Region({ - // obscure text - Text{ "Know-It-All Brothers' House", /*french*/ "la Cabane des frères Je-Sais-Tout", - /*spanish*/ "la casa de los hermanos Sabelotodo" }, - }); - - hintTable[KF_KOKIRI_SHOP] = HintText::Region({ - // obscure text - Text{ "the #Kokiri Shop#", /*french*/ "le #Magasin Kokiri#", /*spanish*/ "la tienda kokiri" }, - }); - - hintTable[LH_LAB] = HintText::Region({ - // obscure text - Text{ "the #Lakeside Laboratory#", /*french*/ "le #Laboratoire du Lac#", - /*spanish*/ "el laboratorio del lago" }, - }); - - hintTable[LH_FISHING_HOLE] = HintText::Region({ - // obscure text - Text{ "the #Fishing Pond#", /*french*/ "l'#Étang#", /*spanish*/ "el estanque" }, - }); - - hintTable[GV_CARPENTER_TENT] = HintText::Region({ - // obscure text - Text{ "the #Carpenters' tent#", /*french*/ "la #Tente des charpentiers#", - /*spanish*/ "la #tienda de campaña de los carpinteros#" }, - }); - - hintTable[MARKET_GUARD_HOUSE] = HintText::Region({ - // obscure text - Text{ "the #Guard House#", /*french*/ "le #poste de garde#", /*spanish*/ "la caseta de guardia" }, - }); - - hintTable[MARKET_MASK_SHOP] = HintText::Region({ - // obscure text - Text{ "the #Happy Mask Shop#", /*french*/ "la #Foire Aux Masques#", - /*spanish*/ "la tienda de La Máscara Feliz" }, - }); - - hintTable[MARKET_BOMBCHU_BOWLING] = HintText::Region({ - // obscure text - Text{ "the #Bombchu Bowling Alley#", /*french*/ "le #Bowling Teigneux#", /*spanish*/ "la Bolera Bombchu" }, - }); - - hintTable[MARKET_POTION_SHOP] = HintText::Region({ - // obscure text - Text{ "the #Market Potion Shop#", /*french*/ "l'#apothicaire de la Place du Marché#", - /*spanish*/ "la tienda de pociones de la plaza del mercado" }, - }); - - hintTable[MARKET_TREASURE_CHEST_GAME] = HintText::Region({ - // obscure text - Text{ "the #Treasure Chest Shop#", /*french*/ "la #Chasse-aux-Trésors#", /*spanish*/ "el Cofre del Tesoro" }, - }); - - hintTable[MARKET_BOMBCHU_SHOP] = HintText::Region({ - // obscure text - Text{ "the #Bombchu Shop#", /*french*/ "le #Magasin de Missiles#", /*spanish*/ "la Tienda Bombchu" }, - }); - - hintTable[MARKET_MAN_IN_GREEN_HOUSE] = HintText::Region({ - // obscure text - Text{ "Man in Green's House", /*french*/ "la #Maison de l'Homme en Vert#", - /*spanish*/ "la casa del hombre de verde" }, - }); - - hintTable[KAK_WINDMILL] = HintText::Region({ - // obscure text - Text{ "the #Windmill#", /*french*/ "le #Moulin#", /*spanish*/ "el #molino#" }, - }); - - hintTable[KAK_CARPENTER_BOSS_HOUSE] = HintText::Region({ - // obscure text - Text{ "the #Carpenters' Boss House#", /*french*/ "la #Maison du Chef des ouvriers#", - /*spanish*/ "la casa del capataz de los carpinteros" }, - }); - - hintTable[KAK_HOUSE_OF_SKULLTULA] = HintText::Region({ - // obscure text - Text{ "the #House of Skulltula#", /*french*/ "la #Maison des Skulltulas#", - /*spanish*/ "la casa de las Skulltulas" }, - }); - - hintTable[KAK_IMPAS_HOUSE] = HintText::Region({ - // obscure text - Text{ "Impa's House", /*french*/ "la #Maison d'Impa#", /*spanish*/ "la casa de Impa" }, - }); - - hintTable[KAK_IMPAS_HOUSE_BACK] = HintText::Region({ - // obscure text - Text{ "Impa's cow cage", /*french*/ "la #cage à vache d'Impa#", /*spanish*/ "la jaula de la vaca de Impa" }, - }); - - hintTable[KAK_ODD_POTION_BUILDING] = HintText::Region({ - // obscure text - Text{ "Granny's Potion Shop", /*french*/ "la #maison bleue de Cocorico#", - /*spanish*/ "la tienda de pociones de la abuela" }, - }); - - hintTable[GRAVEYARD_DAMPES_HOUSE] = HintText::Region({ - // obscure text - Text{ "Dampé's Hut", /*french*/ "la #Cabane du Fossoyeur#", /*spanish*/ "la cabaña de Dampé" }, - }); - - hintTable[GC_SHOP] = HintText::Region({ - // obscure text - Text{ "the #Goron Shop#", /*french*/ "la #Boutique Goron#", /*spanish*/ "la #tienda goron#" }, - }); - - hintTable[ZD_SHOP] = HintText::Region({ - // obscure text - Text{ "the #Zora Shop#", /*french*/ "la #Boutique Zora#", /*spanish*/ "la #tienda zora#" }, - }); - - hintTable[LLR_TALONS_HOUSE] = HintText::Region({ - // obscure text - Text{ "Talon's House", /*french*/ "la #Maison de Talon#", /*spanish*/ "la casa de Talon" }, - }); - - hintTable[LLR_STABLES] = HintText::Region({ - // obscure text - Text{ "a #stable#", /*french*/ "l'#Étable#", /*spanish*/ "el establo" }, - }); - - hintTable[LLR_TOWER] = HintText::Region({ - // obscure text - Text{ "the #Lon Lon Tower#", /*french*/ "le #silo du Ranch Lon Lon#", /*spanish*/ "la torre Lon Lon" }, - }); - - hintTable[MARKET_BAZAAR] = HintText::Region({ - // obscure text - Text{ "the #Market Bazaar#", /*french*/ "le #Bazar de la Place du Marché#", - /*spanish*/ "el bazar de la plaza del mercado" }, - }); - - hintTable[MARKET_SHOOTING_GALLERY] = HintText::Region({ - // obscure text - Text{ "a #Slingshot Shooting Gallery#", /*french*/ "le #Jeu d'Adresse de la Place du Marché#", - /*spanish*/ "el Tiro al Blanco con tirachinas" }, - }); - - hintTable[KAK_BAZAAR] = HintText::Region({ - // obscure text - Text{ "the #Kakariko Bazaar#", /*french*/ "le #Bazar de Cocorico#", /*spanish*/ "el bazar de Kakariko" }, - }); - - hintTable[KAK_POTION_SHOP_FRONT] = HintText::Region({ - // obscure text - Text{ "the #Kakariko Potion Shop#", /*french*/ "l'#apothicaire de Cocorico#", - /*spanish*/ "la tienda de pociones de Kakariko" }, - }); - - hintTable[KAK_POTION_SHOP_BACK] = HintText::Region({ - // obscure text - Text{ "the #Kakariko Potion Shop#", /*french*/ "l'#apothicaire de Cocorico#", - /*spanish*/ "la tienda de pociones de Kakariko" }, - }); - - hintTable[KAK_SHOOTING_GALLERY] = HintText::Region({ - // obscure text - Text{ "a #Bow Shooting Gallery#", /*french*/ "le #jeu d'adresse de Cocorico#", - /*spanish*/ "el Tiro al Blanco con arco" }, - }); - - hintTable[COLOSSUS_GREAT_FAIRY_FOUNTAIN] = HintText::Region({ - // obscure text - Text{ "a #Great Fairy Fountain#", /*french*/ "une #Fontaine Royale des Fées#", - /*spanish*/ "una fuente de la Gran Hada" }, - }); - - hintTable[HC_GREAT_FAIRY_FOUNTAIN] = HintText::Region({ - // obscure text - Text{ "a #Great Fairy Fountain#", /*french*/ "une #Fontaine Royale des Fées#", - /*spanish*/ "una fuente de la Gran Hada" }, - }); - - hintTable[OGC_GREAT_FAIRY_FOUNTAIN] = HintText::Region({ - // obscure text - Text{ "a #Great Fairy Fountain#", /*french*/ "une #Fontaine Royale des Fées#", - /*spanish*/ "una fuente de la Gran Hada" }, - }); - - hintTable[DMC_GREAT_FAIRY_FOUNTAIN] = HintText::Region({ - // obscure text - Text{ "a #Great Fairy Fountain#", /*french*/ "une #Fontaine Royale des Fées#", - /*spanish*/ "una fuente de la Gran Hada" }, - }); - - hintTable[DMT_GREAT_FAIRY_FOUNTAIN] = HintText::Region({ - // obscure text - Text{ "a #Great Fairy Fountain#", /*french*/ "une #Fontaine Royale des Fées#", - /*spanish*/ "una fuente de la Gran Hada" }, - }); - - hintTable[ZF_GREAT_FAIRY_FOUNTAIN] = HintText::Region({ - // obscure text - Text{ "a #Great Fairy Fountain#", /*french*/ "une #Fontaine Royale des Fées#", - /*spanish*/ "una fuente de la Gran Hada" }, - }); - - hintTable[GRAVEYARD_SHIELD_GRAVE] = HintText::Region({ - // obscure text - Text{ "a #grave with a free chest#", /*french*/ "le #tombeau avec un trésor#", - /*spanish*/ "la #tumba con un cofre#" }, - }); - - hintTable[GRAVEYARD_HEART_PIECE_GRAVE] = HintText::Region({ - // obscure text - Text{ "a chest spawned by #Sun's Song#", /*french*/ "un #coffre apparaît avec le Chant du Soleil#", - /*spanish*/ "la #tumba de la Canción del Sol#" }, - }); - - hintTable[GRAVEYARD_COMPOSERS_GRAVE] = HintText::Region({ - // obscure text - Text{ "the #Composers' Grave#", /*french*/ "la #Tombe royale#", /*spanish*/ "el #Panteón Real#" }, - }); - - hintTable[GRAVEYARD_DAMPES_GRAVE] = HintText::Region({ - // obscure text - Text{ "Dampé's Grave", /*french*/ "la #Tombe d'Igor#", /*spanish*/ "la #tumba de Dampé#" }, - }); - - hintTable[DMT_COW_GROTTO] = HintText::Region({ - // obscure text - Text{ "a solitary #Cow#", /*french*/ "la #grotte avec une vache#", /*spanish*/ "una #vaca# solitaria" }, - }); - - hintTable[HC_STORMS_GROTTO] = HintText::Region({ - // obscure text - Text{ "a sandy grotto with #fragile walls#", /*french*/ "la #grotte avec des murs fragiles#", - /*spanish*/ "la arenosa gruta de #frágiles paredes#" }, - }); - - hintTable[HF_TEKTITE_GROTTO] = HintText::Region({ - // obscure text - Text{ "a pool guarded by a #Tektite#", /*french*/ "l'#étang sous-terrain avec un Araknon#", - /*spanish*/ "un charco custodiado por un #Tektite#" }, - }); - - hintTable[HF_NEAR_KAK_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #Big Skulltula# guarding a Gold one", /*french*/ "la #grotte d'araignées#", - /*spanish*/ "una #gran Skulltula# custodiando una dorada" }, - }); - - hintTable[HF_COW_GROTTO] = HintText::Region({ - // obscure text - Text{ "a grotto full of #spider webs#", /*french*/ "la #grotte couverte de toiles d'araignées#", - /*spanish*/ "una gruta llena de #telarañas#" }, - }); - - hintTable[KAK_REDEAD_GROTTO] = HintText::Region({ - // obscure text - Text{ "#ReDeads# guarding a chest", /*french*/ "le tombeau de #deux morts#", - /*spanish*/ "los #ReDeads# que custodian un cofre" }, - }); - - hintTable[SFM_WOLFOS_GROTTO] = HintText::Region({ - // obscure text - Text{ "#Wolfos# guarding a chest", /*french*/ "la #grotte iridescente#", - /*spanish*/ "los #Wolfos# que custodian un cofre" }, - }); - - hintTable[GV_OCTOROK_GROTTO] = HintText::Region({ - // obscure text - Text{ "an #Octorok# guarding a rich pool", /*french*/ "un #étang sous-terrain avec un Octorok#", - /*spanish*/ "un #Octorok# que custodia un lujoso charco" }, - }); - - hintTable[DEKU_THEATER] = HintText::Region({ - // obscure text - Text{ "the #Lost Woods Stage#", /*french*/ "le #théâtre sylvestre#", - /*spanish*/ "el #escenario del Bosque Perdido#" }, - }); - - hintTable[ZR_OPEN_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #generic grotto#", /*french*/ "une #grotte avec un trésor#", /*spanish*/ "una #cueva genérica#" }, - }); - - hintTable[DMC_UPPER_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #generic grotto#", /*french*/ "une #grotte avec un trésor#", /*spanish*/ "una #cueva genérica#" }, - }); - - hintTable[DMT_STORMS_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #generic grotto#", /*french*/ "une #grotte avec un trésor#", /*spanish*/ "una #cueva genérica#" }, - }); - - hintTable[KAK_OPEN_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #generic grotto#", /*french*/ "une #grotte avec un trésor#", /*spanish*/ "una #cueva genérica#" }, - }); - - hintTable[HF_NEAR_MARKET_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #generic grotto#", /*french*/ "une #grotte avec un trésor#", /*spanish*/ "una #cueva genérica#" }, - }); - - hintTable[HF_OPEN_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #generic grotto#", /*french*/ "une #grotte avec un trésor#", /*spanish*/ "una #cueva genérica#" }, - }); - - hintTable[HF_SOUTHEAST_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #generic grotto#", /*french*/ "une #grotte avec un trésor#", /*spanish*/ "una #cueva genérica#" }, - }); - - hintTable[KF_STORMS_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #generic grotto#", /*french*/ "une #grotte avec un trésor#", /*spanish*/ "una #cueva genérica#" }, - }); - - hintTable[LW_NEAR_SHORTCUTS_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #generic grotto#", /*french*/ "une #grotte avec un trésor#", /*spanish*/ "una #cueva genérica#" }, - }); - - hintTable[HF_INSIDE_FENCE_GROTTO] = HintText::Region({ - // obscure text - Text{ "a #single Upgrade Deku Scrub#", /*french*/ "une #grotte avec une peste Mojo#", - /*spanish*/ "una cueva con un #solitario mercader deku#" }, - }); - - hintTable[LW_SCRUBS_GROTTO] = HintText::Region({ - // obscure text - Text{ "#2 Deku Scrubs# including an Upgrade one", /*french*/ "une #grotte avec deux pestes Mojo#", - /*spanish*/ "una cueva con #dos mercaderes deku#" }, - }); - - hintTable[COLOSSUS_GROTTO] = HintText::Region({ - // obscure text - Text{ "2 Deku Scrubs", /*french*/ "une #grotte avec deux pestes Mojo#", - /*spanish*/ "una cueva con #dos mercaderes deku#" }, - }); - - hintTable[ZR_STORMS_GROTTO] = HintText::Region({ - // obscure text - Text{ "2 Deku Scrubs", /*french*/ "une #grotte avec deux pestes Mojo#", - /*spanish*/ "una cueva con #dos mercaderes deku#" }, - }); - - hintTable[SFM_STORMS_GROTTO] = HintText::Region({ - // obscure text - Text{ "2 Deku Scrubs", /*french*/ "une #grotte avec deux pestes Mojo#", - /*spanish*/ "una cueva con #dos mercaderes deku#" }, - }); - - hintTable[GV_STORMS_GROTTO] = HintText::Region({ - // obscure text - Text{ "2 Deku Scrubs", /*french*/ "une #grotte avec deux pestes Mojo#", - /*spanish*/ "una cueva con #dos mercaderes deku#" }, - }); - - hintTable[LH_GROTTO] = HintText::Region({ - // obscure text - Text{ "3 Deku Scrubs", /*french*/ "une #grotte avec trois pestes Mojo#", - /*spanish*/ "una cueva con #tres mercaderes deku#" }, - }); - - hintTable[DMC_HAMMER_GROTTO] = HintText::Region({ - // obscure text - Text{ "3 Deku Scrubs", /*french*/ "une #grotte avec trois pestes Mojo#", - /*spanish*/ "una cueva con #tres mercaderes deku#" }, - }); - - hintTable[GC_GROTTO] = HintText::Region({ - // obscure text - Text{ "3 Deku Scrubs", /*french*/ "une #grotte avec trois pestes Mojo#", - /*spanish*/ "una cueva con #tres mercaderes deku#" }, - }); - - hintTable[LLR_GROTTO] = HintText::Region({ - // obscure text - Text{ "3 Deku Scrubs", /*french*/ "une #grotte avec trois pestes Mojo#", - /*spanish*/ "una cueva con #tres mercaderes deku#" }, - }); - - hintTable[ZR_FAIRY_GROTTO] = HintText::Region({ - // obscure text - Text{ "a small #Fairy Fountain#", /*french*/ "une #fontaine de fées#", - /*spanish*/ "una pequeña #fuente de hadas#" }, - }); - - hintTable[HF_FAIRY_GROTTO] = HintText::Region({ - // obscure text - Text{ "a small #Fairy Fountain#", /*french*/ "une #fontaine de fées#", - /*spanish*/ "una pequeña #fuente de hadas#" }, - }); - - hintTable[SFM_FAIRY_GROTTO] = HintText::Region({ - // obscure text - Text{ "a small #Fairy Fountain#", /*french*/ "une #fontaine de fées#", - /*spanish*/ "una pequeña #fuente de hadas#" }, - }); - - hintTable[ZD_STORMS_GROTTO] = HintText::Region({ - // obscure text - Text{ "a small #Fairy Fountain#", /*french*/ "une #fontaine de fées#", - /*spanish*/ "una pequeña #fuente de hadas#" }, - }); - - hintTable[GF_STORMS_GROTTO] = HintText::Region({ - // obscure text - Text{ "a small #Fairy Fountain#", /*french*/ "une #fontaine de fées#", - /*spanish*/ "una pequeña #fuente de hadas#" }, - }); + hintTextTable[RHT_KF_LINKS_HOUSE] = HintText(CustomMessage("Link's House", + /*german*/ "Links Haus", + /*french*/ "la #maison de @#")); + // /*spanish*/la casa de @ + + hintTextTable[RHT_KF_MIDOS_HOUSE] = HintText(CustomMessage("Mido's house", + /*german*/ "Midos Haus", + /*french*/ "la Cabane du Grand Mido")); + // /*spanish*/la casa de Mido + + hintTextTable[RHT_KF_SARIAS_HOUSE] = HintText(CustomMessage("Saria's House", + /*german*/ "Salias Haus", + /*french*/ "la Cabane de Saria")); + // /*spanish*/la casa de Saria + + hintTextTable[RHT_KF_HOUSE_OF_TWINS] = HintText(CustomMessage("the #House of Twins#", + /*german*/ "das #Haus der Zwillinge#", + /*french*/ "la Cabane des Jumelles")); + // /*spanish*/la casa de las gemelas + + hintTextTable[RHT_KF_KNOW_IT_ALL_HOUSE] = HintText(CustomMessage("Know-It-All Brothers' House", + /*german*/ "das #Haus der allwissenden Brüder#", + /*french*/ "la Cabane des frères Je-Sais-Tout")); + // /*spanish*/la casa de los hermanos Sabelotodo + + hintTextTable[RHT_KF_KOKIRI_SHOP] = HintText(CustomMessage("the #Kokiri Shop#", + /*german*/ "der #Kokiri-Laden#", + /*french*/ "le #Magasin Kokiri#")); + // /*spanish*/la tienda kokiri + + hintTextTable[RHT_LH_LAB] = HintText(CustomMessage("the #Lakeside Laboratory#", + /*german*/ "das #Laboratorium des Sees#", + /*french*/ "le #Laboratoire du Lac#")); + // /*spanish*/el laboratorio del lago + + hintTextTable[RHT_LH_FISHING_HOLE] = HintText(CustomMessage("the #Fishing Pond#", + /*german*/ "der #Angelteich#", + /*french*/ "l'#Étang#")); + // /*spanish*/el estanque + + hintTextTable[RHT_GV_CARPENTER_TENT] = HintText(CustomMessage("the #Carpenters' tent#", + /*german*/ "das #Zelt der Zimmerleute#", + /*french*/ "la #Tente des charpentiers#")); + // /*spanish*/la #tienda de campaña de los carpinteros# + + hintTextTable[RHT_MARKET_GUARD_HOUSE] = HintText(CustomMessage("the #Guard House#", + /*german*/ "das #Haus der Wachen#", + /*french*/ "le #poste de garde#")); + // /*spanish*/la caseta de guardia + + hintTextTable[RHT_MARKET_MASK_SHOP] = HintText(CustomMessage("the #Happy Mask Shop#", + /*german*/ "der #Fröhliche Maskenladen#", + /*french*/ "la #Foire Aux Masques#")); + // /*spanish*/la tienda de La Máscara Feliz + + hintTextTable[RHT_MARKET_BOMBCHU_BOWLING] = HintText(CustomMessage("the #Bombchu Bowling Alley#", + /*german*/ "die #Krabbelminenbowlingbahn", + /*french*/ "le #Bowling Teigneux#")); + // /*spanish*/la Bolera Bombchu + + hintTextTable[RHT_MARKET_POTION_SHOP] = HintText(CustomMessage("the #Market Potion Shop#", + /*german*/ "der #Magie-Laden des Marktes#", + /*french*/ "l'#apothicaire de la Place du Marché#")); + // /*spanish*/la tienda de pociones de la plaza del mercado + + hintTextTable[RHT_MARKET_TREASURE_CHEST_GAME] = HintText(CustomMessage("the #Treasure Chest Shop#", + /*german*/ "der #Schatztruhen-Laden#", + /*french*/ "la #Chasse-aux-Trésors#")); + // /*spanish*/el Cofre del Tesoro + + hintTextTable[RHT_MARKET_BOMBCHU_SHOP] = HintText(CustomMessage("the #Bombchu Shop#", + /*german*/ "der #Krabbelminen-Laden#", + /*french*/ "le #Magasin de Missiles#")); + // /*spanish*/la Tienda Bombchu + + hintTextTable[RHT_MARKET_MAN_IN_GREEN_HOUSE] = HintText(CustomMessage("Man in Green's House", + /*german*/ "das #Haus des Mannes in grün#", + /*french*/ "la #Maison de l'Homme en Vert#")); + // /*spanish*/la casa del hombre de verde + + hintTextTable[RHT_KAK_WINDMILL] = HintText(CustomMessage("the #Windmill#", + /*german*/ "die #Windmühle#", + /*french*/ "le #Moulin#")); + // /*spanish*/el #molino# + + hintTextTable[RHT_KAK_CARPENTER_BOSS_HOUSE] = HintText(CustomMessage("the #Carpenters' Boss House#", + /*german*/ "das #Haus des Chefs der Zimmerleute#", + /*french*/ "la #Maison du Chef des ouvriers#")); + // /*spanish*/la casa del capataz de los carpinteros + + hintTextTable[RHT_KAK_HOUSE_OF_SKULLTULA] = HintText(CustomMessage("the #House of Skulltula#", + /*german*/ "das #Haus der Skulltula#", + /*french*/ "la #Maison des Skulltulas#")); + // /*spanish*/la casa de las Skulltulas + + hintTextTable[RHT_KAK_IMPAS_HOUSE] = HintText(CustomMessage("Impa's House", + /*german*/ "das #Haus von Impa#", + /*french*/ "la #Maison d'Impa#")); + // /*spanish*/la casa de Impa + + hintTextTable[RHT_KAK_IMPAS_HOUSE_BACK] = HintText(CustomMessage("Impa's cow cage", + /*german*/ "der #Kuhkäfig von Impa#", + /*french*/ "la #cage à vache d'Impa#")); + // /*spanish*/la jaula de la vaca de Impa + + hintTextTable[RHT_KAK_ODD_POTION_BUILDING] = HintText(CustomMessage("Granny's Potion Shop", + /*german*/ "Asas Hexenladen", + /*french*/ "la #maison bleue de Cocorico#")); + // /*spanish*/la tienda de pociones de la abuela + + hintTextTable[RHT_GRAVEYARD_DAMPES_HOUSE] = HintText(CustomMessage("Dampé's Hut", + /*german*/ "der #Hut von Boris#", + /*french*/ "la #Cabane du Fossoyeur#")); + // /*spanish*/la cabaña de Dampé + + hintTextTable[RHT_GC_SHOP] = HintText(CustomMessage("the #Goron Shop#", + /*german*/ "der #Goronen-Laden#", + /*french*/ "la #Boutique Goron#")); + // /*spanish*/la #tienda goron# + + hintTextTable[RHT_ZD_SHOP] = HintText(CustomMessage("the #Zora Shop#", + /*german*/ "der #Zora-Laden#", + /*french*/ "la #Boutique Zora#")); + // /*spanish*/la #tienda zora# + + hintTextTable[RHT_LLR_TALONS_HOUSE] = HintText(CustomMessage("Talon's House", + /*german*/ "das #Haus von Talon#", + /*french*/ "la #Maison de Talon#")); + // /*spanish*/la casa de Talon + + hintTextTable[RHT_LLR_STABLES] = HintText(CustomMessage("a #stable#", + /*german*/ "ein #Stall#", + /*french*/ "l'#Étable#")); + // /*spanish*/el establo + + hintTextTable[RHT_LLR_TOWER] = HintText(CustomMessage("the #Lon Lon Tower#", + /*german*/ "der #Lon Lon-Turm#", + /*french*/ "le #silo du Ranch Lon Lon#")); + // /*spanish*/la torre Lon Lon + + hintTextTable[RHT_MARKET_BAZAAR] = HintText(CustomMessage("the #Market Bazaar#", + /*german*/ "der #Basar des Marktes#", + /*french*/ "le #Bazar de la Place du Marché#")); + // /*spanish*/el bazar de la plaza del mercado + + hintTextTable[RHT_MARKET_SHOOTING_GALLERY] = HintText(CustomMessage("a #Slingshot Shooting Gallery#", + /*german*/ "die #Schießbude des Marktes#", + /*french*/ "le #Jeu d'Adresse de la Place du Marché#")); + // /*spanish*/el Tiro al Blanco con tirachinas + + hintTextTable[RHT_KAK_BAZAAR] = HintText(CustomMessage("the #Kakariko Bazaar#", + /*german*/ "der #Basar von Kakariko#", + /*french*/ "le #Bazar de Cocorico#")); + // /*spanish*/el bazar de Kakariko + + hintTextTable[RHT_KAK_POTION_SHOP_FRONT] = HintText(CustomMessage("the #Kakariko Potion Shop#", + /*german*/ "der #Magie-Laden von Kakariko#", + /*french*/ "l'#apothicaire de Cocorico#")); + // /*spanish*/la tienda de pociones de Kakariko + + hintTextTable[RHT_KAK_POTION_SHOP_BACK] = HintText(CustomMessage("the #Kakariko Potion Shop#", + /*german*/ "der #Magie-Laden von Kakariko#", + /*french*/ "l'#apothicaire de Cocorico#")); + // /*spanish*/la tienda de pociones de Kakariko + + hintTextTable[RHT_KAK_SHOOTING_GALLERY] = HintText(CustomMessage("a #Bow Shooting Gallery#", + /*german*/ "eine #Schießbude von Kakariko#", + /*french*/ "le #jeu d'adresse de Cocorico#")); + // /*spanish*/el Tiro al Blanco con arco + + hintTextTable[RHT_COLOSSUS_GREAT_FAIRY_FOUNTAIN] = HintText(CustomMessage("a #Great Fairy Fountain#", + /*german*/ "eine #Feen-Quelle#", + /*french*/ "une #Fontaine Royale des Fées#")); + // /*spanish*/una fuente de la Gran Hada + + hintTextTable[RHT_HC_GREAT_FAIRY_FOUNTAIN] = HintText(CustomMessage("a #Great Fairy Fountain#", + /*german*/ "eine #Feen-Quelle#", + /*french*/ "une #Fontaine Royale des Fées#")); + // /*spanish*/una fuente de la Gran Hada + + hintTextTable[RHT_OGC_GREAT_FAIRY_FOUNTAIN] = HintText(CustomMessage("a #Great Fairy Fountain#", + /*german*/ "eine #Feen-Quelle#", + /*french*/ "une #Fontaine Royale des Fées#")); + // /*spanish*/una fuente de la Gran Hada + + hintTextTable[RHT_DMC_GREAT_FAIRY_FOUNTAIN] = HintText(CustomMessage("a #Great Fairy Fountain#", + /*german*/ "eine #Feen-Quelle#", + /*french*/ "une #Fontaine Royale des Fées#")); + // /*spanish*/una fuente de la Gran Hada + + hintTextTable[RHT_DMT_GREAT_FAIRY_FOUNTAIN] = HintText(CustomMessage("a #Great Fairy Fountain#", + /*german*/ "eine #Feen-Quelle#", + /*french*/ "une #Fontaine Royale des Fées#")); + // /*spanish*/una fuente de la Gran Hada + + hintTextTable[RHT_ZF_GREAT_FAIRY_FOUNTAIN] = HintText(CustomMessage("a #Great Fairy Fountain#", + /*german*/ "eine #Feen-Quelle#", + /*french*/ "une #Fontaine Royale des Fées#")); + // /*spanish*/una fuente de la Gran Hada + + hintTextTable[RHT_GRAVEYARD_SHIELD_GRAVE] = HintText(CustomMessage("a #grave with a free chest#", + /*german*/ "ein #Grab mit einer Gratistruhe#", + /*french*/ "le #tombeau avec un trésor#")); + // /*spanish*/la #tumba con un cofre# + + hintTextTable[RHT_GRAVEYARD_HEART_PIECE_GRAVE] = HintText(CustomMessage("a chest spawned by #Sun's Song#", + /*german*/ "eine von der #Hymne der Sonne# geschaffene Truhe", + /*french*/ "un #coffre apparaît avec le Chant du Soleil#")); + // /*spanish*/la #tumba de la Canción del Sol# + + hintTextTable[RHT_GRAVEYARD_COMPOSERS_GRAVE] = HintText(CustomMessage("the #Composers' Grave#", + /*german*/ "das Königsgrab", + /*french*/ "la #Tombe royale#")); + // /*spanish*/el #Panteón Real# + + hintTextTable[RHT_GRAVEYARD_DAMPES_GRAVE] = HintText(CustomMessage("Dampé's Grave", + /*german*/ "das Grab von Boris", + /*french*/ "la #Tombe d'Igor#")); + // /*spanish*/la #tumba de Dampé# + + hintTextTable[RHT_DMT_COW_GROTTO] = HintText(CustomMessage("a solitary #Cow#", + /*german*/ "eine solitäre #Kuh#", + /*french*/ "la #grotte avec une vache#")); + // /*spanish*/una #vaca# solitaria + + hintTextTable[RHT_HC_STORMS_GROTTO] = HintText(CustomMessage("a sandy grotto with #fragile walls#", + /*german*/ "eine sandige Grotte mit #fragilen Wänden#", + /*french*/ "la #grotte avec des murs fragiles#")); + // /*spanish*/la arenosa gruta de #frágiles paredes# + + hintTextTable[RHT_HF_TEKTITE_GROTTO] = HintText(CustomMessage("a pool guarded by a #Tektite#", + /*german*/ "ein poolbewachender #Arachno#", + /*french*/ "l'#étang sous-terrain avec un Araknon#")); + // /*spanish*/un charco custodiado por un #Tektite# + + hintTextTable[RHT_HF_NEAR_KAK_GROTTO] = HintText(CustomMessage("a #Big Skulltula# guarding a Gold one", + /*german*/ "eine goldene Skulltula bewachende #große Skulltula#", + /*french*/ "la #grotte d'araignées#")); + // /*spanish*/una #gran Skulltula# custodiando una dorada + + hintTextTable[RHT_HF_COW_GROTTO] = HintText(CustomMessage("a grotto full of #spider webs#", + /*german*/ "eine mit #Spinnweben# gefüllte Grotte", + /*french*/ "la #grotte couverte de toiles d'araignées#")); + // /*spanish*/una gruta llena de #telarañas# + + hintTextTable[RHT_KAK_REDEAD_GROTTO] = HintText(CustomMessage("#ReDeads# guarding a chest", + /*german*/ "truhenbewachende #Remorts#", + /*french*/ "le tombeau de #deux morts#")); + // /*spanish*/los #ReDeads# que custodian un cofre + + hintTextTable[RHT_SFM_WOLFOS_GROTTO] = HintText(CustomMessage("#Wolfos# guarding a chest", + /*german*/ "truhenbewachende #Wolfos#", + /*french*/ "la #grotte iridescente#")); + // /*spanish*/los #Wolfos# que custodian un cofre + + hintTextTable[RHT_GV_OCTOROK_GROTTO] = HintText(CustomMessage("an #Octorok# guarding a rich pool", + /*german*/ "ein poolbewachender #Oktorok#", + /*french*/ "un #étang sous-terrain avec un Octorok#")); + // /*spanish*/un #Octorok# que custodia un lujoso charco + + hintTextTable[RHT_DEKU_THEATER] = HintText(CustomMessage("the #Lost Woods Stage#", + /*german*/ "die #Verlorenen Wälder#", + /*french*/ "le #théâtre sylvestre#")); + // /*spanish*/el #escenario del Bosque Perdido# + + hintTextTable[RHT_ZR_OPEN_GROTTO] = HintText(CustomMessage("a #generic grotto#", + /*german*/ "eine #generische Grotte#", + /*french*/ "une #grotte avec un trésor#")); + // /*spanish*/una #cueva genérica# + + hintTextTable[RHT_DMC_UPPER_GROTTO] = HintText(CustomMessage("a #generic grotto#", + /*german*/ "eine #generische Grotte#", + /*french*/ "une #grotte avec un trésor#")); + // /*spanish*/una #cueva genérica# + + hintTextTable[RHT_DMT_STORMS_GROTTO] = HintText(CustomMessage("a #generic grotto#", + /*german*/ "eine #generische Grotte#", + /*french*/ "une #grotte avec un trésor#")); + // /*spanish*/una #cueva genérica# + + hintTextTable[RHT_KAK_OPEN_GROTTO] = HintText(CustomMessage("a #generic grotto#", + /*german*/ "eine #generische Grotte#", + /*french*/ "une #grotte avec un trésor#")); + // /*spanish*/una #cueva genérica# + + hintTextTable[RHT_HF_NEAR_MARKET_GROTTO] = HintText(CustomMessage("a #generic grotto#", + /*german*/ "eine #generische Grotte#", + /*french*/ "une #grotte avec un trésor#")); + // /*spanish*/una #cueva genérica# + + hintTextTable[RHT_HF_OPEN_GROTTO] = HintText(CustomMessage("a #generic grotto#", + /*german*/ "eine #generische Grotte#", + /*french*/ "une #grotte avec un trésor#")); + // /*spanish*/una #cueva genérica# + + hintTextTable[RHT_HF_SOUTHEAST_GROTTO] = HintText(CustomMessage("a #generic grotto#", + /*german*/ "eine #generische Grotte#", + /*french*/ "une #grotte avec un trésor#")); + // /*spanish*/una #cueva genérica# + + hintTextTable[RHT_KF_STORMS_GROTTO] = HintText(CustomMessage("a #generic grotto#", + /*german*/ "eine #generische Grotte#", + /*french*/ "une #grotte avec un trésor#")); + // /*spanish*/una #cueva genérica# + + hintTextTable[RHT_LW_NEAR_SHORTCUTS_GROTTO] = HintText(CustomMessage("a #generic grotto#", + /*german*/ "eine #generische Grotte#", + /*french*/ "une #grotte avec un trésor#")); + // /*spanish*/una #cueva genérica# + + hintTextTable[RHT_HF_INSIDE_FENCE_GROTTO] = HintText(CustomMessage("a #single Upgrade Deku Scrub#", + /*german*/ "ein #einzelner Upgrade-Deku#", + /*french*/ "une #grotte avec une peste Mojo#")); + // /*spanish*/una cueva con un #solitario mercader deku# + + hintTextTable[RHT_LW_SCRUBS_GROTTO] = HintText(CustomMessage("#2 Deku Scrubs# including an Upgrade one", + /*german*/ "#zwei Dekus# inklusive einem Upgrade-Deku", + /*french*/ "une #grotte avec deux pestes Mojo#")); + // /*spanish*/una cueva con #dos mercaderes deku# + + hintTextTable[RHT_COLOSSUS_GROTTO] = HintText(CustomMessage("2 Deku Scrubs", + /*german*/ "zwei Dekus", + /*french*/ "une #grotte avec deux pestes Mojo#")); + // /*spanish*/una cueva con #dos mercaderes deku# + + hintTextTable[RHT_ZR_STORMS_GROTTO] = HintText(CustomMessage("2 Deku Scrubs", + /*german*/ "zwei Dekus", + /*french*/ "une #grotte avec deux pestes Mojo#")); + // /*spanish*/una cueva con #dos mercaderes deku# + + hintTextTable[RHT_SFM_STORMS_GROTTO] = HintText(CustomMessage("2 Deku Scrubs", + /*german*/ "zwei Dekus", + /*french*/ "une #grotte avec deux pestes Mojo#")); + // /*spanish*/una cueva con #dos mercaderes deku# + + hintTextTable[RHT_GV_STORMS_GROTTO] = HintText(CustomMessage("2 Deku Scrubs", + /*german*/ "zwei Dekus", + /*french*/ "une #grotte avec deux pestes Mojo#")); + // /*spanish*/una cueva con #dos mercaderes deku# + + hintTextTable[RHT_LH_GROTTO] = HintText(CustomMessage("3 Deku Scrubs", + /*german*/ "drei Dekus", + /*french*/ "une #grotte avec trois pestes Mojo#")); + // /*spanish*/una cueva con #tres mercaderes deku# + + hintTextTable[RHT_DMC_HAMMER_GROTTO] = HintText(CustomMessage("3 Deku Scrubs", + /*german*/ "drei Dekus", + /*french*/ "une #grotte avec trois pestes Mojo#")); + // /*spanish*/una cueva con #tres mercaderes deku# + + hintTextTable[RHT_GC_GROTTO] = HintText(CustomMessage("3 Deku Scrubs", + /*german*/ "drei Dekus", + /*french*/ "une #grotte avec trois pestes Mojo#")); + // /*spanish*/una cueva con #tres mercaderes deku# + + hintTextTable[RHT_LLR_GROTTO] = HintText(CustomMessage("3 Deku Scrubs", + /*german*/ "drei Dekus", + /*french*/ "une #grotte avec trois pestes Mojo#")); + // /*spanish*/una cueva con #tres mercaderes deku# + + hintTextTable[RHT_ZR_FAIRY_GROTTO] = HintText(CustomMessage("a small #Fairy Fountain#", + /*german*/ "ein kleiner #Feen-Brunnen#", + /*french*/ "une #fontaine de fées#")); + // /*spanish*/una pequeña #fuente de hadas# + + hintTextTable[RHT_HF_FAIRY_GROTTO] = HintText(CustomMessage("a small #Fairy Fountain#", + /*german*/ "ein kleiner #Feen-Brunnen#", + /*french*/ "une #fontaine de fées#")); + // /*spanish*/una pequeña #fuente de hadas# + + hintTextTable[RHT_SFM_FAIRY_GROTTO] = HintText(CustomMessage("a small #Fairy Fountain#", + /*german*/ "ein kleiner #Feen-Brunnen#", + /*french*/ "une #fontaine de fées#")); + // /*spanish*/una pequeña #fuente de hadas# + + hintTextTable[RHT_ZD_STORMS_GROTTO] = HintText(CustomMessage("a small #Fairy Fountain#", + /*german*/ "ein kleiner #Feen-Brunnen#", + /*french*/ "une #fontaine de fées#")); + // /*spanish*/una pequeña #fuente de hadas# + + hintTextTable[RHT_GF_STORMS_GROTTO] = HintText(CustomMessage("a small #Fairy Fountain#", + /*german*/ "ein kleiner #Feen-Brunnen#", + /*french*/ "une #fontaine de fées#")); + // /*spanish*/una pequeña #fuente de hadas# /*-------------------------- | JUNK HINT TEXT | ---------------------------*/ - hintTable[JUNK02] = HintText::Junk({ - // obscure text - Text{ "They say you must read the names of \"Special Deal\" shop items carefully.", - /*french*/ "Selon moi, les \"Offres spéciales\" sont parfois trompeuses... Lisez les attentivement!", - /*spanish*/ "Según dicen, se debería prestar atención a los nombres de las ofertas especiales." }, - }); - - hintTable[JUNK03] = HintText::Junk({ - // obscure text - Text{ "They say that Zelda is a poor leader.", /*french*/ "Selon moi, Zelda ne ferait pas un bon monarque.", - /*spanish*/ "Según dicen, Zelda es mala líder." }, - }); - - hintTable[JUNK04] = HintText::Junk({ - // obscure text - Text{ "These hints can be quite useful. This is an exception.", - /*french*/ "Ces indices sont très utiles, à l'exception de celui-ci.", - /*spanish*/ "Las pistas suelen servir de ayuda. En cambio, esta no." }, - }); - - hintTable[JUNK05] = HintText::Junk({ - // obscure text - Text{ "They say that the Lizalfos in Dodongo's Cavern like to play in lava.", - /*french*/ "Selon moi, les Lézalfos de la Caverne Dodongo aiment patauger dans la lave.", - /*spanish*/ "Según dicen, a los Lizalfos de la Cueva de los Dodongos les gusta jugar en la lava." }, - }); - - hintTable[JUNK06] = HintText::Junk({ - // obscure text - Text{ "They say that all the Zora drowned in Wind Waker.", - /*french*/ "Selon moi, les Zoras se sont noyés dans Wind Waker.", - /*spanish*/ "Según dicen, en Wind Waker todos los zora se ahogaron." }, - }); - - hintTable[JUNK07] = HintText::Junk({ - // obscure text - Text{ "If Gorons eat rocks, does that mean I'm in danger?", - /*french*/ "Ne dis pas au Gorons que je suis ici. Ils mangent des roches, tu sais!", - /*spanish*/ "Si los Goron se tragan las piedras, ¿no me hace ser una especia vulnarable o algo así" }, - }); - - hintTable[JUNK08] = HintText::Junk({ - // obscure text - Text{ - "'Member when Ganon was a blue pig?^I 'member.", - /*french*/ "Dans mon temps, Ganon était un cochon bleu...^Pff! Les jeunes de nos jours, et leur Ganondorf!", - /*spanish*/ "¿T'acuerdas cuando Ganon era un cerdo azul?^Qué tiempos, chico." }, - }); - - hintTable[JUNK09] = HintText::Junk({ - // obscure text - Text{ "One who does not have Triforce can't go in.", /*french*/ "Ceux sans Triforce doivent rebrousser chemin.", - /*spanish*/ "Aquel que no porte la Trifuerza no podrá pasar." }, - }); - - hintTable[JUNK10] = HintText::Junk({ - // obscure text - Text{ "Save your future, end the Happy Mask Salesman.", - /*french*/ "Selon moi, tu t'éviteras des jours de malheur si tu vaincs le vendeur de masques...", - /*spanish*/ "Salva tu futuro, acaba con el dueño de La Máscara Feliz." }, - }); - - hintTable[JUNK11] = HintText::Junk({ - // obscure text - Text{ "Glitches are a pathway to many abilities some consider to be... Unnatural.", /*french*/ - "Les glitchs sont un moyen d'acquérir de nombreuses facultés considérées par certains comme... contraire " - "à la nature.", - /*spanish*/ "Los glitches son el camino a muchas habilidades que varios consideran... nada natural." }, - }); - - hintTable[JUNK12] = HintText::Junk({ - // obscure text - Text{ "I'm stoned. Get it?", /*french*/ "Allez, roche, papier, ciseau...&Roche.", - /*spanish*/ "Me he quedado de piedra. ¿Lo pillas?" }, - }); - - hintTable[JUNK13] = HintText::Junk({ - // obscure text - Text{ "Hoot! Hoot! Would you like me to repeat that?", /*french*/ "Hou hou! Veux-tu que je répète tout ça?", - /*spanish*/ "¡Buuu, buuu! ¿Te lo vuelvo a repetir?" }, - }); - - hintTable[JUNK14] = HintText::Junk({ - // obscure text - Text{ "Gorons are stupid. They eat rocks.", /*french*/ "Les Gorons sont des vraies têtes dures.", - /*spanish*/ "Los Goron son tontos. Se comen las piedras." }, - }); - - hintTable[JUNK15] = HintText::Junk({ - // obscure text - Text{ "They say that Lon Lon Ranch prospered under Ingo.", - /*french*/ "Selon moi, le Ranch Lon Lon était plus prospère sous Ingo.", - /*spanish*/ "Según dicen, el Rancho Lon Lon prosperó gracias a Ingo." }, - }); - - hintTable[JUNK16] = HintText::Junk({ - // obscure text - Text{ "The single rupee is a unique item.", /*french*/ "Nul objet n'est plus unique que le rubis vert.", - /*spanish*/ "La rupia de uno es un objeto singular." }, - }); - - hintTable[JUNK17] = HintText::Junk({ - // obscure text - Text{ "Without the Lens of Truth, the Treasure Chest Mini-Game is a 1 out of 32 chance.^Good luck!", - /*french*/ "Gagner la Chasse-aux-Trésors est 1 chance sur 32.^Bonne chance!", /*spanish*/ - "Sin la Lupa de la Verdad, ganarías 1/32 veces en el Cofre del Tesoro.^¡Buena suerte con ello!" }, - }); - - hintTable[JUNK18] = HintText::Junk({ - // obscure text - Text{ "Use bombs wisely.", /*french*/ "Utilise les bombes avec précaution.", - /*spanish*/ "No desperdicies las bombas." }, - }); - - hintTable[JUNK19] = HintText::Junk({ - // obscure text - Text{ "They say that Volvagia hates splinters", /*french*/ "Selon moi, Volvagia déteste les échardes.", - /*spanish*/ "Según dicen, Volvagia le teme a las astillas." }, - }); - - hintTable[JUNK20] = HintText::Junk({ - // obscure text - Text{ "They say that funky monkeys can be spotted on Friday.", - /*french*/ "Selon moi, des capucins coquins sortent le vendredi.", - /*spanish*/ "Según dicen, en los viernes puedes hallar monos marchosos." }, - }); - - hintTable[JUNK21] = HintText::Junk({ - // obscure text - Text{ "I found you, faker!", /*french*/ "Ah-ha! Je t'ai trouvé!", /*spanish*/ "¡Ahí estás, impostor!" }, - }); - - hintTable[JUNK22] = HintText::Junk({ - // obscure text - Text{ "They say the Groose is loose.", /*french*/ "Selon moi, Hergo est le vrai héros.", - /*spanish*/ "Según dicen, Malton es un espanto." }, - }); - - hintTable[JUNK23] = HintText::Junk({ - // obscure text - Text{ - "They say that players who select the \"ON\" option for \"MOTION CONTROL\" are the real \"Zelda players!\"", - /*french*/ "Selon moi, ceux qui utilisent les contrôles gyroscopiques sont les VRAIS joueurs.", /*spanish*/ - "Según dicen, aquellos que juegan usando el control por movimiento son los verdaderos jugadores de " - "Zelda." }, - }); - - hintTable[JUNK24] = HintText::Junk({ - // obscure text - Text{ "What happened to Sheik?", /*french*/ "Donc... Qu'est-ce qui arrive avec Sheik?", - /*spanish*/ "¿Qué la habrá pasado a Sheik?" }, - }); - - hintTable[JUNK25] = HintText::Junk({ - // obscure text - Text{ "L2P @.", /*french*/ "Arrête de lire les indices et joue comme un grand, @.", - /*spanish*/ "Mira que eres novato, @." }, - }); - - hintTable[JUNK26] = HintText::Junk({ - // obscure text - Text{ "I've heard you can cheat at Sploosh Kaboom.", - /*french*/ "Selon moi, il y a une carte aux trésors à Mercantîle... Duh!", - /*spanish*/ "He oído por ahí que puedes hacer trampa en el Sploosh Kaboom." }, - }); - - hintTable[JUNK27] = HintText::Junk({ - // obscure text - Text{ "I'm Lonk from Pennsylvania.", /*french*/ "Je suis Lonk, le héros de Pennsylvanie!", - /*spanish*/ "Soy Lonk, de Pensilvania." }, - }); - - hintTable[JUNK28] = HintText::Junk({ - // obscure text - Text{ "I bet you'd like to have more bombs.", /*french*/ "Je parie que tu veux plus de bombes.", - /*spanish*/ "Me apuesto a que quisieras tener más bombas." }, - }); - - hintTable[JUNK29] = HintText::Junk({ - // obscure text - Text{ "When all else fails, use Fire.", /*french*/ "Quand rien ne marche, utilise le feu.", - /*spanish*/ "Cuando nada funcione, usa el fuego." }, - }); - - hintTable[JUNK30] = HintText::Junk({ - // obscure text - Text{ "Here's a hint, @. Don't be bad.", /*french*/ "Selon moi, la #Triforce# n'est pas dans le jeu... Duh!", - /*spanish*/ "Aquí tienes una pista, @: deja de ser manco." }, - }); - - hintTable[JUNK31] = HintText::Junk({ - // obscure text - Text{ "Game Over. Return of Ganon.", /*french*/ "Partie terminée. RETour de Ganon.", - /*spanish*/ "Fin de la partida. El regreso de Ganon." }, - }); - - hintTable[JUNK32] = HintText::Junk({ - // obscure text - Text{ "May the way of the Hero lead to the Triforce.", - /*french*/ "Que le chemin du héros te mène à la Triforce.", - /*spanish*/ "Puede que la senda del héroe te lleve hacia la Trifuerza." }, - }); - - hintTable[JUNK33] = HintText::Junk({ - // obscure text - Text{ "Can't find an item? Scan an Amiibo.", /*french*/ "Tu cherches de quoi? Utilise un Amiibo!", - /*spanish*/ "¿No encuentras algo? Escanea un amiibo." }, - }); - - hintTable[JUNK34] = HintText::Junk({ - // obscure text - Text{ "They say this game has just a few glitches.", - /*french*/ "Selon moi, ce jeu est complètement exempt de glitchs.", - /*spanish*/ "Dicen que este juego apenas tiene glitches." }, - }); - - hintTable[JUNK35] = HintText::Junk({ - // obscure text - Text{ "BRRING BRRING This is Ulrira. Wrong number?", - /*french*/ "DRING DRING!! Pépé le Ramollo à l'appareil... Quoi? Faux numéro?", - /*spanish*/ "¡Ring! ¡Ring! Al habla Ulrira. ¿Me he equivocado de número?" }, - }); - - hintTable[JUNK36] = HintText::Junk({ - // obscure text - Text{ "Tingle Tingle Kooloo Limpah!", /*french*/ "Tingle! Tingle! Kooloolin... Pah!", - /*spanish*/ "Tingle, Tingle, Kurulín... ¡PA!" }, - }); - - hintTable[JUNK37] = HintText::Junk({ - // obscure text - Text{ "L is real 2401", /*french*/ "L is real 2401", /*spanish*/ "L es real 2401." }, - }); - - hintTable[JUNK38] = HintText::Junk({ - // obscure text - Text{ "They say that Ganondorf will appear in the next Mario Tennis.", - /*french*/ "Selon moi, Ganondorf sera la nouvelle recrue dans Mario Tennis.", - /*spanish*/ "Según dicen, Ganondorf estará en el próximo Mario Tennis." }, - }); - - hintTable[JUNK39] = HintText::Junk({ - // obscure text - Text{ "Medigoron sells the earliest Breath of the Wild demo.", - /*french*/ "Selon moi, Medigoron vend une démo de #Breath of the Wild#.", - /*spanish*/ "Medigoron vende la primera demo del Breath of the Wild." }, - }); - - hintTable[JUNK40] = HintText::Junk({ - // obscure text - Text{ "Can you move me? I don't get great service here.", - /*french*/ "Peux-tu me déplacer? J'ai pas une bonne réception ici.", - /*spanish*/ "¿Puedes llevarme a otro lado? Aquí nadie me presta atención." }, - }); - - hintTable[JUNK41] = HintText::Junk({ - // obscure text - Text{ "They say if you use Strength on the truck, you can find Mew.", - /*french*/ "Selon moi, #Mew# se trouve dessous le camion... Duh!", - /*spanish*/ "Según dicen, puedes hallar un Mew usando Fuerza contra el camión de Ciudad Carmín." }, - }); - - hintTable[JUNK42] = HintText::Junk({ - // obscure text - Text{ "I'm a helpful hint Gossip Stone!^See, I'm helping.", - /*french*/ "Salut! Je suis une pierre de bons conseils!^Tiens, tu vois? J'aide bien, hein?", - /*spanish*/ "Soy una Piedra Sheikah muy útil.^¡Mira cómo te ayudo!" }, - }); - - hintTable[JUNK43] = HintText::Junk({ - // obscure text - Text{ - "Dear @, please come to the castle. I've baked a cake for you.&Yours truly, Princess Zelda.", /*french*/ - "Mon très cher @:&Viens vite au château, je t'ai préparé&un délicieux gâteau...^À bientôt, Princesse Zelda", - /*spanish*/ - "Querido @: Por favor, ven al castillo. He hecho una tarta para ti.&Sinceramente tuya: Princesa Zelda." }, - }); - - hintTable[JUNK44] = HintText::Junk({ - // obscure text - Text{ "They say all toasters toast toast.", /*french*/ "Selon moi, les grille-pains grillent du pain.", - /*spanish*/ "Según dicen, todas las tostadoras tostan tostadas tostadas." }, - }); - - hintTable[JUNK45] = HintText::Junk({ - // obscure text - Text{ "You thought it would be a useful hint, but it was me, junk hint!", - /*french*/ "Tu t'attendais à un bon indice... Mais c'était moi, un mauvais indice!", /*spanish*/ - "Je... Creeías que iba a ser una piedra de utilidad, ¡pero no, era yo, la piedra de la agonía!" }, - }); - - hintTable[JUNK46] = HintText::Junk({ - // obscure text - Text{ "They say that quest guidance can be found at a talking rock.", - /*french*/ "Selon moi, des #indices# se trouvent auprès d'une pierre parlante... Duh!", - /*spanish*/ "Según dicen, puedes consultarle ayuda a rocas parlanchinas." }, - }); - - hintTable[JUNK47] = HintText::Junk({ - // obscure text - Text{ "They say that the final item you're looking for can be found somewhere in Hyrule.", - /*french*/ "Selon moi, le #dernier objet# se trouve quelque part dans Hyrule... Duh!", - /*spanish*/ "Según dicen, el último objeto que te falte puede estar en cualquier rincón de Hyrule." }, - }); - - hintTable[JUNK48] = HintText::Junk({ - // obscure text - Text{ "Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.", - /*french*/ "Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.", - /*spanish*/ "Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep." }, - }); - - hintTable[JUNK49] = HintText::Junk({ - // obscure text - Text{ "They say that Barinade fears Deku Nuts.", /*french*/ "Selon moi, Barinade a la frousse des noix Mojo.", - /*spanish*/ "Según dicen, lo que más teme a Barinade son las nueces deku." }, - }); - - hintTable[JUNK50] = HintText::Junk({ - // obscure text - Text{ "They say that Flare Dancers do not fear Goron-crafted blades.", - /*french*/ "Selon moi, le danse-flamme n'a pas peur des armes de Goron.", - /*spanish*/ "Según dicen, los Bailafuegos no le temen a las armas forjadas por Gorons." }, - }); - - hintTable[JUNK51] = HintText::Junk({ - // obscure text - Text{ "They say that Morpha is easily trapped in a corner.", - /*french*/ "Selon moi, Morpha est facilement coincé.", - /*spanish*/ "Según dicen, puedes atrapar a Morpha con facilidad en una esquina." }, - }); - - hintTable[JUNK52] = HintText::Junk({ - // obscure text - Text{ "They say that Bongo Bongo really hates the cold.", - /*french*/ "Selon moi, Bongo Bongo a facilement froid aux doigts.", - /*spanish*/ "Según dicen, Bongo Bongo odia a muerte el frío." }, - }); - - hintTable[JUNK53] = HintText::Junk({ - // obscure text - Text{ "They say that your sword is most powerful when you put it away.", - /*french*/ "Selon moi, ton épée est à pleine puissance quand tu la rengaines.", - /*spanish*/ "Según dicen, tu espada se vuelve más poderosa si la guardas." }, - }); - - hintTable[JUNK54] = HintText::Junk({ - // obscure text - Text{ "They say that bombing the hole Volvagia last flew into can be rewarding.", - /*french*/ "Selon moi, le trou où se creuse Volvagia est vulnérable aux bombes.", /*spanish*/ - "Según dicen, trae buena suerte colocar una bomba en el último agujero de donde salió Volvagia." }, - }); - - hintTable[JUNK55] = HintText::Junk({ - // obscure text - Text{ "They say that invisible ghosts can be exposed with Deku Nuts.", - /*french*/ "Selon moi, des fantômes invisibles apparaissent avec des noix Mojo.", - /*spanish*/ "Según dicen, puedes exponer a los espectros invisibles con nueces deku." }, - }); - - hintTable[JUNK56] = HintText::Junk({ - // obscure text - Text{ "They say that the real Phantom Ganon is bright and loud.", - /*french*/ "Selon moi, le vrai spectre de Ganon est clair et bruyant.", - /*spanish*/ "Según dicen, el verdadero Ganon Fantasma es brillante y ruidoso." }, - }); - - hintTable[JUNK57] = HintText::Junk({ - // obscure text - Text{ "They say that walking backwards is very fast.", - /*french*/ "Selon moi, tu fais marche arrière très rapidement pour un héros.", - /*spanish*/ "Según dicen, es más rápido caminar hacia atrás." }, - }); - - hintTable[JUNK58] = HintText::Junk({ - // obscure text - Text{ - "They say that leaping above the Market entrance enriches most children.", - /*french*/ "Selon moi, les enfants riches se pavanent en haut du pont-levis.", - /*spanish*/ "Según dicen, saltar por las cadenas a la entrada de la plaza enriquece a muchos chiquillos." }, - }); - - hintTable[JUNK59] = HintText::Junk({ - // obscure text - Text{ "They say Ingo is not very good at planning ahead.", - /*french*/ "Selon moi, Ingo ne fait pas un très bon geôlier.", - /*spanish*/ "Según dicen, a Ingo no se le da especialmente bien planificar con antelación." }, - }); - - hintTable[JUNK60] = HintText::Junk({ - // obscure text - Text{ "You found a spiritual Stone! By which I mean, I worship Nayru.", - /*french*/ "Vous avez trouvé une Pierre Ancestrale! En effet, je vénère la déesse Hylia.", - /*spanish*/ "¡Has encontrado una piedra espiritual! Es que le rindo culto a Nayru..." }, - }); - - hintTable[JUNK61] = HintText::Junk({ - // obscure text - Text{ "They say that a flying strike with a Deku Stick is no stronger than a grounded one.", - /*french*/ "Selon moi, un coup de bâton sauté n'est pas meilleur qu'au sol.", - /*spanish*/ "Según dicen, los golpes aéreos con palos deku son tan fuertes como los normales." }, - }); - - hintTable[JUNK62] = HintText::Junk({ - // obscure text - Text{ "Open your eyes.^Open your eyes.^Wake up, @.", - /*french*/ "Réveille-toi...^Réveille-toi.^Ouvre les yeux, @.", - /*spanish*/ "Abre los ojos...^Abre los ojos...^Despierta, @..." }, - }); - - hintTable[JUNK63] = HintText::Junk({ - // obscure text - Text{ "They say that the Nocturne of Shadow can bring you very close to Ganon.", - /*french*/ "Selon moi, le nocturne de l'ombre peut t'amener très près de Ganon.", - /*spanish*/ "Según dicen, el Nocturno de la sombra te puede acercar mucho a Ganon." }, - }); - - hintTable[JUNK64] = HintText::Junk({ - // obscure text - Text{ "They say that Twinrova always casts the same spell the first three times.", - /*french*/ "Selon moi, Twinrova lance toujours les mêmes trois premiers sorts.", - /*spanish*/ "Según dicen, Birova siempre lanza el mismo hechizo las tres primeras veces." }, - }); - - hintTable[JUNK65] = HintText::Junk({ - // obscure text - Text{ "They say that the nightly builds may be unstable.", - /*french*/ "Selon moi, les \"nightly builds\" peuvent être instables.", - /*spanish*/ "Según dicen, las últimas nightlies pueden llegar a ser algo inestables." }, - }); - - hintTable[JUNK66] = HintText::Junk({ - // obscure text - Text{ "You're playing a Randomizer. I'm randomized!^Here's a random number: #4#.&Enjoy your Randomizer!", - /*french*/ "Tu joues à un randomizer. Je suis aléatoire!^Voici un nombre aléatoire: #4#.&Bonne partie!", - /*spanish*/ - "¡Estás jugando un Randomizer! ¡Yo también estoy aleatorizada!^Aquí tienes un número aleatorio: " - "#8#.&¡Diviértete!" }, - }); - - hintTable[JUNK67] = HintText::Junk({ - // obscure text - Text{ "They say Ganondorf's bolts can be reflected with glass or steel.", - /*french*/ "Selon moi, les éclairs de Ganon se reflètent sur l'acier et le verre.", - /*spanish*/ "Según dicen, puedes reflejar las esferas de energía de Ganondorf con cristal y acero." }, - }); - - hintTable[JUNK68] = HintText::Junk({ - // obscure text - Text{ "They say Ganon's tail is vulnerable to nuts, arrows, swords, explosives, hammers...^...sticks, seeds, " - "boomerangs...^...rods, shovels, iron balls, angry bees...", - /*french*/ - "Selon moi, la queue de Ganon est vulnérable aux noix, flèches, épées, bombes, marteaux...^...bâtons, " - "graines, boomerangs...^...baguettes, pelles, boulets de fer, abeilles enragées...", - /*spanish*/ - "Según dicen, la cola de Ganon es vulnerable a nueces, flechas, espadas, explosivos, " - "martillos...^...palos, semillas, bumeráns...^...cetros, palas, bolas de hierro, abejas..." }, - }); - - hintTable[JUNK69] = HintText::Junk({ - // obscure text - Text{ - "They say that you're wasting time reading this hint, but I disagree. Talk to me again!", - /*french*/ "Selon moi... tu sais quoi? Parle-moi encore, et je te le dirai!", /*spanish*/ - "Según dicen, pierdes el tiempo en leer esta pista, pero no pienso igual. ¡Vuelve a hablarme, ya verás!" }, - }); - - hintTable[JUNK70] = HintText::Junk({ - // obscure text - Text{ "They say Ganondorf knows where to find the instrument of his doom.", - /*french*/ "Selon moi, Ganondorf sait où il a caché son point faible.", - /*spanish*/ "Según dicen, Ganondorf sabe dónde hallar el instrumento de su perdición." }, - }); - - hintTable[JUNK71] = HintText::Junk({ - // obscure text - Text{ "I heard @ is pretty good at Zelda.", /*french*/ "Apparemment, @ est super bon à Zelda.", - /*spanish*/ "He oído que a @ se le dan muy bien los Zelda." }, - }); - - hintTable[JUNK72] = HintText::Junk({ - // obscure text - Text{ "Hi @, we've been trying to reach you about your car's extended warranty. ", - /*french*/ "Bonjour, @. Vous avez une voiture? Vous savez, nous offrons des assurances abordables...", - /*spanish*/ - "Buenas, @. Le llamamos para ofrecerle un nuevo seguro de hogar que puede pagar en cómodos plazos, sin " - "intereses ni comisiones." }, - }); - - hintTable[JUNK73] = HintText::Junk({ - // obscure text - Text{ "They say that the best weapon against Iron Knuckles is item 176.", - /*french*/ "Selon moi, les hache-viandes sont vulnérables contre l'objet 176.", - /*spanish*/ "Según dicen, la mejor arma para enfrentarse a los Nudillos de hierro es el objeto 176." }, - }); - - hintTable[JUNK74] = HintText::Junk({ - // obscure text - Text{ "They say that it's actually possible to beat the running man.", - /*french*/ "Selon moi, il est possible de battre le coureur.&Donc, tu prends ton arc, et...", - /*spanish*/ "Según dicen, con mucha perseverancia puedes ganarle al corredor con la capucha de conejo." }, - }); - - hintTable[JUNK75] = HintText::Junk({ - // obscure text - Text{ "They say that the stone-cold guardian of the Well is only present during work hours.", - /*french*/ "Selon moi, le gardien de pierre du Puits quitte le soir pour aller se coucher.", - /*spanish*/ "Según dicen, la inmensa roca que bloquea el pozo solo trabaja en horas laborales." }, - }); - - hintTable[JUNK76] = HintText::Junk({ - // obscure text - Text{ - "They say this hint makes more sense in other languages.", - /*french*/ "Selon moi, ces indices auraient pu être mieux traduits... Duh!", - /*spanish*/ "Según dicen, esta pista revela algo de vital importancia si cambias el idioma del juego..." }, - }); - - hintTable[JUNK77] = HintText::Junk({ - // obscure text - Text{ "BOK? No way.", /*french*/ "BD'accord? Hors de question.", /*spanish*/ "¿BVale? Ni hablar." }, - }); + hintTextTable[RHT_JUNK02] = HintText(CustomMessage("They say you must read the names of \"Special Deal\" shop items carefully.", + /*german*/ "", + /*french*/ "Selon moi, les \"Offres spéciales\" sont parfois trompeuses... Lisez les attentivement!")); + // /*spanish*/"Según dicen, se debería prestar atención a los nombres de las ofertas especiales." + + hintTextTable[RHT_JUNK03] = HintText(CustomMessage("They say that Zelda is a poor leader.", + /*german*/ "", + /*french*/ "Selon moi, Zelda ne ferait pas un bon monarque.")); + // /*spanish*/Según dicen, Zelda es mala líder. + + hintTextTable[RHT_JUNK04] = HintText(CustomMessage("These hints can be quite useful. This is an exception.", + /*german*/ "", + /*french*/ "Ces indices sont très utiles, à l'exception de celui-ci.")); + // /*spanish*/Las pistas suelen servir de ayuda. En cambio, esta no. + + hintTextTable[RHT_JUNK05] = HintText(CustomMessage("They say that the Lizalfos in Dodongo's Cavern like to play in lava.", + /*german*/ "", + /*french*/ "Selon moi, les Lézalfos de la Caverne Dodongo aiment patauger dans la lave.")); + // /*spanish*/Según dicen, a los Lizalfos de la Cueva de los Dodongos les gusta jugar en la lava. + + hintTextTable[RHT_JUNK06] = HintText(CustomMessage("They say that all the Zora drowned in Wind Waker.", + /*german*/ "", + /*french*/ "Selon moi, les Zoras se sont noyés dans Wind Waker.")); + // /*spanish*/Según dicen, en Wind Waker todos los zora se ahogaron. + + hintTextTable[RHT_JUNK07] = HintText(CustomMessage("If Gorons eat rocks, does that mean I'm in danger?", + /*german*/ "", + /*french*/ "Ne dis pas au Gorons que je suis ici. Ils mangent des roches, tu sais!")); + // /*spanish*/Si los Goron se tragan las piedras, ¿no me hace ser una especia vulnarable o algo así + + hintTextTable[RHT_JUNK08] = HintText(CustomMessage("'Member when Ganon was a blue pig?^I 'member.", + /*german*/ "", + /*french*/ "Dans mon temps, Ganon était un cochon bleu...^Pff! Les jeunes de nos jours, et leur Ganondorf!")); + // /*spanish*/¿T'acuerdas cuando Ganon era un cerdo azul?^Qué tiempos, chico. + + hintTextTable[RHT_JUNK09] = HintText(CustomMessage("One who does not have Triforce can't go in.", + /*german*/ "", + /*french*/ "Ceux sans Triforce doivent rebrousser chemin.")); + // /*spanish*/Aquel que no porte la Trifuerza no podrá pasar. + + hintTextTable[RHT_JUNK10] = HintText(CustomMessage("Save your future, end the Happy Mask Salesman.", + /*german*/ "", + /*french*/ "Selon moi, tu t'éviteras des jours de malheur si tu vaincs le vendeur de masques...")); + // /*spanish*/Salva tu futuro, acaba con el dueño de La Máscara Feliz. + + hintTextTable[RHT_JUNK11] = HintText(CustomMessage("Glitches are a pathway to many abilities some consider to be... Unnatural.", + /*german*/ "", + /*french*/ "Les glitchs sont un moyen d'acquérir de nombreuses facultés considérées par certains comme... contraire ")); + // /*spanish*/ Los glitches son el camino a muchas habilidades que varios consideran... nada natural. + + hintTextTable[RHT_JUNK12] = HintText(CustomMessage("I'm stoned. Get it?", + /*german*/ "", + /*french*/ "Allez, roche, papier, ciseau...&Roche.")); + // /*spanish*/Me he quedado de piedra. ¿Lo pillas? + + hintTextTable[RHT_JUNK13] = HintText(CustomMessage("Hoot! Hoot! Would you like me to repeat that?", + /*german*/ "", + /*french*/ "Hou hou! Veux-tu que je répète tout ça?")); + // /*spanish*/¡Buuu, buuu! ¿Te lo vuelvo a repetir? + + hintTextTable[RHT_JUNK14] = HintText(CustomMessage("Gorons are stupid. They eat rocks.", + /*german*/ "", + /*french*/ "Les Gorons sont des vraies têtes dures.")); + // /*spanish*/Los Goron son tontos. Se comen las piedras. + + hintTextTable[RHT_JUNK15] = HintText(CustomMessage("They say that Lon Lon Ranch prospered under Ingo.", + /*german*/ "", + /*french*/ "Selon moi, le Ranch Lon Lon était plus prospère sous Ingo.")); + // /*spanish*/Según dicen, el Rancho Lon Lon prosperó gracias a Ingo. + + hintTextTable[RHT_JUNK16] = HintText(CustomMessage("The single rupee is a unique item.", + /*german*/ "", + /*french*/ "Nul objet n'est plus unique que le rubis vert.")); + // /*spanish*/La rupia de uno es un objeto singular. + + hintTextTable[RHT_JUNK17] = HintText(CustomMessage("Without the Lens of Truth, the Treasure Chest Mini-Game is a 1 out of 32 chance.^Good luck!", + /*german*/ "", + /*french*/ "Gagner la Chasse-aux-Trésors est 1 chance sur 32.^Bonne chance!")); + // /*spanish*/Sin la Lupa de la Verdad, ganarías 1/32 veces en el Cofre del Tesoro.^¡Buena suerte con ello! + + hintTextTable[RHT_JUNK18] = HintText(CustomMessage("Use bombs wisely.", + /*german*/ "", + /*french*/ "Utilise les bombes avec précaution.")); + // /*spanish*/No desperdicies las bombas. + + hintTextTable[RHT_JUNK19] = HintText(CustomMessage("They say that Volvagia hates splinters", + /*german*/ "", + /*french*/ "Selon moi, Volvagia déteste les échardes.")); + // /*spanish*/Según dicen, Volvagia le teme a las astillas. + + hintTextTable[RHT_JUNK20] = HintText(CustomMessage("They say that funky monkeys can be spotted on Friday.", + /*german*/ "", + /*french*/ "Selon moi, des capucins coquins sortent le vendredi.")); + // /*spanish*/Según dicen, en los viernes puedes hallar monos marchosos. + + hintTextTable[RHT_JUNK21] = HintText(CustomMessage("I found you, faker!", + /*german*/ "", + /*french*/ "Ah-ha! Je t'ai trouvé!")); + // /*spanish*/¡Ahí estás, impostor! + + hintTextTable[RHT_JUNK22] = HintText(CustomMessage("They say the Groose is loose.", + /*german*/ "", + /*french*/ "Selon moi, Hergo est le vrai héros.")); + // /*spanish*/Según dicen, Malton es un espanto. + + hintTextTable[RHT_JUNK23] = HintText(CustomMessage("They say that players who select the \"ON\" option for \"MOTION CONTROL\" are the real \"Zelda players!\"", + /*german*/ "", + /*french*/ "Selon moi, ceux qui utilisent les contrôles gyroscopiques sont les VRAIS joueurs.")); + // /*spanish*/ "Según dicen, aquellos que juegan usando el control por movimiento son los verdaderos jugadores de Zelda." + + hintTextTable[RHT_JUNK24] = HintText(CustomMessage("What happened to Sheik?", + /*german*/ "", + /*french*/ "Donc... Qu'est-ce qui arrive avec Sheik?")); + // /*spanish*/¿Qué la habrá pasado a Sheik? + + hintTextTable[RHT_JUNK25] = HintText(CustomMessage("L2P @.", + /*german*/ "", + /*french*/ "Arrête de lire les indices et joue comme un grand, @.")); + // /*spanish*/Mira que eres novato, @. + + hintTextTable[RHT_JUNK26] = HintText(CustomMessage("I've heard you can cheat at Sploosh Kaboom.", + /*german*/ "", + /*french*/ "Selon moi, il y a une carte aux trésors à Mercantîle... Duh!")); + // /*spanish*/He oído por ahí que puedes hacer trampa en el Sploosh Kaboom. + + hintTextTable[RHT_JUNK27] = HintText(CustomMessage("I'm Lonk from Pennsylvania.", + /*german*/ "", + /*french*/ "Je suis Lonk, le héros de Pennsylvanie!")); + // /*spanish*/Soy Lonk, de Pensilvania. + + hintTextTable[RHT_JUNK28] = HintText(CustomMessage("I bet you'd like to have more bombs.", + /*german*/ "", + /*french*/ "Je parie que tu veux plus de bombes.")); + // /*spanish*/Me apuesto a que quisieras tener más bombas. + + hintTextTable[RHT_JUNK29] = HintText(CustomMessage("When all else fails, use Fire.", + /*german*/ "", + /*french*/ "Quand rien ne marche, utilise le feu.")); + // /*spanish*/Cuando nada funcione, usa el fuego. + + hintTextTable[RHT_JUNK30] = HintText(CustomMessage("Here's a hint, @. Don't be bad.", + /*german*/ "", + /*french*/ "Selon moi, la #Triforce# n'est pas dans le jeu... Duh!")); + // /*spanish*/Aquí tienes una pista, @: deja de ser manco. + + hintTextTable[RHT_JUNK31] = HintText(CustomMessage("Game Over. Return of Ganon.", + /*german*/ "", + /*french*/ "Partie terminée. RETour de Ganon.")); + // /*spanish*/Fin de la partida. El regreso de Ganon. + + hintTextTable[RHT_JUNK32] = HintText(CustomMessage("May the way of the Hero lead to the Triforce.", + /*german*/ "", + /*french*/ "Que le chemin du héros te mène à la Triforce.")); + // /*spanish*/Puede que la senda del héroe te lleve hacia la Trifuerza. + + hintTextTable[RHT_JUNK33] = HintText(CustomMessage("Can't find an item? Scan an Amiibo.", + /*german*/ "", + /*french*/ "Tu cherches de quoi? Utilise un Amiibo!")); + // /*spanish*/¿No encuentras algo? Escanea un amiibo. + + hintTextTable[RHT_JUNK34] = HintText(CustomMessage("They say this game has just a few glitches.", + /*german*/ "", + /*french*/ "Selon moi, ce jeu est complètement exempt de glitchs.")); + // /*spanish*/Dicen que este juego apenas tiene glitches. + + hintTextTable[RHT_JUNK35] = HintText(CustomMessage("BRRING BRRING This is Ulrira. Wrong number?", + /*german*/ "", + /*french*/ "DRING DRING!! Pépé le Ramollo à l'appareil... Quoi? Faux numéro?")); + // /*spanish*/¡Ring! ¡Ring! Al habla Ulrira. ¿Me he equivocado de número? + + hintTextTable[RHT_JUNK36] = HintText(CustomMessage("Tingle Tingle Kooloo Limpah!", + /*german*/ "", + /*french*/ "Tingle! Tingle! Kooloolin... Pah!")); + // /*spanish*/Tingle, Tingle, Kurulín... ¡PA! + + hintTextTable[RHT_JUNK37] = HintText(CustomMessage("L is real 2401", + /*german*/ "", + /*french*/ "L is real 2401")); + // /*spanish*/L es real 2401. + + hintTextTable[RHT_JUNK38] = HintText(CustomMessage("They say that Ganondorf will appear in the next Mario Tennis.", + /*german*/ "", + /*french*/ "Selon moi, Ganondorf sera la nouvelle recrue dans Mario Tennis.")); + // /*spanish*/Según dicen, Ganondorf estará en el próximo Mario Tennis. + + hintTextTable[RHT_JUNK39] = HintText(CustomMessage("Medigoron sells the earliest Breath of the Wild demo.", + /*german*/ "", + /*french*/ "Selon moi, Medigoron vend une démo de #Breath of the Wild#.")); + // /*spanish*/Medigoron vende la primera demo del Breath of the Wild. + + hintTextTable[RHT_JUNK40] = HintText(CustomMessage("Can you move me? I don't get great service here.", + /*german*/ "", + /*french*/ "Peux-tu me déplacer? J'ai pas une bonne réception ici.")); + // /*spanish*/¿Puedes llevarme a otro lado? Aquí nadie me presta atención. + + hintTextTable[RHT_JUNK41] = HintText(CustomMessage("They say if you use Strength on the truck, you can find Mew.", + /*german*/ "", + /*french*/ "Selon moi, #Mew# se trouve dessous le camion... Duh!")); + // /*spanish*/Según dicen, puedes hallar un Mew usando Fuerza contra el camión de Ciudad Carmín. + + hintTextTable[RHT_JUNK42] = HintText(CustomMessage("I'm a helpful hint Gossip Stone!^See, I'm helping.", + /*german*/ "", + /*french*/ "Salut! Je suis une pierre de bons conseils!^Tiens, tu vois? J'aide bien, hein?")); + // /*spanish*/Soy una Piedra Sheikah muy útil.^¡Mira cómo te ayudo! + + hintTextTable[RHT_JUNK43] = HintText(CustomMessage("Dear @, please come to the castle. I've baked a cake for you.&Yours truly, Princess Zelda.", + /*german*/ "", + /*french*/ "Mon très cher @:&Viens vite au château, je t'ai préparé&un délicieux gâteau...^À bientôt, Princesse Zelda")); + // /*spanish*/Querido @: Por favor, ven al castillo. He hecho una tarta para ti.&Sinceramente tuya: Princesa Zelda. + + hintTextTable[RHT_JUNK44] = HintText(CustomMessage("They say all toasters toast toast.", + /*german*/ "", + /*french*/ "Selon moi, les grille-pains grillent du pain.")); + // /*spanish*/Según dicen, todas las tostadoras tostan tostadas tostadas. + + hintTextTable[RHT_JUNK45] = HintText(CustomMessage("You thought it would be a useful hint, but it was me, junk hint!", + /*german*/ "", + /*french*/ "Tu t'attendais à un bon indice... Mais c'était moi, un mauvais indice!")); + // /*spanish*/Je... Creeías que iba a ser una piedra de utilidad, ¡pero no, era yo, la piedra de la agonía! + + hintTextTable[RHT_JUNK46] = HintText(CustomMessage("They say that quest guidance can be found at a talking rock.", + /*german*/ "", + /*french*/ "Selon moi, des #indices# se trouvent auprès d'une pierre parlante... Duh!")); + // /*spanish*/Según dicen, puedes consultarle ayuda a rocas parlanchinas. + + hintTextTable[RHT_JUNK47] = HintText(CustomMessage("They say that the final item you're looking for can be found somewhere in Hyrule.", + /*german*/ "", + /*french*/ "Selon moi, le #dernier objet# se trouve quelque part dans Hyrule... Duh!")); + // /*spanish*/Según dicen, el último objeto que te falte puede estar en cualquier rincón de Hyrule. + + hintTextTable[RHT_JUNK48] = HintText(CustomMessage("Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.", + /*german*/ "", + /*french*/ "Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.")); + // /*spanish*/Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep. + + hintTextTable[RHT_JUNK49] = HintText(CustomMessage("They say that Barinade fears Deku Nuts.", + /*german*/ "", + /*french*/ "Selon moi, Barinade a la frousse des noix Mojo.")); + // /*spanish*/Según dicen, lo que más teme a Barinade son las nueces deku. + + hintTextTable[RHT_JUNK50] = HintText(CustomMessage("They say that Flare Dancers do not fear Goron-crafted blades.", + /*german*/ "", + /*french*/ "Selon moi, le danse-flamme n'a pas peur des armes de Goron.")); + // /*spanish*/Según dicen, los Bailafuegos no le temen a las armas forjadas por Gorons. + + hintTextTable[RHT_JUNK51] = HintText(CustomMessage("They say that Morpha is easily trapped in a corner.", + /*german*/ "", + /*french*/ "Selon moi, Morpha est facilement coincé.")); + // /*spanish*/Según dicen, puedes atrapar a Morpha con facilidad en una esquina. + + hintTextTable[RHT_JUNK52] = HintText(CustomMessage("They say that Bongo Bongo really hates the cold.", + /*german*/ "", + /*french*/ "Selon moi, Bongo Bongo a facilement froid aux doigts.")); + // /*spanish*/Según dicen, Bongo Bongo odia a muerte el frío. + + hintTextTable[RHT_JUNK53] = HintText(CustomMessage("They say that your sword is most powerful when you put it away.", + /*german*/ "", + /*french*/ "Selon moi, ton épée est à pleine puissance quand tu la rengaines.")); + // /*spanish*/Según dicen, tu espada se vuelve más poderosa si la guardas. + + hintTextTable[RHT_JUNK54] = HintText(CustomMessage("They say that bombing the hole Volvagia last flew into can be rewarding.", + /*german*/ "", + /*french*/ "Selon moi, le trou où se creuse Volvagia est vulnérable aux bombes.")); + // /*spanish*/Según dicen, trae buena suerte colocar una bomba en el último agujero de donde salió Volvagia. + + hintTextTable[RHT_JUNK55] = HintText(CustomMessage("They say that invisible ghosts can be exposed with Deku Nuts.", + /*german*/ "", + /*french*/ "Selon moi, des fantômes invisibles apparaissent avec des noix Mojo.")); + // /*spanish*/Según dicen, puedes exponer a los espectros invisibles con nueces deku. + + hintTextTable[RHT_JUNK56] = HintText(CustomMessage("They say that the real Phantom Ganon is bright and loud.", + /*german*/ "", + /*french*/ "Selon moi, le vrai spectre de Ganon est clair et bruyant.")); + // /*spanish*/Según dicen, el verdadero Ganon Fantasma es brillante y ruidoso. + + hintTextTable[RHT_JUNK57] = HintText(CustomMessage("They say that walking backwards is very fast.", + /*german*/ "", + /*french*/ "Selon moi, tu fais marche arrière très rapidement pour un héros.")); + // /*spanish*/Según dicen, es más rápido caminar hacia atrás. + + hintTextTable[RHT_JUNK58] = HintText(CustomMessage("They say that leaping above the Market entrance enriches most children.", + /*german*/ "", + /*french*/ "Selon moi, les enfants riches se pavanent en haut du pont-levis.")); + // /*spanish*/Según dicen, saltar por las cadenas a la entrada de la plaza enriquece a muchos chiquillos. + + hintTextTable[RHT_JUNK59] = HintText(CustomMessage("They say Ingo is not very good at planning ahead.", + /*german*/ "", + /*french*/ "Selon moi, Ingo ne fait pas un très bon geôlier.")); + // /*spanish*/Según dicen, a Ingo no se le da especialmente bien planificar con antelación. + + hintTextTable[RHT_JUNK60] = HintText(CustomMessage("You found a spiritual Stone! By which I mean, I worship Nayru.", + /*german*/ "", + /*french*/ "Vous avez trouvé une Pierre Ancestrale! En effet, je vénère la déesse Hylia.")); + // /*spanish*/¡Has encontrado una piedra espiritual! Es que le rindo culto a Nayru... + + hintTextTable[RHT_JUNK61] = HintText(CustomMessage("They say that a flying strike with a Deku Stick is no stronger than a grounded one.", + /*german*/ "", + /*french*/ "Selon moi, un coup de bâton sauté n'est pas meilleur qu'au sol.")); + // /*spanish*/Según dicen, los golpes aéreos con palos deku son tan fuertes como los normales. + + hintTextTable[RHT_JUNK62] = HintText(CustomMessage("Open your eyes.^Open your eyes.^Wake up, @.", + /*german*/ "", + /*french*/ "Réveille-toi...^Réveille-toi.^Ouvre les yeux, @.")); + // /*spanish*/Abre los ojos...^Abre los ojos...^Despierta, @... + + hintTextTable[RHT_JUNK63] = HintText(CustomMessage("They say that the Nocturne of Shadow can bring you very close to Ganon.", + /*german*/ "", + /*french*/ "Selon moi, le nocturne de l'ombre peut t'amener très près de Ganon.")); + // /*spanish*/Según dicen, el Nocturno de la sombra te puede acercar mucho a Ganon. + + hintTextTable[RHT_JUNK64] = HintText(CustomMessage("They say that Twinrova always casts the same spell the first three times.", + /*german*/ "", + /*french*/ "Selon moi, Twinrova lance toujours les mêmes trois premiers sorts.")); + // /*spanish*/Según dicen, Birova siempre lanza el mismo hechizo las tres primeras veces. + + hintTextTable[RHT_JUNK65] = HintText(CustomMessage("They say that the nightly builds may be unstable.", + /*german*/ "", + /*french*/ "Selon moi, les \"nightly builds\" peuvent être instables.")); + // /*spanish*/Según dicen, las últimas nightlies pueden llegar a ser algo inestables. + + hintTextTable[RHT_JUNK66] = HintText(CustomMessage("You're playing a Randomizer. I'm randomized!^Here's a random number: #4#.&Enjoy your Randomizer!", + /*german*/ "", + /*french*/ "Tu joues à un randomizer. Je suis aléatoire!^Voici un nombre aléatoire: #4#.&Bonne partie!")); + // /*spanish*/¡Estás jugando un Randomizer! ¡Yo también estoy aleatorizada!^Aquí tienes un número aleatorio: #8#.&¡Diviértete! + + hintTextTable[RHT_JUNK67] = HintText(CustomMessage("They say Ganondorf's bolts can be reflected with glass or steel.", + /*german*/ "", + /*french*/ "Selon moi, les éclairs de Ganon se reflètent sur l'acier et le verre.")); + // /*spanish*/Según dicen, puedes reflejar las esferas de energía de Ganondorf con cristal y acero. + + hintTextTable[RHT_JUNK68] = HintText(CustomMessage("They say Ganon's tail is vulnerable to nuts, arrows, swords, explosives, hammers...^...sticks, seeds, " + "boomerangs...^...rods, shovels, iron balls, angry bees...", + /*german*/ "", + /*french*/ "Selon moi, la queue de Ganon est vulnérable aux noix, flèches, épées, bombes, marteaux...^...bâtons, " + "graines, boomerangs...^...baguettes, pelles, boulets de fer, abeilles enragées...")); + // /*spanish*/Según dicen, la cola de Ganon es vulnerable a nueces, flechas, espadas, explosivos, + // martillos...^...palos, semillas, bumeráns...^...cetros, palas, bolas de hierro, abejas... + + hintTextTable[RHT_JUNK69] = HintText(CustomMessage("They say that you're wasting time reading this hint, but I disagree. Talk to me again!", + /*german*/ "", + /*french*/ "Selon moi... tu sais quoi? Parle-moi encore, et je te le dirai!")); + // /*spanish*/Según dicen, pierdes el tiempo en leer esta pista, pero no pienso igual. ¡Vuelve a hablarme, ya verás! + + hintTextTable[RHT_JUNK70] = HintText(CustomMessage("They say Ganondorf knows where to find the instrument of his doom.", + /*german*/ "", + /*french*/ "Selon moi, Ganondorf sait où il a caché son point faible.")); + // /*spanish*/Según dicen, Ganondorf sabe dónde hallar el instrumento de su perdición. + + hintTextTable[RHT_JUNK71] = HintText(CustomMessage("I heard @ is pretty good at Zelda.", + /*german*/ "", + /*french*/ "Apparemment, @ est super bon à Zelda.")); + // /*spanish*/He oído que a @ se le dan muy bien los Zelda. + + hintTextTable[RHT_JUNK72] = HintText(CustomMessage("Hi @, we've been trying to reach you about your car's extended warranty. ", + /*german*/ "", + /*french*/ "Bonjour, @. Vous avez une voiture? Vous savez, nous offrons des assurances abordables...")); + // /*spanish*/Buenas, @. Le llamamos para ofrecerle un nuevo seguro de hogar que puede pagar en cómodos plazos, sin + // intereses ni comisiones. + + hintTextTable[RHT_JUNK73] = HintText(CustomMessage("They say that the best weapon against Iron Knuckles is item 176.", + /*german*/ "", + /*french*/ "Selon moi, les hache-viandes sont vulnérables contre l'objet 176.")); + // /*spanish*/Según dicen, la mejor arma para enfrentarse a los Nudillos de hierro es el objeto 176. + + hintTextTable[RHT_JUNK74] = HintText(CustomMessage("They say that it's actually possible to beat the running man.", + /*german*/ "", + /*french*/ "Selon moi, il est possible de battre le coureur.&Donc, tu prends ton arc, et...")); + // /*spanish*/Según dicen, con mucha perseverancia puedes ganarle al corredor con la capucha de conejo. + + hintTextTable[RHT_JUNK75] = HintText(CustomMessage("They say that the stone-cold guardian of the Well is only present during work hours.", + /*german*/ "", + /*french*/ "Selon moi, le gardien de pierre du Puits quitte le soir pour aller se coucher.")); + // /*spanish*/Según dicen, la inmensa roca que bloquea el pozo solo trabaja en horas laborales. + + hintTextTable[RHT_JUNK76] = HintText(CustomMessage("They say this hint makes more sense in other languages.", + /*german*/ "", + /*french*/ "Selon moi, ces indices auraient pu être mieux traduits... Duh!")); + // /*spanish*/Según dicen, esta pista revela algo de vital importancia si cambias el idioma del juego... + + hintTextTable[RHT_JUNK77] = HintText(CustomMessage("BOK? No way.", + /*german*/ "", + /*french*/ "BD'accord? Hors de question.")); + // /*spanish*/¿BVale? Ni hablar. // ^ junk hints above are from 3drando // v junk hints below are new to soh rando @@ -2082,1162 +1845,1072 @@ void HintTable_Init() { #define HINT_TEXT_NEEDS_TRANSLATION_FR \ "Erreur 0x69a504:&Traduction manquante^C'est de la faute à Purple Hato!&J'vous jure!" - hintTable[JUNK78] = HintText::Junk({ - //obscure text - Text{"They say blarg...^...or at least briaguya does.", /*french*/"Tout ce que j'ai à dire, c'est blarg...^... 'fin c'est plutôt ce que briaguya dirait.", /*spanish*/"blarg"}, - }); - - hintTable[JUNK79] = HintText::Junk({ - //obscure text - Text{"They say this peace is what all true warriors strive for.", /*french*/"Selon moi, cette paix est ce pour quoi luttent tous les vrais guerriers.", /*spanish*/"blarg"}, - }); - - hintTable[JUNK80] = HintText::Junk({ - //obscure text - Text{"They say this ship is what all true gamers strive for.", /*french*/"Selon moi, cette version du port est ce pour quoi luttent tous les vrais gamers.", /*spanish*/"blarg"}, - }); - - hintTable[JUNK81] = HintText::Junk({ - //obscure text - Text{"They say that Glowsticks can be found in the Raveyard.", /*french*/"On peut trouver des Bâtons Lumineux sur le dancefloor du cimetière.", /*spanish*/"blarg"}, - }); - - hintTable[JUNK_WTC_1] = HintText::Junk({ - Text{ "They say %rthere are no more than 18&people on this island.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_2] = HintText::Junk({ - Text{ "They say I am one yet many", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_3] = HintText::Junk({ - Text{ "They say its all in the name of guiding&humanity down the right path.", HINT_TEXT_NEEDS_TRANSLATION_FR, - "blarg" }, - }); - - hintTable[JUNK_WTC_4] = HintText::Junk({ - Text{ "They say \"Repetition requested\"", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_5] = HintText::Junk({ - Text{ "They say %rThe red tells only the truth!", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_6] = HintText::Junk({ - Text{ "They say good tidings to you^my traitorous @", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_7] = HintText::Junk({ - Text{ "They say when the seagulls cried,&none were left alive.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_7] = HintText::Junk({ - Text{ "They say when the seagulls cried,&none were left alive.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_8] = HintText::Junk({ - Text{ "They say she is lying with the red letters!", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_9] = HintText::Junk({ - Text{ "They say we'll meet again,&when something else cries.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_10] = HintText::Junk({ - Text{ "They say \"Forgive me, but-^Your script will not be used.&....After all...^The one writing the rest of " - "the script...&will be me.\"", - HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_11] = HintText::Junk({ - Text{ "They say tea is best enjoyed...^\"\"With your fellow monsters.\"\"", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_WTC_12] = HintText::Junk({ - Text{ "They say I shall make you some black tea. With my own hands, not magic.", HINT_TEXT_NEEDS_TRANSLATION_FR, - "blarg" }, - }); - - hintTable[JUNK_SEI_1] = HintText::Junk({ - Text{ "They say you know I've kiboshed before...^and I will kibosh again.", HINT_TEXT_NEEDS_TRANSLATION_FR, - "blarg" }, - }); - - hintTable[JUNK_SEI_2] = HintText::Junk({ - Text{ "They say if relationship @ walks through that door,^they will KILL independent @.", - HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_3] = HintText::Junk({ - Text{ "They say you gotta have the BIG Salad.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_4] = HintText::Junk({ - Text{ "They say it's a festivus miracle", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_5] = HintText::Junk({ - Text{ "They say there are no houses in Tuscany to rent.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_6] = HintText::Junk({ - Text{ "They say my last boyfriend had a real&Kroner comprehension problem.", HINT_TEXT_NEEDS_TRANSLATION_FR, - "blarg" }, - }); - - hintTable[JUNK_SEI_7] = HintText::Junk({ - Text{ "They say it's a festivus miracle.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_8] = HintText::Junk({ - Text{ "They say Louis quit the importing&to focus on the exporting.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_9] = HintText::Junk({ - Text{ "They say no thanks, I can't drink coffee&late at night, it keeps me up.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_10] = HintText::Junk({ - Text{ "They say it's not a lie if you believe it.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); + hintTextTable[RHT_JUNK78] = HintText(CustomMessage("They say blarg...^...or at least briaguya does.", + /*german*/ "", + /*french*/ "Tout ce que j'ai à dire, c'est blarg...^... 'fin c'est plutôt ce que briaguya dirait.")); + // /*spanish*/blarg - hintTable[JUNK_SEI_11] = HintText::Junk({ - Text{ "They say there was a second spitter.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); + hintTextTable[RHT_JUNK79] = HintText(CustomMessage("They say this peace is what all true warriors strive for.", + /*german*/ "", + /*french*/ "Selon moi, cette paix est ce pour quoi luttent tous les vrais guerriers.")); + // /*spanish*/blarg - hintTable[JUNK_SEI_12] = HintText::Junk({ - Text{ "They say there was a second spitter.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); + hintTextTable[RHT_JUNK80] = HintText(CustomMessage("They say this ship is what all true gamers strive for.", + /*german*/ "", + /*french*/ "Selon moi, cette version du port est ce pour quoi luttent tous les vrais gamers.")); + // /*spanish*/blarg - hintTable[JUNK_SEI_13] = HintText::Junk({ - Text{ "They say the jerk store called,^they're running out of YOU.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_14] = HintText::Junk({ - Text{ "They say when you look annoyed all the time,&people thing you are busy.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_15] = HintText::Junk({ - Text{ "They say when you look annoyed all the time,&people think you are busy.", HINT_TEXT_NEEDS_TRANSLATION_FR, - "blarg" }, - }); - - hintTable[JUNK_SEI_16] = HintText::Junk({ - Text{ "They say he fires people like its a bodily function.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_17] = HintText::Junk({ - Text{ "They say he threatened to move the ship to New Jersey&just to upset people.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_18] = HintText::Junk({ - Text{ "They say there was significant shrinkage.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_19] = HintText::Junk({ - Text{ "They say if it wasn't for the toilet there'd be no books.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_20] = HintText::Junk({ - Text{ "They say if it wasn't for the toilet there'd be no books.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_21] = HintText::Junk({ - Text{ "They say don't trust men in capes.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_22] = HintText::Junk({ - Text{ "They say @'s uncle works for Nintendo.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_23] = HintText::Junk({ - Text{ "They say @'s stole the marble rye.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_24] = HintText::Junk({ - Text{ "They say there is no better harmony&than the black and white cookie.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_25] = HintText::Junk({ - Text{ "They say @ hasn't vomited since 1983.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_26] = HintText::Junk({ - Text{ "They say you gotta have the early bird special.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_27] = HintText::Junk({ - Text{ "They say a donation has been made in your name&to the human fund.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_28] = HintText::Junk({ - Text{ "They say you want to be my latex salesman.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SEI_29] = HintText::Junk({ - Text{ "They say if every instinct you have is wrong...^... then the opposite would have to be right.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_OTR_MEANS_1] = HintText::Junk({ - Text{ "They say OTR stands for&Over the Rainbow", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_2] = HintText::Junk({ - Text{ "They say that OTR stands for&Onions, Tomatoes, and Radishes", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_3] = HintText::Junk({ - Text{ "They say that OTR stands for&Ocarina of Time Resources", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_4] = HintText::Junk({ - Text{ "They say that OTR stands for&Over the Road", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_5] = HintText::Junk({ - Text{ "They say that OTR stands for&Off the Record", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_6] = HintText::Junk({ - Text{ "They say that OTR stands for&Office of Tax and Revenue", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_7] = HintText::Junk({ - Text{ "They say OTR stands for&Over the Rainbow", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_8] = HintText::Junk({ - Text{ "They say that OTR stands for&Office of Trade Relations", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_9] = HintText::Junk({ - Text{ "They say that OTR stands for&Original Theatrical Release", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_10] = HintText::Junk({ - Text{ "They say that OTR stands for&Operational Test Requirement", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_11] = HintText::Junk({ - Text{ "They say that OTR stands for&Operational Trouble Report", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_12] = HintText::Junk({ - Text{ "They say that OTR stands for&Oxygen Transmission Rate", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_13] = HintText::Junk({ - Text{ "They say that OTR stands for&One Touch Recording", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_14] = HintText::Junk({ - Text{ "They say that OTR stands for&Olympic Torch Relay", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_15] = HintText::Junk({ - Text{ "They say that OTR stands for&Off the Rack", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_16] = HintText::Junk({ - Text{ "They say that OTR stands for&Overhead Transfer Rate", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_17] = HintText::Junk({ - Text{ "They say that OTR stands for&Operational TurnaRound", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_18] = HintText::Junk({ - Text{ "They say that OTR stands for&Opportunity to Recall", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_19] = HintText::Junk({ - Text{ "They say that OTR stands for&Operability Test Report", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_20] = HintText::Junk({ - Text{ "They say that OTR stands for&Overall Tuning Range", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_21] = HintText::Junk({ - Text{ "They say that OTR stands for&One Time Requisition", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_22] = HintText::Junk({ - Text{ "They say that OTR stands for&Oblivious to Reality", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_23] = HintText::Junk({ - Text{ "They say that OTR stands for&On the Run", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_24] = HintText::Junk({ - Text{ "They say that OTR stands for&On Time Reporting", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_25] = HintText::Junk({ - Text{ "They say that OTR stands for&Order to Receipt", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_26] = HintText::Junk({ - Text{ "They say that OTR stands for&Other Terrestrial Radio", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_27] = HintText::Junk({ - Text{ "They say that OTR stands for&On Target Reports", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_28] = HintText::Junk({ - Text{ "They say that OTR stands for&One Time Repair", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_29] = HintText::Junk({ - Text{ "They say that OTR stands for&Own the Room", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - hintTable[JUNK_OTR_MEANS_30] = HintText::Junk({ - Text{ "They say that OTR stands for&Online Text Repository", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_1] = HintText::Junk({ - Text{ "They say %gKenix%w isn't a developer...^...Just a PR guy", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_2] = HintText::Junk({ - Text {"They say... No", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg"}, - }); - - hintTable[JUNK_MISC_3] = HintText::Junk({ - Text{ "They say BIG RIGS: OTR", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" } - }); - - hintTable[JUNK_MISC_4] = HintText::Junk({ - Text{ "They say you wanted to see me %pMr. Kenix%w?", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_5] = HintText::Junk({ - Text{ "They say Louis once saw an&equals not get set equals", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_6] = HintText::Junk({ - Text{ "They say only you can find your rom.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_7] = HintText::Junk({ - Text{ "They say ZAPD is good software.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_8] = HintText::Junk({ - Text{ "They say you can encounter&a parascode in tall grass.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_9] = HintText::Junk({ - Text{ "They say the ship sails on March 32nd.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_10] = HintText::Junk({ - Text{ "They say bombing dodongos is fun.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_11] = HintText::Junk({ - Text{ "They say shopkeepers don't give credits.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_12] = HintText::Junk({ - Text{ "They say shopkeepers don't give credits.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_13] = HintText::Junk({ - Text{ "They say Malon is glitched.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_14] = HintText::Junk({ - Text{ "They say do I look like I know&what a DList is?", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_15] = HintText::Junk({ - Text{ "They say do I look like I know&what an AList is?", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_16] = HintText::Junk({ - Text{ "They say the king drinks enthusiastically", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_MISC_17] = HintText::Junk({ - Text{ "They say Rubies are on the path to&Lamp Oil, Rope, and Bombs", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SG_1] = HintText::Junk({ - Text{ "They say %rError. Human is dead, mismatch.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SG_2] = HintText::Junk({ - Text{ "They say this is the choice of the&steins gate.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SG_3] = HintText::Junk({ - Text{ "They say el psy kongroo.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SG_4] = HintText::Junk({ - Text{ "They say tutturu~.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - - hintTable[JUNK_SG_5] = HintText::Junk({ - Text{ "They say im not Christina!.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); - - hintTable[JUNK_SG_6] = HintText::Junk({ - Text{ "They say you know where to find an IBN5100.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); + hintTextTable[RHT_JUNK81] = HintText(CustomMessage("They say that Glowsticks can be found in the Raveyard.", + /*german*/ "", + /*french*/ "On peut trouver des Bâtons Lumineux sur le dancefloor du cimetière.")); + // /*spanish*/blarg + + hintTextTable[RHT_JUNK_WTC_1] = HintText(CustomMessage("They say %rthere are no more than 18&people on this island.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_WTC_2] = HintText(CustomMessage("They say I am one yet many", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_WTC_3] = HintText(CustomMessage("They say its all in the name of guiding&humanity down the right path.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_WTC_4] = HintText(CustomMessage("They say \"Repetition requested\"", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_WTC_5] = HintText(CustomMessage("They say %rThe red tells only the truth!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_WTC_6] = HintText(CustomMessage("They say good tidings to you^my traitorous @", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_WTC_7] = HintText(CustomMessage("They say when the seagulls cried,&none were left alive.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_WTC_8] = HintText(CustomMessage("They say she is lying with the red letters!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_WTC_9] = HintText(CustomMessage("They say we'll meet again,&when something else cries.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_WTC_10] = HintText(CustomMessage("They say \"Forgive me, but-^Your script will not be used.&....After all...^The one writing the rest of " + "the script...&will be me.\"", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_WTC_11] = HintText(CustomMessage("They say tea is best enjoyed...^\"\"With your fellow monsters.\"\"", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + + hintTextTable[RHT_JUNK_WTC_12] = HintText(CustomMessage("They say I shall make you some black tea. With my own hands, not magic.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_1] = HintText(CustomMessage("They say you know I've kiboshed before...^and I will kibosh again.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_2] = HintText(CustomMessage("They say if relationship @ walks through that door,^they will KILL independent @.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_3] = HintText(CustomMessage("They say you gotta have the BIG Salad.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_4] = HintText(CustomMessage("They say it's a festivus miracle", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_5] = HintText(CustomMessage("They say there are no houses in Tuscany to rent.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_6] = HintText(CustomMessage("They say my last boyfriend had a real&Kroner comprehension problem.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_7] = HintText(CustomMessage("They say it's a festivus miracle.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_8] = HintText(CustomMessage("They say Louis quit the importing&to focus on the exporting.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_9] = HintText(CustomMessage("They say no thanks, I can't drink coffee&late at night, it keeps me up.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_10] = HintText(CustomMessage("They say it's not a lie if you believe it.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_11] = HintText(CustomMessage("They say there was a second spitter.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_12] = HintText(CustomMessage("They say there was a second spitter.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_13] = HintText(CustomMessage("They say the jerk store called,^they're running out of YOU.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_14] = HintText(CustomMessage("They say when you look annoyed all the time,&people thing you are busy.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_15] = HintText(CustomMessage("They say when you look annoyed all the time,&people think you are busy.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_16] = HintText(CustomMessage("They say he fires people like its a bodily function.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_17] = HintText(CustomMessage("They say he threatened to move the ship to New Jersey&just to upset people.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_18] = HintText(CustomMessage("They say there was significant shrinkage.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_19] = HintText(CustomMessage("They say if it wasn't for the toilet there'd be no books.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_20] = HintText(CustomMessage("They say if it wasn't for the toilet there'd be no books.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_21] = HintText(CustomMessage("They say don't trust men in capes.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_22] = HintText(CustomMessage("They say @'s uncle works for Nintendo.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_23] = HintText(CustomMessage("They say @'s stole the marble rye.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_24] = HintText(CustomMessage("They say there is no better harmony&than the black and white cookie.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_25] = HintText(CustomMessage("They say @ hasn't vomited since 1983.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_26] = HintText(CustomMessage("They say you gotta have the early bird special.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_27] = HintText(CustomMessage("They say a donation has been made in your name&to the human fund.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_28] = HintText(CustomMessage("They say you want to be my latex salesman.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SEI_29] = HintText(CustomMessage("They say if every instinct you have is wrong...^... then the opposite would have to be right.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_1] = HintText(CustomMessage("They say OTR stands for&Over the Rainbow", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_2] = HintText(CustomMessage("They say that OTR stands for&Onions, Tomatoes, and Radishes", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_3] = HintText(CustomMessage("They say that OTR stands for&Ocarina of Time Resources", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_4] = HintText(CustomMessage("They say that OTR stands for&Over the Road", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_5] = HintText(CustomMessage("They say that OTR stands for&Off the Record", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_6] = HintText(CustomMessage("They say that OTR stands for&Office of Tax and Revenue", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_7] = HintText(CustomMessage("They say OTR stands for&Over the Rainbow", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_8] = HintText(CustomMessage("They say that OTR stands for&Office of Trade Relations", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_9] = HintText(CustomMessage("They say that OTR stands for&Original Theatrical Release", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); - hintTable[JUNK_SG_7] = HintText::Junk({ - Text{ "They say when you're on a chicken bender&grab a box of chicken tenders.", HINT_TEXT_NEEDS_TRANSLATION_FR, "blarg" }, - }); + hintTextTable[RHT_JUNK_OTR_MEANS_10] = HintText(CustomMessage("They say that OTR stands for&Operational Test Requirement", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); - hintTable[JUNK_SG_8] = HintText::Junk({ - Text{ "Juicy Chicken #1! Wow!.", HINT_TEXT_NEEDS_TRANSLATION_FR, - "blarg" }, - }); + hintTextTable[RHT_JUNK_OTR_MEANS_11] = HintText(CustomMessage("They say that OTR stands for&Operational Trouble Report", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_12] = HintText(CustomMessage("They say that OTR stands for&Oxygen Transmission Rate", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_13] = HintText(CustomMessage("They say that OTR stands for&One Touch Recording", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_14] = HintText(CustomMessage("They say that OTR stands for&Olympic Torch Relay", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_15] = HintText(CustomMessage("They say that OTR stands for&Off the Rack", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_16] = HintText(CustomMessage("They say that OTR stands for&Overhead Transfer Rate", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_17] = HintText(CustomMessage("They say that OTR stands for&Operational TurnaRound", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_18] = HintText(CustomMessage("They say that OTR stands for&Opportunity to Recall", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_19] = HintText(CustomMessage("They say that OTR stands for&Operability Test Report", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_20] = HintText(CustomMessage("They say that OTR stands for&Overall Tuning Range", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_21] = HintText(CustomMessage("They say that OTR stands for&One Time Requisition", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_22] = HintText(CustomMessage("They say that OTR stands for&Oblivious to Reality", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_23] = HintText(CustomMessage("They say that OTR stands for&On the Run", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_24] = HintText(CustomMessage("They say that OTR stands for&On Time Reporting", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_25] = HintText(CustomMessage("They say that OTR stands for&Order to Receipt", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_26] = HintText(CustomMessage("They say that OTR stands for&Other Terrestrial Radio", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_27] = HintText(CustomMessage("They say that OTR stands for&On Target Reports", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_28] = HintText(CustomMessage("They say that OTR stands for&One Time Repair", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_29] = HintText(CustomMessage("They say that OTR stands for&Own the Room", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_OTR_MEANS_30] = HintText(CustomMessage("They say that OTR stands for&Online Text Repository", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_1] = HintText(CustomMessage("They say #Kenix# isn't a developer...^...Just a PR guy", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR, + {QM_GREEN})); + + hintTextTable[RHT_JUNK_MISC_2] = HintText(CustomMessage("They say... No", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_3] = HintText(CustomMessage("They say BIG RIGS: OTR", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_4] = HintText(CustomMessage("They say you wanted to see me #Mr. Kenix#?", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR, + {QM_PINK})); + + hintTextTable[RHT_JUNK_MISC_5] = HintText(CustomMessage("They say Louis once saw an&equals not get set equals", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_6] = HintText(CustomMessage("They say only you can find your rom.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_7] = HintText(CustomMessage("They say ZAPD is good software.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_8] = HintText(CustomMessage("They say you can encounter&a parascode in tall grass.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_9] = HintText(CustomMessage("They say the ship sails on March 32nd.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_10] = HintText(CustomMessage("They say bombing dodongos is fun.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_11] = HintText(CustomMessage("They say shopkeepers don't give credits.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_12] = HintText(CustomMessage("They say shopkeepers don't give credits.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_13] = HintText(CustomMessage("They say Malon is glitched.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_14] = HintText(CustomMessage("They say do I look like I know&what a DList is?", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_15] = HintText(CustomMessage("They say do I look like I know&what an AList is?", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_16] = HintText(CustomMessage("They say the king drinks enthusiastically", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_MISC_17] = HintText(CustomMessage("They say Rubies are on the path to&Lamp Oil, Rope, and Bombs", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SG_1] = HintText(CustomMessage("They say %rError. Human is dead, mismatch.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SG_2] = HintText(CustomMessage("They say this is the choice of the&steins gate.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SG_3] = HintText(CustomMessage("They say el psy kongroo.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SG_4] = HintText(CustomMessage("They say tutturu~.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SG_5] = HintText(CustomMessage("They say im not Christina!.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SG_6] = HintText(CustomMessage("They say you know where to find an IBN5100.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SG_7] = HintText(CustomMessage("They say when you're on a chicken bender&grab a box of chicken tenders.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_SG_8] = HintText(CustomMessage("Juicy Chicken #1! Wow!.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); /*-------------------------- | DUNGEON HINT TEXT | ---------------------------*/ - hintTable[DEKU_TREE] = HintText::DungeonName( - { - // obscure text - Text{ "an ancient tree", /*french*/ "le vieil arbre", /*spanish*/ "un ancestral árbol" }, - }, - {}, - // clear text - Text{ "Deku Tree", /*french*/ "l'Arbre Mojo", /*spanish*/ "el Gran Árbol Deku" }); - - hintTable[DODONGOS_CAVERN] = HintText::DungeonName( - { - // obscure text - Text{ "an immense cavern", /*french*/ "l'immense caverne", /*spanish*/ "una descomunal cueva" }, - }, - {}, - // clear text - Text{ "Dodongo's Cavern", /*french*/ "la Caverne Dodongo", /*spanish*/ "la Cueva de los Dodongos" }); - - hintTable[JABU_JABUS_BELLY] = HintText::DungeonName( - { - // obscure text - Text{ "the belly of a deity", /*french*/ "le ventre d'un gardien", - /*spanish*/ "la tripa de cierta deidad" }, - }, - {}, - // clear text - Text{ "Jabu-Jabu's Belly", /*french*/ "le Ventre de Jabu-Jabu", /*spanish*/ "tripa de Jabu-Jabu" }); - - hintTable[FOREST_TEMPLE] = HintText::DungeonName( - { - // obscure text - Text{ "a deep forest", /*french*/ "la profonde forêt", /*spanish*/ "las profundidades del bosque" }, - }, - {}, - // clear text - Text{ "Forest Temple", /*french*/ "le Temple de la Forêt", /*spanish*/ "el Templo del Bosque" }); - - hintTable[FIRE_TEMPLE] = HintText::DungeonName( - { - // obscure text - Text{ "a high mountain", /*french*/ "la grande montagne", /*spanish*/ "una alta montaña" }, - }, - {}, - // clear text - Text{ "Fire Temple", /*french*/ "le Temple du Feu", /*spanish*/ "el Templo del Fuego" }); - - hintTable[WATER_TEMPLE] = HintText::DungeonName( - { - // obscure text - Text{ "a vast lake", /*french*/ "le vaste lac", /*spanish*/ "un lago inmenso" }, - }, - {}, - // clear text - Text{ "Water Temple", /*french*/ "le Temple de l'Eau", /*spanish*/ "el Templo del Agua" }); - - hintTable[SPIRIT_TEMPLE] = HintText::DungeonName( - { - // obscure text - Text{ "the goddess of the sand", /*french*/ "la déesse des sables", /*spanish*/ "la diosa de las arenas" }, - }, - {}, - // clear text - Text{ "Spirit Temple", /*french*/ "le Temple de l'Esprit", /*spanish*/ "el Templo del Espíritu" } - - ); - - hintTable[SHADOW_TEMPLE] = HintText::DungeonName( - { - // obscure text - Text{ "the house of the dead", /*french*/ "la maison des morts", /*spanish*/ "la casa de la muerte" }, - }, - {}, - // clear text - Text{ "Shadow Temple", /*french*/ "le Temple de l'Ombre", /*spanish*/ "el Templo de las Sombras" }); - - hintTable[ICE_CAVERN] = HintText::DungeonName( - { - // obscure text - Text{ "a frozen maze", /*french*/ "le dédale glacé", /*spanish*/ "un gélido laberinto" }, - }, - {}, - // clear text - Text{ "Ice Cavern", /*french*/ "la caverne de glace", /*spanish*/ "la caverna de hielo" }); - - hintTable[BOTTOM_OF_THE_WELL] = HintText::DungeonName( - { - // obscure text - Text{ "a shadow\'s prison", /*french*/ "la prison d'une ombre", /*spanish*/ "la prisión de las sombras" }, - }, - {}, - // clear text - Text{ "Bottom of the Well", /*french*/ "le fonds du Puits", /*spanish*/ "el fondo del pozo" }); - - hintTable[GERUDO_TRAINING_GROUNDS] = HintText::DungeonName( - { - // obscure text - Text{ "the test of thieves", /*french*/ "l'épreuve des voleurs", /*spanish*/ "la prueba de las bandidas" }, - }, - {}, - // clear text - Text{ "Gerudo Training Grounds", /*french*/ "le Gymnase Gerudo", - /*spanish*/ "el Centro de Instrucción Gerudo" }); - - hintTable[GANONS_CASTLE] = HintText::DungeonName( - { - // obscure text - Text{ "a conquered citadel", /*french*/ "la citadelle assiégée", /*spanish*/ "una conquistada ciudadela" }, - }, - {}, - // clear text - Text{ "Inside Ganon's Castle", /*french*/ "l'intérieur du Château de Ganon", - /*spanish*/ "el interior del Castillo de Ganon" }); + + hintTextTable[RHT_DEKU_TREE] = HintText(CustomMessage("Deku Tree", + /*german*/ "Deku-Baum", + /*french*/ "l'Arbre Mojo"), + // /*spanish*/el Gran Árbol Deku + {}, + {CustomMessage("an ancient tree", + /*german*/ "ein antiker Baum", + /*french*/ "le vieil arbre")}); + // /*spanish*/un ancestral árbol + + hintTextTable[RHT_DODONGOS_CAVERN] = HintText(CustomMessage("Dodongo's Cavern", + /*german*/ "Dodongos Kaverne", + /*french*/ "la Caverne Dodongo"), + // /*spanish*/la Cueva de los Dodongos + {}, + {CustomMessage("an immense cavern", + /*german*/ "eine riesige Kaverne", + /*french*/ "l'immense caverne")}); + // /*spanish*/una descomunal cueva + + hintTextTable[RHT_JABU_JABUS_BELLY] = HintText(CustomMessage("Jabu-Jabu's Belly", + /*german*/ "Jabu-Jabus Bauch", + /*french*/ "le Ventre de Jabu-Jabu"), + // /*spanish*/tripa de Jabu-Jabu + {}, + {CustomMessage("the belly of a deity", + /*german*/ "der Bauch einer Gottheit", + /*french*/ "le ventre d'un gardien")}); + // /*spanish*/la tripa de cierta deidad + + hintTextTable[RHT_FOREST_TEMPLE] = HintText(CustomMessage("Forest Temple", + /*german*/ "Waldtempel", + /*french*/ "le Temple de la Forêt"), + // /*spanish*/el Templo del Bosque + {}, + {CustomMessage("a deep forest", + /*german*/ "ein tiefer Wald", + /*french*/ "la profonde forêt")}); + // /*spanish*/las profundidades del bosque + + hintTextTable[RHT_FIRE_TEMPLE] = HintText(CustomMessage("Fire Temple", + /*german*/ "Feuertempel", + /*french*/ "le Temple du Feu"), + // /*spanish*/el Templo del Fuego + {}, + {CustomMessage("a high mountain", + /*german*/ "ein hoher Berg", + /*french*/ "la grande montagne")}); + // /*spanish*/una alta montaña + + hintTextTable[RHT_WATER_TEMPLE] = HintText(CustomMessage("Water Temple", + /*german*/ "Wassertempel", + /*french*/ "le Temple de l'Eau"), + // /*spanish*/el Templo del Agua + {}, + {CustomMessage("a vast lake", + /*german*/ "ein gewaltiger See", + /*french*/ "le vaste lac")}); + // /*spanish*/un lago inmenso + + hintTextTable[RHT_SPIRIT_TEMPLE] = HintText(CustomMessage("Spirit Temple", + /*german*/ "Geistertempel", + /*french*/ "le Temple de l'Esprit"), + // /*spanish*/el Templo del Espíritu + {}, + {CustomMessage("the goddess of the sand", + /*german*/ "die Göttin des Sandes", + /*french*/ "la déesse des sables")}); + // /*spanish*/la diosa de las arenas + + hintTextTable[RHT_SHADOW_TEMPLE] = HintText(CustomMessage("Shadow Temple", + /*german*/ "Schattentempel", + /*french*/ "le Temple de l'Ombre"), + // /*spanish*/el Templo de las Sombras + {}, + {CustomMessage("the house of the dead", + /*german*/ "das Haus der Toten", + /*french*/ "la maison des morts")}); + // /*spanish*/la casa de la muerte + + hintTextTable[RHT_ICE_CAVERN] = HintText(CustomMessage("Ice Cavern", + /*german*/ "Eishöhle", + /*french*/ "la caverne de glace"), + // /*spanish*/la caverna de hielo + {}, + {CustomMessage("a frozen maze", + /*german*/ "ein gefrorenes Labyrinth", + /*french*/ "le dédale glacé")}); + // /*spanish*/un gélido laberinto + + hintTextTable[RHT_BOTTOM_OF_THE_WELL] = HintText(CustomMessage("Bottom of the Well", + /*german*/ "Grund des Brunnens", + /*french*/ "le fonds du Puits"), + // /*spanish*/el fondo del pozo + {}, + {CustomMessage("a shadow\'s prison", + /*german*/ "das Gefängnis eines Schattens", + /*french*/ "la prison d'une ombre")}); + // /*spanish*/la prisión de las sombras + + hintTextTable[RHT_GERUDO_TRAINING_GROUND] = HintText(CustomMessage("Gerudo Training Grounds", + /*german*/ "Gerudo-Trainingsgelände", + /*french*/ "le Gymnase Gerudo"), + // /*spanish*/el Centro de Instrucción Gerudo + {}, + {CustomMessage("the test of thieves", + /*german*/ "die Prüfung der Diebe", + /*french*/ "l'épreuve des voleurs")}); + // /*spanish*/la prueba de las bandidas + + hintTextTable[RHT_GANONS_CASTLE] = HintText(CustomMessage("Inside Ganon's Castle", + /*german*/ "In Ganons Schloß", + /*french*/ "l'intérieur du Château de Ganon"), + // /*spanish*/el interior del Castillo de Ganon + {}, + {CustomMessage("a conquered citadel", + /*german*/ "eine eroberte Zitadelle", + /*french*/ "la citadelle assiégée")}); + // /*spanish*/una conquistada ciudadela /*-------------------------- | BOSS HINT TEXT | ---------------------------*/ - hintTable[QUEEN_GOHMA] = HintText::Boss({ - // obscure text - Text{"the #Parasitic Armored Arachnid# holds", /*french*/"le #monstre insectoïde géant# possède", /*spanish*/"el #arácnido parasitario acorazado# porta"}, - }, {}, - //clear text - Text{"#Queen Gohma# holds", /*french*/"la #Reine Gohma# possède", /*spanish*/"la #Reina Goma# porta"}); - - hintTable[KING_DODONGO] = HintText::Boss({ - //obscure text - Text{"the #Infernal Dinosaur# holds", /*french*/"le #dinosaure infernal# possède", /*spanish*/"el #dinosaurio infernal# porta"}, - }, {}, - //clear text - Text{"#King Dodongo# holds", /*french*/"le #Roi Dodongo# possède", /*spanish*/"el #Rey Dodongo# porta"}); - - hintTable[BARINADE] = HintText::Boss({ - //obscure text - Text{"the #Bio-Electric Anemone# holds", /*french*/"l'#anémone bioélectrique# possède", /*spanish*/"la #anémona bioeléctrica# porta"}, - }, {}, - //clear text - Text{"#Barinade# holds", /*french*/"#Barinade# possède", /*spanish*/"#Barinade# porta"}); - - hintTable[PHANTOM_GANON] = HintText::Boss({ - //obscure text - Text{"the #Evil Spirit from Beyond# holds", /*french*/"l'#esprit maléfique de l'au-delà# possède", /*spanish*/"el #espíritu maligno de ultratumba# porta"}, - }, {}, - //clear text - Text{"#Phantom Ganon# holds", /*french*/"#Ganon Spectral# possède", /*spanish*/"#Ganon Fantasma# porta"}); - - hintTable[VOLVAGIA] = HintText::Boss({ - //obscure text - Text{"the #Subterranean Lava Dragon# holds", /*french*/"le #dragon des profondeurs# possède", /*spanish*/"el #dragón de lava subterráneo# porta"}, - }, {}, - //clear text - Text{"#Volvagia# holds", /*french*/"#Volvagia# possède", /*spanish*/"#Volvagia# porta"}); - - hintTable[MORPHA] = HintText::Boss({ - //obscure text - Text{"the #Giant Aquatic Amoeba# holds", /*french*/"l'#amibe aquatique géante# possède", /*spanish*/"la #ameba acuática gigante# porta"}, - }, {}, - //clear text - Text{"#Morpha# holds", /*french*/"#Morpha# possède", /*spanish*/"#Morpha# porta"}); - - hintTable[BONGO_BONGO] = HintText::Boss({ - //obscure text - Text{"the #Phantom Shadow Beast# holds", /*french*/"le #monstre de l'ombre# possède", /*spanish*/"la #alimaña oscura espectral# porta"}, - }, {}, - //clear text - Text{"#Bongo Bongo# holds", /*french*/"#Bongo Bongo# possède", /*spanish*/"#Bongo Bongo# porta"}); - - hintTable[TWINROVA] = HintText::Boss({ - //obscure text - Text{"the #Sorceress Sisters# hold", /*french*/"#les sorcières jumelles# possède", /*spanish*/"las #hermanas hechiceras# portan"}, - }, {}, - //clear text - Text{"#Twinrova# holds", /*french*/"#Twinrova# possède", /*spanish*/"#Birova# porta"}); - // - // [LINKS_POCKET_BOSS] = HintText::Boss({ - // //obscure text - // Text{"#@'s pocket# rewards", /*french*/"#@ débute avec#", /*spanish*/"el #bolsillo de @# - // premia con"}, - // }, - // //clear text - // Text{"#@ already has#", /*french*/"#@ a déjà#", /*spanish*/"el #bolsillo de @ ya - // tiene#"} - // ); - + hintTextTable[RHT_QUEEN_GOHMA] = HintText(CustomMessage("#Queen Gohma# holds", + /*german*/ "#Königin Gohma# hält", + /*french*/ "la #Reine Gohma# possède"), + // /*spanish*/la #Reina Goma# porta + {}, + {CustomMessage("the #Parasitic Armored Arachnid# holds", + /*german*/ "die #gepanzerte parasitäre Spinne# hält", + /*french*/ "le #monstre insectoïde géant# possède")}); + // /*spanish*/el #arácnido parasitario acorazado# porta + + hintTextTable[RHT_KING_DODONGO] = HintText(CustomMessage("#King Dodongo# holds", + /*german*/ "#König Dodongo# hält", + /*french*/ "le #Roi Dodongo# possède"), + // /*spanish*/el #Rey Dodongo# porta + {}, + {CustomMessage("the #Infernal Dinosaur# holds", + /*german*/ "der #infernalische Dinosaurier# hält", + /*french*/ "le #dinosaure infernal# possède")}); + // /*spanish*/el #dinosaurio infernal# porta + + hintTextTable[RHT_BARINADE] = HintText(CustomMessage("#Barinade# holds", + /*german*/ "#Barinade# hält", + /*french*/ "#Barinade# possède"), + // /*spanish*/#Barinade# porta + {}, + {CustomMessage("the #Bio-Electric Anemone# holds", + /*german*/ "die #bioelektrische Anemone# hält", + /*french*/ "l'#anémone bioélectrique# possède")}); + // /*spanish*/la #anémona bioeléctrica# porta + + hintTextTable[RHT_PHANTOM_GANON] = HintText(CustomMessage("#Phantom Ganon# holds", + /*german*/ "#Phantom-Ganon# hält", + /*french*/ "#Ganon Spectral# possède"), + // /*spanish*/#Ganon Fantasma# porta + {}, + {CustomMessage("the #Evil Spirit from Beyond# holds", + /*german*/ "der #böse Geist aus dem Jenseits# hält", + /*french*/ "l'#esprit maléfique de l'au-delà# possède")}); + // /*spanish*/el #espíritu maligno de ultratumba# porta + + hintTextTable[RHT_VOLVAGIA] = HintText(CustomMessage("#Volvagia# holds", + /*german*/ "#Volvagia# hält", + /*french*/ "#Volvagia# possède"), + // /*spanish*/#Volvagia# porta + {}, + {CustomMessage("the #Subterranean Lava Dragon# holds", + /*german*/ "der #subterrane Lavadrache# hält", + /*french*/ "le #dragon des profondeurs# possède")}); + // /*spanish*/el #dragón de lava subterráneo# porta + + hintTextTable[RHT_MORPHA] = HintText(CustomMessage("#Morpha# holds", + /*german*/ "#Morpha# hält", + /*french*/ "#Morpha# possède"), + // /*spanish*/#Morpha# porta + {}, + {CustomMessage("the #Giant Aquatic Amoeba# holds", + /*german*/ "die #gigantische aquatische Amöbe# hält", + /*french*/ "l'#amibe aquatique géante# possède")}); + // /*spanish*/la #ameba acuática gigante# porta + + hintTextTable[RHT_BONGO_BONGO] = HintText(CustomMessage("#Bongo Bongo# holds", + /*german*/ "#Bongo Bongo# hält", + /*french*/ "#Bongo Bongo# possède"), + // /*spanish*/#Bongo Bongo# porta + {}, + {CustomMessage("the #Phantom Shadow Beast# holds", + /*german*/ "das #Phantomschattenbiest# hält", + /*french*/ "le #monstre de l'ombre# possède")}); + // /*spanish*/la #alimaña oscura espectral# porta + + hintTextTable[RHT_TWINROVA] = HintText(CustomMessage("#Twinrova# holds", + /*german*/ "#Twinrova# hält", + /*french*/ "#Twinrova# possède"), + // /*spanish*/#Birova# porta + {}, + {CustomMessage("the #Sorceress Sisters# hold", + /*german*/ "die #Hexenschwestern# halten", + /*french*/ "#les sorcières jumelles# possède")}); + // /*spanish*/las #hermanas hechiceras# portan /*-------------------------- | BRIDGE HINT TEXT | ---------------------------*/ - hintTable[BRIDGE_OPEN_HINT] = HintText::Bridge({ - // obscure text - Text{ "The awakened ones have already&created a bridge to the castle&where the evil dwells.", - /*french*/ "Les êtres de sagesse ont&déjà créé un pont vers&le repaire du mal.", - /*spanish*/ "Los sabios #ya habrán creado un puente#&al castillo, de donde emana el mal." }, - }); - - hintTable[BRIDGE_VANILLA_HINT] = HintText::Bridge({ - // obscure text - Text{ "The awakened ones require&the Shadow and Spirit Medallions&as well as the Light Arrows.", - /*french*/ - "Les êtres de sagesse attendront&le héros muni des %rMédaillons de&l'Ombre et l'Esprit%w et des&%yFlèches de Lumière%w.", - /*spanish*/ - "Los sabios aguardarán a que el héroe&obtenga tanto el #Medallón de las&Sombras y el del Espíritu# junto " - "a la #flecha de luz#." }, - }); - - hintTable[BRIDGE_STONES_HINT] = HintText::Bridge({ - // obscure text singular plural - Text{ - "The awakened ones will&await for the Hero to collect&%d |Spiritual Stone|Spiritual Stones|.", - /*french*/ "Les êtres de sagesse attendront&le héros muni de %r%d |Pierre&Ancestrale|Pierres&Ancestrales|%w.", - /*spanish*/ "Los sabios aguardarán a que el héroe&obtenga #%d |piedra espiritual|piedras espirituales|#." }, - }); - - hintTable[BRIDGE_MEDALLIONS_HINT] = HintText::Bridge({ - // obscure text singular plural - Text{ "The awakened ones will await&for the Hero to collect&%d |Medallion|Medallions|.", - /*french*/ "Les êtres de sagesse attendront&le héros muni de %r#%d |Médaillon|Médaillons|%w.", - /*spanish*/ "Los sabios aguardarán a que el héroe&obtenga #%d |medallón|medallones|#." }, - }); - - hintTable[BRIDGE_REWARDS_HINT] = HintText::Bridge({ - // obscure text singular plural - Text{ "The awakened ones will await&for the Hero to collect&%d |Spiritual Stone or Medallion|Spiritual Stones " - "and Medallions|.", - /*french*/ - "Les êtres de sagesse attendront&le héros muni de %r%d |Pierre&Ancestrale ou Médaillon|Pierres&Ancestrales ou Médaillons|%w.", - /*spanish*/ - "Los sabios aguardarán a que el héroe&obtenga #%d |piedra espiritual o medallón|piedras espirtuales y " - "medallones|#." }, - }); - - hintTable[BRIDGE_DUNGEONS_HINT] = HintText::Bridge({ - // obscure text singular plural - Text{ "The awakened ones will await&for the Hero to conquer&%d |Dungeon|Dungeons|.", - /*french*/ "Les êtres de sagesse attendront&la conquête de %r%d |Donjon|Donjons|%w.", - /*spanish*/ "Los sabios aguardarán a que el héroe& complete #%d |mazmorra|mazmorras|#." }, - }); - - hintTable[BRIDGE_TOKENS_HINT] = HintText::Bridge({ - // obscure text - Text{ "The awakened ones will await&for the Hero to collect&%d |Gold Skulltula Token|Gold Skulltula Tokens|.", - /*french*/ "Les êtres de sagesse attendront&le héros muni de %r%d |Symbole|Symboles| &de Skulltula d'or%w.", - /*spanish*/ "Los sabios aguardarán a que el héroe&obtenga #%d |símbolo|símbolos| de&skulltula dorada#." }, - }); - - hintTable[BRIDGE_GREG_HINT] = HintText::Bridge({ - // obscure text - Text{ "The awakened ones will await&for the Hero to find %gGreg%w.", - /*french*/ "The awakened ones will await&for the Hero to find %gGreg%w.", - /*spanish*/ "The awakened ones will await&for the Hero to find %gGreg%w." }, - }); + hintTextTable[RHT_BRIDGE_OPEN_HINT] = HintText(CustomMessage("$lThe awakened ones have #already created a bridge# to the castle where the evil dwells.^", + /*german*/ "$lDie Weisen haben #bereits&eine Brücke zum Portal von&Ganons Schloß gelegt#...^", + /*french*/ "$lLes êtres de sagesse ont#déjà créé un pont# vers le repaire du mal.^", + {QM_LBLUE})); + // /*spanish*/$lLos sabios #ya habrán creado un puente#&al castillo, de donde emana el mal.^ + + + hintTextTable[RHT_BRIDGE_VANILLA_HINT] = HintText(CustomMessage("$6The awakened ones require the #Shadow and Spirit Medallions# as well as the #Light Arrows#.^", + /*german*/ "$6Die Weisen werden darauf warten, daß der Held das #Amulett des Schattens, Amulett der Geister# und die #Licht-Pfeile# sammelt.^", + /*french*/ "$6Les êtres de sagesse attendront le héros muni des #Médaillons de l'Ombre et l'Esprit# et des #Flèches de Lumière#.^", + {QM_RED, QM_YELLOW})); + // /*spanish*/$6Los sabios aguardarán a que el héroe obtenga tanto el #Medallón de las Sombras y el del Espíritu# junto + // a la #flecha de luz#.^ + + hintTextTable[RHT_BRIDGE_STONES_HINT] = HintText(CustomMessage("$0The awakened ones will await for the Hero to collect #[[d]] Spiritual Stone||s|#.^", + /*german*/ "$0Die Weisen werden darauf warten, daß der Held #[[d]] |Heiligen Stein|Heilige Steine|# sammelt.^", + /*french*/ "$0Les êtres de sagesse attendront le héros muni de #[[d]] |Pierre Ancestrale|Pierres Ancestrales|#.^", + {QM_BLUE})); + // /*spanish*/$0Los sabios aguardarán a que el héroe&obtenga #[[d]] |piedra espiritual|piedras espirituales|#.^ + + hintTextTable[RHT_BRIDGE_MEDALLIONS_HINT] = HintText(CustomMessage("$8The awakened ones will await for the Hero to collect #[[d]] Medallion||s|#.^", + /*german*/ "$8Die Weisen werden darauf warten, daß der Held #[[d]] Amulett||e|# sammelt.^", + /*french*/ "$8Les êtres de sagesse attendront le héros muni de #[[d]] Médaillon||s|#.^", + {QM_RED})); + // /*spanish*/$8Los sabios aguardarán a que el héroe&obtenga #[[d]] |medallón|medallones|#.^ + + hintTextTable[RHT_BRIDGE_REWARDS_HINT] = HintText(CustomMessage("$CThe awakened ones will await for the Hero to collect #[[d]]# |#Spiritual Stone# or #Medallion#|" + "#Spiritual Stones# and #Medallions#|.^", + /*german*/ "$CDie Weisen werden darauf warten, daß der Held #[[d]]# |#Heiligen Stein# oder #Amulett#|" + "#Heilige Steine# oder #Amulette#| sammelt.^", + /*french*/ "$CLes êtres de sagesse attendront le héros muni de #[[d]]# |#Pierre Ancestrale# ou #Médaillon#" + "|#Pierres Ancestrales# ou #Médaillons#|.^", + {QM_YELLOW, QM_BLUE, QM_RED})); + // /*spanish*/$CLos sabios aguardarán a que el héroe obtenga #[[d]]# |#piedra espiritual# o #medallón#| + //#piedras espirtuales# y #medallones#|.^ + + hintTextTable[RHT_BRIDGE_DUNGEONS_HINT] = HintText(CustomMessage("$mThe awakened ones will await for the Hero to conquer #[[d]] Dungeon||s|#.^", + /*german*/ "$mDie Weisen werden darauf warten, daß der Held #[[d]] Labyrinth||e|# abschließt.^", + /*french*/ "$mLes êtres de sagesse attendront la conquête de #[[d]] Donjon||s|#.^", + {QM_PINK})); + // /*spanish*/$mLos sabios aguardarán a que el héroe complete #[[d]] mazmorra||s|#.^ + + hintTextTable[RHT_BRIDGE_TOKENS_HINT] = HintText(CustomMessage("$sThe awakened ones will await for the Hero to collect #[[d]] Gold Skulltula Token||s|#.^", + /*german*/ "$sDie Weisen werden darauf warten, daß der Held #[[d]] Skulltula-Symbol||e|# sammelt.^", + /*french*/ "$sLes êtres de sagesse attendront le héros muni de #[[d]] Symbole||s| de Skulltula d'or#.^", + {QM_YELLOW})); + // /*spanish*/$sLos sabios aguardarán a que el héroe obtenga #[[d]] símbolo||s| de skulltula dorada#.^ + + hintTextTable[RHT_BRIDGE_GREG_HINT] = HintText(CustomMessage("$gThe awakened ones will await for the Hero to find #Greg#.^", + {QM_GREEN})); + /*-------------------------- | GANON BOSS KEY HINT TEXT | ---------------------------*/ - hintTable[GANON_BK_START_WITH_HINT] = HintText::GanonsBossKey({ - // obscure text - Text{ "And the %revil one%w's key will&be given %rfrom the start%w.", - /*french*/ "Aussi, la %rclé du Malin%w sera&possession %rmême du héros%w.", - /*spanish*/ "Y obtendrás la llave del #señor del mal# desde el #inicio#." }, - }); - - hintTable[GANON_BK_VANILLA_HINT] = HintText::GanonsBossKey({ - // obscure text - Text{ "And the %revil one%w's key will&be kept in a big chest&%rinside its tower%w.", - /*french*/ "Aussi, la %rclé du Malin%w sera&encoffrée %rdans sa tour%w.", - /*spanish*/ "Y la llave del #señor del mal# aguardará en un gran cofre de #su torre#." }, - }); - - hintTable[GANON_BK_OWN_DUNGEON_HINT] = HintText::GanonsBossKey({ - // obscure text - Text{ "And the %revil one%w's key will&be hidden somewhere %rinside&its castle%w.", - /*french*/ "Aussi, la %rclé du Malin%w sera&cachée %rdans son vaste château%w.", - /*spanish*/ "Y la llave del #señor del mal# aguardará en #algún lugar de su castillo#." }, - }); - - hintTable[GANON_BK_OVERWORLD_HINT] = HintText::GanonsBossKey({ - // obscure text - Text{ "And the %revil one%w's key will&be hidden %routside of&dungeons%w in Hyrule.", - /*french*/ "Aussi, la %rclé du Malin%w se&trouve %rhors des donjons%w d'Hyrule.", - /*spanish*/ "Y la llave del #señor del mal# aguardará #fuera de las mazmorras# de Hyrule." }, - }); - - hintTable[GANON_BK_ANY_DUNGEON_HINT] = HintText::GanonsBossKey({ - // obscure text - Text{ "And the %revil one%w's key will&be hidden %rinside a&dungeon%w in Hyrule.", - /*french*/ "Aussi, la %rclé du Malin%w se&trouve %rdans un donjon%w d'Hyrule.", - /*spanish*/ "Y la llave del #señor del mal# aguardará #en una mazmorra# de Hyrule." }, - }); - - hintTable[GANON_BK_ANYWHERE_HINT] = HintText::GanonsBossKey({ - // obscure text - Text{ "And the %revil one%w's key will&be hidden somewhere&%rin Hyrule%w.", - /*french*/ "Aussi, la %rclé du Malin%w se&trouve quelque part %rdans Hyrule%w.", - /*spanish*/ "Y la llave del #señor del mal# aguardará en #cualquier lugar de Hyrule#." }, - }); - - hintTable[GANON_BK_TRIFORCE_HINT] = HintText::GanonsBossKey({ - // obscure text - Text{ "And the %revil one%w's key will&be given to the Hero once&the %rTriforce%w is completed.", - /*french*/ "Aussi, la %rclé du Malin%w se&révèlera une fois la %rTriforce%w&assemblée.", - /*spanish*/ "Y el héroe recibirá la llave del #señor del mal# cuando haya completado la #Trifuerza#." }, - }); - - hintTable[GANON_BK_SKULLTULA_HINT] = HintText::GanonsBossKey({ - // obscure text - Text { "And the %revil one%w's key will be&provided by the cursed rich man&once %r100 Gold Skulltula Tokens%w&are retrieved.", - /*french*/ "Aussi, la %rclé du Malin%w sera&donnée par l'homme maudit une&fois que %r100 Symboles de&Skulltula d'or%w auront été trouvés.", - /*spanish*/ "Y el rico maldito entregará la llave&del #señor de mal# tras obtener&100 símbolos de skulltula dorada#."}, - }); - - /*-------------------------- - | LACS HINT TEXT | - ---------------------------*/ + hintTextTable[RHT_GANON_BK_START_WITH_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be #given from the start#.^", + /*german*/ "$bUnd der #Schlüssel des Bösen#, wird #von Anfang an, im Besitz des Helden# sein.^", + /*french*/ "$bAussi, la #clé du Malin# sera #possession même du héros#.^", + {QM_PINK, QM_LBLUE})); + // /*spanish*/$bY obtendrás la llave del #señor del mal# desde el #inicio#.^ + + hintTextTable[RHT_GANON_BK_VANILLA_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be kept in a big chest #inside its tower#.^", + /*german*/ "$bUnd der #Schlüssel des Bösen#, wird in der großen Truhe #im Teufelsturm# zu finden sein.^", + /*french*/ "$bAussi, la #clé du Malin# sera encoffrée #dans sa tour#.^", + {QM_PINK, QM_LBLUE})); + // /*spanish*/$bY la llave del #señor del mal# aguardará en un gran cofre de #su torre#.^ + + hintTextTable[RHT_GANON_BK_OWN_DUNGEON_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be hidden somewhere #inside its castle#.^", + /*german*/ "$bUnd der #Schlüssel des Bösen#, wird irgendwo #in Ganons Schloß# zu finden sein.^", + /*french*/ "$bAussi, la #clé du Malin# sera cachée #dans son vaste château#.^", + {QM_PINK, QM_PINK})); + // /*spanish*/$bY la llave del #señor del mal# aguardará en #algún lugar de su castillo#.^ + + hintTextTable[RHT_GANON_BK_OVERWORLD_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be hidden #outside of dungeons# in Hyrule.^", + /*german*/ "$bUnd der #Schlüssel des Bösen#, wird irgendwo #in Hyrule, außerhalb von Labyrinthen# zu finden sein.^", + /*french*/ "$bAussi, la #clé du Malin# se trouve #hors des donjons# d'Hyrule.^", + {QM_PINK, QM_GREEN})); + // /*spanish*/$bY la llave del #señor del mal# aguardará #fuera de las mazmorras# de Hyrule.^ + + hintTextTable[RHT_GANON_BK_ANY_DUNGEON_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be hidden #inside a dungeon# in Hyrule.^", + /*german*/ "$bUnd der #Schlüssel des Bösen#, wird irgendwo #in Hyrule, innerhalb eines Labyrinths# zu finden sein.^", + /*french*/ "$bAussi, la #clé du Malin# se trouve #dans un donjon# d'Hyrule.^", + {QM_PINK, QM_PINK})); + // /*spanish*/$bY la llave del #señor del mal# aguardará #en una mazmorra# de Hyrule.^ + + hintTextTable[RHT_GANON_BK_ANYWHERE_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be hidden somewhere&#in Hyrule#.^", + /*german*/ "$bUnd der #Schlüssel des Bösen#, wird irgendwo #in Hyrule# zu finden sein.^", + /*french*/ "$bAussi, la #clé du Malin# se trouve quelque part #dans Hyrule#.^", + {QM_PINK, QM_BLUE})); + // /*spanish*/$bY la llave del #señor del mal# aguardará en #cualquier lugar de Hyrule#.^ + + hintTextTable[RHT_GANON_BK_TRIFORCE_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be given to the Hero once the #Triforce## is completed.^", + /*german*/ "$bUnd der #Schlüssel des Bösen# wird verliehen, sobald das #Triforce# vervollständigt wurde.^", + /*french*/ "$bAussi, la #clé du Malin# se&révèlera une fois la #Triforce#&assemblée.^", + {QM_PINK, QM_YELLOW})); + // /*spanish*/$bY el héroe recibirá la llave del #señor del mal# cuando haya completado la #Trifuerza#.^ + + hintTextTable[RHT_GANON_BK_SKULLTULA_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by the cursed rich man once #100 Gold Skulltula Tokens# are retrieved.^", + /*german*/ "$bUnd der #Schlüssel des Bösen# wird von einem verfluchten reichen Mann verliehen, sobald #100 Goldene Skulltula-Symbole# wiedererlangt wurden.^", + /*french*/ "$bAussi, la #clé du Malin# sera&donnée par l'homme maudit une fois que #100 Symboles de Skulltula d'or# auront été trouvés.^", + {QM_PINK, QM_YELLOW})); + // /*spanish*/$bY el rico maldito entregará la llave&del #señor de mal# tras obtener&100 símbolos de skulltula dorada#.^ + + hintTextTable[RHT_LACS_VANILLA_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once the #Shadow and Spirit Medallions# are retrieved.^", + /*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #die Amulette des Schattens und der Geister# geborgen wurden.^", + /*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois que les #Médaillons de l'Ombre et de l'Esprit# seront récupérés.^", + {QM_PINK, QM_YELLOW, QM_RED})); + // /*spanish*/$bY #Zelda# entregará la llave del #señor del mal# tras obtener #el medallón de las sombras y del espíritu#.^ + + hintTextTable[RHT_LACS_MEDALLIONS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once #[[d]] Medallion|# is|s# are| retrieved.^", + /*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #[[d]] Amulett|# geborgen wurde|e# geborgen wurden|.^", + /*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois |qu' #[[d]] Médaillon# aura été récupéré|que #[[d]] Médaillons# auront été récupérés|.^", + {QM_PINK, QM_YELLOW, QM_RED})); + // /*spanish*/$bY #Zelda# entregará la llave&del #señor del mal# tras obtener #[[d]] |medallón|medallones|#.^ + + hintTextTable[RHT_LACS_STONES_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once #[[d]] Spiritual Stone|# is|s# are| retrieved.^", + /*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #[[d]] Heilige|r Stein# geborgen wurde| Steine# geborgen wurden|.^", + /*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois |qu' #[[d]] Pierre Ancestrale# aura été&récupérée|que #[[d]] Pierres Ancestrales# auront été récupérées|.^", + {QM_PINK, QM_YELLOW, QM_BLUE})); + // /*spanish*/$bY #Zelda# entregará la llave del #señor del mal# tras obtener #[[d]] piedra| espiritual|s espirituales|#.^ + + hintTextTable[RHT_LACS_REWARDS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once #[[d]]# #Spiritual Stone|# or #Medallion# is|s# and #Medallions# are| retrieved.^", + /*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #[[d]]# #Heilige|r Stein# oder #Amulett#&geborgen wurde| Steine# oder #Amulette#&geborgen wurden|.^", + /*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois qu|' #[[d]]# #Pierre Ancestrale# ou #[[d]] Médaillon# sera récupéré|e&#[[d]]# #Pierres Ancestrales# et&#Médaillons# seront récupérés|.^", + {QM_PINK, QM_YELLOW, QM_YELLOW, QM_BLUE, QM_RED})); + // /*spanish*/$bY #Zelda# entregará la llave del #señor del mal# tras obtener #[[d]]# piedra| espiritual o medallón|s espirituales o medallones|#.^ + + hintTextTable[RHT_LACS_DUNGEONS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once #[[d]] Dungeon|# is|s# are| conquered.^", + /*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #[[d]] Labyrinth|# abgeschlossen wurde|e# abgeschlossen wurden|.^", + /*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois qu|' #[[d]] donjon #sera conquis|e #[[d]] donjons# seront conquis|.^", + {QM_PINK, QM_YELLOW, QM_PINK})); + // /*spanish*/$bY #Zelda# entregará la llave del #señor del mal# tras completar #[[d]] mazmorra||s|#.^ + + hintTextTable[RHT_LACS_TOKENS_HINT] = HintText(CustomMessage("$bAnd the #evil one#'s key will be provided by #Zelda# once #[[d]] Gold Skulltula Token|# is|s# are| retrieved.^", + /*german*/ "$bUnd der #Schlüssel des Bösen# wird von #Zelda# verliehen, sobald #[[d]] Skulltula-Symbol|# gesammelt wurde|e# gesammelt wurden|.^", + /*french*/ "$bAussi, la #clé du Malin# sera fournie par #Zelda# une fois |qu' #[[d]] symbole de Skulltula d'or #sera récupuéré" + "|que &#[[d]] symboles de Skulltula d'or&#seront recupérés|.^", + {QM_PINK, QM_YELLOW, QM_YELLOW})); + // /*spanish*/$bY #Zelda# entregará la llave del #señor del mal# tras obtener #[[d]] símbolo + // ||s| de skulltula dorada#.^ - hintTable[LACS_VANILLA_HINT] = HintText::LACS({ - // obscure text - Text{ - "And the %revil one%w's key will be&provided by Zelda once the&%rShadow and Spirit Medallions%w&are retrieved.", - /*french*/ "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois que &les %rMédaillons de l'Ombre et de&l'Esprit%w seront récupérés.", - /*spanish*/ - "Y Zelda entregará la llave&del #señor del mal# tras obtener&#el medallón de las sombras y del " - "espíritu#." }, - }); - - hintTable[LACS_MEDALLIONS_HINT] = HintText::LACS({ - // obscure text singular plural - Text{ "And the %revil one%w's key will be&provided by Zelda once %r%d&|Medallion%w is|Medallions%w are| retrieved.", - /*french*/ "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois |qu'&%r%d Médaillon%w aura été&récupéré|que&%r%d Médaillons%w auront été&récupérés|.", - /*spanish*/ "Y Zelda entregará la llave&del #señor del mal# tras obtener&#%d |medallón|medallones|#." }, - }); - - hintTable[LACS_STONES_HINT] = HintText::LACS({ - // obscure text singular plural - Text{ - "And the %revil one%w's key will be&provided by Zelda once %r%d&|Spiritual Stone%w is|Spiritual Stones%w are| " - "retrieved.", - /*french*/ "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois |qu'&%r%d Pierre Ancestrale%w aura été&récupérée|que&%r%d Pierres Ancestrales%w auront été&récupérées|.", - /*spanish*/ - "Y Zelda entregará la llave&del #señor del mal# tras obtener&#%d |piedra espiritual|piedras " - "espirituales|#." }, - }); - - hintTable[LACS_REWARDS_HINT] = HintText::LACS({ - // obscure text singular plural - Text{ "And the %revil one%w's key will be&provided by Zelda once %r%d&|Spiritual Stone or Medallion%w&" - "is|Spiritual Stones and Medallions%w&are| retrieved.", - /*french*/ - "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois |qu'&%r%d Pierre Ancestrale ou %d&Médaillon%w sera récupéré|que&%r%d Pierres Ancestrales et&Médaillons%w seront récupérés|.", - /*spanish*/ - "Y Zelda entregará la llave&del #señor del mal# tras obtener&#%d |piedra espiritual o medallón|piedras " - "espirituales o medallones|#." }, - }); - - hintTable[LACS_DUNGEONS_HINT] = HintText::LACS({ - // obscure text singular plural - Text{ "And the %revil one%w's key will be&provided by Zelda once %r%d&|Dungeon%w is|Dungeons%w are| conquered.", - /*french*/ "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois |qu'&%r%d donjon %wsera conquis|que&%r%d donjons%w seront conquis|.", - /*spanish*/ "Y Zelda entregará la llave&del #señor del mal# tras completar&#%d |mazmorra|mazmorras|#." }, - }); - - hintTable[LACS_TOKENS_HINT] = HintText::LACS({ - // obscure text singular plural - Text{ "And the %revil one%w's key will be&provided by Zelda once %r%d |Gold&Skulltula Token%w is|Gold&Skulltula " - "Tokens%w are| retrieved.", - /*french*/ "Aussi, la %rclé du Malin%w sera&fournie par Zelda une fois |qu'&%r%d symbole de Skulltula d'or&%wsera récupuéré|que &%r%d symboles de Skulltula d'or&%wseront recupérés|.", - /*spanish*/ - "Y Zelda entregará la llave&del #señor del mal# tras obtener&#%d |símbolo|símbolos| de&skulltula " - "dorada#." }, - }); /*-------------------------- | TRIAL HINT TEXT | ---------------------------*/ - hintTable[SIX_TRIALS] = HintText::Exclude({ - // obscure text - Text{ "#Ganon's Tower# is protected by a powerful barrier.", - /*french*/ "#la Tour de Ganon# est protégée par une puissante barrière", - /*spanish*/ "la #torre de Ganon# está protegida por una poderosa barrera" }, - }); - - hintTable[ZERO_TRIALS] = HintText::Exclude({ - // obscure text - Text{ "Sheik dispelled the barrier around #Ganon's Tower#.", - /*french*/ "Sheik a dissipé la barrière autour de #la Tour de Ganon#", - /*spanish*/ "Sheik disipó la barrera alrededor de la #torre de Ganon#." }, - }); - - hintTable[FOUR_TO_FIVE_TRIALS] = HintText::Exclude({ - // obscure text - Text{ " was dispelled by Sheik.", /*french*/ " a été dissipée par Sheik.", - /*spanish*/ " se disipó gracias a Sheik." }, - }); - - hintTable[ONE_TO_THREE_TRIALS] = HintText::Exclude({ - // obscure text - Text{ " protects Ganons Tower.", /*french*/ " protège la Tour de Ganon.", - /*spanish*/ " protege la torre de Ganon" }, - }); + hintTextTable[RHT_SIX_TRIALS] = HintText(CustomMessage("They say that #Ganon's Tower# is protected by a powerful barrier.", + /*german*/ "Man erzählt sich, daß der #Teufelsturm# von einer mächtigen Barriere geschützt sei.", + /*french*/ "Selon moi, #la Tour de Ganon# est protégée par une puissante barrière", {QM_PINK})); + // /*spanish*/Según dicen, la #torre de Ganon# está protegida por una poderosa barrera + + hintTextTable[RHT_ZERO_TRIALS] = HintText(CustomMessage("They say that Sheik dispelled the barrier around #Ganon's Tower#.", + /*german*/ "Man erzählt sich, Shiek habe die Barriere um den #Teufelsturm# aufgelöst.", + /*french*/ "Selon moi, Sheik a dissipé la barrière autour de #la Tour de Ganon#", {QM_YELLOW})); + // /*spanish*/Según dicen, Sheik disipó la barrera alrededor de la #torre de Ganon#. + + hintTextTable[RHT_TRIAL_OFF] = HintText(CustomMessage("They say that #[[1]]# was dispelled by Sheik.", + /*german*/ "Man erzählt sich, daß #[[1]]# von Shiek aufgelöst worden sei.", + /*french*/ "Selon moi, #[[1]]# a été dissipée par Sheik.", {QM_YELLOW})); + // /*spanish*/Según dicen, #[[1]]# se disipó gracias a Sheik. + + hintTextTable[RHT_TRIAL_ON] = HintText(CustomMessage("They say that #[[1]]# protects Ganons Tower.", + /*german*/ "Man erzählt sich, daß #[[1]]# den Teufelsturm schütze.", + /*french*/ "Selon moi, #[[1]]# protège la Tour de Ganon.", {QM_PINK})); + // /*spanish*/Según dicen, #[[1]]# protege la torre de Ganon + + hintTextTable[RHT_LIGHT_TRIAL] = HintText(CustomMessage("the Light Trial", + /*german*/ "die Prüfung des Lichts", + /*french*/ "l'épreuve de la Lumière")); + // /*spanish*/la prueba de la luz + + hintTextTable[RHT_FOREST_TRIAL] = HintText(CustomMessage("the Forest Trial", + /*german*/ "die Prüfung des Waldes", + /*french*/ "l'épreuve de la Forêt")); + // /*spanish*/la prueba del bosque + + hintTextTable[RHT_FIRE_TRIAL] = HintText(CustomMessage("the Fire Trial", + /*german*/ "die Prüfung des Feuers", + /*french*/ "l'épreuve du Feu")); + // /*spanish*/la prueba del fuego + + hintTextTable[RHT_WATER_TRIAL] = HintText(CustomMessage("the Water Trial", + /*german*/ "die Prüfung des Wassers", + /*french*/ "l'épreuve de l'Eau")); + // /*spanish*/la prueba del agua + + hintTextTable[RHT_SPIRIT_TRIAL] = HintText(CustomMessage("the Spirit Trial", + /*german*/ "die Prüfung der Geister", + /*french*/ "l'épreuve de l'Esprit")); + // /*spanish*/la prueba del espíritu + + hintTextTable[RHT_SHADOW_TRIAL] = HintText(CustomMessage("the Shadow Trial", + /*german*/ "die Prüfung des Schattens", + /*french*/ "l'épreuve de l'Ombre")); + // /*spanish*/la prueba de las sombras /*-------------------------- | ALTAR TEXT | ---------------------------*/ - hintTable[SPIRITUAL_STONE_TEXT_START] = HintText::Altar({ - // obscure text - Text{ "3 Spiritual Stones found in Hyrule...", - /*french*/ "Les trois Pierres Ancestrales cachées&dans Hyrule...", - /*spanish*/ "Tres piedras espirituales halladas por Hyrule..." }, - }); - - hintTable[CHILD_ALTAR_TEXT_END_DOTOPEN] = HintText::Altar({ - // obscure text - Text{ "Ye who may become a Hero...&The path to the future is open...", - /*french*/ "À celui qui a quête de devenir&héros...&Le futur vous accueille béant...", - /*spanish*/ "Para aquel que se convierta en el héroe...&La puerta al futuro está a su disposición..." }, - }); - - hintTable[CHILD_ALTAR_TEXT_END_DOTSONGONLY] = HintText::Altar({ - // obscure text - Text{ - "Ye who may become a Hero...&Stand with the Ocarina and&play the Song of Time.", - /*french*/ "À celui qui a quête de devenir&héros...&Portez l'Ocarina et jouez&le chant du temps.", - /*spanish*/ "Para aquel que se convierta en el héroe...&Tome la ocarina y&entone la Canción del Tiempo." }, - }); - - hintTable[CHILD_ALTAR_TEXT_END_DOTCLOSED] = HintText::Altar({ - // obscure text - Text{ "Ye who may become a Hero...&Offer the spiritual stones and&play the Song of Time.", - /*french*/ - "À celui qui a quête de devenir&héros... Présentez les Pierres&Ancestrales et jouez&le chant du temps.", - /*spanish*/ - "Para aquel que se convierta en el héroe...&Tome las piedras espirituales y&entone la Canción del " - "Tiempo." }, - }); - - hintTable[ADULT_ALTAR_TEXT_START] = HintText::Altar({ - // obscure text - Text{ "An awakening voice from the Sacred&Realm will call those destined to be&Sages, who dwell in the five " - "temples.", - /*french*/ - "Quand le mal aura triomphé, une voix&du Saint Royaume appellera ceux&cachés dans les cinq temples, " - "destinés^à être Sages.", - /*spanish*/ - "Cuando el mal lo impregne todo, desde el Reino Sagrado surgirá una voz que hará despertar a los sabios " - "que moran en los #cinco templos#." }, - }); - - hintTable[ADULT_ALTAR_TEXT_END] = HintText::Altar({ - // obscure text - Text{ - "$kTogether with the Hero of Time,&the awakened ones will return&the light of peace to the world...", - /*french*/ - "$kEnsemble avec le Héros du &Temps, ces Sages emprisonneront&le mal et réinstaureront la&lumière de paix " - "dans le monde...", - /*spanish*/ - "Con el Héroe del Tiempo, aquellos&que despierten detendrán el mal y&volverán al mundo de luz la paz..." }, - }); + hintTextTable[RHT_CHILD_ALTAR_STONES] = HintText(CustomMessage("3 Spiritual Stone's found in Hyrule...^$0#[[1]]#...^$1#[[2]]#...^$2#[[3]]#...^", + /*german*/ "Drei Heilige Steine, zu finden in Hyrule...$0#[[1]]#...^$1#[[2]]#...^$2#[[3]]#...^", + /*french*/ "Les trois Pierres Ancestrales cachées&dans Hyrule...$0#[[1]]#...^$1#[[2]]#...^$2#[[3]]#...^", + {QM_GREEN, QM_RED, QM_BLUE}, {true, true, true})); + // /*spanish*/ Tres piedras espirituales halladas por Hyrule...$0#[[1]]#...^$1#[[2]]#...^$2#[[3]]#...^ + + hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTOPEN] = HintText(CustomMessage("$oYe who may become a Hero...&The path to the future is open...", + /*german*/ "$oJener auf dem Weg des Helden...&Der Pfad zur Zukunft sei geöffnet...", + /*french*/ "$oÀ celui qui a quête de devenir&héros...&Le futur vous accueille béant...")); + // /*spanish*/$oPara aquel que se convierta en el héroe...&La puerta al futuro está a su disposición... + + hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTSONGONLY] = HintText(CustomMessage("$cYe who may become a Hero...&Stand with the Ocarina and&play the Song of Time.", + /*german*/ "$cJener auf dem Weg des Helden...&Nehme er seine Okarina zur Hand und&spiele hier die Hymne der Zeit.", + /*french*/ "$cÀ celui qui a quête de devenir&héros...&Portez l'Ocarina et jouez&le chant du temps.")); + // /*spanish*/$cPara aquel que se convierta en el héroe...&Tome la ocarina y&entone la Canción del Tiempo. + + hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTCLOSED] = HintText(CustomMessage("$iYe who may become a Hero...&Offer the spiritual stones and&play the Song of Time.", + /*german*/ "$iJener mit den drei Heiligen Steinen&nehme seine Okarina zur Hand und&spiele hier die Hymne der Zeit.", + /*french*/ "$iÀ celui qui a quête de devenir&héros... Présentez les Pierres&Ancestrales et jouez&le chant du temps.")); + // /*spanish*/$iPara aquel que se convierta en el héroe...&Tome las piedras espirituales y&entone la Canción del Tiempo. + + hintTextTable[RHT_ADULT_ALTAR_MEDALLIONS] = HintText(CustomMessage("An awakening voice from the Sacred Realm will call those destined to be Sages, who dwell in the #five temples#.^" + "$8#[[1]]#...^$3#[[2]]#...^$4#[[3]]#...^$5#[[4]]#...^$6#[[5]]#...^$7#[[6]]#...^" , + /*german*/ "Beherrscht das Böse die Welt, weilen&jene Weisen, die von der Stimme des Heiligen Reiches erweckt werden, noch&in den #fünf Tempeln#.^" + "$8#[[1]]#...^$3#[[2]]#...^$4#[[3]]#...^$5#[[4]]#...^$6#[[5]]#...^$7#[[6]]#...^", + /*french*/ "Quand le mal aura triomphé, une voix du Saint Royaume appellera ceux cachés dans les #cinq temples#, destinés^à être Sages.^" + "$8#[[1]]#...^$3#[[2]]#...^$4#[[3]]#...^$5#[[4]]#...^$6#[[5]]#...^$7#[[6]]#...^", + { QM_RED, QM_YELLOW, QM_GREEN, QM_RED, QM_BLUE, QM_YELLOW, QM_PINK}, {true, true, true, true, true, true}, TEXTBOX_TYPE_BLUE)); + // /*spanish*/Cuando el mal lo impregne todo, desde el Reino Sagrado surgirá una voz que hará despertar a los sabios que moran en los #cinco templos#.^ + // $8#[[1]]#...^$3#[[2]]#...^$4#[[3]]#...^$5#[[4]]#...^$6#[[5]]#...^$7#[[6]]#...^ + + hintTextTable[RHT_ADULT_ALTAR_TEXT_END] = HintText(CustomMessage("$kTogether with the Hero of Time, the awakened ones will return the light of peace to the world...", + /*german*/ "$kZusammen mit dem Auserwählten werden diese ihre Kräfte einsetzen, um der Welt den Frieden wiederzugeben.", + /*french*/ "$kEnsemble avec le Héros du Temps, ces Sages emprisonneront le mal et réinstaureront la lumière de paix dans le monde...")); + // /*spanish*/Con el Héroe del Tiempo, aquellos&que despierten detendrán el mal y&volverán al mundo de luz la paz... /*-------------------------- - | VALIDATION LINE TEXT | + | Static Item Hints | ---------------------------*/ - hintTable[VALIDATION_LINE] = HintText::Validation({ - // obscure text - Text{ "Hmph... Since you made it this far, I'll let you know what glorious prize of Ganon's you likely missed " - "out on in my tower.^Behold...^", - /*french*/ - "Pah! Puisque tu t'es rendu ici, je te dirai quel trésor tu as manqué dans ma tour.^Et c'est...^", - /*spanish*/ - "Mmm... Ya que has llegado hasta aquí, te diré qué preciado objeto de mi propiedad puedes haberte dejado " - "en mi torre.^He aquí...^" }, - }); + hintTextTable[RHT_GANONDORF_HINT_LA_ONLY] = HintText(CustomMessage("Ha ha ha... You'll never beat me by reflecting my lightning bolts and unleashing the arrows from #[[1]]#!", + /*german*/ "", + /*french*/ "Ha ha ha... Pauvre fou! Tu ne pourras jamais me vaincre sans les flèches que j'ai cachées dans #[[1]]#!", + {QM_RED})); + // /*spanish*/Ja, ja, ja... Nunca me derrotarás reflejando mis esferas de energía y desplegando la flecha de luz de #[[1]]#! + + hintTextTable[RHT_GANONDORF_HINT_MS_ONLY] = HintText(CustomMessage("Ha ha ha... You'll never defeat me, drop a castle on me and finish me off with the sacred blade from #[[2]]#!", + /*german*/ "", + /*french*/ "", + {QM_RED})); + + hintTextTable[RHT_GANONDORF_HINT_LA_AND_MS] = HintText(CustomMessage("Ha ha ha... You'll never beat me by reflecting my lightning bolts and unleashing the arrows from #[[1]]#!" + "^And even if you do, you'll never find the legendary blade hidden in #[[2]]#!", + /*german*/ "", + /*french*/ "Ha ha ha... Pauvre fou! Tu ne pourras jamais me vaincre sans les flèches que j'ai cachées dans #[[1]]#!" + "^Et même si tu les trouves, tu ne touveras jamais l'épée de légende cachée dans #[[2]]#!", + {QM_RED, QM_RED})); + // /*spanish*/Ja, ja, ja... Nunca me derrotarás reflejando mis esferas de energía y desplegando la flecha de luz de #[[1]]#! + // ^E incluso si lo haces, nunca encontrarás la espada legendaria escondida en #[[2]]#! + + hintTextTable[RHT_SHEIK_HINT_LA_ONLY] = HintText(CustomMessage("I overheard Ganondorf say that he misplaced the #Light Arrows# in #[[1]]#.", + /*german*/ "", + /*french*/ "J'ai entendu dire que Ganondorf aurait caché les #Flèches de Lumière# dans #[[1]]#.", + {QM_YELLOW, QM_RED})); + + hintTextTable[RHT_DAMPE_DIARY] = HintText(CustomMessage("Whoever reads this, please enter #[[1]]#. I will let you have my #stretching, shrinking keepsake#.^I'm waiting for you.&--Dampé", + /*german*/ "Wer immer dies liest, der möge folgenden Ort aufsuchen: #[[1]]#. Ihm gebe ich meinen #dehnenden, schrumpfenden Schatz#.^Ich warte!&Boris", //RANDOTODO color in whatever refers to the hookshot + /*french*/ "Toi qui lit ce journal, rends-toi dans #[[1]]#. Et peut-être auras-tu droit à mon précieux #trésor#.^Je t'attends...&--Igor", + {QM_RED, QM_RED})); + + hintTextTable[RHT_GREG_HINT] = HintText(CustomMessage("By the way, if you're interested, I saw the shiniest #Green Rupee# somewhere in #[[1]]#.^It's said to have #mysterious powers#...^But then, it could just be another regular rupee.&Oh well.", + /*german*/ "", + /*french*/ "Au fait, si ça t'intéresse, j'ai aperçu le plus éclatant des #Rubis Verts# quelque part à #[[1]]#. On dit qu'il possède des pouvoirs mystérieux... Mais bon, ça pourrait juste être un autre rubis ordinaire.",//RANDOTODO color in mysterious powers + {QM_GREEN, QM_RED, QM_RED})); + + hintTextTable[RHT_SARIA_TALK_HINT] = HintText(CustomMessage("Did you feel the #surge of magic# recently? A mysterious bird told me it came from #[[1]]#.^You should check that place out, @!", + /*german*/ "", + /*french*/ "As-tu récemment ressenti une vague de #puissance magique#? Un mystérieux hibou m'a dit qu'elle provenait du #[[1]]#. Tu devrais aller y jeter un coup d'oeil, @!", + {QM_GREEN, QM_RED})); + + hintTextTable[RHT_SARIA_SONG_HINT] = HintText(CustomMessage("Did you feel the #surge of magic# recently? A mysterious bird told me it came from #[[1]]#.^You should check that place out, @!\x0B", + /*german*/ "", + /*french*/ "As-tu récemment ressenti une vague de #puissance magique#? Un mystérieux hibou m'a dit qu'elle provenait du #[[1]]#. Tu devrais aller y jeter un coup d'oeil, @!\x0B", + {QM_GREEN, QM_RED}, {}, TEXTBOX_TYPE_BLUE)); + + hintTextTable[RHT_LOACH_HINT] = HintText(CustomMessage("What?^You wanna know about the&%rHyrule Loach%w?^It's a big fish, but it's so rare that I'll give my %g[[1]]%w to anyone who catches it. Seriously!", + {QM_RED})); + + hintTextTable[RHT_FISHING_POLE_HINT] = HintText(CustomMessage("^If I remember correctly, I lost it somewhere in #[[1]]#...&Let me know if you find it!", + {QM_RED})); /*-------------------------- - | LIGHT ARROW LOCATION TEXT| + | Static Entrance Hint | ---------------------------*/ - hintTable[LIGHT_ARROW_LOCATION_HINT] = HintText::LightArrow({ - // obscure text - Text{ - "Ha ha ha... You'll never beat me by reflecting my lightning bolts and unleashing the arrows from ", - /*french*/ - "Ha ha ha... Pauvre fou! Tu ne pourras jamais me vaincre sans les flèches que j'ai cachées dans ", - /*spanish*/ - "Ja, ja, ja... Nunca me derrotarás reflejando mis esferas de energía y desplegando la flecha de luz de " }, - }); - - + hintTextTable[RHT_WARP_SONG] = HintText(CustomMessage("Warp to&#[[1]]#?&" + TWO_WAY_CHOICE() + "#OK&No#", + /*german*/ "Zu&#[[1]]#?&" + TWO_WAY_CHOICE() + "#OK&No#", + /*french*/ "Se téléporter vers&#[[1]]#?&" + TWO_WAY_CHOICE() + "#OK!&Non#", + {QM_RED, QM_GREEN})); + /*-------------------------- - |MASTER SWORD LOCATION TEXT| + | STATIC LOCATION HINTS | ---------------------------*/ - hintTable[MASTER_SWORD_LOCATION_HINT] = HintText::MasterSword({ - // obscure text - Text{"And even if you do, you'll never find the legendary blade hidden in ", - /*french*/ - "Et même si tu les trouves, tu ne touveras jamais l'épée de légende cachée dans ", - /*spanish*/ - "E incluso si lo haces, nunca encontrarás la espada legendaria escondida en " }, - }); + hintTextTable[RHT_HBA_HINT_SIGN] = HintText(CustomMessage("#Horseback Archery# Range Prizes:&1000: #[[1]]#&1500: #[[2]]#^@'s Record: #" + CustomMessage::POINTS(HS_HORSE_ARCHERY) + "#", + {QM_RED, QM_GREEN, QM_GREEN, QM_GREEN}, {}, TEXTBOX_TYPE_WOODEN)); - hintTable[YOUR_POCKET] = HintText::Exclude({ - // obscure text - Text{ "your pocket", /*french*/ "tes poches", /*spanish*/ "tu bolsillo" }, - }); + hintTextTable[RHT_HBA_HINT_NOT_ON_HORSE] = HintText(CustomMessage("Hey, rookie!&Come back on your #horse# and take on then #Horseback Archery# challenge!^" + "Impress me with a high score of 1000 to win a #[[1]]# or score 1500 for my #[[2]]#!", + {QM_RED, QM_RED, QM_GREEN, QM_GREEN})); - /*-------------------------- - | GANON LINE TEXT | - ---------------------------*/ + hintTextTable[RHT_HBA_HINT_INITIAL] = HintText(CustomMessage("Hey, rookie!&Want to take on the #Horseback Archery# challenge?^" + "Impress me with a high score of 1000 to win a #[[1]]# or score 1500 for my #[[2]]#!\x0B", + {QM_RED, QM_GREEN, QM_GREEN})); - hintTable[GANON_LINE01] = HintText::GanonLine({ - // obscure text - Text{ "Oh! It's @.&I was expecting someone called Sheik.&Do you know what happened to them?", - /*french*/ "Ah, c'est @.&J'attendais un certain Sheik.&Tu sais ce qui lui est arrivé?", - /*spanish*/ - "¡Oh! Pero si es @.&Estaba esperando a alguien llamado Sheik. ¿Sabes qué puede haberle pasado?" }, - }); - - hintTable[GANON_LINE02] = HintText::GanonLine({ - // obscure text - Text{ "I knew I shouldn't have put the key on the other side of my door.", - /*french*/ "J'aurais dû garder la clé ici. Hélas...", - /*spanish*/ "Sabía que no tendría que haber dejado la llave al otro lado de la puerta." }, - }); - - hintTable[GANON_LINE03] = HintText::GanonLine({ - // obscure text - Text{ "Looks like it's time for a round of tennis.", - /*french*/ "C'est l'heure de jouer au tennis.", - /*spanish*/ "Parece que es hora de una pachanga de tenis." }, - }); - - hintTable[GANON_LINE04] = HintText::GanonLine({ - // obscure text - Text{ "You'll never deflect my bolts of energy with your sword, then shoot me with those Light Arrows you " - "happen to have.", - /*french*/ - "Ne perds pas ton temps à frapper mes éclairs d'énergie avec ton épée et me tirer avec tes flèches de " - "Lumière!", - /*spanish*/ - "Nunca reflejarás mis esferas de energía con tu espada, para después dispararme con las flechas de luz " - "que tendrás." }, - }); - - hintTable[GANON_LINE05] = HintText::GanonLine({ - // obscure text - Text{ "Why did I leave my trident back in the desert?", - /*french*/ "Sale bêtise... Et j'ai oublié mon trident dans le désert!", - /*spanish*/ "Santa Hylia... ¿Por qué me habré dejado el tridente en el desierto?" }, - }); - - hintTable[GANON_LINE06] = HintText::GanonLine({ - // obscure text - Text{ "Zelda is probably going to do something stupid, like send you back to your own timeline.^So this is " - "quite meaningless. Do you really want to save this moron?", - /*french*/ - "Même si je suis vaincu... Zelda te renverra dans ton ère, et je reviendrai conquérir!^Telle est la " - "prophécie d'Hyrule Historia!", - /*spanish*/ - "Seguro que Zelda trata de hacer alguna tontería, como enviarte de vuelta a tu línea temporal.^No tiene " - "ningún sentido alguno. ¿De verdad quieres salvar a esa tonta?" }, - }); - - hintTable[GANON_LINE07] = HintText::GanonLine({ - // obscure text - Text{ "What about Zelda makes you think&she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the " - "hungry,&and my castle floats.", - /*french*/ - "Zelda ne sera jamais un meilleur monarque que moi!^J'ai un château volant, mes sujets sont des belles " - "amazones... et mes Moblins sont clairement plus puissants que jamais!", - /*spanish*/ - "¿Qué te hace pensar que Zelda gobierna mejor que yo?^Yo he salvado el Rancho Lon Lon,&he alimentado a " - "los hambrientos&y hasta hago que mi castillo flote." }, - }); - - hintTable[GANON_LINE08] = HintText::GanonLine({ - // obscure text - Text{ "I've learned this spell,&it's really neat,&I'll keep it later&for your treat!", - /*french*/ - "Gamin, ton destin achève,&sous mon sort tu périras!&Cette partie ne fut pas brève,&et cette mort, tu " - "subiras!", - /*spanish*/ - "Veamos ahora que harás,&la batalla ha de comenzar,&te enviaré de una vez al más allá,&¿listo para " - "afrontar la verdad?" }, - }); - - hintTable[GANON_LINE09] = HintText::GanonLine({ - // obscure text - Text{ "Many tricks are up my sleeve,&to save yourself&you'd better leave!", - /*french*/ "Sale petit garnement,&tu fais erreur!&C'est maintenant que marque&ta dernière heure!", - /*spanish*/ "¿No osarás a mí enfrentarte?&Rimas aparte,&¡voy a matarte!" }, - }); - - hintTable[GANON_LINE10] = HintText::GanonLine({ - // obscure text - Text{ "After what you did to Koholint Island, how can you call me the bad guy?", - /*french*/ "J'admire ce que tu as fait à l'Île Koholint... Toi et moi, nous devrions faire équipe!", - /*spanish*/ "Después de lo que le hiciste a la Isla Koholint, ¿cómo te atreves a llamarme malvado?" }, - }); - - hintTable[GANON_LINE11] = HintText::GanonLine({ - // obscure text - Text{ "Today, let's begin down&'The Hero is Defeated' timeline.", - /*french*/ - "Si tu me vaincs, Hyrule sera englouti... mais si tu meurs, on aura A Link to the Past, le meilleur opus " - "de la série!", - /*spanish*/ - "Hoy daremos lugar a la línea temporal del Héroe Derrotado.&¡Prepárate para el culmen de esta saga!" }, - }); + hintTextTable[RHT_HBA_HINT_HAVE_1000] = HintText(CustomMessage("Hey, newcomer!&Want to take on the #Horseback Archery# challenge?^" + "Prove yourself to be a horsemaster by scoring 1500 points to win my #[[1]]#!\x0B", + {QM_RED, QM_GREEN})); - /*-------------------------- - | MERCHANTS' ITEMS | - ---------------------------*/ + hintTextTable[RHT_MALON_HINT_HOW_IS_EPONA] = HintText(CustomMessage("@! You should come back with Epona and try to beat my time on the #Obstacle Course#!^" + "If you beat my time, I'll give you my favourite #cow# Elsie and her toy #[[1]]#!", + {QM_RED, QM_BLUE, QM_GREEN})); - hintTable[MEDIGORON_DIALOG_FIRST] = HintText::MerchantsDialogs({ - // obscure text - Text{ "How about buying ", - /*french*/ "Veux-tu acheter ", - /*spanish*/ "¿Me compras " }, - }); - - hintTable[MEDIGORON_DIALOG_SECOND] = HintText::MerchantsDialogs({ - // obscure text - Text{ " for #200 Rupees#?&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#", - /*french*/ " pour #200 rubis#?&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#", - /*spanish*/ " por #200 rupias#?&" + TWO_WAY_CHOICE() + "#Comprar&No comprar#" }, - }); - - hintTable[CARPET_SALESMAN_DIALOG_FIRST] = HintText::MerchantsDialogs({ - // obscure text - Text{ "Welcome!^I am selling stuff, strange and rare, from&all over the world to everybody. Today's&special " - "is...^", - /*french*/ - "Bienvenue!^Je vends des objets rares et merveilleux du&monde entier. En spécial aujourd'hui...^", - /*spanish*/ - "¡Acércate!^Vendo productos extraños y difíciles de&encontrar... De todo el mundo a todo el&mundo. La " - "oferta de hoy es...^¡" }, - }); - - hintTable[CARPET_SALESMAN_DIALOG_SECOND] = HintText::MerchantsDialogs({ - // obscure text - Text{ - "! Terrifying!&I won't tell you what it is until I see the&money...^How about #200 Rupees#?&&" + - TWO_WAY_CHOICE() + "#Buy&Don't buy#", - /*french*/ - "! Un&concentré de puissance! Mais montre tes&rubis avant que je te dise ce que c'est...^Disons #200 " - "rubis#?&&" + - TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#", - /*spanish*/ - "! ¡Terrorífico!&No te revelaré su nombre hasta que&vea el dinero...^#200 rupias#, ¿qué te parece?&&" + - TWO_WAY_CHOICE() + "#Comprar&No comprar#" }, - }); - - hintTable[CARPET_SALESMAN_DIALOG_THIRD] = HintText::MerchantsDialogs({ - // obscure text - Text{ "Thank you very much!^What I'm selling is... #", - /*french*/ "Merci beaucoup!^Cet objet extraordinaire est... #", - /*spanish*/ "¡Muchas gracias!^Lo que vendo es... #¡" }, - }); - - hintTable[CARPET_SALESMAN_DIALOG_FOURTH] = HintText::MerchantsDialogs({ - // obscure text - Text{ "!#^The mark that will lead you to the #Spirit&Temple# is the #flag on the " + IF_NOT_MQ() + "left" + - MQ_ELSE() + "right" + MQ_END() + "# outside the shop. Be seeing you!", - /*french*/ "!#^La marque qui te mènera au #Temple de l'Esprit# est le #drapeau " + IF_NOT_MQ() + - "gauche" + MQ_ELSE() + "droite" + MQ_END() + "# en sortant d'ici. À la prochaine!", - /*spanish*/ "!#^La marca que te guiará al #Templo del&Espíritu# es la #bandera que está a la&" + - IF_NOT_MQ() + "izquierda" + MQ_ELSE() + "derecha" + MQ_END() + "# al salir de aquí. ¡Nos vemos!" }, - }); - - hintTable[GRANNY_DIALOG] = HintText::MerchantsDialogs({ - // obscure text - Text{ "! How about #100 Rupees#?&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#", - /*french*/ "! Que dis-tu de #100 rubis#?&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#", - /*spanish*/ ". Vendo por #100 rupias#.&" + TWO_WAY_CHOICE() + "#Comprar&No comprar#" }, - }); -} + hintTextTable[RHT_MALON_HINT_OBSTICLE_COURSE] = HintText(CustomMessage("How about trying the #Obstacle Course?# If you beat my time I'll let you keep my favourite #cow# Elsie and her toy #[[1]]#!^" + "Challenge the #Obstacle Course?#&\x1B&#Let's go&No thanks#", + {QM_RED, QM_BLUE, QM_GREEN, QM_RED, QM_GREEN})); -int32_t StonesRequiredBySettings() { - int32_t stones = 0; - if (Settings::Bridge.Is(RAINBOWBRIDGE_STONES)) { - stones = std::max({ stones, (int32_t)Settings::BridgeStoneCount.Value() }); - } - if (Settings::Bridge.Is(RAINBOWBRIDGE_REWARDS)) { - stones = std::max({ stones, (int32_t)Settings::BridgeRewardCount.Value() - 6 }); - } - if ((Settings::Bridge.Is(RAINBOWBRIDGE_DUNGEONS)) && (Settings::ShuffleRewards.Is(REWARDSHUFFLE_END_OF_DUNGEON))) { - stones = std::max({ stones, (int32_t)Settings::BridgeDungeonCount.Value() - 6 }); - } - if (Settings::GanonsBossKey.Is(GANONSBOSSKEY_LACS_STONES)) { - stones = std::max({ stones, (int32_t)Settings::LACSStoneCount.Value() }); - } - if (Settings::GanonsBossKey.Is(GANONSBOSSKEY_LACS_REWARDS)) { - stones = std::max({ stones, (int32_t)Settings::LACSRewardCount.Value() - 6 }); - } - if (Settings::GanonsBossKey.Is(GANONSBOSSKEY_LACS_DUNGEONS)) { - stones = std::max({ stones, (int32_t)Settings::LACSDungeonCount.Value() - 6 }); - } - return stones; -} + hintTextTable[RHT_MALON_HINT_TURNING_EVIL] = HintText(CustomMessage("@? Is that you? ^If I ran the ranch, I'd build an #Obstacle Course#, and whoever gets the best time would win a #cow#!^" + "Elsie loves sharing her #[[1]]# with new people, It'll be fun!^...But Ingo won't let me...", + {QM_RED, QM_BLUE, QM_GREEN})); -int32_t MedallionsRequiredBySettings() { - int32_t medallions = 0; - if (Settings::Bridge.Is(RAINBOWBRIDGE_MEDALLIONS)) { - medallions = std::max({ medallions, (int32_t)Settings::BridgeMedallionCount.Value() }); - } - if (Settings::Bridge.Is(RAINBOWBRIDGE_REWARDS)) { - medallions = std::max({ medallions, (int32_t)Settings::BridgeRewardCount.Value() - 3 }); - } - if ((Settings::Bridge.Is(RAINBOWBRIDGE_DUNGEONS)) && (Settings::ShuffleRewards.Is(REWARDSHUFFLE_END_OF_DUNGEON))) { - medallions = std::max({ medallions, (int32_t)Settings::BridgeDungeonCount.Value() - 3 }); - } - if (Settings::GanonsBossKey.Is(GANONSBOSSKEY_LACS_MEDALLIONS)) { - medallions = std::max({ medallions, (int32_t)Settings::LACSMedallionCount.Value() }); - } - if (Settings::GanonsBossKey.Is(GANONSBOSSKEY_LACS_REWARDS)) { - medallions = std::max({ medallions, (int32_t)Settings::LACSRewardCount.Value() - 3 }); - } - if (Settings::GanonsBossKey.Is(GANONSBOSSKEY_LACS_DUNGEONS)) { - medallions = std::max({ medallions, (int32_t)Settings::LACSDungeonCount.Value() - 3 }); - } - return medallions; -} + hintTextTable[RHT_MALON_HINT_INGO_TEMPTED] = HintText(CustomMessage("@! You should come back in the morning and try to beat my time on the #Obstacle Course#!^" + "If you beat my time, I'll give you my favourite #cow# Elsie and her toy #[[1]]#!", + {QM_RED, QM_BLUE, QM_GREEN})); -int32_t TokensRequiredBySettings() { - int32_t tokens = 0; - if (Settings::Bridge.Is(RAINBOWBRIDGE_TOKENS)) { - tokens = std::max({ tokens, (int32_t)Settings::BridgeTokenCount.Value() }); - } - if (Settings::GanonsBossKey.Is(GANONSBOSSKEY_LACS_TOKENS)) { - tokens = std::max({ tokens, (int32_t)Settings::LACSTokenCount.Value() }); - } - return tokens; -} + hintTextTable[RHT_CHICKENS_HINT] = HintText(CustomMessage("You! Please!&Bring my Cucco's back to my pen!&I'll give you my #[[1]]#!", + {QM_GREEN})); -std::array conditionalAlwaysHints = { - std::make_pair(MARKET_10_BIG_POES, - []() { - return Settings::BigPoeTargetCount.Value() >= 3; - }), // Remember, the option's value being 3 means 4 are required - std::make_pair(DEKU_THEATER_MASK_OF_TRUTH, []() { return !Settings::CompleteMaskQuest; }), - std::make_pair(SONG_FROM_OCARINA_OF_TIME, []() { return StonesRequiredBySettings() < 2; }), - std::make_pair(HF_OCARINA_OF_TIME_ITEM, []() { return StonesRequiredBySettings() < 2; }), - std::make_pair(SHEIK_IN_KAKARIKO, []() { return MedallionsRequiredBySettings() < 5; }), - std::make_pair(DMT_TRADE_CLAIM_CHECK, []() { return false; }), - std::make_pair(KAK_30_GOLD_SKULLTULA_REWARD, []() { return TokensRequiredBySettings() < 30; }), - std::make_pair(KAK_40_GOLD_SKULLTULA_REWARD, []() { return TokensRequiredBySettings() < 40; }), - std::make_pair(KAK_50_GOLD_SKULLTULA_REWARD, []() { return TokensRequiredBySettings() < 50; }) -}; - -const HintText& Hint(const uint32_t hintKey) { - return hintTable[hintKey]; -} + hintTextTable[RHT_BIG_POES_HINT] = HintText(CustomMessage("You have #\x1E\x01 Poe Points#! Reach 1000 and you'll get a #[[1]]#!", + {QM_YELLOW, QM_GREEN})); -std::vector GetHintCategory(HintCategory category) { + hintTextTable[RHT_BIGGORON_HINT] = HintText(CustomMessage("Arrrrrre you here to claim my finest #[[1]]#? Shoooooow me your #Claim Check#.", + {QM_GREEN, QM_RED})); - std::vector hintsInCategory = {}; + hintTextTable[RHT_FROGS_HINT] = HintText(CustomMessage("Some frogs holding #[[1]]# are looking at you from underwater...", + /*german*/ "Unter Wasser gibt es Frösche, die #[[1]]# bei sich haben und Dich neugierig beobachten...", + /*french*/ "Des grenouilles se trouvant sous l'eau vous fixent attentivement, tenant fermement #[[1]]#.", + {QM_GREEN})); - for (const auto& hint : hintTable) { - if (hint.GetType() == category) { - hintsInCategory.push_back(hint); - } - } - return hintsInCategory; + hintTextTable[RHT_OOT_HINT] = HintText(CustomMessage("Bring the #Spiritual Stones# to the past so you can receive #[[1]]# from Zelda and learn #[[2]]#!", + {QM_BLUE, QM_GREEN, QM_GREEN})); + + hintTextTable[RHT_SKULLS_HINT] = HintText(CustomMessage("Yeaaarrgh! I'm cursed!!^Please save me by destroying #[[d]] Spiders of the Curse# and I will give you my #[[1]]#!", + /*german*/ "Yeaaarrgh! Ich bin verflucht!^Bitte rette mich, indem Du #[[d]] Skulltulas# zerstörst und ich werde Dir dafür #[[1]]# geben!", + /*french*/ "Yeaaarrgh! Je suis maudit!^Détruit encore #[[d]] Araignées de la Malédiction# et j'aurai quelque chose à te donner! #([[1]])#", + {QM_YELLOW, QM_GREEN})); + + hintTextTable[RHT_MASK_SHOP_HINT] = HintText(CustomMessage("Some young scrubs in the #Deku Theatre# love seeing Masks!^" + "They'll give you #[[1]]# if you show them the #Skull Mask#, and #[[2]]# if you show them the #Mask of Truth#!", + {QM_GREEN, QM_GREEN, QM_RED, QM_GREEN, QM_RED})); + + /*-------------------------- + | GANON LINE TEXT | + ---------------------------*/ + + hintTextTable[RHT_GANON_JOKE01] = HintText(CustomMessage("Oh! It's @.&I was expecting someone called Sheik.&Do you know what happened to them?", + /*german*/ "", + /*french*/ "Ah, c'est @.&J'attendais un certain Sheik.&Tu sais ce qui lui est arrivé?")); + // /*spanish*/¡Oh! Pero si es @.&Estaba esperando a alguien llamado Sheik. ¿Sabes qué puede haberle pasado? + + hintTextTable[RHT_GANON_JOKE02] = HintText(CustomMessage("I knew I shouldn't have put the key on the other side of my door.", + /*german*/ "", + /*french*/ "J'aurais dû garder la clé ici. Hélas...")); + // /*spanish*/Sabía que no tendría que haber dejado la llave al otro lado de la puerta. + + hintTextTable[RHT_GANON_JOKE03] = HintText(CustomMessage("Looks like it's time for a round of tennis.", + /*german*/ "", + /*french*/ "C'est l'heure de jouer au tennis.")); + // /*spanish*/Parece que es hora de una pachanga de tenis. + + hintTextTable[RHT_GANON_JOKE04] = HintText(CustomMessage("You'll never deflect my bolts of energy with your sword, then shoot me with those Light Arrows you happen to have.", + /*german*/ "", + /*french*/ "Ne perds pas ton temps à frapper mes éclairs d'énergie avec ton épée et me tirer avec tes flèches de Lumière!")); + // /*spanish*/Nunca reflejarás mis esferas de energía con tu espada, para después dispararme con las flechas de luz que tendrás. + + hintTextTable[RHT_GANON_JOKE05] = HintText(CustomMessage("Why did I leave my trident back in the desert?", + /*german*/ "", + /*french*/ "Sale bêtise... Et j'ai oublié mon trident dans le désert!")); + // /*spanish*/Santa Hylia... ¿Por qué me habré dejado el tridente en el desierto? + + hintTextTable[RHT_GANON_JOKE06] = HintText(CustomMessage("Zelda is probably going to do something stupid, like send you back to your own timeline.^So this is " + "quite meaningless. Do you really want to save this moron?", + /*german*/ "", + /*french*/ "Même si je suis vaincu... Zelda te renverra dans ton ère, et je reviendrai conquérir!^Telle est la " + "prophécie d'Hyrule Historia!")); + // /*spanish*/Seguro que Zelda trata de hacer alguna tontería, como enviarte de vuelta a tu línea temporal.^No tiene + // ningún sentido alguno. ¿De verdad quieres salvar a esa tonta? + + hintTextTable[RHT_GANON_JOKE07] = HintText(CustomMessage("What about Zelda makes you think&she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the " + "hungry,&and my castle floats.", + /*german*/ "", + /*french*/ "Zelda ne sera jamais un meilleur monarque que moi!^J'ai un château volant, mes sujets sont des belles " + "amazones... et mes Moblins sont clairement plus puissants que jamais!")); + // /*spanish*/¿Qué te hace pensar que Zelda gobierna mejor que yo?^Yo he salvado el Rancho Lon Lon,&he alimentado a + // los hambrientos&y hasta hago que mi castillo flote. + + hintTextTable[RHT_GANON_JOKE08] = HintText(CustomMessage("I've learned this spell,&it's really neat,&I'll keep it later&for your treat!", + /*german*/ "", + /*french*/ "Gamin, ton destin achève,&sous mon sort tu périras!&Cette partie ne fut pas brève,&et cette mort, tu subiras!")); + // /*spanish*/Veamos ahora que harás,&la batalla ha de comenzar,&te enviaré de una vez al más allá,&¿listo para + // afrontar la verdad? + + hintTextTable[RHT_GANON_JOKE09] = HintText(CustomMessage("Many tricks are up my sleeve,&to save yourself&you'd better leave!", + /*german*/ "", + /*french*/ "Sale petit garnement,&tu fais erreur!&C'est maintenant que marque&ta dernière heure!")); + // /*spanish*/¿No osarás a mí enfrentarte?&Rimas aparte,&¡voy a matarte! + + hintTextTable[RHT_GANON_JOKE10] = HintText(CustomMessage("After what you did to Koholint Island, how can you call me the bad guy?", + /*german*/ "", + /*french*/ "J'admire ce que tu as fait à l'Île Koholint... Toi et moi, nous devrions faire équipe!")); + // /*spanish*/Después de lo que le hiciste a la Isla Koholint, ¿cómo te atreves a llamarme malvado? + + hintTextTable[RHT_GANON_JOKE10] = HintText(CustomMessage("Today, let's begin down&'The Hero is Defeated' timeline.", + /*german*/ "", + /*french*/ "Si tu me vaincs, Hyrule sera englouti... mais si tu meurs, on aura A Link to the Past, le meilleur opus " + "de la série!")); + // /*spanish*/Hoy daremos lugar a la línea temporal del Héroe Derrotado.&¡Prepárate para el culmen de esta saga! + + /*-------------------------- + | Misc utilities | + ---------------------------*/ + + hintTextTable[RHT_YOUR_POCKET] = HintText(CustomMessage("your pocket", + /*german*/ "deine Tasche", + /*french*/ "tes poches")); + // /*spanish*/tu bolsillo + + hintTextTable[RHT_ISOLATED_PLACE] = HintText(CustomMessage("an Isolated Place")); + + hintTextTable[RHT_DUNGEON_ORDINARY] = HintText(CustomMessage(" It's ordinary.", + /*german*/ "&Sieht aus wie immer.", + /*french*/ "&Elle vous semble %rordinaire%w.")); + + hintTextTable[RHT_DUNGEON_MASTERFUL] = HintText(CustomMessage(" It's masterful!", + /*german*/ "&Man kann darauf die Worte&%r\"Master Quest\"%w entziffern...", + /*french*/ "&Étrange... les mots %r\"Master&Quest\"%w sont gravés dessus.")); + +} } diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.hpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.hpp deleted file mode 100644 index f6029717958..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "hints.hpp" -#include "keys.hpp" - -#include - -extern std::array hintTable; - -void HintTable_Init(); -const HintText& Hint(uint32_t hintKey); -std::vector GetHintCategory(HintCategory category); - -void HintTable_Init_Item(); -void HintTable_Init_Exclude_Overworld(); -void HintTable_Init_Exclude_Dungeon(); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp index ed54508ca47..c2117c4eb38 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp @@ -1,1964 +1,1999 @@ -#include "../hint_list.hpp" +#include "../../static_data.h" +#include "../hints.hpp" +#include "../../../custom-message/CustomMessageManager.h" -void HintTable_Init_Exclude_Dungeon() { +namespace Rando { +void StaticData::HintTable_Init_Exclude_Dungeon() { /*-------------------------- | DEKU TREE | ---------------------------*/ - hintTable[DEKU_TREE_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"in the #center of the Deku Tree# lies", /*french*/"#le coeur de l'Arbre Mojo# recèle", /*spanish*/"al #centro del Gran Árbol Deku# yace"}, - }); - - hintTable[DEKU_TREE_SLINGSHOT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #treasure guarded by a scrub# in the Deku Tree is", /*french*/"le #trésor protégé par une peste# dans l'Arbre Mojo est", /*spanish*/"un #deku del Gran Árbol Deku# esconde"}, - }); - - hintTable[DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #treasure guarded by a scrub# in the Deku Tree is", /*french*/"le #trésor protégé par une peste# dans l'Arbre Mojo est", /*spanish*/"un #deku del Gran Árbol Deku# esconde"}, - }); - - hintTable[DEKU_TREE_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#pillars of wood# in the Deku Tree lead to", /*french*/"les #piliers de bois# dans l'Arbre Mojo indiquent", /*spanish*/"los #salientes del Gran Árbol Deku# conducen a"}, - }); - - hintTable[DEKU_TREE_COMPASS_ROOM_SIDE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#pillars of wood# in the Deku Tree lead to", /*french*/"les #piliers de bois# dans l'Arbre Mojo indiquent", /*spanish*/"los #salientes del Gran Árbol Deku# conducen a"}, - }); - - hintTable[DEKU_TREE_BASEMENT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#webs in the Deku Tree# hide", /*french*/"les #toiles dans l'Arbre Mojo# cachent", /*spanish*/"entre #telarañas del Gran Árbol Deku# yace"}, - }); - - - hintTable[DEKU_TREE_MQ_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"in the #center of the Deku Tree# lies", /*french*/"#le coeur de l'Arbre Mojo# recèle", /*spanish*/"al #centro del Gran Árbol Deku# yace"}, - }); - - hintTable[DEKU_TREE_MQ_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #treasure guarded by a large spider# in the Deku Tree is", /*french*/"le #trésor protégé par une grosse araignée# dans l'Arbre Mojo est", /*spanish*/"una #gran araña del Gran Árbol Deku# esconde"}, - }); - - hintTable[DEKU_TREE_MQ_SLINGSHOT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#pillars of wood# in the Deku Tree lead to", /*french*/"les #piliers de bois# dans l'Arbre Mojo indiquent", /*spanish*/"los #salientes del Gran Árbol Deku# conducen a"}, - }); - - hintTable[DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST] = HintText::Exclude({ - //obscure text - Text{"#pillars of wood# in the Deku Tree lead to", /*french*/"les #piliers de bois# dans l'Arbre Mojo indiquent", /*spanish*/"los #salientes del Gran Árbol Deku# conducen a"}, - }); - - hintTable[DEKU_TREE_MQ_BASEMENT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#webs in the Deku Tree# hide", /*french*/"les #toiles dans l'Arbre Mojo# cachent", /*spanish*/"entre #telarañas del Gran Árbol Deku# yace"}, - }); - - hintTable[DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST] = HintText::Exclude({ - //obscure text - Text{"#magical fire in the Deku Tree# leads to", /*french*/"le #feu magique dans l'Arbre Mojo# éclaire", /*spanish*/"el #fuego mágico en el Gran Árbol Deku# conduce a"}, - }); - - hintTable[DEKU_TREE_QUEEN_GOHMA_HEART] = HintText::Exclude({ - //obscure text - Text{"the #Parasitic Armored Arachnid# holds", /*french*/"le #monstre insectoïde géant# possède", /*spanish*/"el #arácnido parasitario acorazado# porta"}, - }, {}, - //clear text - Text{"#Queen Gohma# holds", /*french*/"la #Reine Gohma# possède", /*spanish*/"la #Reina Goma# porta"} - ); - - hintTable[DEKU_TREE_GS_BASEMENT_BACK_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider deep within the Deku Tree# hides", /*french*/"une #Skulltula au coeur de l'Arbre Mojo# a", /*spanish*/"una #Skulltula en las profundidades del Árbol Deku# otorga"}, - }); - - hintTable[DEKU_TREE_GS_BASEMENT_GATE] = HintText::Exclude({ - //obscure text - Text{"a #web protects a spider# within the Deku Tree holding", /*french*/"une #Skulltula derrière une toile dans l'Arbre Mojo# a", /*spanish*/"una #Skulltula protegida por su tela# del Árbol Deku otorga"}, - }); - - hintTable[DEKU_TREE_GS_BASEMENT_VINES] = HintText::Exclude({ - //obscure text - Text{"a #web protects a spider# within the Deku Tree holding", /*french*/"une #Skulltula derrière une toile dans l'Arbre Mojo# a", /*spanish*/"una #Skulltula protegida por su tela# del Árbol Deku otorga"}, - }); - - hintTable[DEKU_TREE_GS_COMPASS_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider atop the Deku Tree# holds", /*french*/"une #Skulltula au sommet de l'Arbre Mojo# a", /*spanish*/"una #Skulltula en lo alto del Árbol Deku# otorga"}, - }); - - - hintTable[DEKU_TREE_MQ_GS_LOBBY] = HintText::Exclude({ - //obscure text - Text{"a #spider in a crate# within the Deku Tree hides", /*french*/"une #Skulltula dans une boîte dans l'Arbre Mojo# a", /*spanish*/"una #Skulltula bajo una caja# del Árbol Deku otorga"}, - }); - - hintTable[DEKU_TREE_MQ_GS_COMPASS_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #wall of rock protects a spider# within the Deku Tree holding", /*french*/"une #Skulltula derrière des rochers dans l'Arbre Mojo# a", /*spanish*/"una #Skulltula protegida por una pared rocosa# del Árbol Deku otorga"}, - }); - - hintTable[DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider deep within the Deku Tree# hides", /*french*/"une #Skulltula au coeur de l'Arbre Mojo# a", /*spanish*/"una #Skulltula en las profundidades del Árbol Deku# otorga"}, - }); - - hintTable[DEKU_TREE_MQ_DEKU_SCRUB] = HintText::Exclude({ - //obscure text - Text{"a #scrub in the Deku Tree# sells", /*french*/"la #peste Mojo dans l'Arbre Mojo# vend", /*spanish*/"un #deku del Gran Árbol Deku# vende"}, - }); + hintTextTable[RHT_DEKU_TREE_MAP_CHEST] = HintText(CustomMessage("They say that in the #center of the Deku Tree# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß im #Zentrum des Deku-Baums# #[[1]]# läge.", + /*french*/ "Selon moi, #le coeur de l'Arbre Mojo# recèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, al #centro del Gran Árbol Deku# yace #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_SLINGSHOT_CHEST] = HintText(CustomMessage("They say that the #treasure guarded by a scrub# in the Deku Tree is #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #von einem Deku bewachter Schatz# im Deku-Baum #[[1]]# sei.", + /*french*/ "Selon moi, le #trésor protégé par une peste# dans l'Arbre Mojo est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #deku del Gran Árbol Deku# esconde #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST] = HintText(CustomMessage("They say that the #treasure guarded by a scrub# in the Deku Tree is #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #von einem Deku bewachter Schatz# im Deku-Baum #[[1]]# sei.", + /*french*/ "Selon moi, le #trésor protégé par une peste# dans l'Arbre Mojo est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #deku del Gran Árbol Deku# esconde #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_COMPASS_CHEST] = HintText(CustomMessage("They say that #pillars of wood# in the Deku Tree lead to #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Säulen aus Holz# im Deku-Baum zu #[[1]]# führen würden.", + /*french*/ "Selon moi, les #piliers de bois# dans l'Arbre Mojo indiquent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #salientes del Gran Árbol Deku# conducen a #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST] = HintText(CustomMessage("They say that #pillars of wood# in the Deku Tree lead to #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Säulen aus Holz# im Deku-Baum zu #[[1]]# führen würden.", + /*french*/ "Selon moi, les #piliers de bois# dans l'Arbre Mojo indiquent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #salientes del Gran Árbol Deku# conducen a #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_BASEMENT_CHEST] = HintText(CustomMessage("They say that #webs in the Deku Tree# hide #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Spinnweben im Deku-Baum# #[[1]]# verbergen würden.", + /*french*/ "Selon moi, les #toiles dans l'Arbre Mojo# cachent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, entre #telarañas del Gran Árbol Deku# yace #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_MAP_CHEST] = HintText(CustomMessage("They say that in the #center of the Deku Tree# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß im #Zentrum des Deku-Baums# #[[1]]# läge.", + /*french*/ "Selon moi, #le coeur de l'Arbre Mojo# recèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, al #centro del Gran Árbol Deku# yace #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_COMPASS_CHEST] = HintText(CustomMessage("They say that a #treasure guarded by a large spider# in the Deku Tree is #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #von einer großen Spinne bewachter Schatz# im Deku-Baum #[[1]]# sei.", + /*french*/ "Selon moi, le #trésor protégé par une grosse araignée# dans l'Arbre Mojo est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #gran araña del Gran Árbol Deku# esconde #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_SLINGSHOT_CHEST] = HintText(CustomMessage("They say that #pillars of wood# in the Deku Tree lead to #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Säulen aus Holz# im Deku-Baum zu #[[1]]# führen würden.", + /*french*/ "Selon moi, les #piliers de bois# dans l'Arbre Mojo indiquent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #salientes del Gran Árbol Deku# conducen a #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST] = HintText(CustomMessage("They say that #pillars of wood# in the Deku Tree lead to #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Säulen aus Holz# im Deku-Baum zu #[[1]]# führen würden.", + /*french*/ "Selon moi, les #piliers de bois# dans l'Arbre Mojo indiquent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #salientes del Gran Árbol Deku# conducen a #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_BASEMENT_CHEST] = HintText(CustomMessage("They say that #webs in the Deku Tree# hide #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Spinnweben im Deku-Baum# #[[1]]# verbergen würden.", + /*french*/ "Selon moi, les #toiles dans l'Arbre Mojo# cachent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, entre #telarañas del Gran Árbol Deku# yace #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST] = HintText(CustomMessage("They say that #magical fire in the Deku Tree# leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #magisches Feuer im Deku-Baum# zu #[[1]]# führe.", + /*french*/ "Selon moi, le #feu magique dans l'Arbre Mojo# éclaire #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #fuego mágico en el Gran Árbol Deku# conduce a #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_QUEEN_GOHMA_HEART] = HintText(CustomMessage("They say that #Queen Gohma# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Königin Gohma# #[[1]]# besäße.", + /*french*/ "Selon moi, la #Reine Gohma# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #Reina Goma# porta #[[1]]#. + {}, { + CustomMessage("They say that the #Parasitic Armored Arachnid# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #gepanzerte parasitäre Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, le #monstre insectoïde géant# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #arácnido parasitario acorazado# porta #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_GS_BASEMENT_BACK_ROOM] = HintText(CustomMessage("They say that a #spider deep within the Deku Tree# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne tief innerhalb des Deku-Baums# #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula au coeur de l'Arbre Mojo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en las profundidades del Árbol Deku# otorga #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_GS_BASEMENT_GATE] = HintText(CustomMessage("They say that a #web protects a spider# within the Deku Tree holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von einer Webe geschützte Spinne# innerhalb des Deku-Baums #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula derrière une toile dans l'Arbre Mojo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula protegida por su tela# del Árbol Deku otorga #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_GS_BASEMENT_VINES] = HintText(CustomMessage("They say that a #web protects a spider# within the Deku Tree holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von einer Webe geschützte Spinne# innerhalb des Deku-Baums #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula derrière une toile dans l'Arbre Mojo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula protegida por su tela# del Árbol Deku otorga #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_GS_COMPASS_ROOM] = HintText(CustomMessage("They say that a #spider atop the Deku Tree# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne auf der Spitze des Deku-Baums# #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula au sommet de l'Arbre Mojo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en lo alto del Árbol Deku# otorga #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_GS_LOBBY] = HintText(CustomMessage("They say that a #spider in a crate# within the Deku Tree hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne in einer Kiste# innerhalb des Deku-Baums #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula dans une boîte dans l'Arbre Mojo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula bajo una caja# del Árbol Deku otorga #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_GS_COMPASS_ROOM] = HintText(CustomMessage("They say that a #wall of rock protects a spider# within the Deku Tree holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von einer Steinwand geschützte Spinne# innerhalb des Deku-Baums #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula derrière des rochers dans l'Arbre Mojo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula protegida por una pared rocosa# del Árbol Deku otorga #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM] = HintText(CustomMessage("They say that a #spider deep within the Deku Tree# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne tief innerhalb des Deku-Baums# #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula au coeur de l'Arbre Mojo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en las profundidades del Árbol Deku# otorga #[[1]]#. + + hintTextTable[RHT_DEKU_TREE_MQ_DEKU_SCRUB] = HintText(CustomMessage("They say that a #scrub in the Deku Tree# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku im Deku-Baum# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #peste Mojo dans l'Arbre Mojo# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #deku del Gran Árbol Deku# vende #[[1]]#. /*-------------------------- | DODONGOS CAVERN | ---------------------------*/ - hintTable[DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"#above King Dodongo# lies", /*french*/"#par dessus le Roi Dodongo# gît", /*spanish*/"#sobre el Rey Dodongo# yace"}, - }); - - hintTable[DODONGOS_CAVERN_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #muddy wall in Dodongo's Cavern# hides", /*french*/"le #mur fragile dans la Caverne Dodongo# recèle", /*spanish*/"tras una #agrietada pared en la Cueva de los Dodongos# yace"}, - }); - - hintTable[DODONGOS_CAVERN_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #statue in Dodongo's Cavern# guards", /*french*/"la #statue dans la Caverne Dodongo# protège", /*spanish*/"una #estatua de la Cueva de los Dodongos# esconde"}, - }); - - hintTable[DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST] = HintText::Exclude({ - //obscure text - Text{"above a #maze of stone# in Dodongo's Cavern lies", /*french*/"sur #un labyrinthe de pierre# dans la Caverne Dodongo gît", /*spanish*/"entre un #laberinto de piedra# en la Cueva de los Dodongos yace"}, - }); - - hintTable[DODONGOS_CAVERN_BOMB_BAG_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #second lizard cavern battle# yields", /*french*/"le #deuxième duel de lézards de caverne# octroie", /*spanish*/"#luchar dos veces contra reptiles en una cueva# conduce a"}, - }); - - hintTable[DODONGOS_CAVERN_END_OF_BRIDGE_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #chest at the end of a bridge# yields", /*french*/"le #trésor à l'extrémité d'un pont# contient", /*spanish*/"un #cofre al final de un quebrado puente# contiene"}, - }); - - - hintTable[DODONGOS_CAVERN_MQ_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #muddy wall in Dodongo's Cavern# hides", /*french*/"le #mur fragile dans la Caverne Dodongo# recèle", /*spanish*/"una #agrietada pared en la Cueva de los Dodongos# esconde"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST] = HintText::Exclude({ - //obscure text - Text{"an #elevated alcove# in Dodongo's Cavern holds", /*french*/"l'#alcove haut perchée# dans la Caverne Dodongo cache", /*spanish*/"una #elevada alcoba# en la Cueva de los Dodongos brinda"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#fire-breathing lizards# in Dodongo's Cavern guard", /*french*/"les #lézards cracheurs de feu# dans la Caverne Dodongo protègent", /*spanish*/"unos #flamígeros reptiles# en la Cueva de los Dodongos esconden"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"#baby spiders# in Dodongo's Cavern guard", /*french*/"les #petites araignées dans la Caverne Dodongo# protègent", /*spanish*/"unas #pequeñas larvas# en la Cueva de los Dodongos esconden"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"above a #maze of stone# in Dodongo's Cavern lies", /*french*/"sur #un labyrinthe de pierre# dans la Caverne Dodongo gît", /*spanish*/"sobre un #laberinto de piedra# en la Cueva de los Dodongos yace"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#beneath a headstone# in Dodongo's Cavern lies", /*french*/"#sous une pierre tombale# dans la Caverne Dodongo gît", /*spanish*/"#bajo una lápida# en la Cueva de los Dodongos yace"}, - }); - - hintTable[DODONGOS_CAVERN_KING_DODONGO_HEART] = HintText::Exclude({ - //obscure text - Text{"the #Infernal Dinosaur# holds", /*french*/"le #dinosaure infernal# possède", /*spanish*/"el #dinosaurio infernal# porta"}, - }, {}, - //clear text - Text{"#King Dodongo# holds", /*french*/"le #Roi Dodongo# possède", /*spanish*/"el #Rey Dodongo# porta"} - ); - - hintTable[DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS] = HintText::Exclude({ - //obscure text - Text{"a #spider entangled in vines# in Dodongo's Cavern guards", /*french*/"une #Skulltula sur les vignes dans la Caverne Dodongo# a", /*spanish*/"una #Skulltula sobre unas cepas# de la Cueva de los Dodongos otorga"}, - }); - - hintTable[DODONGOS_CAVERN_GS_SCARECROW] = HintText::Exclude({ - //obscure text - Text{"a #spider among explosive slugs# hides", /*french*/"une #Skulltula dans l'alcove du couloir dans la Caverne Dodongo# a", /*spanish*/"una #Skulltula rodeada de explosivos gusanos# otorga"}, - }); - - hintTable[DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS] = HintText::Exclude({ - //obscure text - Text{"a #spider just out of reach# in Dodongo's Cavern holds", /*french*/"une #Skulltula au haut des escaliers de la Caverne Dodongo# a", /*spanish*/"una #Skulltula fuera del alcance# de la Cueva de los Dodongos otorga"}, - }); - - hintTable[DODONGOS_CAVERN_GS_BACK_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider behind a statue# in Dodongo's Cavern holds", /*french*/"une #Skulltula au coeur de la Caverne Dodongo# a", /*spanish*/"una #Skulltula tras una estatua# de la Cueva de los Dodongos otorga"}, - }); - - hintTable[DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = HintText::Exclude({ - //obscure text - Text{"a #spider among bats# in Dodongo's Cavern holds", /*french*/"une #Skulltula entourée de Saigneurs dans la Caverne Dodongo# a", /*spanish*/"una #Skulltula rodeada de murciélagos# de la Cueva de los Dodongos otorga"}, - }); - - - hintTable[DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider high on a wall# in Dodongo's Cavern holds", /*french*/"une #Skulltula haut perchée dans la Caverne Dodongo# a", /*spanish*/"una #Skulltula en lo alto de una pared# de la Cueva de los Dodongos otorga"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider on top of a pillar of rock# in Dodongo's Cavern holds", /*french*/"une #Skulltula sur l'énorme pilier de roc de la Caverne Dodongo# a", /*spanish*/"una #Skulltula en lo alto de un pilar# de la Cueva de los Dodongos otorga"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider in a crate# in Dodongo's Cavern holds", /*french*/"une #Skulltula dans une boîte de la Caverne Dodongo# a", /*spanish*/"una #Skulltula bajo una caja# de la Cueva de los Dodongos otorga"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_GS_BACK_AREA] = HintText::Exclude({ - //obscure text - Text{"a #spider among graves# in Dodongo's Cavern holds", /*french*/"une #Skulltula parmi les tombes de la Caverne Dodongo# a", /*spanish*/"una #Skulltula entre lápidas# en la Cueva de los Dodongos otorga"}, - }); - - hintTable[DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = HintText::Exclude({ - //obscure text - Text{"a pair of #scrubs in Dodongo's Cavern# sells", /*french*/"le #duo de peste Mojo dans la Caverne Dodongo# vend", /*spanish*/"un #par de dekus en la Cueva de los Dodongos# venden"}, - }); - - hintTable[DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = HintText::Exclude({ - //obscure text - Text{"a #scrub guarded by Lizalfos# sells", /*french*/"la #peste Mojo au coeur de la Caverne Dodongo# vend", /*spanish*/"un #deku custodiado por Lizalfos# vende"}, - }); - - hintTable[DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = HintText::Exclude({ - //obscure text - Text{"a pair of #scrubs in Dodongo's Cavern# sells", /*french*/"le #duo de peste Mojo dans la Caverne Dodongo# vend", /*spanish*/"un #par de dekus en la Cueva de los Dodongos# venden"}, - }); - - hintTable[DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = HintText::Exclude({ - //obscure text - Text{"a #scrub in Dodongo's Cavern# sells", /*french*/"la #peste Mojo dans l'entrée de la Caverne Dodongo# vend", /*spanish*/"un #deku en la Cueva de los Dodongos# vende"}, - }); - - - hintTable[DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = HintText::Exclude({ - //obscure text - Text{"a pair of #scrubs in Dodongo's Cavern# sells", /*french*/"le #duo de peste Mojo dans l'entrée de la Caverne Dodongo# vend", /*spanish*/"un #par de dekus en la Cueva de los Dodongos# venden"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = HintText::Exclude({ - //obscure text - Text{"a pair of #scrubs in Dodongo's Cavern# sells", /*french*/"le #duo de peste Mojo dans l'entrée de la Caverne Dodongo# vend", /*spanish*/"un #par de dekus en la Cueva de los Dodongos# venden"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = HintText::Exclude({ - //obscure text - Text{"a #scrub in Dodongo's Cavern# sells", /*french*/"la #peste Mojo au sommet des escaliers dans la Caverne Dodongo# vend", /*spanish*/"un #deku en la Cueva de los Dodongos# vende"}, - }); - - hintTable[DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = HintText::Exclude({ - //obscure text - Text{"a #scrub guarded by Lizalfos# sells", /*french*/"la #peste Mojo au coeur de la Caverne Dodongo# vend", /*spanish*/"un #deku custodiado por Lizalfos# vende"}, - }); +hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("They say that #above King Dodongo# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #auf König Dodongo# #[[1]]# läge.", + /*french*/ "Selon moi, #par dessus le Roi Dodongo# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #sobre el Rey Dodongo# yace #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MAP_CHEST] = HintText(CustomMessage("They say that a #muddy wall in Dodongo's Cavern# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #schlammige Wand in Dodongos Höhle# #[[1]]# verstecke.", + /*french*/ "Selon moi, le #mur fragile dans la Caverne Dodongo# recèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, tras una #agrietada pared en la Cueva de los Dodongos# yace #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_COMPASS_CHEST] = HintText(CustomMessage("They say that a #statue in Dodongo's Cavern# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Statue in Dodongos Höhle# #[[1]]# bewache.", + /*french*/ "Selon moi, la #statue dans la Caverne Dodongo# protège #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #estatua de la Cueva de los Dodongos# esconde #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST] = HintText(CustomMessage("They say that above a #maze of stone# in Dodongo's Cavern lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf einem #Labyrinth aus Stein# in Dodongos Höhle #[[1]]# läge.", + /*french*/ "Selon moi, sur #un labyrinthe de pierre# dans la Caverne Dodongo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, entre un #laberinto de piedra# en la Cueva de los Dodongos yace #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_BOMB_BAG_CHEST] = HintText(CustomMessage("They say that the #second lizard cavern battle# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #zweite Reptilienkampf der Höhle# #[[1]]# brächte.", + /*french*/ "Selon moi, le #deuxième duel de lézards de caverne# octroie #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #luchar dos veces contra reptiles en una cueva# conduce a #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST] = HintText(CustomMessage("They say that a #chest at the end of a bridge# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Truhe am Ende der Brücke# #[[1]]# brächte.", + /*french*/ "Selon moi, le #trésor à l'extrémité d'un pont# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #cofre al final de un quebrado puente# contiene #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_MAP_CHEST] = HintText(CustomMessage("They say that a #muddy wall in Dodongo's Cavern# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #schlammige Wand in Dodongos Höhle# #[[1]]# verstecke.", + /*french*/ "Selon moi, le #mur fragile dans la Caverne Dodongo# recèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #agrietada pared en la Cueva de los Dodongos# esconde #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST] = HintText(CustomMessage("They say that an #elevated alcove# in Dodongo's Cavern holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #erhöhter Alkoven# in Dodongos Höhle #[[1]]# hielte.", + /*french*/ "Selon moi, l'#alcove haut perchée# dans la Caverne Dodongo cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #elevada alcoba# en la Cueva de los Dodongos brinda #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_COMPASS_CHEST] = HintText(CustomMessage("They say that #fire-breathing lizards# in Dodongo's Cavern guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #feuerschnaubende Reptilien# in Dodongos Höhle #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #lézards cracheurs de feu# dans la Caverne Dodongo protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unos #flamígeros reptiles# en la Cueva de los Dodongos esconden #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST] = HintText(CustomMessage("They say that #baby spiders# in Dodongo's Cavern guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #kleine Spinnen# in Dodongos Höhle #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #petites araignées dans la Caverne Dodongo# protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unas #pequeñas larvas# en la Cueva de los Dodongos esconden #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST] = HintText(CustomMessage("They say that above a #maze of stone# in Dodongo's Cavern lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf einem #Labyrinth aus Stein# in Dodongos Höhle #[[1]]# läge.", + /*french*/ "Selon moi, sur #un labyrinthe de pierre# dans la Caverne Dodongo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, sobre un #laberinto de piedra# en la Cueva de los Dodongos yace #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST] = HintText(CustomMessage("They say that #beneath a headstone# in Dodongo's Cavern lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #unterhalb eines Grabsteins# in Dodongos Höhle #[[1]]# läge.", + /*french*/ "Selon moi, #sous une pierre tombale# dans la Caverne Dodongo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #bajo una lápida# en la Cueva de los Dodongos yace #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_KING_DODONGO_HEART] = HintText(CustomMessage("They say that #King Dodongo# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #König Dodongo# #[[1]]# besäße.", + /*french*/ "Selon moi, le #Roi Dodongo# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, el #Rey Dodongo# porta #[[1]]#. + {}, { + CustomMessage("They say that the #Infernal Dinosaur# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #infernalische Dinosaurier# #[[1]]# besäße.", + /*french*/ "Selon moi, le #dinosaure infernal# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #dinosaurio infernal# porta #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS] = HintText(CustomMessage("They say that a #spider entangled in vines# in Dodongo's Cavern guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine in #Reben verwobene Spinne# in Dodongos Höhle #[[1]]# bewache.", + /*french*/ "Selon moi, une #Skulltula sur les vignes dans la Caverne Dodongo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula sobre unas cepas# de la Cueva de los Dodongos otorga #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_GS_SCARECROW] = HintText(CustomMessage("They say that a #spider among explosive slugs# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne inmitten explosiver Schnecken# #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula dans l'alcove du couloir dans la Caverne Dodongo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula rodeada de explosivos gusanos# otorga #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS] = HintText(CustomMessage("They say that a #spider just out of reach# in Dodongo's Cavern holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne außer Reichweite# in Dodongos Höhle #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula au haut des escaliers de la Caverne Dodongo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula fuera del alcance# de la Cueva de los Dodongos otorga #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_GS_BACK_ROOM] = HintText(CustomMessage("They say that a #spider behind a statue# in Dodongo's Cavern holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne hinter einer Statue# in Dodongos Höhle #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula au coeur de la Caverne Dodongo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula tras una estatua# de la Cueva de los Dodongos otorga #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = HintText(CustomMessage("They say that a #spider among bats# in Dodongo's Cavern holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne inmitten von Fledermäusen# in Dodongos Höhle #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula entourée de Saigneurs dans la Caverne Dodongo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula rodeada de murciélagos# de la Cueva de los Dodongos otorga #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM] = HintText(CustomMessage("They say that a #spider high on a wall# in Dodongo's Cavern holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #hoch an einer Wand befindliche Spinne# in Dodongos Höhle #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula haut perchée dans la Caverne Dodongo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en lo alto de una pared# de la Cueva de los Dodongos otorga #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM] = HintText(CustomMessage("They say that a #spider on top of a pillar of rock# in Dodongo's Cavern holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne auf einer Steinsäule# in Dodongos Höhle #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula sur l'énorme pilier de roc de la Caverne Dodongo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en lo alto de un pilar# de la Cueva de los Dodongos otorga #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM] = HintText(CustomMessage("They say that a #spider in a crate# in Dodongo's Cavern holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne in einer Kiste# in Dodongos Höhle #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula dans une boîte de la Caverne Dodongo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula bajo una caja# de la Cueva de los Dodongos otorga #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_GS_BACK_AREA] = HintText(CustomMessage("They say that a #spider among graves# in Dodongo's Cavern holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne inmitten von Gräbern# in Dodongos Höhle #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula parmi les tombes de la Caverne Dodongo# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula entre lápidas# en la Cueva de los Dodongos otorga #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = HintText(CustomMessage("They say that a pair of #scrubs in Dodongo's Cavern# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar in Dodongos Höhle# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo dans la Caverne Dodongo# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus en la Cueva de los Dodongos# venden #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = HintText(CustomMessage("They say that a #scrub guarded by Lizalfos# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #von Lizalfos bewachter Deku# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #peste Mojo au coeur de la Caverne Dodongo# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #deku custodiado por Lizalfos# vende #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = HintText(CustomMessage("They say that a pair of #scrubs in Dodongo's Cavern# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar in Dodongos Höhle# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo dans la Caverne Dodongo# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus en la Cueva de los Dodongos# venden #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = HintText(CustomMessage("They say that a #scrub in Dodongo's Cavern# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku in Dodongos Höhle# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #peste Mojo dans l'entrée de la Caverne Dodongo# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #deku en la Cueva de los Dodongos# vende #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = HintText(CustomMessage("They say that a pair of #scrubs in Dodongo's Cavern# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar in Dodongos Höhle# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo dans l'entrée de la Caverne Dodongo# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus en la Cueva de los Dodongos# venden #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = HintText(CustomMessage("They say that a pair of #scrubs in Dodongo's Cavern# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar in Dodongos Höhle# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo dans l'entrée de la Caverne Dodongo# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus en la Cueva de los Dodongos# venden #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = HintText(CustomMessage("They say that a #scrub in Dodongo's Cavern# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar in Dodongos Höhle# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #peste Mojo au sommet des escaliers dans la Caverne Dodongo# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #deku en la Cueva de los Dodongos# vende #[[1]]#. + + hintTextTable[RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = HintText(CustomMessage("They say that a #scrub guarded by Lizalfos# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #von Lizalfos bewachter Deku# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #peste Mojo au coeur de la Caverne Dodongo# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #deku custodiado por Lizalfos# vende #[[1]]#. /*-------------------------- | JABU JABUS BELLY | ---------------------------*/ - hintTable[JABU_JABUS_BELLY_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"#tentacle trouble# in a deity's belly guards", /*french*/"la #membrane# dans le ventre du gardien protège", /*spanish*/"un #problema tentaculoso# en la tripa de cierta deidad esconde"}, - }, {}, - //clear text - Text{"a #slimy thing# guards", /*french*/"la #chose gluante# gardien protège", /*spanish*/"un #tentáculo parasitario# protege"} - ); - - hintTable[JABU_JABUS_BELLY_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#bubble trouble# in a deity's belly guards", /*french*/"un #horde de bulles# dans le ventre du gardien protègent", /*spanish*/"un #problema burbujesco# en la tripa de cierta deidad esconde"}, - }, {}, - //clear text - Text{"#bubbles# guard", /*french*/"des #bulles# entourent", /*spanish*/"unas #burbujas# protegen"} - ); - - - hintTable[JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST] = HintText::Exclude({ - //obscure text - Text{"shooting a #mouth cow# reveals", /*french*/"tirer sur une #vache# révèle", /*spanish*/"#dispararle a una vaca# revela"}, - }); - - hintTable[JABU_JABUS_BELLY_MQ_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"#pop rocks# hide", /*french*/"des #pierres aux reins# cachent", /*spanish*/"#cepillarse los dientes con explosivos# revela"}, - Text{"an #explosive palate# holds", /*french*/"des #gargouillis explosifs# cachent", /*spanish*/"un #paladar explosivo# esconde"}, - }, {}, - //clear text - Text{"a #boulder before cows# hides", /*french*/"des #rochers près des vaches# cachent", /*spanish*/"cierta #roca rodeada de vacas# esconde"} - ); - - hintTable[JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST] = HintText::Exclude({ - //obscure text - Text{"near a #spiked elevator# lies", /*french*/"près d'un #ascenseur visqueux# gît", /*spanish*/"cerca de un #ascensor puntiagudo# yace"}, - }); - - hintTable[JABU_JABUS_BELLY_MQ_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #drowning cow# unveils", /*french*/"une #vache à l'eau# a", /*spanish*/"una #vaca sumergida# revela"}, - }); - - hintTable[JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST] = HintText::Exclude({ - //obscure text - Text{"#moving anatomy# creates a path to", /*french*/"un #organe descendant# mène à", /*spanish*/"un #ser movedizo entre paredes# conduce a"}, - }); - - hintTable[JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #pair of digested cows# hold", /*french*/"#deux boeufs digérés# détiennent", /*spanish*/"un #par de digeridas vacas# otorgan"}, - }); - - hintTable[JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #pair of digested cows# hold", /*french*/"#deux boeufs digérés# détiennent", /*spanish*/"un #par de digeridas vacas# otorgan"}, - }); - - hintTable[JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #final cows' reward# in a deity's belly is", /*french*/"le #cadeau des dernières vaches# estomacales est", /*spanish*/"las #vacas al final# de la tripa de cierta deidad otorgan"}, - }); - - hintTable[JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"#cows protected by falling monsters# in a deity's belly guard", /*french*/"des #vaches protégées par des monstres tombants# cachent", /*spanish*/"unas #vacas custodiadas por monstruos del techo# de la tripa de cierta deidad otorgan"}, - }); - - hintTable[JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST] = HintText::Exclude({ - //obscure text - Text{"a school of #stingers swallowed by a deity# guard", /*french*/"les #raies avallées par le gardien# protègent", /*spanish*/"unos #stingers engullidos por cierta deidad# guardan"}, - }, {}, - //clear text - Text{"a school of #stingers swallowed by Jabu-Jabu# guard", /*french*/"les #raies avallées par Jabu-Jabu# protègent", /*spanish*/"unos #stingers engullidos por Jabu-Jabu# guardan"} - ); - - hintTable[JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST] = HintText::Exclude({ - //obscure text - Text{"a school of #stingers swallowed by a deity# guard", /*french*/"les #raies avallées par le gardien# protègent", /*spanish*/"unos #stingers engullidos por cierta deidad# guardan"}, - }, {}, - //clear text - Text{"a school of #stingers swallowed by Jabu-Jabu# guard", /*french*/"les #raies avallées par Jabu-Jabu# protègent", /*spanish*/"unos #stingers engullidos por Jabu-Jabu# guardan"} - ); - - hintTable[JABU_JABUS_BELLY_BARINADE_HEART] = HintText::Exclude({ - //obscure text - Text{"the #Bio-Electric Anemone# holds", /*french*/"l'#anémone bioélectrique# possède", /*spanish*/"la #anémona bioeléctrica# porta"}, - }, {}, - //clear text - Text{"#Barinade# holds", /*french*/"#Barinade# possède", /*spanish*/"#Barinade# porta"} - ); - - hintTable[JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER] = HintText::Exclude({ - //obscure text - Text{"a #spider resting near a princess# in Jabu-Jabu's Belly holds", /*french*/"une #Skulltula près de la princesse dans le Ventre de Jabu-Jabu# a", /*spanish*/"una #Skulltula junto a una princesa# en la Tripa de Jabu-Jabu otorga"}, - }); - - hintTable[JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER] = HintText::Exclude({ - //obscure text - Text{"a #spider resting near a princess# in Jabu-Jabu's Belly holds", /*french*/"une #Skulltula près de la princesse dans le Ventre de Jabu-Jabu# a", /*spanish*/"una #Skulltula junto a una princesa# en la Tripa de Jabu-Jabu otorga"}, - }); - - hintTable[JABU_JABUS_BELLY_GS_NEAR_BOSS] = HintText::Exclude({ - //obscure text - Text{"#jellyfish surround a spider# holding", /*french*/"une #Skulltula entourée de méduses dans le Ventre de Jabu-Jabu# a", /*spanish*/"una #Skulltula rodeada de medusas# otorga"}, - }); - - hintTable[JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider guarded by a school of stingers# in Jabu-Jabu's Belly holds", /*french*/"une #Skulltula protégée par des raies dans le Ventre de Jabu-Jabu# a", /*spanish*/"una #Skulltula rodeada por unos stingers# en la Tripa de Jabu-Jabu otorga"}, - }); - - - hintTable[JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider surrounded by electricity# in Jabu-Jabu's Belly holds", /*french*/"une #Skulltula entourée d'électricité dans le Ventre de Jabu-Jabu# a", /*spanish*/"una #Skulltula rodeada de electricidad# en la Tripa de Jabu-Jabu otorga"}, - }); - - hintTable[JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider guarded by a school of stingers# in Jabu-Jabu's Belly holds", /*french*/"une #Skulltula protégée par des raies dans le Ventre de Jabu-Jabu# a", /*spanish*/"una #Skulltula protegida por unos stingers# en la Tripa de Jabu-Jabu otorga"}, - }); - - hintTable[JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS] = HintText::Exclude({ - //obscure text - Text{"a #spider in a web within Jabu-Jabu's Belly# holds", /*french*/"une #Skulltula sur une toile dans le Ventre de Jabu-Jabu# a", /*spanish*/"una #Skulltula sobre una red# en la Tripa de Jabu-Jabu otorga"}, - }); - - hintTable[JABU_JABUS_BELLY_DEKU_SCRUB] = HintText::Exclude({ - //obscure text - Text{"a #scrub in a deity# sells", /*french*/"la #peste Mojo dans le ventre du gardien# vend", /*spanish*/"un #deku dentro de cierta deidad# vende"}, - }); - + hintTextTable[RHT_JABU_JABUS_BELLY_MAP_CHEST] = HintText(CustomMessage("They say that a #slimy thing# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #schleimiges Ding# #[[1]]# bewache.", + /*french*/ "Selon moi, la #chose gluante# gardien protège #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, un #tentáculo parasitario# protege #[[1]]#. + {}, { + CustomMessage("They say that #tentacle trouble# in a deity's belly guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Tentakel# im Bauch einer Gottheit #[[1]]# bewachen würden.", + /*french*/ "Selon moi, la #membrane# dans le ventre du gardien protège #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #problema tentaculoso# en la tripa de cierta deidad esconde #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_COMPASS_CHEST] = HintText(CustomMessage("They say that #bubbles# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Blasen# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, des #bulles# entourent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, unas #burbujas# protegen #[[1]]#. + {}, { + CustomMessage("They say that #bubble trouble# in a deity's belly guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Blasen# im Bauch einer Gottheit #[[1]]# bewachen würden.", + /*french*/ "Selon moi, un #horde de bulles# dans le ventre du gardien protègent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #problema burbujesco# en la tripa de cierta deidad esconde #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST] = HintText(CustomMessage("They say that shooting a #mouth cow# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Kuhmund# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, tirer sur une #vache# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #dispararle a una vaca# revela #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_MAP_CHEST] = HintText(CustomMessage("They say that a #boulder before cows# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Findling vor Kühen# #[[1]]# verstecke.", + /*french*/ "Selon moi, des #rochers près des vaches# cachent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, cierta #roca rodeada de vacas# esconde #[[1]]#. + {}, { + CustomMessage("They say that #pop rocks# hide #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Knallfelsen# #[[1]]# verbergen würden.", + /*french*/ "Selon moi, des #pierres aux reins# cachent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #cepillarse los dientes con explosivos# revela #[[1]]#. + CustomMessage("They say that an #explosive palate# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #explosiver Gaumen# #[[1]]# hielte.", + /*french*/ "Selon moi, des #gargouillis explosifs# cachent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #paladar explosivo# esconde #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST] = HintText(CustomMessage("They say that near a #spiked elevator# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß in der Nähe eines #stachligen Aufzugs# #[[1]]# läge.", + /*french*/ "Selon moi, près d'un #ascenseur visqueux# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, cerca de un #ascensor puntiagudo# yace #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_COMPASS_CHEST] = HintText(CustomMessage("They say that a #drowning cow# unveils #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #ertrinkende Kuh# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, une #vache à l'eau# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #vaca sumergida# revela #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST] = HintText(CustomMessage("They say that #moving anatomy# creates a path to #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #sich bewegende Anatomie# einen Pfad zu #[[1]]# kreiere.", + /*french*/ "Selon moi, un #organe descendant# mène à #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #ser movedizo entre paredes# conduce a #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST] = HintText(CustomMessage("They say that a #pair of digested cows# hold #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Paar verdauter Kühe# #[[1]]# hielte.", + /*french*/ "Selon moi, #deux boeufs digérés# détiennent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de digeridas vacas# otorgan #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST] = HintText(CustomMessage("They say that a #pair of digested cows# hold #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Paar verdauter Kühe# #[[1]]# hielte.", + /*french*/ "Selon moi, #deux boeufs digérés# détiennent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de digeridas vacas# otorgan #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST] = HintText(CustomMessage("They say that the #final cows' reward# in a deity's belly is #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Belohnung der letzten Kuh# im Bauch einer Gottheit #[[1]]# sei.", + /*french*/ "Selon moi, le #cadeau des dernières vaches# estomacales est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #vacas al final# de la tripa de cierta deidad otorgan #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST] = HintText(CustomMessage("They say that #cows protected by falling monsters# in a deity's belly guard hide #[[1]]#.", + /*german*/ "Man erzählt sich, daß #von fallenden Monstern bewachte Kühe# im Bauch einer Gottheit #[[1]]# verstecken würden.", + /*french*/ "Selon moi, des #vaches protégées par des monstres tombants# cachent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unas #vacas custodiadas por monstruos del techo# de la tripa de cierta deidad otorgan #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST] = HintText(CustomMessage("They say that a school of #stingers swallowed by Jabu-Jabu# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß von #Jabu-Jabu verschluckte Rochen# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #raies avallées par Jabu-Jabu# protègent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, unos #stingers engullidos por Jabu-Jabu# guardan #[[1]]#. + {}, { + CustomMessage("They say that a school of #stingers swallowed by a deity# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß von #einer Gottheit verschluckte Rochen# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #raies avallées par le gardien# protègent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, unos #stingers engullidos por cierta deidad# guardan #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST] = HintText(CustomMessage("They say that a school of #stingers swallowed by Jabu-Jabu# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß von #Jabu-Jabu verschluckte Rochen# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #raies avallées par Jabu-Jabu# protègent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, unos #stingers engullidos por Jabu-Jabu# guardan #[[1]]#. + {}, { + CustomMessage("They say that a school of #stingers swallowed by a deity# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß von #einer Gottheit verschluckte Rochen# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #raies avallées par le gardien# protègent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, unos #stingers engullidos por cierta deidad# guardan #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_BARINADE_HEART] = HintText(CustomMessage("They say that #Barinade# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Barinade# #[[1]]# besäße.", + /*french*/ "Selon moi, #Barinade# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #Barinade# porta #[[1]]#. + {}, { + CustomMessage("They say that the #Bio-Electric Anemone# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #bioelektrische Anemone# #[[1]]# besäße.", + /*french*/ "Selon moi, l'#anémone bioélectrique# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, la #anémona bioeléctrica# porta #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER] = HintText(CustomMessage("They say that a #spider resting near a princess# in Jabu-Jabu's Belly holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in der Nähe einer Prinzessin ruhende Spinne# in Jabu-Jabus Bauch #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula près de la princesse dans le Ventre de Jabu-Jabu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula junto a una princesa# en la Tripa de Jabu-Jabu otorga #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER] = HintText(CustomMessage("They say that a #spider resting near a princess# in Jabu-Jabu's Belly holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in der Nähe einer Prinzessin ruhende Spinne# in Jabu-Jabus Bauch #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula près de la princesse dans le Ventre de Jabu-Jabu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula junto a una princesa# en la Tripa de Jabu-Jabu otorga #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_GS_NEAR_BOSS] = HintText(CustomMessage("They say that #a spider surrounded by jellyfish# in Jabu-Jabu's Belly holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von Quallen umgebene Spinne# in Jabu-Jabus Bauch #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula entourée de méduses dans le Ventre de Jabu-Jabu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula rodeada de medusas# otorga #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM] = HintText(CustomMessage("They say that a #spider guarded by a school of stingers# in Jabu-Jabu's Belly holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von Rochen bewachte Spinne# in Jabu-Jabus Bauch #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula protégée par des raies dans le Ventre de Jabu-Jabu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula rodeada por unos stingers# en la Tripa de Jabu-Jabu otorga #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM] = HintText(CustomMessage("They say that a #spider surrounded by electricity# in Jabu-Jabu's Belly holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von Elektrizität umgebene Spinne# in Jabu-Jabus Bauch #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula entourée d'électricité dans le Ventre de Jabu-Jabu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula rodeada de electricidad# en la Tripa de Jabu-Jabu otorga #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM] = HintText(CustomMessage("They say that a #spider guarded by a school of stingers# in Jabu-Jabu's Belly holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von Rochen bewachte Spinne# in Jabu-Jabus Bauch #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula protégée par des raies dans le Ventre de Jabu-Jabu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula protegida por unos stingers# en la Tripa de Jabu-Jabu otorga #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS] = HintText(CustomMessage("They say that a #spider in a web within Jabu-Jabu's Belly# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne innerhalb einer Webe in Jabu-Jabus Bauch# #[[1]]# hielte.", + /*french*/ "Selon moi, une #Skulltula sur une toile dans le Ventre de Jabu-Jabu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula sobre una red# en la Tripa de Jabu-Jabu otorga #[[1]]#. + + hintTextTable[RHT_JABU_JABUS_BELLY_DEKU_SCRUB] = HintText(CustomMessage("They say that a #scrub in a deity# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku in einer Gottheit #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #peste Mojo dans le ventre du gardien# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #deku dentro de cierta deidad# vende #[[1]]#. /*-------------------------- | FOREST TEMPLE | ---------------------------*/ - hintTable[FOREST_TEMPLE_FIRST_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #tree in the Forest Temple# supports", /*french*/"sur l'#arbre dans le Temple de la Forêt# gît", /*spanish*/"sobre un #árbol del Templo del Bosque# yace"}, - }); - - hintTable[FOREST_TEMPLE_FIRST_STALFOS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#defeating enemies beneath a falling ceiling# in Forest Temple yields", /*french*/"#deux squelettes# dans le Temple de la Forêt protègent", /*spanish*/"#derrotar enemigos caídos de lo alto# del Templo del Bosque revela"}, - }); - - hintTable[FOREST_TEMPLE_WELL_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #sunken chest deep in the woods# contains", /*french*/"le #coffre submergé dans la forêt# contient", /*spanish*/"un #sumergido cofre en lo profundo del bosque# contiene"}, - }); - - hintTable[FOREST_TEMPLE_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #fiery skull# in Forest Temple guards", /*french*/"le #crâne enflammé# dans le Temple de la Forêt protège", /*spanish*/"una #ardiente calavera# del Templo del Bosque esconde"}, - }); - - hintTable[FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #chest on a small island# in the Forest Temple holds", /*french*/"le #coffre sur l'îlot# du Temple de la Forêt contient", /*spanish*/"un #cofre sobre una isla# del Templo del Bosque contiene"}, - }); - - hintTable[FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"beneath a #checkerboard falling ceiling# lies", /*french*/"sous #l'échiquier tombant# gît", /*spanish*/"tras un #techo de ajedrez# yace"}, - }); - - hintTable[FOREST_TEMPLE_EYE_SWITCH_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #sharp eye# will spot", /*french*/"l'#oeil perçant# dans la forêt verra", /*spanish*/"un #afilado ojo# revela"}, - }, {}, - //clear text - Text{"#blocks of stone# in the Forest Temple surround", /*french*/"les #blocs dans le Temple de la Forêt# entourent", /*spanish*/"cerca de unos #bloques de piedra# del Templo del Bosque yace"} - ); - - hintTable[FOREST_TEMPLE_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #turned trunk# contains", /*french*/"le #coffre pivoté# contient", /*spanish*/"en una #sala con otro punto de vista# se esconde"}, - }); - - hintTable[FOREST_TEMPLE_FLOORMASTER_CHEST] = HintText::Exclude({ - //obscure text - Text{"deep in the forest #shadows guard a chest# containing", /*french*/"l'#ombre de la forêt# protège un coffre contenant", /*spanish*/"en lo profundo del bosque #unas sombras# esconden"}, - }); - - hintTable[FOREST_TEMPLE_BOW_CHEST] = HintText::Exclude({ - //obscure text - Text{"an #army of the dead# guards", /*french*/"des #squelettes sylvestres# protègent", /*spanish*/"un #ejército de soldados caídos# guarda"}, - }, {}, - //clear text - Text{"#Stalfos deep in the Forest Temple# guard", /*french*/"#trois squelettes dans le Temple de la Forêt# protègent", /*spanish*/"los #Stalfos en lo profundo del Templo del Bosque# guardan"} - ); - - hintTable[FOREST_TEMPLE_RED_POE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#Joelle# guards", /*french*/"#Joelle# protège", /*spanish*/"#Joelle# guarda"}, - }, {}, - //clear text - Text{"a #red ghost# guards", /*french*/"le #fantôme rouge# protège", /*spanish*/"un #espectro rojo# guarda"} - ); - - hintTable[FOREST_TEMPLE_BLUE_POE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#Beth# guards", /*french*/"#Beth# protège", /*spanish*/"#Beth# guarda"}, - }, {}, - //clear text - Text{"a #blue ghost# guards", /*french*/"le #fantôme bleu# protège", /*spanish*/"un #espectro azul# guarda"} - ); - - hintTable[FOREST_TEMPLE_BASEMENT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#revolving walls# in the Forest Temple conceal", /*french*/"des #murs rotatifs dans la forêt# recèlent", /*spanish*/"las #paredes giratorias# del Templo del Bosque conceden"}, - }); - - - hintTable[FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #tree in the Forest Temple# supports", /*french*/"sur l'#arbre dans le Temple de la Forêt# gît", /*spanish*/"sobre un #árbol del Templo del Bosque# yace"}, - }); - - hintTable[FOREST_TEMPLE_MQ_WOLFOS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#defeating enemies beneath a falling ceiling# in Forest Temple yields", /*french*/"#deux squelettes# dans le Temple de la Forêt protègent", /*spanish*/"#derrotar enemigos caídos de lo alto# del Templo del Bosque revela"}, - }); - - hintTable[FOREST_TEMPLE_MQ_BOW_CHEST] = HintText::Exclude({ - //obscure text - Text{"an #army of the dead# guards", /*french*/"des #squelettes sylvestres# protègent", /*spanish*/"un #ejército de soldados caídos# guarda"}, - }, {}, - //clear text - Text{"#Stalfos deep in the Forest Temple# guard", /*french*/"#trois squelettes dans le Temple de la Forêt# protègent", /*spanish*/"los #Stalfos en lo profundo del Templo del Bosque# guardan"} - ); - - hintTable[FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #chest on a small island# in the Forest Temple holds", /*french*/"le #coffre sur l'îlot# du Temple de la Forêt contient", /*spanish*/"un #cofre sobre una isla# del Templo del Bosque contiene"}, - }); - - hintTable[FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST] = HintText::Exclude({ - //obscure text - Text{"#high in a courtyard# within the Forest Temple is", /*french*/"#haut perché dans le jardin# du Temple de la Forêt gît", /*spanish*/"un #cofre en lo alto de un patio# del Templo del Bosque contiene"}, - }); - - hintTable[FOREST_TEMPLE_MQ_WELL_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #sunken chest deep in the woods# contains", /*french*/"le #coffre submergé dans la forêt# contient", /*spanish*/"un #sumergido cofre en lo profundo del bosque# contiene"}, - }); - - hintTable[FOREST_TEMPLE_MQ_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"#Joelle# guards", /*french*/"#Joelle# protège", /*spanish*/"#Joelle# guarda"}, - }, {}, - //clear text - Text{"a #red ghost# guards", /*french*/"le #fantôme rouge# protège", /*spanish*/"un #fantasma rojo# guarda"} - ); - - hintTable[FOREST_TEMPLE_MQ_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#Beth# guards", /*french*/"#Beth# protège", /*spanish*/"#Beth# guarda"}, - }, {}, - //clear text - Text{"a #blue ghost# guards", /*french*/"le #fantôme bleu# protège", /*spanish*/"un #fantasma azul# guarda"} - ); - - hintTable[FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"beneath a #checkerboard falling ceiling# lies", /*french*/"sous #l'échiquier tombant# gît", /*spanish*/"tras un #techo de ajedrez# yace"}, - }); - - hintTable[FOREST_TEMPLE_MQ_BASEMENT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#revolving walls# in the Forest Temple conceal", /*french*/"des #murs rotatifs dans la forêt# recèlent", /*spanish*/"las #paredes giratorias# del Templo del Bosque conceden"}, - }); - - hintTable[FOREST_TEMPLE_MQ_REDEAD_CHEST] = HintText::Exclude({ - //obscure text - Text{"deep in the forest #undead guard a chest# containing", /*french*/"des #revenants dans le Temple de la Forêt# protègent", /*spanish*/"en lo profundo del bosque #guardias del más allá# guardan"}, - }); - - hintTable[FOREST_TEMPLE_MQ_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #turned trunk# contains", /*french*/"le #coffre pivoté# contient", /*spanish*/"en una #sala con otro punto de vista# se esconde"}, - }); - - hintTable[FOREST_TEMPLE_PHANTOM_GANON_HEART] = HintText::Exclude({ - //obscure text - Text{"the #Evil Spirit from Beyond# holds", /*french*/"l'#esprit maléfique de l'au-delà# possède", /*spanish*/"el #espíritu maligno de ultratumba# porta"}, - }, {}, - //clear text - Text{"#Phantom Ganon# holds", /*french*/"#Ganon Spectral# possède", /*spanish*/"#Ganon Fantasma# porta"} - ); - - hintTable[FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD] = HintText::Exclude({ - //obscure text - Text{"a #spider on a small island# in the Forest Temple holds", /*french*/"une #Skulltula sur l'îlot du Temple de la Forêt# a", /*spanish*/"una #Skulltula sobre una pequeña isla# del Templo del Bosque otorga"}, - }); - - hintTable[FOREST_TEMPLE_GS_FIRST_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider high on a wall of vines# in the Forest Temple holds", /*french*/"une #Skulltula sur un mur de vignes du Temple de la Forêt# a", /*spanish*/"una #Skulltula en lo alto de una pared de cepas# del Templo del Bosque otorga"}, - }); - - hintTable[FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD] = HintText::Exclude({ - //obscure text - Text{"#stone columns# lead to a spider in the Forest Temple hiding", /*french*/"une #Skulltula haut perchée dans le jardin du Temple de la Forêt# a", /*spanish*/"unas #columnas del Templo del Bosque# conducen a una Skulltula que otorga"}, - }); - - hintTable[FOREST_TEMPLE_GS_LOBBY] = HintText::Exclude({ - //obscure text - Text{"a #spider among ghosts# in the Forest Temple guards", /*french*/"une #Skulltula dans la grande salle du Temple de la Forêt# a", /*spanish*/"una #Skulltula rodeada de fantasmas# del Templo del Bosque otorga"}, - }); - - hintTable[FOREST_TEMPLE_GS_BASEMENT] = HintText::Exclude({ - //obscure text - Text{"a #spider within revolving walls# in the Forest Temple holds", /*french*/"une #Skulltula derrière les murs pivotants du Temple de la Forêt# a", /*spanish*/"una #Skulltula entre paredes giratorias# del Templo del Bosque otorga"}, - }); - - - hintTable[FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY] = HintText::Exclude({ - //obscure text - Text{"an #ivy-hidden spider# in the Forest Temple hoards", /*french*/"une #Skulltula près de l'entrée du Temple de la Forêt# a", /*spanish*/"una #Skulltula escondida entre cepas# del Templo del Bosque otorga"}, - }); - - hintTable[FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider in a hidden nook# within the Forest Temple holds", /*french*/"une #Skulltula dans un recoin caché du Temple de la Forêt# a", /*spanish*/"una #Skulltula en una esquina oculta# del Templo del Bosque otorga"}, - }); - - hintTable[FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD] = HintText::Exclude({ - //obscure text - Text{"a #spider on an arch# in the Forest Temple holds", /*french*/"une #Skulltula sur une arche du Temple de la Forêt# a", /*spanish*/"una #Skulltula sobre un arco# del Templo del Bosque otorga"}, - }); - - hintTable[FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD] = HintText::Exclude({ - //obscure text - Text{"a #spider on a ledge# in the Forest Temple holds", /*french*/"une #Skulltula dans le jardin du Temple de la Forêt# a", /*spanish*/"una #Skulltula en un borde# del Templo del Bosque otorga"}, - }); - - hintTable[FOREST_TEMPLE_MQ_GS_WELL] = HintText::Exclude({ - //obscure text - Text{"#draining a well# in Forest Temple uncovers a spider with", /*french*/"une #Skulltula au fond du Puits du Temple de la Forêt# a", /*spanish*/"#vaciar el pozo# del Templo del Bosque desvela una Skulltula que otorga"}, - }); - + hintTextTable[RHT_FOREST_TEMPLE_FIRST_ROOM_CHEST] = HintText(CustomMessage("They say that a #tree in the Forest Temple# supports #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Baum im Waldtempel# #[[1]]# unterstütze.", + /*french*/ "Selon moi, sur l'#arbre dans le Temple de la Forêt# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, sobre un #árbol del Templo del Bosque# yace #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_FIRST_STALFOS_CHEST] = HintText(CustomMessage("They say that #defeating enemies beneath a falling ceiling# in Forest Temple yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Besiegen von Gegnern unter einer fallenden Decke# im Waldtempel #[[1]]# brächte.", + /*french*/ "Selon moi, #deux squelettes# dans le Temple de la Forêt protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #derrotar enemigos caídos de lo alto# del Templo del Bosque revela #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_WELL_CHEST] = HintText(CustomMessage("They say that a #sunken chest deep in the woods# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #gesunkene Truhe tief im Wald# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #coffre submergé dans la forêt# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #sumergido cofre en lo profundo del bosque# contiene #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say that a #fiery skull# in Forest Temple guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #feuriger Schädel# im Waldtempel #[[1]]# bewache.", + /*french*/ "Selon moi, le #crâne enflammé# dans le Temple de la Forêt protège #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #ardiente calavera# del Templo del Bosque esconde #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST] = HintText(CustomMessage("They say that a #chest on a small island# in the Forest Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine ##Truhe auf einer kleinen Insel# im Waldtempel #[[1]]# enthielte.", + /*french*/ "Selon moi, le #coffre sur l'îlot# du Temple de la Forêt contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #cofre sobre una isla# del Templo del Bosque contiene #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST] = HintText(CustomMessage("They say that beneath a #checkerboard falling ceiling# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß unter einer #fallenden Schachbrettdecke# #[[1]]# läge.", + /*french*/ "Selon moi, sous #l'échiquier tombant# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, tras un #techo de ajedrez# yace #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_EYE_SWITCH_CHEST] = HintText(CustomMessage("They say that #blocks of stone# in the Forest Temple surround #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Steinblöcke# im Waldtempel #[[1]]# umgeben würden.", + /*french*/ "Selon moi, les #blocs dans le Temple de la Forêt# entourent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, cerca de unos #bloques de piedra# del Templo del Bosque yace #[[1]]#. + {}, { + CustomMessage("They say that a #sharp eye# will spot #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #scharfes Auge# #[[1]]# erkennen würde.", + /*french*/ "Selon moi, l'#oeil perçant# dans la forêt verra #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #afilado ojo# revela #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that a #turned trunk# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #gedrehter Baumstamm# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #coffre pivoté# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en una #sala con otro punto de vista# se esconde #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_FLOORMASTER_CHEST] = HintText(CustomMessage("They say that deep in the forest #shadows guard a chest# containing #[[1]]#.", + /*german*/ "Man erzählt sich, daß tief im Wald, #Schatten eine Truhe bewachen#, welche [[1]]# enthielte.", + /*french*/ "Selon moi, l'#ombre de la forêt# protège un coffre contenant #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en lo profundo del bosque #unas sombras# esconden #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_BOW_CHEST] = HintText(CustomMessage("They say that #Stalfos deep in the Forest Temple# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Stalfos tief im Waldtempel# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, #trois squelettes dans le Temple de la Forêt# protègent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, los #Stalfos en lo profundo del Templo del Bosque# guardan #[[1]]#. + {}, { + CustomMessage("They say that an #army of the dead# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Armee der Toten# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, des #squelettes sylvestres# protègent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #ejército de soldados caídos# guarda #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_RED_POE_CHEST] = HintText(CustomMessage("They say that a #red ghost# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #roter Geist# #[[1]]# bewachen würde.", + /*french*/ "Selon moi, le #fantôme rouge# protège #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, un #espectro rojo# guarda #[[1]]#. + {}, { + CustomMessage("They say that #Joelle# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Joelle# #[[1]]# bewachen würde.", + /*french*/ "Selon moi, #Joelle# protège #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, #Joelle# guarda #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_BLUE_POE_CHEST] = HintText(CustomMessage("They say that a #blue ghost# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #blauer Geist# #[[1]]# bewachen würde.", + /*french*/ "Selon moi, le #fantôme bleu# protège #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, un #espectro azul# guarda #[[1]]#. + {}, { + CustomMessage("They say that #Beth# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Beth# #[[1]]# bewachen würde.", + /*french*/ "Selon moi, #Beth# protège #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, #Beth# guarda #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_BASEMENT_CHEST] = HintText(CustomMessage("They say that #revolving walls# in the Forest Temple conceal #[[1]]#.", + /*german*/ "Man erzählt sich, daß #drehende Wände# im Waldtempel #[[1]]# verbergen würden.", + /*french*/ "Selon moi, des #murs rotatifs dans la forêt# recèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #paredes giratorias# del Templo del Bosque conceden #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST] = HintText(CustomMessage("They say that a #tree in the Forest Temple# supports #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Baum im Waldtempel# #[[1]]# unterstütze.", + /*french*/ "Selon moi, sur l'#arbre dans le Temple de la Forêt# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, sobre un #árbol del Templo del Bosque# yace #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_WOLFOS_CHEST] = HintText(CustomMessage("They say that #defeating enemies beneath a falling ceiling# in Forest Temple yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Besiegen von Gegnern unter einer fallenden Decke# im Waldtempel #[[1]]# brächte.", + /*french*/ "Selon moi, #deux squelettes# dans le Temple de la Forêt protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #derrotar enemigos caídos de lo alto# del Templo del Bosque revela #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_BOW_CHEST] = HintText(CustomMessage("They say that #Stalfos deep in the Forest Temple# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Stalfos tief im Waldtempel# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, #trois squelettes dans le Temple de la Forêt# protègent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, los #Stalfos en lo profundo del Templo del Bosque# guardan #[[1]]#. + {}, { + CustomMessage("They say that an #army of the dead# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Armee der Toten# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, des #squelettes sylvestres# protègent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #ejército de soldados caídos# guarda #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST] = HintText(CustomMessage("They say that a #chest on a small island# in the Forest Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine ##Truhe auf einer kleinen Insel# im Waldtempel #[[1]]# enthielte.", + /*french*/ "Selon moi, le #coffre sur l'îlot# du Temple de la Forêt contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #cofre sobre una isla# del Templo del Bosque contiene #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST] = HintText(CustomMessage("They say that #high in a courtyard# within the Forest Temple is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #hoch in einem Hof# innerhalb des Waldtempels #[[1]]# sei.", + /*french*/ "Selon moi, #haut perché dans le jardin# du Temple de la Forêt gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #cofre en lo alto de un patio# del Templo del Bosque contiene #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_WELL_CHEST] = HintText(CustomMessage("They say that a #sunken chest deep in the woods# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #gesunkene Truhe tief im Wald# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #coffre submergé dans la forêt# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #sumergido cofre en lo profundo del bosque# contiene #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_MAP_CHEST] = HintText(CustomMessage("They say that a #red ghost# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #roter Geist# #[[1]]# bewachen würde.", + /*french*/ "Selon moi, le #fantôme rouge# protège #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, un #fantasma rojo# guarda #[[1]]#. + {}, { + CustomMessage("They say that #Joelle# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Joelle# #[[1]]# bewachen würde.", + /*french*/ "Selon moi, #Joelle# protège #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, #Joelle# guarda #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_COMPASS_CHEST] = HintText(CustomMessage("They say that a #blue ghost# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #blauer Geist# #[[1]]# bewachen würde.", + /*french*/ "Selon moi, le #fantôme bleu# protège #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, un #fantasma azul# guarda #[[1]]#. + {}, { + CustomMessage("They say that #Beth# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Beth# #[[1]]# bewachen würde.", + /*french*/ "Selon moi, #Beth# protège #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, #Beth# guarda #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST] = HintText(CustomMessage("They say that beneath a #checkerboard falling ceiling# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß unter einer #fallenden Schachbrettdecke# #[[1]]# läge.", + /*french*/ "Selon moi, sous #l'échiquier tombant# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, tras un #techo de ajedrez# yace #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_BASEMENT_CHEST] = HintText(CustomMessage("They say that #revolving walls# in the Forest Temple conceal #[[1]]#.", + /*german*/ "Man erzählt sich, daß #drehende Wände# im Waldtempel #[[1]]# verbergen würden.", + /*french*/ "Selon moi, des #murs rotatifs dans la forêt# recèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #paredes giratorias# del Templo del Bosque conceden #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_REDEAD_CHEST] = HintText(CustomMessage("They say that deep in the forest #undead guard a chest# containing #[[1]]#.", + /*german*/ "Man erzählt sich, daß tief im Wald #Untote eine Truhe bewachen#, welche #[[1]]# enthielte.", + /*french*/ "Selon moi, des #revenants dans le Temple de la Forêt# protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en lo profundo del bosque #guardias del más allá# guardan #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that a #turned trunk# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #gedrehter Baumstamm# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #coffre pivoté# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en una #sala con otro punto de vista# se esconde #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_PHANTOM_GANON_HEART] = HintText(CustomMessage("They say that #Phantom Ganon# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Phantom-Ganon# #[[1]]# besäße.", + /*french*/ "Selon moi, #Ganon Spectral# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #Ganon Fantasma# porta #[[1]]#. + {}, { + CustomMessage("They say that the #Evil Spirit from Beyond# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #böse Geist aus dem Jenseits# #[[1]]# besäße.", + /*french*/ "Selon moi, l'#esprit maléfique de l'au-delà# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #espíritu maligno de ultratumba# porta #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD] = HintText(CustomMessage("They say that a #spider on a small island# in the Forest Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne auf einer kleinen Insel# im Waldtempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur l'îlot du Temple de la Forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula sobre una pequeña isla# del Templo del Bosque otorga #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_GS_FIRST_ROOM] = HintText(CustomMessage("They say that a #spider high on a wall of vines# in the Forest Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne hoch auf einer Wand aus Reben# im Waldtempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur un mur de vignes du Temple de la Forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en lo alto de una pared de cepas# del Templo del Bosque otorga #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD] = HintText(CustomMessage("They say that #stone columns# lead to a spider in the Forest Temple hiding #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Säulen aus Stein# zu einer Spinne im Waldtempel führen, welche #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula haut perchée dans le jardin du Temple de la Forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unas #columnas del Templo del Bosque# conducen a una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_GS_LOBBY] = HintText(CustomMessage("They say that a #spider among ghosts# in the Forest Temple guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne inmitten von Geistern# im Waldtempel #[[1]]# bewache.", + /*french*/ "Selon moi, une #Skulltula dans la grande salle du Temple de la Forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula rodeada de fantasmas# del Templo del Bosque otorga #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_GS_BASEMENT] = HintText(CustomMessage("They say that a #spider within revolving walls# in the Forest Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne inmitten drehender Wände# im Waldtempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula derrière les murs pivotants du Temple de la Forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula entre paredes giratorias# del Templo del Bosque otorga #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY] = HintText(CustomMessage("They say that an #ivy-hidden spider# in the Forest Temple hoards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #unter Efeu versteckte Spinne# im Waldtempel #[[1]]# horte.", + /*french*/ "Selon moi, une #Skulltula près de l'entrée du Temple de la Forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula escondida entre cepas# del Templo del Bosque otorga #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM] = HintText(CustomMessage("They say that a #spider in a hidden nook# within the Forest Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne in einem versteckten Winkel# im Waldtempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans un recoin caché du Temple de la Forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en una esquina oculta# del Templo del Bosque otorga #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD] = HintText(CustomMessage("They say that a #spider on an arch# in the Forest Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne auf einem Bogen# im Waldtempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une arche du Temple de la Forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula sobre un arco# del Templo del Bosque otorga #[[1]]#. + + hintTextTable[RHT_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD] = HintText(CustomMessage("They say that a #spider on a ledge# in the Forest Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne auf einem Vorsprung# im Waldtempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans le jardin du Temple de la Forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en un borde# del Templo del Bosque otorga #[[1]]#. + hintTextTable[RHT_FOREST_TEMPLE_MQ_GS_WELL] = HintText(CustomMessage("They say that #draining a well# in Forest Temple uncovers a spider with #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Entleeren eines Brunnens# im Waldtempel eine Spinne mit #[[1]]# enthülle.", + /*french*/ "Selon moi, une #Skulltula au fond du Puits du Temple de la Forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #vaciar el pozo# del Templo del Bosque desvela una Skulltula que otorga #[[1]]#. + /*-------------------------- | FIRE TEMPLE | ---------------------------*/ - hintTable[FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#near a dragon# is", /*french*/"#près d'un dragon# gît", /*spanish*/"#cerca de un dragón# yace"}, - }); - - hintTable[FIRE_TEMPLE_FLARE_DANCER_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Flare Dancer behind a totem# guards", /*french*/"le #Danse-Flamme derrière un totem# protège", /*spanish*/"el #Bailafuego tras unos tótems# esconde"}, - }); - - hintTable[FIRE_TEMPLE_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #prison beyond a totem# holds", /*french*/"la #prison derrière un totem# contient", /*spanish*/"en una #prisión tras unos tótems# yace"}, - }); - - hintTable[FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = HintText::Exclude({ - //obscure text - Text{"#explosives over a lava pit# unveil", /*french*/"des #explosifs dans un lac de lave# révèlent", /*spanish*/"los #explosivos en un mar de llamas# revelan"}, - }); - - hintTable[FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #Goron trapped near lava# holds", /*french*/"le #Goron emprisonné près de la lave# a", /*spanish*/"un #goron atrapado cerca de un mar de llamas# guarda"}, - }); - - hintTable[FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #Goron at the end of a maze# holds", /*french*/"le #Goron dans le labyrinthe# a", /*spanish*/"un #goron al final de un laberinto# guarda"}, - }); - - hintTable[FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #Goron above a maze# holds", /*french*/"le #Goron au dessus du labyrinthe# a", /*spanish*/"un #goron sobre un laberinto# guarda"}, - }); - - hintTable[FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #Goron hidden near a maze# holds", /*french*/"le #Goron caché près du labyrinthe# a", /*spanish*/"un #goron escondido tras un laberinto# guarda"}, - }); - - hintTable[FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #blocked path# in Fire Temple holds", /*french*/"un #sol fragile dans le Temple du Feu# contient", /*spanish*/"en un #camino bloqueado# del Templo del Fuego yace"}, - }); - - hintTable[FIRE_TEMPLE_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #caged chest# in the Fire Temple hoards", /*french*/"un #coffre emprisonné# dans le Temple du Feu contient", /*spanish*/"un #cofre entre rejas# del Templo del Fuego contiene"}, - }); - - hintTable[FIRE_TEMPLE_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #chest in a fiery maze# contains", /*french*/"un #coffre dans un labyrinthe enflammé# contient", /*spanish*/"un #cofre de un ardiente laberinto# contiene"}, - }); - - hintTable[FIRE_TEMPLE_HIGHEST_GORON_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #Goron atop the Fire Temple# holds", /*french*/"le #Goron au sommet du Temple du Feu# a", /*spanish*/"un #goron en lo alto del Templo del Fuego# guarda"}, - }); - - - hintTable[FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#near a dragon# is", /*french*/"#près d'un dragon# gît", /*spanish*/"#cerca de un dragón# yace"}, - }); - - hintTable[FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Flare Dancer in the depths of a volcano# guards", /*french*/"le #Danse-Flamme au coeur du volcan# a", /*spanish*/"el #Bailafuego en lo profundo del volcán# esconde"}, - }, {}, - //clear text - Text{"the #Flare Dancer in the depths of the Fire Temple# guards", /*french*/"le #Danse-Flamme au coeur du volcan# a", /*spanish*/"el #Bailafuego en lo profundo del Templo del Fuego# esconde"} - ); - - hintTable[FIRE_TEMPLE_MQ_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #blocked path# in Fire Temple holds", /*french*/"le #chemin scellé# dans le Temple du Feu contient", /*spanish*/"en un #camino bloqueado# del Templo del Fuego yace"}, - }); - - hintTable[FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST] = HintText::Exclude({ - //obscure text - Text{"#crates in a maze# contain", /*french*/"des #boîtes dans le labyrinthe# contiennent", /*spanish*/"las #cajas de un laberinto# contienen"}, - }); - - hintTable[FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST] = HintText::Exclude({ - //obscure text - Text{"#crates in a maze# contain", /*french*/"des #boîtes dans le labyrinthe# contiennent", /*spanish*/"las #cajas de un laberinto# contienen"}, - }); - - hintTable[FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #falling slug# in the Fire Temple guards", /*french*/"la #limace tombante# dans le Temple du Feu protège", /*spanish*/"una #babosa del techo# del Templo del Fuego guarda"}, - }); - - hintTable[FIRE_TEMPLE_MQ_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"using a #hammer in the depths of the Fire Temple# reveals", "frapper du #marteau au coeur du volcan# révèle", /*spanish*/"usar el #martillo en lo profundo del Templo del Fuego# revela"}, - }); - - hintTable[FIRE_TEMPLE_MQ_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"#illuminating a lava pit# reveals the path to", /*french*/"#éclairer le lac de lave# révèle", /*spanish*/"#iluminar un mar de llamas# revela"}, - }); - - hintTable[FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = HintText::Exclude({ - //obscure text - Text{"#explosives over a lava pit# unveil", /*french*/"des #explosifs dans un lac de lave# révèlent", /*spanish*/"los #explosivos en un mar de llamas# revelan"}, - }); - - hintTable[FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #Goron hidden near a maze# holds", /*french*/"le #Goron caché près du labyrinthe# a", /*spanish*/"un #goron cerca de un laberinto# guarda"}, - }); - - hintTable[FIRE_TEMPLE_MQ_FREESTANDING_KEY] = HintText::Exclude({ - //obscure text - Text{"hidden #beneath a block of stone# lies", /*french*/"caché #derrière un bloc de pierre# gît", /*spanish*/"#bajo unos bloques de piedra# yace"}, - }); - - hintTable[FIRE_TEMPLE_VOLVAGIA_HEART] = HintText::Exclude({ - //obscure text - Text{"the #Subterranean Lava Dragon# holds", /*french*/"le #dragon des profondeurs# possède", /*spanish*/"el #dragón de lava subterráneo# porta"}, - }, {}, - //clear text - Text{"#Volvagia# holds", /*french*/"#Volvagia# possède", /*spanish*/"#Volvagia# porta"} - ); - - hintTable[FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM] = HintText::Exclude({ - //obscure text - Text{"#eight tiles of malice# guard a spider holding", /*french*/"une #Skulltula protégée par huit tuiles dans le Temple du Feu# a", /*spanish*/"#ocho baldosas de maldad# custodian una Skulltula que otorga"}, - }); - - hintTable[FIRE_TEMPLE_GS_BOSS_KEY_LOOP] = HintText::Exclude({ - //obscure text - Text{"#five tiles of malice# guard a spider holding", /*french*/"une #Skulltula protégée par cinq tuiles dans le Temple du Feu# a", /*spanish*/"#cinco baldosas de maldad# custodian una Skulltula que otorga"}, - }); - - hintTable[FIRE_TEMPLE_GS_BOULDER_MAZE] = HintText::Exclude({ - //obscure text - Text{"#explosives in a maze# unveil a spider hiding", /*french*/"une #Skulltula derrière un mur fragile du Temple du Feu# a", /*spanish*/"los #explosivos en un laberinto# desvelan una Skulltula que otorga"}, - }); - - hintTable[FIRE_TEMPLE_GS_SCARECROW_TOP] = HintText::Exclude({ - //obscure text - Text{"a #spider-friendly scarecrow# atop a volcano hides", /*french*/"une #Skulltula repérée par l'épouvantail du volcan# a", /*spanish*/"un #espantapájaros en lo alto de un volcán# custodia una Skulltula que otorga"}, - }, {}, - //clear text - Text{"a #spider-friendly scarecrow# atop the Fire Temple hides", /*french*/"une #Skulltula repérée par l'épouvantail du Temple du Feu# a", /*spanish*/"un #espantapájaros del Templo del Fuego# custodia una Skulltula que otorga"} - ); - - hintTable[FIRE_TEMPLE_GS_SCARECROW_CLIMB] = HintText::Exclude({ - //obscure text - Text{"a #spider-friendly scarecrow# atop a volcano hides", /*french*/"une #Skulltula repérée par l'épouvantail du volcan# a", /*spanish*/"un #espantapájaros en lo alto de un volcán# custodia una Skulltula que otorga"}, - }, {}, - //clear text - Text{"a #spider-friendly scarecrow# atop the Fire Temple hides", /*french*/"une #Skulltula repérée par l'épouvantail du Temple du Feu# a", /*spanish*/"un #espantapájaros del Templo del Fuego# custodia una Skulltula que otorga"} - ); - - - hintTable[FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE] = HintText::Exclude({ - //obscure text - Text{"a #spider above a fiery maze# holds", /*french*/"une #Skulltula au dessus du labyrinthe enflammé du Temple du Feu# a", /*spanish*/"una #Skulltula sobre un ardiente laberinto# otorga"}, - }); - - hintTable[FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = HintText::Exclude({ - //obscure text - Text{"a #spider within a fiery maze# holds", /*french*/"une #Skulltula dans le labyrinthe enflammé du Temple du Feu# a", /*spanish*/"una #Skulltula en el interior de un ardiente laberinto# otorga"}, - }); - - hintTable[FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = HintText::Exclude({ - //obscure text - Text{"a #Goron trapped near lava# befriended a spider with", /*french*/"une #Skulltula emprisonnée près du lac de lave du Temple du Feu# a", /*spanish*/"una #Skulltula amiga de un Goron atrapado junto a la lava# otorga"}, - }); - - hintTable[FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider beside a fiery maze# holds", /*french*/"une #Skulltula près du labyrinthe enflammé du Temple du Feu# a", /*spanish*/"una #Skulltula junto a un ardiente laberinto# otorga"}, - }); +hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They say that #near a dragon# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #nahe eines Drachens# #[[1]]# sei.", + /*french*/ "Selon moi, #près d'un dragon# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #cerca de un dragón# yace #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_FLARE_DANCER_CHEST] = HintText(CustomMessage("They say that the #Flare Dancer behind a totem# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Flammenderwische hinter einem Totem# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, le #Danse-Flamme derrière un totem# protège #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Bailafuego tras unos tótems# esconde #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that a #prison beyond a totem# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Gefängnis jenseits eines Totems# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #prison derrière un totem# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en una #prisión tras unos tótems# yace #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = HintText(CustomMessage("They say that #explosives over a lava pit# unveil #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Explosives über einem Lavastrom# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, des #explosifs dans un lac de lave# révèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #explosivos en un mar de llamas# revelan #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST] = HintText(CustomMessage("They say that a #Goron trapped near lava# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #nahe der Lava gefangene Gorone# #[[1]]# besäße.", + /*french*/ "Selon moi, le #Goron emprisonné près de la lave# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #goron atrapado cerca de un mar de llamas# guarda #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST] = HintText(CustomMessage("They say that a #Goron at the end of a maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Gorone am Ende eines Labyrinths# #[[1]]# besäße.", + /*french*/ "Selon moi, le #Goron dans le labyrinthe# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #goron al final de un laberinto# guarda #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST] = HintText(CustomMessage("They say that a #Goron above a maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Gorone oberhalb eines Labyrinths# #[[1]]# besäße.", + /*french*/ "Selon moi, le #Goron au dessus du labyrinthe# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #goron sobre un laberinto# guarda #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST] = HintText(CustomMessage("They say that a #Goron hidden near a maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #nahe eines Labyrinths versteckter Gorone# #[[1]]# besäße.", + /*french*/ "Selon moi, le #Goron caché près du labyrinthe# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #goron escondido tras un laberinto# guarda #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST] = HintText(CustomMessage("They say that a #blocked path# in Fire Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #blockierter Pfad# im Feuertempel #[[1]]# enthielte.", + /*french*/ "Selon moi, un #sol fragile dans le Temple du Feu# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en un #camino bloqueado# del Templo del Fuego yace #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say that a #caged chest# in the Fire Temple hoards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #eingesperrte Truhe# im Feuertempel #[[1]]# enthielte.", + /*french*/ "Selon moi, un #coffre emprisonné# dans le Temple du Feu contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #cofre entre rejas# del Templo del Fuego contiene #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_COMPASS_CHEST] = HintText(CustomMessage("They say that a #chest in a fiery maze# contains #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Truhe in einem feurigen Labyrinth# #[[1]]# enthielte.", + /*french*/ "Selon moi, un #coffre dans un labyrinthe enflammé# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #cofre de un ardiente laberinto# contiene #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_HIGHEST_GORON_CHEST] = HintText(CustomMessage("They say that a #Goron atop the Fire Temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Gorone auf der Spitze des Feuertempels# #[[1]]# besäße.", + /*french*/ "Selon moi, le #Goron au sommet du Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #goron en lo alto del Templo del Fuego# guarda #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST] = HintText(CustomMessage("They say that #near a dragon# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #nahe eines Drachens# #[[1]]# sei.", + /*french*/ "Selon moi, #près d'un dragon# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #cerca de un dragón# yace #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST] = HintText(CustomMessage("They say that the #Flare Dancer in the depths of the Fire Temple# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Flammenderwische in den Tiefen des Feuertempels# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, le #Danse-Flamme au coeur du volcan# a #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, el #Bailafuego en lo profundo del Templo del Fuego# esconde #[[1]]#. + {}, { + CustomMessage("They say that the #Flare Dancer in the depths of a volcano# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Flammenderwische in den Tiefen eines Vulkans# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, le #Danse-Flamme au coeur du volcan# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #Bailafuego en lo profundo del volcán# esconde #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_COMPASS_CHEST] = HintText(CustomMessage("They say that a #blocked path# in Fire Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #blockierter Pfad# im Feuertempel #[[1]]# enthielte.", + /*french*/ "Selon moi, le #chemin scellé# dans le Temple du Feu contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en un #camino bloqueado# del Templo del Fuego yace #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST] = HintText(CustomMessage("They say that #crates in a maze# contain #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Kisten in einem Labyrinth# #[[1]]# enthielten.", + /*french*/ "Selon moi, des #boîtes dans le labyrinthe# contiennent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #cajas de un laberinto# contienen #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST] = HintText(CustomMessage("They say that #crates in a maze# contain #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Kisten in einem Labyrinth #[[1]]# enthielten.", + /*french*/ "Selon moi, des #boîtes dans le labyrinthe# contiennent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #cajas de un laberinto# contienen #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST] = HintText(CustomMessage("They say that a #falling slug# in the Fire Temple guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #fallende Schnecke# im Feuertempel #[[1]]# bewache.", + /*french*/ "Selon moi, la #limace tombante# dans le Temple du Feu protège #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #babosa del techo# del Templo del Fuego guarda #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_MAP_CHEST] = HintText(CustomMessage("They say that using a #hammer in the depths of the Fire Temple# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Benutzung eines #Hammers in den Tiefen des Feuertempels# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, frapper du #marteau au coeur du volcan# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, usar el #martillo en lo profundo del Templo del Fuego# revela #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that #illuminating a lava pit# reveals the path to #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Illumination einer Lavagrube# den Pfad zu #[[1]]# enthülle.", + /*french*/ "Selon moi, #éclairer le lac de lave# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #iluminar un mar de llamas# revela #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = HintText(CustomMessage("They say that #explosives over a lava pit# unveil #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Explosives oberhalb einer Lavagrube# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, des #explosifs dans un lac de lave# révèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #explosivos en un mar de llamas# revelan #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST] = HintText(CustomMessage("They say that a #Goron hidden near a maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #nahe eines Labyrinths versteckter Gorone# #[[1]]# besäße.", + /*french*/ "Selon moi, le #Goron caché près du labyrinthe# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #goron cerca de un laberinto# guarda #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_FREESTANDING_KEY] = HintText(CustomMessage("They say that hidden #beneath a block of stone# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß versteckt #unter einem Steinblock# #[[1]]# läge.", + /*french*/ "Selon moi, caché #derrière un bloc de pierre# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #bajo unos bloques de piedra# yace #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_VOLVAGIA_HEART] = HintText(CustomMessage("They say that #Volvagia# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Volvagia# #[[1]]# besäße.", + /*french*/ "Selon moi, #Volcania# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #Volvagia# porta #[[1]]#. + {}, { + CustomMessage("They say that the #Subterranean Lava Dragon# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #subterrane Lavadrache# #[[1]]# besäße.", + /*french*/ "Selon moi, le #dragon des profondeurs# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #dragón de lava subterráneo# porta #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM] = HintText(CustomMessage("They say that #eight tiles of malice# guard a spider holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß #acht Kacheln der Arglist# eine Spinne bewachen würden, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula protégée par huit tuiles dans le Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #ocho baldosas de maldad# custodian una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_GS_BOSS_KEY_LOOP] = HintText(CustomMessage("They say that #five tiles of malice# guard a spider holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß #fünf Kacheln der Arglist# eine Spinne bewachen würden, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula protégée par cinq tuiles dans le Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #cinco baldosas de maldad# custodian una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_GS_BOULDER_MAZE] = HintText(CustomMessage("They say that #explosives in a maze# unveil a spider hiding #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Explosives in einem Labyrinth# eine Spinne enthüllen würde, welche #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula derrière un mur fragile du Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #explosivos en un laberinto# desvelan una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_GS_SCARECROW_TOP] = HintText(CustomMessage("They say that a #spider-friendly scarecrow# atop the Fire Temple hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #spinnenfreundliche Vogelscheuche# auf der Spitze des Feuertempels #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula repérée par l'épouvantail du Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, un #espantapájaros del Templo del Fuego# custodia una Skulltula que otorga #[[1]]#. + {}, { + CustomMessage("They say that a #spider-friendly scarecrow# atop a volcano hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #spinnenfreundliche Vogelscheuche# auf der Spitze eines Vulkans #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula repérée par l'épouvantail du volcan# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #espantapájaros en lo alto de un volcán# custodia una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_GS_SCARECROW_CLIMB] = HintText(CustomMessage("They say that a #spider-friendly scarecrow# atop the Fire Temple hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #spinnenfreundliche Vogelscheuche# auf der der Spitze des Feuertempels #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula repérée par l'épouvantail du Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, un #espantapájaros del Templo del Fuego# custodia una Skulltula que otorga #[[1]]#. + {}, { + CustomMessage("They say that a #spider-friendly scarecrow# atop a volcano hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #spinnenfreundliche Vogelscheuche# auf der Spitze eines Vulkans #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula repérée par l'épouvantail du volcan# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #espantapájaros en lo alto de un volcán# custodia una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE] = HintText(CustomMessage("They say that a #spider above a fiery maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne oberhalb eines feurigen Labyrinths #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au dessus du labyrinthe enflammé du Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula sobre un ardiente laberinto# otorga #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = HintText(CustomMessage("They say that a #spider within a fiery maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne innerhalb eines feurigen Labyrinths# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans le labyrinthe enflammé du Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en el interior de un ardiente laberinto# otorga #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = HintText(CustomMessage("They say that a #Goron trapped near lava# befriended a spider with #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #nahe der Lava gefangener Gorone# sich mit einer Spinne angefreundet hat, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula emprisonnée près du lac de lave du Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula amiga de un Goron atrapado junto a la lava# otorga #[[1]]#. + + hintTextTable[RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = HintText(CustomMessage("They say that a #spider beside a fiery maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne neben einem feurigen Labyrinth# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula près du labyrinthe enflammé du Temple du Feu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula junto a un ardiente laberinto# otorga #[[1]]#. /*-------------------------- | WATER TEMPLE | ---------------------------*/ - hintTable[WATER_TEMPLE_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"#rolling spikes# in the Water Temple surround", /*french*/"des #Spikes# dans le Temple de l'Eau entourent", /*spanish*/"unas #rodantes púas# del Templo del Agua guardan"}, - }); - - hintTable[WATER_TEMPLE_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#roaming stingers in the Water Temple# guard", /*french*/"des #raies dans le Temple de l'Eau# protègent", /*spanish*/"unos #errantes stingers# del Templo del Agua guardan"}, - }); - - hintTable[WATER_TEMPLE_TORCHES_CHEST] = HintText::Exclude({ - //obscure text - Text{"#fire in the Water Temple# reveals", /*french*/"des #flammes dans le Temple de l'Eau# révèlent", /*spanish*/"el #fuego en el Templo del Agua# revela"}, - }); - - hintTable[WATER_TEMPLE_DRAGON_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #serpent's prize# in the Water Temple is", /*french*/"la #récompense du dragon submergé# est", /*spanish*/"el #escamado premio# del Templo del Agua se trata de"}, - }); - - hintTable[WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST] = HintText::Exclude({ - //obscure text - Text{"#blinding an eye# in the Water Temple leads to", /*french*/"#l'oeil# du Temple de l'Eau voit", /*spanish*/"#cegar un ojo# del Templo del Agua conduce a"}, - }); - - hintTable[WATER_TEMPLE_CENTRAL_PILLAR_CHEST] = HintText::Exclude({ - //obscure text - Text{"in the #depths of the Water Temple# lies", /*french*/"le #coeur du Temple de l'Eau# cache", /*spanish*/"en las #profundidades del Templo del Agua# yace"}, - }); - - hintTable[WATER_TEMPLE_CRACKED_WALL_CHEST] = HintText::Exclude({ - //obscure text - Text{"#through a crack# in the Water Temple is", /*french*/"le #mur fragile# du Temple de l'Eau cache", /*spanish*/"tras una #agrietada pared# del Templo del Agua yace"}, - }); - - hintTable[WATER_TEMPLE_LONGSHOT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#facing yourself# reveals", /*french*/"se #vaincre soi-même# révèle", /*spanish*/"#luchar contra ti mismo# revela"}, - Text{"a #dark reflection# of yourself guards", /*french*/"son #propre reflet# cache", /*spanish*/"el #oscuro reflejo de ti mismo# guarda"}, - }, {}, - //clear text - Text{"#Dark Link# guards", /*french*/"l'#Ombre de @# protège", /*spanish*/"#@ Oscuro# guarda"} - ); - - - hintTable[WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST] = HintText::Exclude({ - //obscure text - Text{"in the #depths of the Water Temple# lies", /*french*/"le #coeur du Temple de l'Eau# cache", /*spanish*/"en las #profundidades del Templo del Agua# yace"}, - }); - - hintTable[WATER_TEMPLE_MQ_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"fire in the Water Temple unlocks a #vast gate# revealing a chest with", /*french*/"des #flammes au coeur du Temple de l'Eau# révèlent", /*spanish*/"el fuego en el Templo del Agua alza una #gran valla# con"}, - }); - - hintTable[WATER_TEMPLE_MQ_LONGSHOT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#through a crack# in the Water Temple is", /*french*/"le #mur fragile# du Temple de l'Eau cache", /*spanish*/"tras una #agrietada pared# del Templo del Agua yace"}, - }); - - hintTable[WATER_TEMPLE_MQ_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#fire in the Water Temple# reveals", /*french*/"des #flammes dans le Temple de l'Eau# révèlent", /*spanish*/"el #fuego en el Templo del Agua# revela"}, - }); - - hintTable[WATER_TEMPLE_MQ_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"#sparring soldiers# in the Water Temple guard", /*french*/"les #soldats du Temple de l'Eau# protègent", /*spanish*/"#acabar con unos soldados# del Templo del Agua revela"}, - }); - - hintTable[WATER_TEMPLE_MORPHA_HEART] = HintText::Exclude({ - //obscure text - Text{"the #Giant Aquatic Amoeba# holds", /*french*/"l'#amibe aquatique géante# possède", /*spanish*/"la #ameba acuática gigante# porta"}, - }, {}, - //clear text - Text{"#Morpha# holds", /*french*/"#Morpha# possède", /*spanish*/"#Morpha# porta"} - ); - - hintTable[WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider over a waterfall# in the Water Temple holds", /*french*/"une #Skulltula au dessus d'une cascade du Temple de l'Eau# a", /*spanish*/"una #Skulltula tras una cascada# del Templo del Agua otorga"}, - }); - - hintTable[WATER_TEMPLE_GS_CENTRAL_PILLAR] = HintText::Exclude({ - //obscure text - Text{"a #spider in the center of the Water Temple# holds", /*french*/"une #Skulltula au centre du Temple de l'Eau# a", /*spanish*/"una #Skulltula en el centro del Templo del Agua# otorga"}, - }); - - hintTable[WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"a spider protected by #rolling boulders under the lake# hides", /*french*/"une #Skulltula derrière les rochers roulants sous le lac# a", /*spanish*/"una #Skulltula protegida por rocas rodantes# bajo el lago otorga"}, - }, {}, - //clear text - Text{"a spider protected by #rolling boulders in the Water Temple# hides", /*french*/"une #Skulltula derrière les rochers roulants du Temple de l'Eau# a", /*spanish*/"una #Skulltula protegida por rocas rodantes# del Templo del Agua otorga"} - ); - - hintTable[WATER_TEMPLE_GS_RIVER] = HintText::Exclude({ - //obscure text - Text{"a #spider over a river# in the Water Temple holds", /*french*/"une #Skulltula au dessus de la rivière du Temple de l'Eau# a", /*spanish*/"una #Skulltula sobre un río# del Templo del Agua otorga"}, - }); - - - hintTable[WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH] = HintText::Exclude({ - //obscure text - Text{"#beyond a pit of lizards# is a spider holding", /*french*/"une #Skulltula près des lézards du Temple de l'Eau# a", /*spanish*/"#más allá de un pozo de reptiles# una Skulltula otorga"}, - }); - - hintTable[WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY] = HintText::Exclude({ - //obscure text - Text{"#lizards guard a spider# in the Water Temple with", /*french*/"une #Skulltula dans les couloirs croisés du Temple de l'Eau# a", /*spanish*/"unos #reptiles custodian una Skulltula# del Templo del Agua que otorga"}, - }); - - hintTable[WATER_TEMPLE_MQ_GS_RIVER] = HintText::Exclude({ - //obscure text - Text{"a #spider over a river# in the Water Temple holds", /*french*/"une #Skulltula au dessus de la rivière du Temple de l'Eau# a", /*spanish*/"una #Skulltula sobre un río# del Templo del Agua otorga"}, - }); + hintTextTable[RHT_WATER_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say that #rolling spikes# in the Water Temple surround #[[1]]#.", + /*german*/ "Man erzählt sich, daß #rollende Stacheln# im Wassertempel #[[1]]# umgeben würden.", + /*french*/ "Selon moi, des #Spikes# dans le Temple de l'Eau entourent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unas #rodantes púas# del Templo del Agua guardan #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_COMPASS_CHEST] = HintText(CustomMessage("They say that #roaming stingers in the Water Temple# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #umherstreifende Rochen im Wassertempel# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, des #raies dans le Temple de l'Eau# protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unos #errantes stingers# del Templo del Agua guardan #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_TORCHES_CHEST] = HintText(CustomMessage("They say that #fire in the Water Temple# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Feuer im Wassertempel# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, des #flammes dans le Temple de l'Eau# révèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #fuego en el Templo del Agua# revela #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_DRAGON_CHEST] = HintText(CustomMessage("They say that a #serpent's prize# in the Water Temple is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Preis einer Schlange# im Wassertempel #[[1]]# sei.", + /*french*/ "Selon moi, la #récompense du dragon submergé# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #escamado premio# del Templo del Agua se trata de #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST] = HintText(CustomMessage("They say that #blinding an eye# in the Water Temple leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Erblinden eines Auges# im Wassertempel zu #[[1]]# führe.", + /*french*/ "Selon moi, #l'oeil# du Temple de l'Eau voit #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #cegar un ojo# del Templo del Agua conduce a #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_CENTRAL_PILLAR_CHEST] = HintText(CustomMessage("They say that in the #depths of the Water Temple# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß in den #Tiefen des Wassertempels# #[[1]]# läge.", + /*french*/ "Selon moi, le #coeur du Temple de l'Eau# cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en las #profundidades del Templo del Agua# yace #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_CRACKED_WALL_CHEST] = HintText(CustomMessage("They say that #through a crack# in the Water Temple is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #in einem Spalt# im Wassertempel #[[1]]# sei.", + /*french*/ "Selon moi, le #mur fragile# du Temple de l'Eau cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, tras una #agrietada pared# del Templo del Agua yace #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_LONGSHOT_CHEST] = HintText(CustomMessage("They say that #Dark Link# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #schwarze Link# #[[1]]# bewache.", + /*french*/ "Selon moi, l'#Ombre de @# protège #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #@ Oscuro# guarda #[[1]]#. + {}, { + CustomMessage("They say that #facing yourself# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Konfrontation mit einem Selbst# #[[1]]# offenbare.", + /*french*/ "Selon moi, se #vaincre soi-même# révèle #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #luchar contra ti mismo# revela #[[1]]#. + CustomMessage("They say that a #dark reflection# of yourself guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #dunkle Reflektion# von einem Selbst #[[1]]# bewache.", + /*french*/ "Selon moi, son #propre reflet# cache #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #oscuro reflejo de ti mismo# guarda #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST] = HintText(CustomMessage("They say that in the #depths of the Water Temple# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß in den #Tiefen des Wassertempels# #[[1]]# läge.", + /*french*/ "Selon moi, le #coeur du Temple de l'Eau# cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en las #profundidades del Templo del Agua# yace #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that fire in the Water Temple unlocks a #vast gate# revealing a chest with #[[1]]#.", + /*german*/ "Man erzählt sich, daß Feuer im Wassertempel ein #großes Tor# entschlüssele, welches eine Truhe mit #[[1]]# offenbare.", + /*french*/ "Selon moi, des #flammes au coeur du Temple de l'Eau# révèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el fuego en el Templo del Agua alza una #gran valla# con #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_LONGSHOT_CHEST] = HintText(CustomMessage("They say that #through a crack# in the Water Temple is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #in einem Spalt# im Wassertempel #[[1]]# sei.", + /*french*/ "Selon moi, le #mur fragile# du Temple de l'Eau cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, tras una #agrietada pared# del Templo del Agua yace #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_COMPASS_CHEST] = HintText(CustomMessage("They say that #fire in the Water Temple# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Feuer im Wassertempel# #[[1]]# offenbare.", + /*french*/ "Selon moi, des #flammes dans le Temple de l'Eau# révèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #fuego en el Templo del Agua# revela #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_MAP_CHEST] = HintText(CustomMessage("They say that #sparring soldiers# in the Water Temple guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #sich duellierende Soldaten# im Wassertempel #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #soldats du Temple de l'Eau# protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #acabar con unos soldados# del Templo del Agua revela #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MORPHA_HEART] = HintText(CustomMessage("They say that #Morpha# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Morpha# #[[1]]# besäße.", + /*french*/ "Selon moi, #Morpha# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #Morpha# porta #[[1]]#. + {}, { + CustomMessage("They say that the #Giant Aquatic Amoeba# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #gigantische aquatische Amöbe# #[[1]]# besäße.", + /*french*/ "Selon moi, l'#amibe aquatique géante# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, la #ameba acuática gigante# porta #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM] = HintText(CustomMessage("They say that a #spider over a waterfall# in the Water Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne über einem Wasserfall# im Wassertempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au dessus d'une cascade du Temple de l'Eau# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula tras una cascada# del Templo del Agua otorga #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_GS_CENTRAL_PILLAR] = HintText(CustomMessage("They say that a #spider in the center of the Water Temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne im Zentrum des Wassertempels# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au centre du Temple de l'Eau# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en el centro del Templo del Agua# otorga #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that a spider protected by #rolling boulders in the Water Temple# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne, welche von #rollenden Felsbrocken im Wassertempel# geschützt werde, #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula derrière les rochers roulants du Temple de l'Eau# a #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, una #Skulltula protegida por rocas rodantes# del Templo del Agua otorga #[[1]]#. + {}, { + CustomMessage("They say that a spider protected by #rolling boulders under the lake# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne, welche von #rollenden Felsbrocken unterhalb eines Flusses# geschützt werde, #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula derrière les rochers roulants sous le lac# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, una #Skulltula protegida por rocas rodantes# bajo el lago otorga #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_GS_RIVER] = HintText(CustomMessage("They say that a #spider over a river# in the Water Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne über einem Fluß# im Wassertempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au dessus de la rivière du Temple de l'Eau# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula sobre un río# del Templo del Agua otorga #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH] = HintText(CustomMessage("They say that #beyond a pit of lizards# is a spider holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß #jenseits einer Reptiliengrube# eine Spinne sei, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula près des lézards du Temple de l'Eau# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #más allá de un pozo de reptiles# una Skulltula otorga #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY] = HintText(CustomMessage("They say that #lizards guard a spider# in the Water Temple with #[[1]]#.", + /*german*/ "Man erzählt sich, daß #eine von Reptilien bewachte Spinne# im Wassertempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans les couloirs croisés du Temple de l'Eau# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unos #reptiles custodian una Skulltula# del Templo del Agua que otorga #[[1]]#. + + hintTextTable[RHT_WATER_TEMPLE_MQ_GS_RIVER] = HintText(CustomMessage("They say that a #spider over a river# in the Water Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne oberhalb eines Flusses# im Wassertempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au dessus de la rivière du Temple de l'Eau# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula sobre un río# del Templo del Agua otorga #[[1]]#. /*-------------------------- | SPIRIT TEMPLE | ---------------------------*/ - hintTable[SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST] = HintText::Exclude({ - //obscure text - Text{"a child conquers a #skull in green fire# in the Spirit Temple to reach", /*french*/"le #crâne au halo vert dans le colosse# cache", /*spanish*/"el joven que #baje el puente# del Templo del Espíritu encontrará"}, - }); - - hintTable[SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST] = HintText::Exclude({ - //obscure text - Text{"a child can find a #caged chest# in the Spirit Temple with", /*french*/"le #coffre embarré dans le colosse# contient", /*spanish*/"un joven puede encontrar un #cofre entre rejas# del Templo del Espíritu con"}, - }); - - hintTable[SPIRIT_TEMPLE_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#across a pit of sand# in the Spirit Temple lies", /*french*/"le #trou sableux dans le colosse# a", /*spanish*/"tras un #pozo de arena# del Templo del Espíritu yace"}, - }); - - hintTable[SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#dodging boulders to collect silver rupees# in the Spirit Temple yields", /*french*/"les #pièces argentées entourées de rochers dans le colosse# révèlent", /*spanish*/"#esquivar rocas y conseguir plateadas rupias# en el Templo del Espíritu conduce a"}, - }); - - hintTable[SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #shadow circling reflected light# in the Spirit Temple guards", /*french*/"l'#ombre près d'un miroir# protège", /*spanish*/"un #círculo de reflectante luz# del Templo del Espíritu guarda"}, - }); - - hintTable[SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #shadow circling reflected light# in the Spirit Temple guards", /*french*/"l'#ombre près d'un miroir# protège", /*spanish*/"un #círculo de reflectante luz# del Templo del Espíritu guarda"}, - }); - - hintTable[SPIRIT_TEMPLE_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"#before a giant statue# in the Spirit Temple lies", /*french*/"#devant la statue# dans le colosse gît", /*spanish*/"#ante una gran estatua# del Templo del Espíritu aguarda"}, - }); - - hintTable[SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST] = HintText::Exclude({ - //obscure text - Text{"#lizards in the Spirit Temple# guard", /*french*/"les #lézards dans le colosse# protègent", /*spanish*/"los #reptiles del Templo del Espíritu# guardan"}, - }); - - hintTable[SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST] = HintText::Exclude({ - //obscure text - Text{"#lizards in the Spirit Temple# guard", /*french*/"les #lézards dans le colosse# protègent", /*spanish*/"los #reptiles del Templo del Espíritu# guardan"}, - }); - - hintTable[SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"#torchlight among Beamos# in the Spirit Temple reveals", /*french*/"les #torches autour des Sentinelles# éclairent", /*spanish*/"las #antorchas junto a Beamos# del Templo del Espíritu revelan"}, - }); - - hintTable[SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #statue in the Spirit Temple# holds", /*french*/"la #statue dans le colosse# tient", /*spanish*/"una #estatua del Templo del Espíritu# esconde"}, - }); - - hintTable[SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST] = HintText::Exclude({ - //obscure text - Text{"on a #ledge by a statue# in the Spirit Temple rests", /*french*/"#haut perché près de la statue# dans le colosse gît", /*spanish*/"al #borde de una estatua# del Templo del Espíritu yace"}, - }); - - hintTable[SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST] = HintText::Exclude({ - //obscure text - Text{"those who #show the light among statues# in the Spirit Temple find", /*french*/"le #soleil près des statues# cache", /*spanish*/"aquellos que #iluminen ante las estatuas# del Templo del Espíritu encontrarán"}, - }); - - hintTable[SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Eye of Truth in the Spirit Temple# reveals", /*french*/"le #trésor invisible près du Hache-Viande# contient", /*spanish*/"el #Ojo de la Verdad# en el Templo del Espíritu revela"}, - }); - - hintTable[SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Eye of Truth in the Spirit Temple# reveals", /*french*/"le #trésor invisible près du Hache-Viande# contient", /*spanish*/"el #Ojo de la Verdad# en el Templo del Espíritu revela"}, - }); - - hintTable[SPIRIT_TEMPLE_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #chest engulfed in flame# in the Spirit Temple holds", /*french*/"le #coffre enflammé dans le colosse# contient", /*spanish*/"un #cofre rodeado de llamas# del Templo del Espíritu contiene"}, - }); - - hintTable[SPIRIT_TEMPLE_TOPMOST_CHEST] = HintText::Exclude({ - //obscure text - Text{"those who #show the light above the Colossus# find", /*french*/"le #soleil au sommet du colosse# révèle", /*spanish*/"aquellos que #iluminen en lo alto del Coloso# encontrarán"}, - }); - - - hintTable[SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#lying unguarded# in the Spirit Temple is", /*french*/"dans #l'entrée du colosse# se trouve", /*spanish*/"en la #entrada del Templo del Espíritu# yace"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #switch in a pillar# within the Spirit Temple drops", /*french*/"l'#interrupteur dans un pilier# du colosse cache", /*spanish*/"el #interruptor de un pilar# del Templo del Espíritu revela"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#collecting rupees through a water jet# reveals", /*french*/"les #pièces argentées dans le jet d'eau# du colosse révèlent", /*spanish*/"#hacerte con rupias tras un géiser# revela"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"an #eye blinded by stone# within the Spirit Temple conceals", /*french*/"#l'oeil derrière le rocher# dans le colosse voit", /*spanish*/"#cegar a un ojo# del Templo del Espíritu revela"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"surrounded by #fire and wrappings# lies", /*french*/"près des #pierres tombales dans le colosse# gît", /*spanish*/"rodeado de #fuego y vendas# yace"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST] = HintText::Exclude({ - //obscure text - Text{"a child defeats a #gauntlet of monsters# within the Spirit Temple to find", /*french*/"l'enfant qui vainc #plusieurs monstres# dans le colosse trouvera", /*spanish*/"el joven que derrote #unos monstruos# del Templo del Espíritu encontrará"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST] = HintText::Exclude({ - //obscure text - Text{"#explosive sunlight# within the Spirit Temple uncovers", /*french*/"le #rayon de lumière explosif dans le colosse# révèle", /*spanish*/"una #explosiva luz solar# del Templo del Espíritu revela"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST] = HintText::Exclude({ - //obscure text - Text{"#trapped by falling enemies# within the Spirit Temple is", /*french*/"des #ennemis tombants# dans le colosse protègent", /*spanish*/"#rodeado de enemigos del cielo# del Templo del Espíritu yace"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#blinding the colossus# unveils", /*french*/"#l'oeil dans le colosse# voit", /*spanish*/"#cegar al coloso# revela"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #royal melody awakens the colossus# to reveal", /*french*/"la #mélodie royale éveille le colosse# et révèle", /*spanish*/"la #melodía real que despierte al coloso# revelará"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Eye of Truth# finds the colossus's hidden", /*french*/"#l'oeil de vérité# verra dans le colosse", /*spanish*/"el #Ojo de la Verdad# en el Templo del Espíritu encontrará"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST] = HintText::Exclude({ - //obscure text - Text{"#the old hide what the young find# to reveal", /*french*/"l'#oeil dans le trou du bloc argent# dans le colosse voit", /*spanish*/"el #adulto esconde lo que el joven anhela#, revelando"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"#sunlight in a maze of fire# hides", /*french*/"#la lumière dans le labyrinthe de feu# du colosse révèle", /*spanish*/"la #luz solar de un ígneo laberinto# esconde"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"#across a pit of sand# in the Spirit Temple lies", /*french*/"le #trou sableux# dans le colosse a", /*spanish*/"#a través del pozo de arena# del Templo del Espíritu yace"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"where #temporal stone blocks the path# within the Spirit Temple lies", /*french*/"les #pierres temporelles# dans le colosse cachent", /*spanish*/"donde los #bloques temporales bloquean# en el Templo del Espíritu yace"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #chest of double purpose# holds", /*french*/"le #coffre à usage double# du colosse contient", /*spanish*/"un #cofre de doble uso# contiene"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #temporal stone blocks the light# leading to", /*french*/"la #pierre temporelle# le colosse fait ombre sur", /*spanish*/"un #bloque temporal bloquea la luz# que conduce a"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"those who #show the light above the Colossus# find", /*french*/"le trésor invisible #au sommet du colosse# contient", /*spanish*/"aquellos que #revelen la luz sobre el Coloso# encontrarán"}, - }); - - hintTable[SPIRIT_TEMPLE_TWINROVA_HEART] = HintText::Exclude({ - //obscure text - Text{"the #Sorceress Sisters# hold", /*french*/"#les sorcières jumelles# possède", /*spanish*/"las #hermanas hechiceras# portan"}, - }, {}, - //clear text - Text{"#Twinrova# holds", /*french*/"#Twinrova# possède", /*spanish*/"#Birova# porta"} - ); - - hintTable[SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM] = HintText::Exclude({ - //obscure text - Text{"a spider in the #hall of a knight# guards", /*french*/"une #Skulltula au dessus d'un escalier du Temple de l'Esprit# a", /*spanish*/"una #Skulltula en el salón de un guerrero# otorga"}, - }); - - hintTable[SPIRIT_TEMPLE_GS_BOULDER_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider behind a temporal stone# in the Spirit Temple yields", /*french*/"une #Skulltula derrière une pierre temporelle du Temple de l'Esprit# a", /*spanish*/"una #Skulltula tras un bloque temporal# del Templo del Espíritu otorga"}, - }); - - hintTable[SPIRIT_TEMPLE_GS_LOBBY] = HintText::Exclude({ - //obscure text - Text{"a #spider beside a statue# holds", /*french*/"une #Skulltula dans la grande salle du Temple de l'Esprit# a", /*spanish*/"una #Skulltula junto a una estatua# del Templo del Espíritu otorga"}, - }); - - hintTable[SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider at the top of a deep shaft# in the Spirit Temple holds", /*french*/"une #Skulltula près d'un mur d'escalade du Temple de l'Esprit# a", /*spanish*/"una #Skulltula en lo alto de un gran hueco# del Templo del Espíritu otorga"}, - }); - - hintTable[SPIRIT_TEMPLE_GS_METAL_FENCE] = HintText::Exclude({ - //obscure text - Text{"a child defeats a #spider among bats# in the Spirit Temple to gain", /*french*/"une #Skulltula sur le grillage du Temple de l'Esprit# a", /*spanish*/"el joven que derrote la #Skulltula entre murciélagos# del Templo del Espíritu hallará"}, - }); - - - hintTable[SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM] = HintText::Exclude({ - //obscure text - Text{"#above a pit of sand# in the Spirit Temple hides", /*french*/"une #Skulltula au dessus du trou sableux du Temple de l'Esprit# a", /*spanish*/"una #Skulltula sobre un pozo de arena# del Templo del Espíritu otorga"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST] = HintText::Exclude({ - //obscure text - Text{"a spider in the #hall of a knight# guards", /*french*/"une #Skulltula dans la salle aux neuf trônes du Temple de l'Esprit# a", /*spanish*/"una #Skulltula en el salón de un guerrero# otorga"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH] = HintText::Exclude({ - //obscure text - Text{"a spider in the #hall of a knight# guards", /*french*/"une #Skulltula dans la salle aux neuf trônes du Temple de l'Esprit# a", /*spanish*/"una #Skulltula en el salón de un guerrero# otorga"}, - }); - - hintTable[SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM] = HintText::Exclude({ - //obscure text - Text{"#upon a web of glass# in the Spirit Temple sits a spider holding", /*french*/"une #Skulltula sur une paroi de verre du Temple de l'Esprit# a", /*spanish*/"#sobre una plataforma de cristal# yace una Skulltula que otorga"}, - }); + hintTextTable[RHT_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST] = HintText(CustomMessage("They say that a child conquers a #skull in green fire# in the Spirit Temple to reach #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein Kind einen #Schädel in grünem Feuer# im Geistertempel erobere, um #[[1]]# zu erreichen.", + /*french*/ "Selon moi, le #crâne au halo vert dans le colosse# cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el joven que #baje el puente# del Templo del Espíritu encontrará #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST] = HintText(CustomMessage("They say that a child can find a #caged chest# in the Spirit Temple with #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein Kind eine #gefangene Truhe# im Geistertempel finden könne, welche #[[1]]# enthielte.", + /*french*/ "Selon moi, le #coffre embarré dans le colosse# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un joven puede encontrar un #cofre entre rejas# del Templo del Espíritu con #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_COMPASS_CHEST] = HintText(CustomMessage("They say that #across a pit of sand# in the Spirit Temple lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #jenseits einer Sandgrube# im Geistertempel #[[1]]# läge.", + /*french*/ "Selon moi, le #trou sableux dans le colosse# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, tras un #pozo de arena# del Templo del Espíritu yace #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST] = HintText(CustomMessage("They say that #dodging boulders to collect silver rupees# in the Spirit Temple yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Ausweichen von Felsbrocken um silberne Rubine zu sammeln# im Geistertempel #[[1]]# einbrächte.", + /*french*/ "Selon moi, les #pièces argentées entourées de rochers dans le colosse# révèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #esquivar rocas y conseguir plateadas rupias# en el Templo del Espíritu conduce a #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST] = HintText(CustomMessage("They say that a #shadow circling reflected light# in the Spirit Temple guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #reflektierendes Licht umzirkelnder Schatten# im Geistertempel #[[1]]# bewachen würde.", + /*french*/ "Selon moi, l'#ombre près d'un miroir# protège #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #círculo de reflectante luz# del Templo del Espíritu guarda #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST] = HintText(CustomMessage("They say that a #shadow circling reflected light# in the Spirit Temple guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #reflektierendes Licht umzirkelnder Schatten# im Geistertempel #[[1]]# bewachen würde.", + /*french*/ "Selon moi, l'#ombre près d'un miroir# protège #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #círculo de reflectante luz# del Templo del Espíritu guarda #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say that #before a giant statue# in the Spirit Temple lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #vor einer riesigen Statue# im Geistertempel #[[1]]# läge.", + /*french*/ "Selon moi, #devant la statue# dans le colosse gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #ante una gran estatua# del Templo del Espíritu aguarda #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST] = HintText(CustomMessage("They say that #lizards in the Spirit Temple# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Reptilien im Geistertempel# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #lézards dans le colosse# protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #reptiles del Templo del Espíritu# guardan #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST] = HintText(CustomMessage("They say that #lizards in the Spirit Temple# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Reptilien im Geistertempel# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #lézards dans le colosse# protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #reptiles del Templo del Espíritu# guardan #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST] = HintText(CustomMessage("They say that #torchlight among Beamos# in the Spirit Temple reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Fackellicht inmitten von Strahlzyklopen# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, les #torches autour des Sentinelles# éclairent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #antorchas junto a Beamos# del Templo del Espíritu revelan #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST] = HintText(CustomMessage("They say that a #statue in the Spirit Temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Statue im Geistertempel# #[[1]]# hielte.", + /*french*/ "Selon moi, la #statue dans le colosse# tient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #estatua del Templo del Espíritu# esconde #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST] = HintText(CustomMessage("They say that on a #ledge by a statue# in the Spirit Temple rests #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf einem #Vorsprung einer Statue# im Geistertempel #[[1]]# ruhe.", + /*french*/ "Selon moi, #haut perché près de la statue# dans le colosse gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, al #borde de una estatua# del Templo del Espíritu yace #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST] = HintText(CustomMessage("They say that those who #show the light among statues# in the Spirit Temple find #[[1]]#.", + /*german*/ "Man erzählt sich, daß jene, welche #das Licht inmitten von Statuen# im Geistertempel zeigen würden, #[[1]]# fänden.", + /*french*/ "Selon moi, le #soleil près des statues# cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, aquellos que #iluminen ante las estatuas# del Templo del Espíritu encontrarán #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth in the Spirit Temple# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Auge der Wahrheit im Geistertempel# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, le #trésor invisible près du Hache-Viande# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Ojo de la Verdad# en el Templo del Espíritu revela #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth in the Spirit Temple# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Auge der Wahrheit im Geistertempel# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, le #trésor invisible près du Hache-Viande# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Ojo de la Verdad# en el Templo del Espíritu revela #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that a #chest engulfed in flame# in the Spirit Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von Flammen eingehüllte Truhe# im Geistertempel #[[1]]# enthielte.", + /*french*/ "Selon moi, le #coffre enflammé dans le colosse# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #cofre rodeado de llamas# del Templo del Espíritu contiene #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_TOPMOST_CHEST] = HintText(CustomMessage("They say that those who #show the light above the Colossus# find #[[1]]#.", + /*german*/ "Man erzählt sich, daß jene, welche #das Licht auf dem Koloss# zeigen würden, #[[1]]# fänden.", + /*french*/ "Selon moi, le #soleil au sommet du colosse# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, aquellos que #iluminen en lo alto del Coloso# encontrarán #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST] = HintText(CustomMessage("They say that #lying unguarded# in the Spirit Temple is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #unbewacht liegend# im Geistertempel #[[1]]# sei.", + /*french*/ "Selon moi, dans #l'entrée du colosse# se trouve #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en la #entrada del Templo del Espíritu# yace #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST] = HintText(CustomMessage("They say that a #switch in a pillar# within the Spirit Temple drops #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Schalter in einer Säule# innerhalb des Geistertempels #[[1]]# erbringe.", + /*french*/ "Selon moi, l'#interrupteur dans un pilier# du colosse cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #interruptor de un pilar# del Templo del Espíritu revela #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST] = HintText(CustomMessage("They say that #collecting rupees through a water jet# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Sammeln von Rubin durch einen Wasserstrom# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, les #pièces argentées dans le jet d'eau# du colosse révèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #hacerte con rupias tras un géiser# revela #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST] = HintText(CustomMessage("They say that an #eye blinded by stone# within the Spirit Temple conceals #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #durch einen Stein erblindetes Auge# im Geistertempel #[[1]]# verberge.", + /*french*/ "Selon moi, #l'oeil derrière le rocher# dans le colosse voit #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #cegar a un ojo# del Templo del Espíritu revela #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_MAP_CHEST] = HintText(CustomMessage("They say that surrounded by #fire and wrappings# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß umgeben von #Feuer umhüllt# #[[1]]# läge.", + /*french*/ "Selon moi, près des #pierres tombales dans le colosse# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, rodeado de #fuego y vendas# yace #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST] = HintText(CustomMessage("They say that a child defeats a #gauntlet of monsters# within the Spirit Temple to find #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein Kind eine #Herausforderung von Monstern# innerhalb des Geistertempels bewältige und #[[1]]# fände.", + /*french*/ "Selon moi, l'enfant qui vainc #plusieurs monstres# dans le colosse trouvera #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el joven que derrote #unos monstruos# del Templo del Espíritu encontrará #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST] = HintText(CustomMessage("They say that #explosive sunlight# within the Spirit Temple uncovers #[[1]]#.", + /*german*/ "Man erzählt sich, daß #explosives Sonnenlicht# innerhalb des Geistertempels #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, le #rayon de lumière explosif dans le colosse# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #explosiva luz solar# del Templo del Espíritu revela #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST] = HintText(CustomMessage("They say that #trapped by falling enemies# within the Spirit Temple is #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich #gefangen von fallenden Feinden# im Geistertempel #[[1]]# befände.", + /*french*/ "Selon moi, des #ennemis tombants# dans le colosse protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #rodeado de enemigos del cielo# del Templo del Espíritu yace #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_COMPASS_CHEST] = HintText(CustomMessage("They say that #blinding the colossus# unveils #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Erblinden des Kolosses# #[[1]]# offenbare.", + /*french*/ "Selon moi, #l'oeil dans le colosse# voit #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #cegar al coloso# revela #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST] = HintText(CustomMessage("They say that a #royal melody awakens the colossus# to reveal #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #königliche Melodie den Koloss erwecke# und #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, la #mélodie royale éveille le colosse# et révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #melodía real que despierte al coloso# revelará #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth# finds the colossus's hidden #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Auge der Wahrheit# des Kolosses verborgene #[[1]]# fände.", + /*french*/ "Selon moi, #l'oeil de vérité# verra dans le colosse #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Ojo de la Verdad# en el Templo del Espíritu encontrará #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST] = HintText(CustomMessage("They say that #the old hide what the young find# to reveal #[[1]]#.", + /*german*/ "Man erzählt sich, daß #der Alte verstecke, was der Junge finde# und #[[1]]# enthüllt würde.", + /*french*/ "Selon moi, l'#oeil dans le trou du bloc argent# dans le colosse voit #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #adulto esconde lo que el joven anhela#, revelando #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST] = HintText(CustomMessage("They say that #sunlight in a maze of fire# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Sonnenlicht in einem Labyrinth aus Feuer# #[[1]]# verstecke.", + /*french*/ "Selon moi, #la lumière dans le labyrinthe de feu# du colosse révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #luz solar de un ígneo laberinto# esconde #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST] = HintText(CustomMessage("They say that #across a pit of sand# in the Spirit Temple lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #jenseits einer Sandgrube# im Geistertempel #[[1]]# läge.", + /*french*/ "Selon moi, le #trou sableux# dans le colosse a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #a través del pozo de arena# del Templo del Espíritu yace #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST] = HintText(CustomMessage("They say that where #temporal stone blocks the path# within the Spirit Temple lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß wo #zeitlicher Stein den Pfad blockiere# im Geistertempel #[[1]]# läge.", + /*french*/ "Selon moi, les #pierres temporelles# dans le colosse cachent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, donde los #bloques temporales bloquean# en el Templo del Espíritu yace #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST] = HintText(CustomMessage("They say that a #chest of double purpose# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Truhe mit doppeltem Zweck# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #coffre à usage double# du colosse contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #cofre de doble uso# contiene #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that a #temporal stone blocks the light# leading to #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #zeitlicher Stein das Licht blockiere#, was zu #[[1]]# führe.", + /*french*/ "Selon moi, la #pierre temporelle# le colosse fait ombre sur #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #bloque temporal bloquea la luz# que conduce a #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST] = HintText(CustomMessage("They say that those who #show the light above the Colossus# find #[[1]]#.", + /*german*/ "Man erzählt sich, daß jene, welche #das Licht auf dem Koloss# zeigen würden, #[[1]]# fänden.", + /*french*/ "Selon moi, le trésor invisible #au sommet du colosse# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, aquellos que #revelen la luz sobre el Coloso# encontrarán #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_TWINROVA_HEART] = HintText(CustomMessage("They say that #Twinrova# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Twinrova# #[[1]]# besäße.", + /*french*/ "Selon moi, #Twinrova# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #Birova# porta #[[1]]#. + {}, { + CustomMessage("They say that the #Sorceress Sisters# hold #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Hexenschwestern# #[[1]]# besäßen.", + /*french*/ "Selon moi, #les sorcières jumelles# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, las #hermanas hechiceras# portan #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM] = HintText(CustomMessage("They say that a spider in the #hall of a knight# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne in der #Halle eines Ritters# #[[1]]# bewache.", + /*french*/ "Selon moi, une #Skulltula au dessus d'un escalier du Temple de l'Esprit# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en el salón de un guerrero# otorga #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_GS_BOULDER_ROOM] = HintText(CustomMessage("They say that a #spider behind a temporal stone# in the Spirit Temple yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne hinter einem zeitlichen Stein# im Geistertempel #[[1]]# einbrächte.", + /*french*/ "Selon moi, une #Skulltula derrière une pierre temporelle du Temple de l'Esprit# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula tras un bloque temporal# del Templo del Espíritu otorga #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_GS_LOBBY] = HintText(CustomMessage("They say that a #spider beside a statue# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne neben einer Statue# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans la grande salle du Temple de l'Esprit# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula junto a una estatua# del Templo del Espíritu otorga #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM] = HintText(CustomMessage("They say that a #spider at the top of a deep shaft# in the Spirit Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne auf der Spitze eines tiefen Stiels# im Geistertempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula près d'un mur d'escalade du Temple de l'Esprit# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en lo alto de un gran hueco# del Templo del Espíritu otorga #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_GS_METAL_FENCE] = HintText(CustomMessage("They say that a child defeats a #spider among bats# in the Spirit Temple to gain #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein Kind #eine Spinne inmitten von Fledermäusen# im Geistertempel besiege und #[[1]]# erhielte.", + /*french*/ "Selon moi, une #Skulltula sur le grillage du Temple de l'Esprit# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el joven que derrote la #Skulltula entre murciélagos# del Templo del Espíritu hallará #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM] = HintText(CustomMessage("They say that #above a pit of sand# in the Spirit Temple hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich #oberhalb einer Sandgrube# im Geistertempel #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula au dessus du trou sableux du Temple de l'Esprit# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula sobre un pozo de arena# del Templo del Espíritu otorga #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST] = HintText(CustomMessage("They say that a spider in the #hall of a knight# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne in der #Halle eines Ritters# #[[1]]# bewache.", + /*french*/ "Selon moi, une #Skulltula dans la salle aux neuf trônes du Temple de l'Esprit# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en el salón de un guerrero# otorga #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH] = HintText(CustomMessage("They say that a spider in the #hall of a knight# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne in der #Halle eines Ritters# #[[1]]# bewache.", + /*french*/ "Selon moi, une #Skulltula dans la salle aux neuf trônes du Temple de l'Esprit# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula en el salón de un guerrero# otorga #[[1]]#. + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM] = HintText(CustomMessage("They say that #upon a web of glass# in the Spirit Temple sits a spider holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß #auf einer Webe aus Glas# im Geistertempel eine Spinne säße, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une paroi de verre du Temple de l'Esprit# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #sobre una plataforma de cristal# yace una Skulltula que otorga #[[1]]#. /*-------------------------- | SHADOW TEMPLE | ---------------------------*/ - hintTable[SHADOW_TEMPLE_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Eye of Truth# pierces a hall of faces to reveal", /*french*/"l'#oeil de vérité# voit dans les couloirs du Temple de l'Ombre", /*spanish*/"el #Ojo de la Verdad# descubrirá un pasillo de facetas con"}, - }); - - hintTable[SHADOW_TEMPLE_HOVER_BOOTS_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #nether dweller in the Shadow Temple# holds", /*french*/"le #spectre du Temple de l'Ombre# a", /*spanish*/"un #temido morador del Templo de las Sombras# guarda"}, - }, {}, - //clear text - Text{"#Dead Hand in the Shadow Temple# holds", /*french*/"le #Poigneur dans le Temple de l'Ombre# cache", /*spanish*/"la #Mano Muerta del Templo de las Sombras# guarda"} - ); - - hintTable[SHADOW_TEMPLE_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#mummies revealed by the Eye of Truth# guard", /*french*/"les #Gibdos dans les couloirs# du Temple de l'Ombre protègent", /*spanish*/"las #momias reveladas por el Ojo de la Verdad# guardan"}, - }); - - hintTable[SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#spinning scythes# protect", /*french*/"les #faucheurs danseurs# du Temple de l'Ombre protègent", /*spanish*/"las #giratorias guadañas# protegen"}, - }); - - hintTable[SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#invisible blades# guard", /*french*/"les #faucheurs invisibles# du Temple de l'Ombre protègent", /*spanish*/"las #hojas invisibles# guardan"}, - }); - - hintTable[SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#invisible blades# guard", /*french*/"les #faucheurs invisibles# du Temple de l'Ombre protègent", /*spanish*/"las #hojas invisibles# guardan"}, - }); - - hintTable[SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST] = HintText::Exclude({ - //obscure text - Text{"#falling spikes# block the path to", /*french*/"la #pluie de clous# surplombe", /*spanish*/"los #pinchos de un techo# conducen a"}, - }); - - hintTable[SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST] = HintText::Exclude({ - //obscure text - Text{"#falling spikes# block the path to", /*french*/"la #pluie de clous# surplombe", /*spanish*/"los #pinchos de un techo# conducen a"}, - }); - - hintTable[SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST] = HintText::Exclude({ - //obscure text - Text{"#falling spikes# block the path to", /*french*/"la #pluie de clous# surplombe", /*spanish*/"los #pinchos de un techo# conducen a"}, - }); - - hintTable[SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #dead roam among invisible spikes# guarding", /*french*/"#parmi les clous invisibles# du Temple de l'Ombre se cache", /*spanish*/"los #muertos que vagan por pinchos invisibles# protegen"}, - }); - - hintTable[SHADOW_TEMPLE_WIND_HINT_CHEST] = HintText::Exclude({ - //obscure text - Text{"an #invisible chest guarded by the dead# holds", /*french*/"le #trésor invisible du cul-de-sac# du Temple de l'Ombre contient", /*spanish*/"un #cofre invisible custodiado por los del más allá# contiene"}, - }); - - hintTable[SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST] = HintText::Exclude({ - //obscure text - Text{"#mummies guarding a ferry# hide", /*french*/"les #Gibdos qui bloquent le traversier# cachent", /*spanish*/"las #momias que protegen un navío# esconden"}, - }); - - hintTable[SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST] = HintText::Exclude({ - //obscure text - Text{"#mummies guarding a ferry# hide", /*french*/"les #Gibdos qui bloquent le traversier# cachent", /*spanish*/"las #momias que protegen un navío# esconden"}, - }); - - hintTable[SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#walls consumed by a ball of fire# reveal", /*french*/"le #piège de bois# du Temple de l'Ombre cache", /*spanish*/"las #paredes consumidas por una esfera ígnea# revelan"}, - }); - - hintTable[SHADOW_TEMPLE_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"#walls consumed by a ball of fire# reveal", /*french*/"le #piège de bois# du Temple de l'Ombre cache", /*spanish*/"las #paredes consumidas por una esfera ígnea# revelan"}, - }); - - hintTable[SHADOW_TEMPLE_FREESTANDING_KEY] = HintText::Exclude({ - //obscure text - Text{"#inside a burning skull# lies", /*french*/"#dans un crâne enflammé# gît", /*spanish*/"en el #interior de una calavera en llamas# aguarda"}, - }); - - - hintTable[SHADOW_TEMPLE_MQ_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Eye of Truth# pierces a hall of faces to reveal", /*french*/"l'#oeil de vérité# voit dans les couloirs du Temple de l'Ombre", /*spanish*/"el #Ojo de la Verdad# descubre un pasillo de facetas con"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#Dead Hand in the Shadow Temple# holds", /*french*/"le #Poigneur dans le Temple de l'Ombre# cache", /*spanish*/"la #Mano Muerta del Templo de las Sombras# guarda"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#mummies revealed by the Eye of Truth# guard", /*french*/"les #Gibdos dans les couloirs# du Temple de l'Ombre protègent", /*spanish*/"las #momias reveladas por el Ojo de la Verdad# guardan"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"#spinning scythes# protect", /*french*/"les #faucheurs danseurs# du Temple de l'Ombre protègent", /*spanish*/"las #giratorias guadañas# protegen"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST] = HintText::Exclude({ - //obscure text - Text{"#collecting rupees in a vast cavern# with the Shadow Temple unveils", /*french*/"les #pièces argentées dans le Temple de l'Ombre# révèlent", /*spanish*/"hacerte con las #rupias en una gran caverna# del Templo de las Sombras revela"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST] = HintText::Exclude({ - //obscure text - Text{"#falling spikes# block the path to", /*french*/"la #pluie de clous# surplombe", /*spanish*/"los #pinchos de un techo# conducen a"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST] = HintText::Exclude({ - //obscure text - Text{"#falling spikes# block the path to", /*french*/"la #pluie de clous# surplombe", /*spanish*/"los #pinchos de un techo# conducen a"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST] = HintText::Exclude({ - //obscure text - Text{"#falling spikes# block the path to", /*french*/"la #pluie de clous# surplombe", /*spanish*/"los #pinchos de un techo# conducen a"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #dead roam among invisible spikes# guarding", /*french*/"#parmi les clous invisibles# du Temple de l'Ombre se cache", /*spanish*/"los #muertos que vagan por pinchos invisibles# protegen"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"#walls consumed by a ball of fire# reveal", /*french*/"le #piège de bois# du Temple de l'Ombre cache", /*spanish*/"las #paredes consumidas por una esfera ígnea# revelan"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#walls consumed by a ball of fire# reveal", /*french*/"le #piège de bois# du Temple de l'Ombre cache", /*spanish*/"las #paredes consumidas por una esfera ígnea# revelan"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST] = HintText::Exclude({ - //obscure text - Text{"near an #empty pedestal# within the Shadow Temple lies", /*french*/"#près d'un pédestal vide du Temple de l'Ombre# gît", /*spanish*/"cerca de un #vacío pedestal# del Templo de las Sombras yace"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#invisible blades# guard", /*french*/"les #faucheurs invisibles# du Temple de l'Ombre protègent", /*spanish*/"unas #hojas invisibles# guardan"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#invisible blades# guard", /*french*/"les #faucheurs invisibles# du Temple de l'Ombre protègent", /*spanish*/"unas #hojas invisibles# guardan"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_WIND_HINT_CHEST] = HintText::Exclude({ - //obscure text - Text{"an #invisible chest guarded by the dead# holds", /*french*/"le #trésor invisible du cul-de-sac# du Temple de l'Ombre contient", /*spanish*/"un #cofre invisible custodiado por los del más allá# contiene"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST] = HintText::Exclude({ - //obscure text - Text{"#mummies guarding a ferry# hide", /*french*/"les #Gibdos qui bloquent le traversier# cachent", /*spanish*/"las #momias que protegen un navío# esconden"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST] = HintText::Exclude({ - //obscure text - Text{"#mummies guarding a ferry# hide", /*french*/"les #Gibdos qui bloquent le traversier# cachent", /*spanish*/"las #momias que protegen un navío# esconden"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#caged near a ship# lies", /*french*/"#dans une cage près du traversier# gît", /*spanish*/"#entre rejas al lado de un navío# yace"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_FREESTANDING_KEY] = HintText::Exclude({ - //obscure text - Text{"#behind three burning skulls# lies", /*french*/"#derrière trois crânes enflammés# gît", /*spanish*/"tras #tres ardientes calaveras# yace"}, - }); - - hintTable[SHADOW_TEMPLE_BONGO_BONGO_HEART] = HintText::Exclude({ - //obscure text - Text{"the #Phantom Shadow Beast# holds", /*french*/"le #monstre de l'ombre# possède", /*spanish*/"la #alimaña oscura espectral# porta"}, - }, {}, - //clear text - Text{"#Bongo Bongo# holds", /*french*/"#Bongo Bongo# possède", /*spanish*/"#Bongo Bongo# porta"} - ); - - hintTable[SHADOW_TEMPLE_GS_SINGLE_GIANT_POT] = HintText::Exclude({ - //obscure text - Text{"#beyond a burning skull# lies a spider with", /*french*/"une #Skulltula derrière un crâne enflammé du Temple de l'Ombre# a", /*spanish*/"#tras una ardiente calavera# yace una Skulltula que otorga"}, - }); - - hintTable[SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider beyond falling spikes# holds", /*french*/"une #Skulltula au delà de la pluie de clous du Temple de l'Ombre# a", /*spanish*/"una #Skulltula tras los pinchos del techo# otorga"}, - }); - - hintTable[SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT] = HintText::Exclude({ - //obscure text - Text{"#beyond three burning skulls# lies a spider with", /*french*/"une #Skulltula derrière trois crânes enflammés du Temple de l'Ombre# a", /*spanish*/"#tras tres ardientes calaveras# yace una Skulltula que otorga"}, - }); - - hintTable[SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM] = HintText::Exclude({ - //obscure text - Text{"a spider guarded by #invisible blades# holds", /*french*/"une #Skulltula protégée par les faucheurs invisibles du Temple de l'Ombre# a", /*spanish*/"una #Skulltula custodiada por hojas invisibles# otorga"}, - }); - - hintTable[SHADOW_TEMPLE_GS_NEAR_SHIP] = HintText::Exclude({ - //obscure text - Text{"a spider near a #docked ship# hoards", /*french*/"une #Skulltula près du traversier du Temple de l'Ombre# a", /*spanish*/"una #Skulltula cercana a un navío# otorga"}, - }); - - - hintTable[SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider beyond falling spikes# holds", /*french*/"une #Skulltula au delà de la pluie de clous du Temple de l'Ombre# a", /*spanish*/"una #Skulltula tras los pinchos del techo# otorga"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider amidst roaring winds# in the Shadow Temple holds", /*french*/"une #Skulltula près des vents du Temple de l'Ombre# a", /*spanish*/"una #Skulltula entre ventarrones# del Templo de las Sombras otorga"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_GS_AFTER_WIND] = HintText::Exclude({ - //obscure text - Text{"a #spider beneath gruesome debris# in the Shadow Temple hides", /*french*/"une #Skulltula sous des débris du Temple de l'Ombre# a", /*spanish*/"una #Skulltula bajo unos horripilantes escombros# del Templo de las Sombras otorga"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_GS_AFTER_SHIP] = HintText::Exclude({ - //obscure text - Text{"a #fallen statue# reveals a spider with", /*french*/"une #Skulltula près de la statue écroulée du Temple de l'Ombre# a", /*spanish*/"una #estatua caída# revelará una Skulltula que otorgue"}, - }); - - hintTable[SHADOW_TEMPLE_MQ_GS_NEAR_BOSS] = HintText::Exclude({ - //obscure text - Text{"a #suspended spider# guards", /*french*/"une #Skulltula près du repère du Temple de l'Ombre# a", /*spanish*/"una #Skulltula flotante# del Templo de las Sombras otorga"}, - }); +hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth# pierces a hall of faces to reveal #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Auge der Wahrheit# eine Halle der Gesichter durchdränge und #[[1]]# offenbaren würde.", + /*french*/ "Selon moi, l'#oeil de vérité# voit dans les couloirs du Temple de l'Ombre #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Ojo de la Verdad# descubrirá un pasillo de facetas con #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_HOVER_BOOTS_CHEST] = HintText(CustomMessage("They say that #Dead Hand in the Shadow Temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #tote Hand im Schattentempel# #[[1]]# hielte.", + /*french*/ "Selon moi, le #Poigneur dans le Temple de l'Ombre# cache #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #Mano Muerta del Templo de las Sombras# guarda #[[1]]#. + {}, { + CustomMessage("They say that a #nether dweller in the Shadow Temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Bewohner der Unterwelt im Schattentempel# #[[1]]# besäße.", + /*french*/ "Selon moi, le #spectre du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #temido morador del Templo de las Sombras# guarda #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_COMPASS_CHEST] = HintText(CustomMessage("They say that #mummies revealed by the Eye of Truth# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #durch das Auge der Wahrheit offenbarte Mumien# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #Gibdos dans les couloirs# du Temple de l'Ombre protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #momias reveladas por el Ojo de la Verdad# guardan #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST] = HintText(CustomMessage("They say that #spinning scythes# protect #[[1]]#.", + /*german*/ "Man erzählt sich, daß #rotierende Sensen# #[[1]]# schützen würden.", + /*french*/ "Selon moi, les #faucheurs danseurs# du Temple de l'Ombre protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #giratorias guadañas# protegen #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST] = HintText(CustomMessage("They say that #invisible blades# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #unsichtbare Klingen# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #faucheurs invisibles# du Temple de l'Ombre protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #hojas invisibles# guardan #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST] = HintText(CustomMessage("They say that #invisible blades# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #unsichtbare Klingen# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #faucheurs invisibles# du Temple de l'Ombre protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #hojas invisibles# guardan #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST] = HintText(CustomMessage("They say that #falling spikes# block the path to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #fallende Stacheln# den Pfad zu #[[1]]# blockieren würden.", + /*french*/ "Selon moi, la #pluie de clous# surplombe #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #pinchos de un techo# conducen a #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST] = HintText(CustomMessage("They say that #falling spikes# block the path to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #fallende Stacheln# den Pfad zu #[[1]]# blockieren würden.", + /*french*/ "Selon moi, la #pluie de clous# surplombe #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #pinchos de un techo# conducen a #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST] = HintText(CustomMessage("They say that #falling spikes# block the path to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #fallende Stacheln# den Pfad zu #[[1]]# blockieren würden.", + /*french*/ "Selon moi, la #pluie de clous# surplombe #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #pinchos de un techo# conducen a #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST] = HintText(CustomMessage("They say that the #dead roam among invisible spikes# guarding #[[1]]#.", + /*german*/ "Man erzählt sich, daß #herumschweifende Tote inmitten von unsichtbaren Stacheln# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, #parmi les clous invisibles# du Temple de l'Ombre se cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #muertos que vagan por pinchos invisibles# protegen #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_WIND_HINT_CHEST] = HintText(CustomMessage("They say that an #invisible chest guarded by the dead# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von Toten bewachte unsichtbare Truhe# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #trésor invisible du cul-de-sac# du Temple de l'Ombre contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #cofre invisible custodiado por los del más allá# contiene #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST] = HintText(CustomMessage("They say that #mummies guarding a ferry# hide #[[1]]#.", + /*german*/ "Man erzählt sich, daß #eine Fähre bewachende Mumien# #[[1]]# verstecken würden.", + /*french*/ "Selon moi, les #Gibdos qui bloquent le traversier# cachent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #momias que protegen un navío# esconden #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST] = HintText(CustomMessage("They say that #mummies guarding a ferry# hide #[[1]]#.", + /*german*/ "Man erzählt sich, daß #eine Fähre bewachende Mumien# #[[1]]# verstecken würden.", + /*french*/ "Selon moi, les #Gibdos qui bloquent le traversier# cachent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #momias que protegen un navío# esconden #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST] = HintText(CustomMessage("They say that #walls consumed by a ball of fire# reveal #[[1]]#.", + /*german*/ "Man erzählt sich, daß #von einem Feuerball verschlungende Wände# #[[1]]# offenbaren würden.", + /*french*/ "Selon moi, le #piège de bois# du Temple de l'Ombre cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #paredes consumidas por una esfera ígnea# revelan #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that #walls consumed by a ball of fire# reveal #[[1]]#.", + /*german*/ "Man erzählt sich, daß #von einem Feuerball verschlungende Wände# #[[1]]# offenbaren würden.", + /*french*/ "Selon moi, le #piège de bois# du Temple de l'Ombre cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #paredes consumidas por una esfera ígnea# revelan #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_FREESTANDING_KEY] = HintText(CustomMessage("They say that #inside a burning skull# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #innerhalb eines brennenden Schädels# #[[1]]# läge.", + /*french*/ "Selon moi, #dans un crâne enflammé# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en el #interior de una calavera en llamas# aguarda #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_COMPASS_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth# pierces a hall of faces to reveal #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Auge der Wahrheit# eine Halle der Gesichter durchdränge und #[[1]]# offenbaren würde.", + /*french*/ "Selon moi, l'#oeil de vérité# voit dans les couloirs du Temple de l'Ombre #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Ojo de la Verdad# descubre un pasillo de facetas con #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST] = HintText(CustomMessage("They say that #Dead Hand in the Shadow Temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #tote Hand im Schattentempel# #[[1]]# hielte.", + /*french*/ "Selon moi, le #Poigneur dans le Temple de l'Ombre# cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #Mano Muerta del Templo de las Sombras# guarda #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST] = HintText(CustomMessage("They say that #mummies revealed by the Eye of Truth# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #durch das Auge der Wahrheit offenbarte Mumien# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #Gibdos dans les couloirs# du Temple de l'Ombre protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #momias reveladas por el Ojo de la Verdad# guardan #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_MAP_CHEST] = HintText(CustomMessage("They say that #spinning scythes# protect #[[1]]#.", + /*german*/ "Man erzählt sich, daß #rotierende Sensen# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #faucheurs danseurs# du Temple de l'Ombre protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #giratorias guadañas# protegen #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST] = HintText(CustomMessage("They say that #collecting rupees in a vast cavern# with the Shadow Temple unveils #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Sammeln von Rubinen in einer riesigen Kaverne# im Schattentempel #[[1]]# offenbaren würde.", + /*french*/ "Selon moi, les #pièces argentées dans le Temple de l'Ombre# révèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, hacerte con las #rupias en una gran caverna# del Templo de las Sombras revela #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST] = HintText(CustomMessage("They say that #falling spikes# block the path to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #fallende Stachel# den Pfad zu #[[1]]# blockieren würden.", + /*french*/ "Selon moi, la #pluie de clous# surplombe #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #pinchos de un techo# conducen a #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST] = HintText(CustomMessage("They say that #falling spikes# block the path to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #fallende Stachel# den Pfad zu #[[1]]# blockieren würden.", + /*french*/ "Selon moi, la #pluie de clous# surplombe #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #pinchos de un techo# conducen a #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST] = HintText(CustomMessage("They say that #falling spikes# block the path to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #fallende Stachel# den Pfad zu #[[1]]# blockieren würden.", + /*french*/ "Selon moi, la #pluie de clous# surplombe #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #pinchos de un techo# conducen a #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST] = HintText(CustomMessage("They say that the #dead roam among invisible spikes# guarding #[[1]]#.", + /*german*/ "Man erzählt sich, daß #herumschweifende Tote inmitten von unsichtbaren Stacheln# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, #parmi les clous invisibles# du Temple de l'Ombre se cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #muertos que vagan por pinchos invisibles# protegen #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that #walls consumed by a ball of fire# reveal #[[1]]#.", + /*german*/ "Man erzählt sich, daß #von einem Feuerball verschlungende Wände# #[[1]]# offenbaren würden.", + /*french*/ "Selon moi, le #piège de bois# du Temple de l'Ombre cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #paredes consumidas por una esfera ígnea# revelan #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST] = HintText(CustomMessage("They say that #walls consumed by a ball of fire# reveal #[[1]]#.", + /*german*/ "Man erzählt sich, daß #von einem Feuerball verschlungende Wände# #[[1]]# offenbaren würden.", + /*french*/ "Selon moi, le #piège de bois# du Temple de l'Ombre cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #paredes consumidas por una esfera ígnea# revelan #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST] = HintText(CustomMessage("They say that near an #empty pedestal# within the Shadow Temple lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß nahe einem #leeren Sockel# im Schattentempel #[[1]]# läge.", + /*french*/ "Selon moi, #près d'un pédestal vide du Temple de l'Ombre# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, cerca de un #vacío pedestal# del Templo de las Sombras yace #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST] = HintText(CustomMessage("They say that #invisible blades# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #unsichtbare Klingen# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #faucheurs invisibles# du Temple de l'Ombre protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unas #hojas invisibles# guardan #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST] = HintText(CustomMessage("They say that #invisible blades# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #unsichtbare Klingen# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #faucheurs invisibles# du Temple de l'Ombre protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unas #hojas invisibles# guardan #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST] = HintText(CustomMessage("They say that an #invisible chest guarded by the dead# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #von Toten bewachte unsichtbare Truhe# #[[1]]# enthielte.", + /*french*/ "Selon moi, le #trésor invisible du cul-de-sac# du Temple de l'Ombre contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #cofre invisible custodiado por los del más allá# contiene #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST] = HintText(CustomMessage("They say that #mummies guarding a ferry# hide #[[1]]#.", + /*german*/ "Man erzählt sich, daß #eine Fähre bewachende Mumien# #[[1]]# verstecken würden.", + /*french*/ "Selon moi, les #Gibdos qui bloquent le traversier# cachent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #momias que protegen un navío# esconden #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST] = HintText(CustomMessage("They say that #mummies guarding a ferry# hide #[[1]]#.", + /*german*/ "Man erzählt sich, daß #eine Fähre bewachende Mumien# #[[1]]# verstecken würden.", + /*french*/ "Selon moi, les #Gibdos qui bloquent le traversier# cachent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #momias que protegen un navío# esconden #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST] = HintText(CustomMessage("They say that #caged near a ship# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #in der Nähe eines Schiffes eingesperrt# #[[1]]# läge.", + /*french*/ "Selon moi, #dans une cage près du traversier# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #entre rejas al lado de un navío# yace #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_FREESTANDING_KEY] = HintText(CustomMessage("They say that #behind three burning skulls# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #hinter drei brennenden Schädeln# #[[1]]# läge.", + /*french*/ "Selon moi, #derrière trois crânes enflammés# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, tras #tres ardientes calaveras# yace #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_BONGO_BONGO_HEART] = HintText(CustomMessage("They say that #Bongo Bongo# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Bongo Bongo# #[[1]]# besäße.", + /*french*/ "Selon moi, #Bongo Bongo# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #Bongo Bongo# porta #[[1]]#. + {}, { + CustomMessage("They say that the #Phantom Shadow Beast# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Phantomschattenbiest# #[[1]]# besäße.", + /*french*/ "Selon moi, le #monstre de l'ombre# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, la #alimaña oscura espectral# porta #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT] = HintText(CustomMessage("They say that #beyond a burning skull# lies a spider with #[[1]]#.", + /*german*/ "Man erzählt sich, daß #jenseits eines brennenden Schädels# eine Spinne läge, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula derrière un crâne enflammé du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #tras una ardiente calavera# yace una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM] = HintText(CustomMessage("They say that a #spider beyond falling spikes# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne jenseits fallender Stacheln# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au delà de la pluie de clous du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula tras los pinchos del techo# otorga #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT] = HintText(CustomMessage("They say that #beyond three burning skulls# lies a spider with #[[1]]#.", + /*german*/ "Man erzählt sich, daß #jenseits drei brennender Schädel# eine Spinne läge, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula derrière trois crânes enflammés du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #tras tres ardientes calaveras# yace una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM] = HintText(CustomMessage("They say that a spider guarded by #invisible blades# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne von #unsichtbaren Klingen# bewacht werde und #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula protégée par les faucheurs invisibles du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula custodiada por hojas invisibles# otorga #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_GS_NEAR_SHIP] = HintText(CustomMessage("They say that a spider near a #docked ship# hoards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne nahe eines #geankerten Schiffs# #[[1]]# horte.", + /*french*/ "Selon moi, une #Skulltula près du traversier du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula cercana a un navío# otorga #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM] = HintText(CustomMessage("They say that a #spider beyond falling spikes# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne jenseits fallender Stacheln# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au delà de la pluie de clous du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula tras los pinchos del techo# otorga #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM] = HintText(CustomMessage("They say that a #spider amidst roaring winds# in the Shadow Temple holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne inmitten stürmischer Winde# im Schattentempel #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula près des vents du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula entre ventarrones# del Templo de las Sombras otorga #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_GS_AFTER_WIND] = HintText(CustomMessage("They say that a #spider beneath gruesome debris# in the Shadow Temple hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne unterhalb grauenvoller Trümmer# im Schattentempel #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula sous des débris du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula bajo unos horripilantes escombros# del Templo de las Sombras otorga #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP] = HintText(CustomMessage("They say that a #fallen statue# reveals a spider with #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #fallende Statue# eine Spinne enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula près de la statue écroulée du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #estatua caída# revelará una Skulltula que otorgue #[[1]]#. + + hintTextTable[RHT_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS] = HintText(CustomMessage("They say that a #suspended spider# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #hängende Spinne# #[[1]]# bewache.", + /*french*/ "Selon moi, une #Skulltula près du repère du Temple de l'Ombre# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula flotante# del Templo de las Sombras otorga #[[1]]#. /*-------------------------- | BOTTOM OF THE WELL | ---------------------------*/ - hintTable[BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Eye of Truth in the well# reveals", /*french*/"l'#oeil de vérité dans le Puits# révèle", /*spanish*/"el #Ojo de la Verdad en el pozo# revela"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#gruesome debris# in the well hides", /*french*/"des #débris dans le Puits# cachent", /*spanish*/"unos #horripilantes escombros# del pozo esconden"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Eye of Truth in the well# reveals", /*french*/"l'#oeil de vérité dans le Puits# révèle", /*spanish*/"el #Ojo de la Verdad en el pozo# revela"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #hidden entrance to a cage# in the well leads to", /*french*/"dans un #chemin caché dans le Puits# gît", /*spanish*/"la #entrada oculta de una celda# del pozo conduce a"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #spider guarding a cage# in the well protects", /*french*/"l'#araignée dans la cage du Puits# protège", /*spanish*/"una #araña protegiendo una celda# del pozo guarda"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#gruesome debris# in the well hides", /*french*/"des #débris dans le Puits# cachent", /*spanish*/"unos #horripilantes escombros# del pozo esconden"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_INVISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#Dead Hand's invisible secret# is", /*french*/"le #trésor invisible du Poigneur# est", /*spanish*/"el #secreto invisible de la Mano Muerta# esconde"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #royal melody in the well# uncovers", /*french*/"la #mélodie royale révèle dans le Puits#", /*spanish*/"una #melodía real en el pozo# revela"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #royal melody in the well# uncovers", /*french*/"la #mélodie royale révèle dans le Puits#", /*spanish*/"una #melodía real en el pozo# revela"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"in the #depths of the well# lies", /*french*/"#dans le coeur du Puits# gît", /*spanish*/"en las #profundidades del pozo# yace"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#perilous pits# in the well guard the path to", /*french*/"#trois trous# dans le Puits protègent", /*spanish*/"#peligrosos fosos# del pozo conducen a"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#locked in a cage# in the well lies", /*french*/"#dans une cage# du Puits gît", /*spanish*/"#entre rejas# en el pozo yace"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_FREESTANDING_KEY] = HintText::Exclude({ - //obscure text - Text{"#inside a coffin# hides", /*french*/"dans #un cercueil# gît", /*spanish*/"en el #interior de un ataúd# yace"}, - }); - - - hintTable[BOTTOM_OF_THE_WELL_MQ_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #royal melody in the well# uncovers", /*french*/"la #mélodie royale révèle dans le Puits#", /*spanish*/"una #melodía real en el pozo# revela"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST] = HintText::Exclude({ - //obscure text - Text{"an #army of the dead# in the well guards", /*french*/"l'#armée des morts# dans le Puits protège", /*spanish*/"un #ejército del más allá# del pozo guarda"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY] = HintText::Exclude({ - //obscure text - Text{"#Dead Hand's explosive secret# is", /*french*/"le #secret explosif du Poigneur# est", /*spanish*/"el #explosivo secreto de la Mano Muerta# esconde"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY] = HintText::Exclude({ - //obscure text - Text{"an #invisible path in the well# leads to", /*french*/"dans un #chemin caché dans le Puits# gît", /*spanish*/"un #camino invisible del pozo# conduce a"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE] = HintText::Exclude({ - //obscure text - Text{"a #spider locked in a cage# in the well holds", /*french*/"une #Skulltula dans une cage au fonds du Puits# a", /*spanish*/"una #Skulltula enjaulada# del pozo otorga"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM] = HintText::Exclude({ - //obscure text - Text{"an #invisible path in the well# leads to", /*french*/"une #Skulltula dans le chemin invisible au fonds du Puits# a", /*spanish*/"un #camino invisible del pozo# conduce a una Skulltula que otorga"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider locked in a crypt# within the well guards", /*french*/"une #Skulltula embarrée dans la crypte au fonds du Puits# a", /*spanish*/"una #Skulltula encerrada en una cripta# del pozo otorga"}, - }); - - - hintTable[BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT] = HintText::Exclude({ - //obscure text - Text{"a #gauntlet of invisible spiders# protects", /*french*/"une #Skulltula protégée par les araignées invisibles au fonds du Puits# a", /*spanish*/"unas #arañas invisibles# custodian una Skulltula que otorga"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider crawling near the dead# in the well holds", /*french*/"une #Skulltula près des cercueils au fonds du Puits# a", /*spanish*/"una #Skulltula junto a los muertos# del pozo otorga"}, - }); - - hintTable[BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider locked in a crypt# within the well guards", /*french*/"une #Skulltula embarrée dans la crypte au fonds du Puits# a", /*spanish*/"una #Skulltula encerrada en una cripta# del pozo otorga"}, - }); + hintTextTable[RHT_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth in the well# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Auge der Wahrheit im Brunnen# #[[1]]# offenbare.", + /*french*/ "Selon moi, l'#oeil de vérité dans le Puits# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Ojo de la Verdad en el pozo# revela #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST] = HintText(CustomMessage("They say that #gruesome debris# in the well hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß #grauenvolle Trümmer# im Brunnen #[[1]]# verbergen würden.", + /*french*/ "Selon moi, des #débris dans le Puits# cachent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unos #horripilantes escombros# del pozo esconden #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth in the well# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Auge der Wahrheit im Brunnen# #[[1]]# offenbare.", + /*french*/ "Selon moi, l'#oeil de vérité dans le Puits# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Ojo de la Verdad en el pozo# revela #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_COMPASS_CHEST] = HintText(CustomMessage("They say that a #hidden entrance to a cage# in the well leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #verborgener Eingang zu einem Käfig# im Brunnen zu #[[1]]# führe.", + /*french*/ "Selon moi, dans un #chemin caché dans le Puits# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #entrada oculta de una celda# del pozo conduce a #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST] = HintText(CustomMessage("They say that a #spider guarding a cage# in the well protects #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #einen Käfig schützende Spinne# im Brunnen #[[1]]# schütze.", + /*french*/ "Selon moi, l'#araignée dans la cage du Puits# protège #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #araña protegiendo una celda# del pozo guarda #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST] = HintText(CustomMessage("They say that #gruesome debris# in the well hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß #grauenvolle Trümmer# im Brunnen #[[1]]# verbergen würde.", + /*french*/ "Selon moi, des #débris dans le Puits# cachent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unos #horripilantes escombros# del pozo esconden #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST] = HintText(CustomMessage("They say that #Dead Hand's invisible secret# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #unsichtbare Geheimnis der toten Hand# #[[1]]# sei.", + /*french*/ "Selon moi, le #trésor invisible du Poigneur# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #secreto invisible de la Mano Muerta# esconde #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST] = HintText(CustomMessage("They say that a #royal melody in the well# uncovers #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #königliche Melodie im Brunnen# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, la #mélodie royale révèle dans le Puits# #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #melodía real en el pozo# revela #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST] = HintText(CustomMessage("They say that a #royal melody in the well# uncovers #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #königliche Melodie im Brunnen# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, la #mélodie royale révèle dans le Puits# #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #melodía real en el pozo# revela #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MAP_CHEST] = HintText(CustomMessage("They say that in the #depths of the well# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß in den #Tiefen des Brunnens# #[[1]]# läge.", + /*french*/ "Selon moi, #dans le coeur du Puits# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en las #profundidades del pozo# yace #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST] = HintText(CustomMessage("They say that #perilous pits# in the well guard the path to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #gefährliche Gruben# im Brunnen den Pfad zu #[[1]]# bewachen würden.", + /*french*/ "Selon moi, #trois trous# dans le Puits protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #peligrosos fosos# del pozo conducen a #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST] = HintText(CustomMessage("They say that #locked in a cage# in the well lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #in einem Käfig eingeschlossen# im Brunnen #[[1]]# läge.", + /*french*/ "Selon moi, #dans une cage# du Puits gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #entre rejas# en el pozo yace #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_FREESTANDING_KEY] = HintText(CustomMessage("They say that #inside a coffin# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß #in einem Sarg# #[[1]]# verborgen läge.", + /*french*/ "Selon moi, dans #un cercueil# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en el #interior de un ataúd# yace #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST] = HintText(CustomMessage("They say that a #royal melody in the well# uncovers #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #königliche Melodie im Brunnen# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, la #mélodie royale révèle dans le Puits# #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #melodía real en el pozo# revela #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST] = HintText(CustomMessage("They say that an #army of the dead# in the well guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Armee der Toten# im Brunnen #[[1]]# bewachen würde.", + /*french*/ "Selon moi, l'#armée des morts# dans le Puits protège #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #ejército del más allá# del pozo guarda #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY] = HintText(CustomMessage("They say that #Dead Hand's explosive secret# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #explosive Geheimnis der toten Hand# #[[1]]# sei.", + /*french*/ "Selon moi, le #secret explosif du Poigneur# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #explosivo secreto de la Mano Muerta# esconde #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY] = HintText(CustomMessage("They say that an #invisible path in the well# leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #unsichtbarer Pfad im Brunnen# zu #[[1]]# führe.", + /*french*/ "Selon moi, dans un #chemin caché dans le Puits# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #camino invisible del pozo# conduce a #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE] = HintText(CustomMessage("They say that a #spider locked in a cage# in the well holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in einem Käfig eingeschlossene Spinne# im Brunnen #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans une cage au fonds du Puits# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula enjaulada# del pozo otorga #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM] = HintText(CustomMessage("They say that an #invisible path in the well# leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #unsichtbarer Pfad im Brunnen# zu #[[1]]# führe.", + /*french*/ "Selon moi, une #Skulltula dans le chemin invisible au fonds du Puits# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #camino invisible del pozo# conduce a una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM] = HintText(CustomMessage("They say that a #spider locked in a crypt# within the well guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in einer Krypta eingeschlossene Spinne# im Brunnen #[[1]]# bewache.", + /*french*/ "Selon moi, une #Skulltula embarrée dans la crypte au fonds du Puits# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula encerrada en una cripta# del pozo otorga #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT] = HintText(CustomMessage("They say that a #gauntlet of invisible spiders# protects #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Herausforderung unsichtbarer Spinnen# #[[1]]# bewache.", + /*french*/ "Selon moi, une #Skulltula protégée par les araignées invisibles au fonds du Puits# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unas #arañas invisibles# custodian una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM] = HintText(CustomMessage("They say that a #spider crawling near the dead# in the well holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #nahe der Toten kriechende Spinne# im Brunnen #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula près des cercueils au fonds du Puits# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula junto a los muertos# del pozo otorga #[[1]]#. + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM] = HintText(CustomMessage("They say that a #spider locked in a crypt# within the well guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in einer Krypta eingeschlossene Spinne# im Brunnen #[[1]]# bewache.", + /*french*/ "Selon moi, une #Skulltula embarrée dans la crypte au fonds du Puits# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula encerrada en una cripta# del pozo otorga #[[1]]#. /*-------------------------- | ICE CAVERN | ---------------------------*/ - hintTable[ICE_CAVERN_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"#winds of ice# surround", /*french*/"#figé dans la glace rouge# gît", /*spanish*/"#heladas borrascas# rodean"}, - }); - - hintTable[ICE_CAVERN_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #wall of ice# protects", /*french*/"#un mur de glace rouge# cache", /*spanish*/"una #gélida pared# protege"}, - }); - - hintTable[ICE_CAVERN_IRON_BOOTS_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #monster in a frozen cavern# guards", /*french*/"le #monstre de la caverne de glace# protège", /*spanish*/"un #monstruo de una helada caverna# guarda"}, - }); - - hintTable[ICE_CAVERN_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"a #wall of ice# protects", /*french*/"un #mur de glace rouge# cache", /*spanish*/"una #gélida pared# protege"}, - }); - - - hintTable[ICE_CAVERN_MQ_IRON_BOOTS_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #monster in a frozen cavern# guards", /*french*/"le #monstre de la caverne de glace# protège", /*spanish*/"un #monstruo de una helada caverna# guarda"}, - }); - - hintTable[ICE_CAVERN_MQ_COMPASS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#winds of ice# surround", /*french*/"#entouré de vent glacial# gît", /*spanish*/"#heladas borrascas# rodean"}, - }); - - hintTable[ICE_CAVERN_MQ_MAP_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #wall of ice# protects", /*french*/"#un mur de glace rouge# cache", /*spanish*/"una #gélida pared# protege"}, - }); - - hintTable[ICE_CAVERN_MQ_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"#winds of ice# surround", /*french*/"#entouré de vent glacial# gît", /*spanish*/"#heladas borrascas# rodean"}, - }); - - hintTable[ICE_CAVERN_GS_PUSH_BLOCK_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider above icy pits# holds", /*french*/"une #Skulltula au dessus d'un goufre glacial# a", /*spanish*/"una #Skulltula sobre gélidos vacíos# otorga"}, - }); - - hintTable[ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM] = HintText::Exclude({ - //obscure text - Text{"#spinning ice# guards a spider holding", /*french*/"une #Skulltula près de deux lames de glace# a", /*spanish*/"unos #témpanos giratorios# custodian una Skulltula que otorga"}, - }); - - hintTable[ICE_CAVERN_GS_HEART_PIECE_ROOM] = HintText::Exclude({ - //obscure text - Text{"a #spider behind a wall of ice# hides", /*french*/"une #Skulltula derrière un mur de glace# a", /*spanish*/"una #Skulltula tras una gélida pared# otorga"}, - }); - - - hintTable[ICE_CAVERN_MQ_GS_SCARECROW] = HintText::Exclude({ - //obscure text - Text{"a #spider above icy pits# holds", /*french*/"une #Skulltula au dessus d'un goufre glacial# a", /*spanish*/"una #Skulltula sobre gélidos vacíos# otorga"}, - }); - - hintTable[ICE_CAVERN_MQ_GS_ICE_BLOCK] = HintText::Exclude({ - //obscure text - Text{"a #web of ice# surrounds a spider with", /*french*/"une #Skulltula protégée d'une toile glacée# a", /*spanish*/"una #gélida red# rodea a una Skulltula que otorga"}, - }); - - hintTable[ICE_CAVERN_MQ_GS_RED_ICE] = HintText::Exclude({ - //obscure text - Text{"a #spider in fiery ice# hoards", /*french*/"une #Skulltula figée dans la glace rouge# a", /*spanish*/"una #Skulltula tras un ardiente hielo# otorga"}, - }); + hintTextTable[RHT_ICE_CAVERN_MAP_CHEST] = HintText(CustomMessage("They say that #winds of ice# surround #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Eiswinde# #[[1]]# umgeben würden.", + /*french*/ "Selon moi, #figé dans la glace rouge# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #heladas borrascas# rodean #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_COMPASS_CHEST] = HintText(CustomMessage("They say that a #wall of ice# protects #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Eiswand# #[[1]]# schütze.", + /*french*/ "Selon moi, #un mur de glace rouge# cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #gélida pared# protege #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_IRON_BOOTS_CHEST] = HintText(CustomMessage("They say that a #monster in a frozen cavern# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Monster in einer gefrorenen Kaverne# #[[1]]# bewache.", + /*french*/ "Selon moi, le #monstre de la caverne de glace# protège #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #monstruo de una helada caverna# guarda #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_FREESTANDING_POH] = HintText(CustomMessage("They say that a #wall of ice# protects #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Eiswand# #[[1]]# schütze.", + /*french*/ "Selon moi, un #mur de glace rouge# cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #gélida pared# protege #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_MQ_IRON_BOOTS_CHEST] = HintText(CustomMessage("They say that a #monster in a frozen cavern# guards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Monster in einer gefrorenen Kaverne# #[[1]]# bewache.", + /*french*/ "Selon moi, le #monstre de la caverne de glace# protège #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #monstruo de una helada caverna# guarda #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_MQ_COMPASS_CHEST] = HintText(CustomMessage("They say that #winds of ice# surround #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Eiswinde# #[[1]]# umgeben würden.", + /*french*/ "Selon moi, #entouré de vent glacial# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #heladas borrascas# rodean #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_MQ_MAP_CHEST] = HintText(CustomMessage("They say that a #wall of ice# protects #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Eiswand# #[[1]]# schütze.", + /*french*/ "Selon moi, #un mur de glace rouge# cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #gélida pared# protege #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_MQ_FREESTANDING_POH] = HintText(CustomMessage("They say that #winds of ice# surround #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Eiswinde# #[[1]]# umgeben würden.", + /*french*/ "Selon moi, #entouré de vent glacial# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #heladas borrascas# rodean #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_GS_PUSH_BLOCK_ROOM] = HintText(CustomMessage("They say that a #spider above icy pits# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne oberhalb eisiger Gruben# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au dessus d'un goufre glacial# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula sobre gélidos vacíos# otorga #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM] = HintText(CustomMessage("They say that #spinning ice# guards a spider holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß #rotierendes Eis# eine Spinne beschütze, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula près de deux lames de glace# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unos #témpanos giratorios# custodian una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_GS_HEART_PIECE_ROOM] = HintText(CustomMessage("They say that a #spider behind a wall of ice# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne hinter einer Eiswand# #[[1]]# verstecke.", + /*french*/ "Selon moi, une #Skulltula derrière un mur de glace# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula tras una gélida pared# otorga #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_MQ_GS_SCARECROW] = HintText(CustomMessage("They say that a #spider above icy pits# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne oberhalb eisiger Gruben# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au dessus d'un goufre glacial# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula sobre gélidos vacíos# otorga #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_MQ_GS_ICE_BLOCK] = HintText(CustomMessage("They say that a #web of ice# surrounds a spider with #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Webe aus Eis# eine Spinne umgebe, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula protégée d'une toile glacée# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #gélida red# rodea a una Skulltula que otorga #[[1]]#. + + hintTextTable[RHT_ICE_CAVERN_MQ_GS_RED_ICE] = HintText(CustomMessage("They say that a #spider in fiery ice# hoards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne in feurigem Eis# #[[1]]# horte.", + /*french*/ "Selon moi, une #Skulltula figée dans la glace rouge# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula tras un ardiente hielo# otorga #[[1]]#. /*-------------------------- | GERUDO TRAINING GROUNDS | ---------------------------*/ - hintTable[GERUDO_TRAINING_GROUNDS_LOBBY_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #blinded eye in the Gerudo Training Grounds# drops", /*french*/"l'#Oeil dans le Gymnase Gerudo# voit", /*spanish*/"#cegar un ojo en el Centro de Instrucción Gerudo# revela"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_LOBBY_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #blinded eye in the Gerudo Training Grounds# drops", /*french*/"l'#Oeil dans le Gymnase Gerudo# voit", /*spanish*/"#cegar un ojo en el Centro de Instrucción Gerudo# revela"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_STALFOS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#soldiers walking on shifting sands# in the Gerudo Training Grounds guard", /*french*/"les #squelettes# du Gymnase Gerudo protègent", /*spanish*/"#soldados en resbaladizas arenas# del Centro de Instrucción Gerudo protegen"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_BEAMOS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#reptilian warriors# in the Gerudo Training Grounds protect", /*french*/"les #lézards# dans le Gymnase Gerudo protègent", /*spanish*/"#unos escamosos guerreros# del Centro de Instrucción Gerudo protegen"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_HIDDEN_CEILING_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Eye of Truth# in the Gerudo Training Grounds reveals", /*french*/"#bien caché# dans le Gymnase Gerudo gît", /*spanish*/"el #Ojo de la Verdad# en el Centro de Instrucción Gerudo revela"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MAZE_PATH_FIRST_CHEST] = HintText::Exclude({ - //obscure text - Text{"the first prize of #the thieves' training# is", /*french*/"le #premier trésor du Gymnase Gerudo# est", /*spanish*/"el primer premio de la #instrucción bandida# se trata de"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MAZE_PATH_SECOND_CHEST] = HintText::Exclude({ - //obscure text - Text{"the second prize of #the thieves' training# is", /*french*/"le #deuxième trésor du Gymnase Gerudo# est", /*spanish*/"el segundo premio de la #instrucción bandida# se trata de"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MAZE_PATH_THIRD_CHEST] = HintText::Exclude({ - //obscure text - Text{"the third prize of #the thieves' training# is", /*french*/"le #troisième trésor du Gymnase Gerudo# est", /*spanish*/"el tercer premio de la #instrucción bandida# se trata de"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_CENTRAL_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Song of Time# in the Gerudo Training Grounds leads to", /*french*/"le #chant du temps# révèle dans le Gymnase Gerudo", /*spanish*/"la #Canción del Tiempo# en el Centro de Instrucción Gerudo conduce a"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_SIDE_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Song of Time# in the Gerudo Training Grounds leads to", /*french*/"le #chant du temps# révèle dans le Gymnase Gerudo", /*spanish*/"la #Canción del Tiempo# en el Centro de Instrucción Gerudo conduce a"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_CLEAR_CHEST] = HintText::Exclude({ - //obscure text - Text{"#fiery foes# in the Gerudo Training Grounds guard", /*french*/"les #limaces de feu# du Gymnase Gerudo protègent", /*spanish*/"unos #flamígeros enemigos# del Centro de Instrucción Gerudo guardan"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_SWITCH_CHEST] = HintText::Exclude({ - //obscure text - Text{"#engulfed in flame# where thieves train lies", /*french*/"le #trésor enflammé# du Gymnase Gerudo est", /*spanish*/"donde entrenan las bandidas #entre llamas# yace"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_EYE_STATUE_CHEST] = HintText::Exclude({ - //obscure text - Text{"thieves #blind four faces# to find", /*french*/"l'#épreuve d'archerie# du Gymnase Gerudo donne", /*spanish*/"las bandidas #ciegan cuatro bustos# para hallar"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_NEAR_SCARECROW_CHEST] = HintText::Exclude({ - //obscure text - Text{"thieves #blind four faces# to find", /*french*/"l'#épreuve d'archerie# du Gymnase Gerudo donne", /*spanish*/"las bandidas #ciegan cuatro bustos# para hallar"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_BEFORE_HEAVY_BLOCK_CHEST] = HintText::Exclude({ - //obscure text - Text{"#before a block of silver# thieves can find", /*french*/"#près d'un bloc argent# dans le Gymnase Gerudo gît", /*spanish*/"#ante un plateado bloque# las bandidas hallan"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FIRST_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #feat of strength# rewards thieves with", /*french*/"#derrière un bloc argent# dans le Gymnase Gerudo gît", /*spanish*/"una #hazaña de fuerza# premia a las bandidas con"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_SECOND_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #feat of strength# rewards thieves with", /*french*/"#derrière un bloc argent# dans le Gymnase Gerudo gît", /*spanish*/"una #hazaña de fuerza# premia a las bandidas con"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_THIRD_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #feat of strength# rewards thieves with", /*french*/"#derrière un bloc argent# dans le Gymnase Gerudo gît", /*spanish*/"una #hazaña de fuerza# premia a las bandidas con"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FOURTH_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #feat of strength# rewards thieves with", /*french*/"#derrière un bloc argent# dans le Gymnase Gerudo gît", /*spanish*/"una #hazaña de fuerza# premia a las bandidas con"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_FREESTANDING_KEY] = HintText::Exclude({ - //obscure text - Text{"the #Song of Time# in the Gerudo Training Grounds leads to", /*french*/"le #chant du temps# révèle dans le Gymnase Gerudo", /*spanish*/"la #Canción del Tiempo# en el Centro de Instrucción Gerudo conduce a"}, - }); - - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_LOBBY_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#thieves prepare for training# with", /*french*/"dans #l'entrée du Gymnase Gerudo# gît", /*spanish*/"las #bandidas se instruyen# con"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_LOBBY_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#thieves prepare for training# with", /*french*/"dans #l'entrée du Gymnase Gerudo# gît", /*spanish*/"las #bandidas se instruyen# con"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_FIRST_IRON_KNUCKLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#soldiers walking on shifting sands# in the Gerudo Training Grounds guard", /*french*/"les #squelettes# du Gymnase Gerudo protègent", /*spanish*/"#soldados en resbaladizas arenas# del Centro de Instrucción Gerudo protegen"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_BEFORE_HEAVY_BLOCK_CHEST] = HintText::Exclude({ - //obscure text - Text{"#before a block of silver# thieves can find", /*french*/"#près d'un bloc argent# dans le Gymnase Gerudo gît", /*spanish*/"#ante un plateado bloque# las bandidas hallan"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_EYE_STATUE_CHEST] = HintText::Exclude({ - //obscure text - Text{"thieves #blind four faces# to find", /*french*/"l'#épreuve d'archerie# du Gymnase Gerudo donne", /*spanish*/"las bandidas #ciegan cuatro bustos# para hallar"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_FLAME_CIRCLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#engulfed in flame# where thieves train lies", /*french*/"le #trésor enflammé# du Gymnase Gerudo est", /*spanish*/"donde entrenan las bandidas #entre llamas# yace"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_SECOND_IRON_KNUCKLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#fiery foes# in the Gerudo Training Grounds guard", /*french*/"les #ennemis de feu# du Gymnase Gerudo protègent", /*spanish*/"unos #flamígeros enemigos# del Centro de Instrucción Gerudo guardan"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_DINOLFOS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#reptilian warriors# in the Gerudo Training Grounds protect", /*french*/"les #lézards# dans le Gymnase Gerudo protègent", /*spanish*/"#unos escamosos guerreros# del Centro de Instrucción Gerudo protegen"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_CENTRAL_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #path of fire# leads thieves to", /*french*/"dans le #chemin enflammé# dans le Gymnase Gerudo gît", /*spanish*/"un #camino de fuego# conduce a las bandidas a"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_FIRST_CHEST] = HintText::Exclude({ - //obscure text - Text{"the first prize of #the thieves' training# is", /*french*/"le #premier trésor du Gymnase Gerudo# est", /*spanish*/"el primer premio de la #instrucción bandida# se trata de"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_SIDE_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #path of fire# leads thieves to", /*french*/"dans le #chemin enflammé# dans le Gymnase Gerudo gît", /*spanish*/"un #camino de fuego# conduce a las bandidas a"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_THIRD_CHEST] = HintText::Exclude({ - //obscure text - Text{"the third prize of #the thieves' training# is", /*french*/"le #troisième trésor du Gymnase Gerudo# est", /*spanish*/"el tercer premio de la #instrucción bandida# se trata de"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_SECOND_CHEST] = HintText::Exclude({ - //obscure text - Text{"the second prize of #the thieves' training# is", /*french*/"le #deuxième trésor du Gymnase Gerudo# est", /*spanish*/"el segundo premio de la #instrucción bandida# se trata de"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_HIDDEN_CEILING_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Eye of Truth# in the Gerudo Training Grounds reveals", /*french*/"#bien caché# dans le Gymnase Gerudo gît", /*spanish*/"el #Ojo de la Verdad# en el Centro de Instrucción Gerudo revela"}, - }); - - hintTable[GERUDO_TRAINING_GROUNDS_MQ_HEAVY_BLOCK_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #feat of strength# rewards thieves with", /*french*/"#derrière un bloc argent# dans le Gymnase Gerudo gît", /*spanish*/"una #hazaña de fuerza# premia a las bandidas con"}, - }); + hintTextTable[RHT_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST] = HintText(CustomMessage("They say that a #blinded eye in the Gerudo Training Grounds# drops #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #erblindetes Auge in der Gerudo-Trainingsarena# #[[1]]# fallen ließe.", + /*french*/ "Selon moi, l'#Oeil dans le Gymnase Gerudo# voit #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #cegar un ojo en el Centro de Instrucción Gerudo# revela #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST] = HintText(CustomMessage("They say that a #blinded eye in the Gerudo Training Grounds# drops #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #erblindetes Auge in der Gerudo-Trainingsarena# #[[1]]# fallen ließe.", + /*french*/ "Selon moi, l'#Oeil dans le Gymnase Gerudo# voit #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #cegar un ojo en el Centro de Instrucción Gerudo# revela #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_STALFOS_CHEST] = HintText(CustomMessage("They say that #soldiers walking on shifting sands# in the Gerudo Training Grounds guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #auf veränderlichen Sanden laufende Soldaten# in der Gerudo-Trainingsarena #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #squelettes# du Gymnase Gerudo protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #soldados en resbaladizas arenas# del Centro de Instrucción Gerudo protegen #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_BEAMOS_CHEST] = HintText(CustomMessage("They say that #reptilian warriors# in the Gerudo Training Grounds protect #[[1]]#.", + /*german*/ "Man erzählt sich, daß #reptilienartige Krieger# in der Gerudo-Trainingsarena #[[1]]# schützen würden.", + /*french*/ "Selon moi, les #lézards# dans le Gymnase Gerudo protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #unos escamosos guerreros# del Centro de Instrucción Gerudo protegen #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth# in the Gerudo Training Grounds reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Auge der Wahrheit# in der Gerudo-Trainingsarena #[[1]]# enthülle.", + /*french*/ "Selon moi, #bien caché# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Ojo de la Verdad# en el Centro de Instrucción Gerudo revela #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST] = HintText(CustomMessage("They say that the first prize of #the thieves' training# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der erste Preis des #Diebestrainings# #[[1]]# sei.", + /*french*/ "Selon moi, le #premier trésor du Gymnase Gerudo# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el primer premio de la #instrucción bandida# se trata de #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST] = HintText(CustomMessage("They say that the second prize of #the thieves' training# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der zweite Preis des #Diebestrainings# #[[1]]# sei.", + /*french*/ "Selon moi, le #deuxième trésor du Gymnase Gerudo# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el segundo premio de la #instrucción bandida# se trata de #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST] = HintText(CustomMessage("They say that the third prize of #the thieves' training# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der dritte Preis des #Diebestrainings# #[[1]]# sei.", + /*french*/ "Selon moi, le #troisième trésor du Gymnase Gerudo# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el tercer premio de la #instrucción bandida# se trata de #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST] = HintText(CustomMessage("They say that the #Song of Time# in the Gerudo Training Grounds leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Hymne der Zeit# in der Gerudo-Trainingsarena zu #[[1]]# führe.", + /*french*/ "Selon moi, le #chant du temps# révèle dans le Gymnase Gerudo #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #Canción del Tiempo# en el Centro de Instrucción Gerudo conduce a #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST] = HintText(CustomMessage("They say that the #Song of Time# in the Gerudo Training Grounds leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Hymne der Zeit# in der Gerudo-Trainingsarena zu #[[1]]# führe.", + /*french*/ "Selon moi, le #chant du temps# révèle dans le Gymnase Gerudo #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #Canción del Tiempo# en el Centro de Instrucción Gerudo conduce a #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST] = HintText(CustomMessage("They say that #fiery foes# in the Gerudo Training Grounds guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #feurige Feinde# in der Gerudo-Trainingsarena #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #limaces de feu# du Gymnase Gerudo protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unos #flamígeros enemigos# del Centro de Instrucción Gerudo guardan #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST] = HintText(CustomMessage("They say that #engulfed in flame# where thieves train lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #von Flammen umschlungen# wo Diebe trainieren #[[1]]# läge.", + /*french*/ "Selon moi, le #trésor enflammé# du Gymnase Gerudo est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, donde entrenan las bandidas #entre llamas# yace #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST] = HintText(CustomMessage("They say that thieves #blind four faces# to find #[[1]]#.", + /*german*/ "Man erzählt sich, daß Diebe #vier Gesichter erblinden# würden und #[[1]]# fänden.", + /*french*/ "Selon moi, l'#épreuve d'archerie# du Gymnase Gerudo donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las bandidas #ciegan cuatro bustos# para hallar #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST] = HintText(CustomMessage("They say that thieves #blind four faces# to find #[[1]]#.", + /*german*/ "Man erzählt sich, daß Diebe #vier Gesichter erblinden# würden und #[[1]]# fänden.", + /*french*/ "Selon moi, l'#épreuve d'archerie# du Gymnase Gerudo donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las bandidas #ciegan cuatro bustos# para hallar #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST] = HintText(CustomMessage("They say that #before a block of silver# thieves can find #[[1]]#.", + /*german*/ "Man erzählt sich, daß #vor einem Block aus Silber# Diebe #[[1]]# finden könnten.", + /*french*/ "Selon moi, #près d'un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #ante un plateado bloque# las bandidas hallan #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST] = HintText(CustomMessage("They say that a #feat of strength# rewards thieves with #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Meisterstück der Stärke# Diebe mit #[[1]]# belohnen würde.", + /*french*/ "Selon moi, #derrière un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #hazaña de fuerza# premia a las bandidas con #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST] = HintText(CustomMessage("They say that a #feat of strength# rewards thieves with #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Meisterstück der Stärke# Diebe mit #[[1]]# belohnen würde.", + /*french*/ "Selon moi, #derrière un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #hazaña de fuerza# premia a las bandidas con #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST] = HintText(CustomMessage("They say that a #feat of strength# rewards thieves with #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Meisterstück der Stärke# Diebe mit #[[1]]# belohnen würde.", + /*french*/ "Selon moi, #derrière un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #hazaña de fuerza# premia a las bandidas con #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST] = HintText(CustomMessage("They say that a #feat of strength# rewards thieves with #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Meisterstück der Stärke# Diebe mit #[[1]]# belohnen würde.", + /*french*/ "Selon moi, #derrière un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #hazaña de fuerza# premia a las bandidas con #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_FREESTANDING_KEY] = HintText(CustomMessage("They say that the #Song of Time# in the Gerudo Training Grounds leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Hymne der Zeit# in der Gerudo-Trainingsarena zu #[[1]]# führe.", + /*french*/ "Selon moi, le #chant du temps# révèle dans le Gymnase Gerudo #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #Canción del Tiempo# en el Centro de Instrucción Gerudo conduce a #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST] = HintText(CustomMessage("They say that #thieves prepare for training# with #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich #Diebe auf das Training vorbereiteten# mit #[[1]]#.", + /*french*/ "Selon moi, dans #l'entrée du Gymnase Gerudo# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #bandidas se instruyen# con #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST] = HintText(CustomMessage("They say that #thieves prepare for training# with #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich #Diebe auf das Training vorbereiteten# mit #[[1]]#.", + /*french*/ "Selon moi, dans #l'entrée du Gymnase Gerudo# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #bandidas se instruyen# con #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST] = HintText(CustomMessage("They say that #soldiers walking on shifting sands# in the Gerudo Training Grounds guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #auf veränderlichen Sanden laufende Soldaten# in der Gerudo-Trainingsarena #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #squelettes# du Gymnase Gerudo protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #soldados en resbaladizas arenas# del Centro de Instrucción Gerudo protegen #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST] = HintText(CustomMessage("They say that #before a block of silver# thieves can find #[[1]]#.", + /*german*/ "Man erzählt sich, daß #vor einem Block aus Silber# Diebe #[[1]]# finden könnten.", + /*french*/ "Selon moi, #près d'un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #ante un plateado bloque# las bandidas hallan #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST] = HintText(CustomMessage("They say that thieves #blind four faces# to find #[[1]]#.", + /*german*/ "Man erzählt sich, daß Diebe #vier Gesichter erblinden# würden und #[[1]]# fänden.", + /*french*/ "Selon moi, l'#épreuve d'archerie# du Gymnase Gerudo donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las bandidas #ciegan cuatro bustos# para hallar #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST] = HintText(CustomMessage("They say that #engulfed in flame# where thieves train lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #von Flammen umschlungen# wo Diebe trainieren #[[1]]# läge.", + /*french*/ "Selon moi, le #trésor enflammé# du Gymnase Gerudo est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, donde entrenan las bandidas #entre llamas# yace #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST] = HintText(CustomMessage("They say that #fiery foes# in the Gerudo Training Grounds guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß #feurige Feinde# in der Gerudo-Trainingsarena #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #ennemis de feu# du Gymnase Gerudo protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unos #flamígeros enemigos# del Centro de Instrucción Gerudo guardan #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST] = HintText(CustomMessage("They say that #reptilian warriors# in the Gerudo Training Grounds protect #[[1]]#.", + /*german*/ "Man erzählt sich, daß #reptilienartige Krieger# in der Gerudo-Trainingsarena #[[1]]# schützen würden.", + /*french*/ "Selon moi, les #lézards# dans le Gymnase Gerudo protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #unos escamosos guerreros# del Centro de Instrucción Gerudo protegen #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST] = HintText(CustomMessage("They say that a #path of fire# leads thieves to #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Pfad des Feuers# Diebe zu #[[1]]# führe.", + /*french*/ "Selon moi, dans le #chemin enflammé# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #camino de fuego# conduce a las bandidas a #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST] = HintText(CustomMessage("They say that the first prize of #the thieves' training# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der erste Preis des #Diebestrainings# #[[1]]# sei.", + /*french*/ "Selon moi, le #premier trésor du Gymnase Gerudo# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el primer premio de la #instrucción bandida# se trata de #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST] = HintText(CustomMessage("They say that a #path of fire# leads thieves to #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Pfad des Feuers# Diebe zu #[[1]]# führe.", + /*french*/ "Selon moi, dans le #chemin enflammé# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #camino de fuego# conduce a las bandidas a #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST] = HintText(CustomMessage("They say that the third prize of #the thieves' training# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der dritte Preis des #Diebestrainings# #[[1]]# sei.", + /*french*/ "Selon moi, le #troisième trésor du Gymnase Gerudo# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el tercer premio de la #instrucción bandida# se trata de #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST] = HintText(CustomMessage("They say that the second prize of #the thieves' training# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der zweite Preis des #Diebestrainings# #[[1]]# sei.", + /*french*/ "Selon moi, le #deuxième trésor du Gymnase Gerudo# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el segundo premio de la #instrucción bandida# se trata de #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth# in the Gerudo Training Grounds reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Auge der Wahrheit# in der Gerudo-Trainingsarena #[[1]]# enthülle.", + /*french*/ "Selon moi, #bien caché# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Ojo de la Verdad# en el Centro de Instrucción Gerudo revela #[[1]]#. + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST] = HintText(CustomMessage("They say that a #feat of strength# rewards thieves with #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Meisterstück der Stärke# Diebe mit #[[1]]# belohnen würde.", + /*french*/ "Selon moi, #derrière un bloc argent# dans le Gymnase Gerudo gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #hazaña de fuerza# premia a las bandidas con #[[1]]#. /*-------------------------- | GANONS CASTLE | ---------------------------*/ - hintTable[GANONS_TOWER_BOSS_KEY_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #Evil King# hoards", /*french*/"le #Roi du Mal# possède", /*spanish*/"el #Rey del Mal# acapara"}, - }); - - - hintTable[GANONS_CASTLE_FOREST_TRIAL_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of the wilds# holds", /*french*/"l'#épreuve des bois# contient", /*spanish*/"la #prueba de la naturaleza# brinda"}, - }); - - hintTable[GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of the seas# holds", /*french*/"l'#épreuve des mers# contient", /*spanish*/"la #prueba del mar# brinda"}, - }); - - hintTable[GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of the seas# holds", /*french*/"l'#épreuve des mers# contient", /*spanish*/"la #prueba del mar# brinda"}, - }); - - hintTable[GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#music in the test of darkness# unveils", /*french*/"la #musique dans l'épreuve des ténèbres# révèle", /*spanish*/"la #música en la prueba de la oscuridad# revela"}, - }); - - hintTable[GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#light in the test of darkness# unveils", /*french*/"la #lumière dans l'épreuve des ténèbres# révèle", /*spanish*/"la #luz en la prueba de la oscuridad# revela"}, - }); - - hintTable[GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of the sands# holds", /*french*/"l'#épreuve des sables# contient", /*spanish*/"la #prueba de las arenas# brinda"}, - }); - - hintTable[GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of the sands# holds", /*french*/"l'#épreuve des sables# contient", /*spanish*/"la #prueba de las arenas# brinda"}, - }); - - hintTable[GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of radiance# holds", /*french*/"l'#épreuve du ciel# contient", /*spanish*/"la #prueba del resplandor# brinda"}, - }); - - hintTable[GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of radiance# holds", /*french*/"l'#épreuve du ciel# contient", /*spanish*/"la #prueba del resplandor# brinda"}, - }); - - hintTable[GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of radiance# holds", /*french*/"l'#épreuve du ciel# contient", /*spanish*/"la #prueba del resplandor# brinda"}, - }); - - hintTable[GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of radiance# holds", /*french*/"l'#épreuve du ciel# contient", /*spanish*/"la #prueba del resplandor# brinda"}, - }); - - hintTable[GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of radiance# holds", /*french*/"l'#épreuve du ciel# contient", /*spanish*/"la #prueba del resplandor# brinda"}, - }); - - hintTable[GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of radiance# holds", /*french*/"l'#épreuve du ciel# contient", /*spanish*/"la #prueba del resplandor# brinda"}, - }); - - hintTable[GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of radiance# holds", /*french*/"l'#épreuve du ciel# contient", /*spanish*/"la #prueba del resplandor# brinda"}, - }); - - hintTable[GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST] = HintText::Exclude({ - //obscure text - Text{"#music in the test of radiance# reveals", /*french*/"la #musique dans l'épreuve du ciel# révèle", /*spanish*/"la #música en la prueba del resplandor# revela"}, - }); - - - hintTable[GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of the seas# holds", /*french*/"l'#épreuve des mers# contient", /*spanish*/"la #prueba del mar# brinda"}, - }); - - hintTable[GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of the wilds# holds", /*french*/"l'#épreuve des bois# contient", /*spanish*/"la #prueba de la naturaleza# brinda"}, - }); - - hintTable[GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of the wilds# holds", /*french*/"l'#épreuve des bois# contient", /*spanish*/"la #prueba de la naturaleza# brinda"}, - }); - - hintTable[GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST] = HintText::Exclude({ - //obscure text - Text{"#music in the test of radiance# reveals", /*french*/"la #musique dans l'épreuve du ciel# révèle", /*spanish*/"la #música en la prueba del resplandor# revela"}, - }); - - hintTable[GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of darkness# holds", /*french*/"l'#épreuve des ténèbres# contient", /*spanish*/"la #prueba de la oscuridad# brinda"}, - }); - - hintTable[GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #test of darkness# holds", /*french*/"l'#épreuve des ténèbres# contient", /*spanish*/"la #prueba de la oscuridad# brinda"}, - }); - - hintTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST] = HintText::Exclude({ - //obscure text - Text{"#reflected light in the test of the sands# reveals", /*french*/"le #soleil dans l'épreuve des sables# révèle", /*spanish*/"#reflejar la luz en la prueba de las arenas# revela"}, - }); - - hintTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#reflected light in the test of the sands# reveals", /*french*/"le #soleil dans l'épreuve des sables# révèle", /*spanish*/"#reflejar la luz en la prueba de las arenas# revela"}, - }); - - hintTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#reflected light in the test of the sands# reveals", /*french*/"le #soleil dans l'épreuve des sables# révèle", /*spanish*/"#reflejar la luz en la prueba de las arenas# revela"}, - }); - - hintTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"#reflected light in the test of the sands# reveals", /*french*/"le #soleil dans l'épreuve des sables# révèle", /*spanish*/"#reflejar la luz en la prueba de las arenas# revela"}, - }); - - hintTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST] = HintText::Exclude({ - //obscure text - Text{"#reflected light in the test of the sands# reveals", /*french*/"le #soleil dans l'épreuve des sables# révèle", /*spanish*/"#reflejar la luz en la prueba de las arenas# revela"}, - }); - - hintTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST] = HintText::Exclude({ - //obscure text - Text{"#reflected light in the test of the sands# reveals", /*french*/"le #soleil dans l'épreuve des sables# révèle", /*spanish*/"#reflejar la luz en la prueba de las arenas# revela"}, - }); - - hintTable[GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY] = HintText::Exclude({ - //obscure text - Text{"the #test of the wilds# holds", /*french*/"l'#épreuve des bois# révèle", /*spanish*/"la #prueba de la naturaleza# brinda"}, - }); - - hintTable[GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = HintText::Exclude({ - //obscure text - Text{"#scrubs in Ganon's Castle# sell", /*french*/"les #pestes Mojo dans le Château de Ganon# vendent", /*spanish*/"los #dekus del Castillo de Ganon# venden"}, - }); - - hintTable[GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = HintText::Exclude({ - //obscure text - Text{"#scrubs in Ganon's Castle# sell", /*french*/"les #pestes Mojo dans le Château de Ganon# vendent", /*spanish*/"los #dekus del Castillo de Ganon# venden"}, - }); - - hintTable[GANONS_CASTLE_DEKU_SCRUB_RIGHT] = HintText::Exclude({ - //obscure text - Text{"#scrubs in Ganon's Castle# sell", /*french*/"les #pestes Mojo dans le Château de Ganon# vendent", /*spanish*/"los #dekus del Castillo de Ganon# venden"}, - }); - - hintTable[GANONS_CASTLE_DEKU_SCRUB_LEFT] = HintText::Exclude({ - //obscure text - Text{"#scrubs in Ganon's Castle# sell", /*french*/"les #pestes Mojo dans le Château de Ganon# vendent", /*spanish*/"los #dekus del Castillo de Ganon# venden"}, - }); - - - hintTable[GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = HintText::Exclude({ - //obscure text - Text{"#scrubs in Ganon's Castle# sell", /*french*/"les #pestes Mojo dans le Château de Ganon# vendent", /*spanish*/"los #dekus del Castillo de Ganon# venden"}, - }); - - hintTable[GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = HintText::Exclude({ - //obscure text - Text{"#scrubs in Ganon's Castle# sell", /*french*/"les #pestes Mojo dans le Château de Ganon# vendent", /*spanish*/"los #dekus del Castillo de Ganon# venden"}, - }); - - hintTable[GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = HintText::Exclude({ - //obscure text - Text{"#scrubs in Ganon's Castle# sell", /*french*/"les #pestes Mojo dans le Château de Ganon# vendent", /*spanish*/"los #dekus del Castillo de Ganon# venden"}, - }); - - hintTable[GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = HintText::Exclude({ - //obscure text - Text{"#scrubs in Ganon's Castle# sell", /*french*/"les #pestes Mojo dans le Château de Ganon# vendent", /*spanish*/"los #dekus del Castillo de Ganon# venden"}, - }); - - hintTable[GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = HintText::Exclude({ - //obscure text - Text{"#scrubs in Ganon's Castle# sell", /*french*/"les #pestes Mojo dans le Château de Ganon# vendent", /*spanish*/"los #dekus del Castillo de Ganon# venden"}, - }); + hintTextTable[RHT_GANONS_TOWER_BOSS_KEY_CHEST] = HintText(CustomMessage("They say that the #Evil King# hoards #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #böse König# #[[1]]# horte.", + /*french*/ "Selon moi, le #Roi du Mal# possède #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #Rey del Mal# acapara #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_FOREST_TRIAL_CHEST] = HintText(CustomMessage("They say that the #test of the wilds# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Wildnis# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des bois# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba de la naturaleza# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST] = HintText(CustomMessage("They say that the #test of the seas# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Meere# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des mers# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba del mar# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST] = HintText(CustomMessage("They say that the #test of the seas# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Meere# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des mers# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba del mar# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST] = HintText(CustomMessage("They say that #music in the test of darkness# unveils #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Musik in der Prüfung des Dunkelheit# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, la #musique dans l'épreuve des ténèbres# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #música en la prueba de la oscuridad# revela #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST] = HintText(CustomMessage("They say that #light in the test of darkness# unveils #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Licht in der Prüfung der Dunkelheit# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, la #lumière dans l'épreuve des ténèbres# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #luz en la prueba de la oscuridad# revela #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST] = HintText(CustomMessage("They say that the #test of the sands# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Sande# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des sables# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba de las arenas# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST] = HintText(CustomMessage("They say that the #test of the sands# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Sande# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des sables# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba de las arenas# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST] = HintText(CustomMessage("They say that the #test of radiance# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung des Glanzes# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve du ciel# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba del resplandor# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST] = HintText(CustomMessage("They say that the #test of radiance# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung des Glanzes# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve du ciel# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba del resplandor# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST] = HintText(CustomMessage("They say that the #test of radiance# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung des Glanzes# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve du ciel# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba del resplandor# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST] = HintText(CustomMessage("They say that the #test of radiance# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung des Glanzes# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve du ciel# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba del resplandor# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST] = HintText(CustomMessage("They say that the #test of radiance# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung des Glanzes# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve du ciel# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba del resplandor# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST] = HintText(CustomMessage("They say that the #test of radiance# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung des Glanzes# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve du ciel# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba del resplandor# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST] = HintText(CustomMessage("They say that the #test of radiance# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung des Glanzes# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve du ciel# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba del resplandor# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST] = HintText(CustomMessage("They say that #music in the test of radiance# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Musik in der Prüfung des Glanzes# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, la #musique dans l'épreuve du ciel# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #música en la prueba del resplandor# revela #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = HintText(CustomMessage("They say that the #test of the seas# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Meere# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des mers# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba del mar# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST] = HintText(CustomMessage("They say that the #test of the wilds# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Wildnis# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des bois# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba de la naturaleza# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST] = HintText(CustomMessage("They say that the #test of the wilds# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Wildnis# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des bois# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba de la naturaleza# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST] = HintText(CustomMessage("They say that #music in the test of radiance# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Musik in der Prüfung des Glanzes# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, la #musique dans l'épreuve du ciel# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #música en la prueba del resplandor# revela #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST] = HintText(CustomMessage("They say that the #test of darkness# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Dunkelheit# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des ténèbres# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba de la oscuridad# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST] = HintText(CustomMessage("They say that the #test of darkness# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Dunkelheit# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des ténèbres# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba de la oscuridad# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST] = HintText(CustomMessage("They say that #reflected light in the test of the sands# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #reflektiertes Licht in der Prüfung der Sande# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, le #soleil dans l'épreuve des sables# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #reflejar la luz en la prueba de las arenas# revela #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST] = HintText(CustomMessage("They say that #reflected light in the test of the sands# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #reflektiertes Licht in der Prüfung der Sande# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, le #soleil dans l'épreuve des sables# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #reflejar la luz en la prueba de las arenas# revela #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST] = HintText(CustomMessage("They say that #reflected light in the test of the sands# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #reflektiertes Licht in der Prüfung der Sande# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, le #soleil dans l'épreuve des sables# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #reflejar la luz en la prueba de las arenas# revela #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST] = HintText(CustomMessage("They say that #reflected light in the test of the sands# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #reflektiertes Licht in der Prüfung der Sande# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, le #soleil dans l'épreuve des sables# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #reflejar la luz en la prueba de las arenas# revela #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST] = HintText(CustomMessage("They say that #reflected light in the test of the sands# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #reflektiertes Licht in der Prüfung der Sande# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, le #soleil dans l'épreuve des sables# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #reflejar la luz en la prueba de las arenas# revela #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST] = HintText(CustomMessage("They say that #reflected light in the test of the sands# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß #reflektiertes Licht in der Prüfung der Sande# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, le #soleil dans l'épreuve des sables# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #reflejar la luz en la prueba de las arenas# revela #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY] = HintText(CustomMessage("They say that the #test of the wilds# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Prüfung der Wildnis# #[[1]]# enthielte.", + /*french*/ "Selon moi, l'#épreuve des bois# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #prueba de la naturaleza# brinda #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = HintText(CustomMessage("They say that #scrubs in Ganon's Castle# sell #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Dekus in Ganons Schloß# #[[1]]# verkaufen würden.", + /*french*/ "Selon moi, les #pestes Mojo dans le Château de Ganon# vendent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #dekus del Castillo de Ganon# venden #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = HintText(CustomMessage("They say that #scrubs in Ganon's Castle# sell #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Dekus in Ganons Schloß# #[[1]]# verkaufen würden.", + /*french*/ "Selon moi, les #pestes Mojo dans le Château de Ganon# vendent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #dekus del Castillo de Ganon# venden #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_DEKU_SCRUB_RIGHT] = HintText(CustomMessage("They say that #scrubs in Ganon's Castle# sell #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Dekus in Ganons Schloß# #[[1]]# verkaufen würden.", + /*french*/ "Selon moi, les #pestes Mojo dans le Château de Ganon# vendent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #dekus del Castillo de Ganon# venden #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_DEKU_SCRUB_LEFT] = HintText(CustomMessage("They say that #scrubs in Ganon's Castle# sell #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Dekus in Ganons Schloß# #[[1]]# verkaufen würden.", + /*french*/ "Selon moi, les #pestes Mojo dans le Château de Ganon# vendent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #dekus del Castillo de Ganon# venden #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = HintText(CustomMessage("They say that #scrubs in Ganon's Castle# sell #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Dekus in Ganons Schloß# #[[1]]# verkaufen würden.", + /*french*/ "Selon moi, les #pestes Mojo dans le Château de Ganon# vendent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #dekus del Castillo de Ganon# venden #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = HintText(CustomMessage("They say that #scrubs in Ganon's Castle# sell #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Dekus in Ganons Schloß# #[[1]]# verkaufen würden.", + /*french*/ "Selon moi, les #pestes Mojo dans le Château de Ganon# vendent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #dekus del Castillo de Ganon# venden #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = HintText(CustomMessage("They say that #scrubs in Ganon's Castle# sell #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Dekus in Ganons Schloß# #[[1]]# verkaufen würden.", + /*french*/ "Selon moi, les #pestes Mojo dans le Château de Ganon# vendent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #dekus del Castillo de Ganon# venden #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = HintText(CustomMessage("They say that #scrubs in Ganon's Castle# sell #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Dekus in Ganons Schloß# #[[1]]# verkaufen würden.", + /*french*/ "Selon moi, les #pestes Mojo dans le Château de Ganon# vendent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #dekus del Castillo de Ganon# venden #[[1]]#. + + hintTextTable[RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = HintText(CustomMessage("They say that #scrubs in Ganon's Castle# sell #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Dekus in Ganons Schloß# #[[1]]# verkaufen würden.", + /*french*/ "Selon moi, les #pestes Mojo dans le Château de Ganon# vendent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, los #dekus del Castillo de Ganon# venden #[[1]]#. +} } diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index f2e11022683..a467c18b513 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp @@ -1,1359 +1,1494 @@ -#include "../hint_list.hpp" - -void HintTable_Init_Exclude_Overworld() { - hintTable[KF_KOKIRI_SWORD_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #hidden treasure of the Kokiri# is", /*french*/"le #trésor des Kokiri# est", /*spanish*/"el #tesoro oculto de los Kokiri# esconde"}, - }); - - hintTable[KF_MIDOS_TOP_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #leader of the Kokiri# hides", /*french*/"le #chef des Kokiri# possède", /*spanish*/"el #líder de los Kokiri# esconde"}, - }, {}, - //clear text - Text{"#inside Mido's house# is", /*french*/"#dans la maison de Mido# gît", /*spanish*/"en la #casa de Mido# yace"} - ); - - hintTable[KF_MIDOS_TOP_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #leader of the Kokiri# hides", /*french*/"le #chef des Kokiri# possède", /*spanish*/"el #líder de los Kokiri# esconde"}, - }, {}, - //clear text - Text{"#inside Mido's house# is", /*french*/"#dans la maison de Mido# gît", /*spanish*/"en la #casa de Mido# yace"} - ); - - hintTable[KF_MIDOS_BOTTOM_LEFT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #leader of the Kokiri# hides", /*french*/"le #chef des Kokiri# possède", /*spanish*/"el #líder de los Kokiri# esconde"}, - }, {}, - //clear text - Text{"#inside Mido's house# is", /*french*/"#dans la maison de Mido# gît", /*spanish*/"en la #casa de Mido# yace"} - ); - - hintTable[KF_MIDOS_BOTTOM_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #leader of the Kokiri# hides", /*french*/"le #chef des Kokiri# possède", /*spanish*/"el #líder de los Kokiri# esconde"}, - }, {}, - //clear text - Text{"#inside Mido's house# is", /*french*/"#dans la maison de Mido# gît", /*spanish*/"en la #casa de Mido# yace"} - ); - - hintTable[GRAVEYARD_SHIELD_GRAVE_CHEST] = HintText::Exclude({ - //obscure text - Text{"the #treasure of a fallen soldier# is", /*french*/"le #trésor du soldat mort# est", /*spanish*/"el #tesoro de un soldado caído# esconde"}, - }); - - hintTable[DMT_CHEST] = HintText::Exclude({ - //obscure text - Text{"hidden behind a wall on a #mountain trail# is", /*french*/"derrière une façade du #chemin montagneux# est", /*spanish*/"tras una pared del #sendero de la montaña# yace"}, - }); - - hintTable[GC_MAZE_RIGHT_CHEST] = HintText::Exclude({ - //obscure text - Text{"in #Goron City# explosives unlock", /*french*/"des explosions dans le #village Goron# révèlent", /*spanish*/"en la #Ciudad Goron# unos explosivos desbloquean"}, - }); - - hintTable[GC_MAZE_CENTER_CHEST] = HintText::Exclude({ - //obscure text - Text{"in #Goron City# explosives unlock", /*french*/"des explosions dans le #village Goron# révèlent", /*spanish*/"en la #Ciudad Goron# unos explosivos desbloquean"}, - }); - - hintTable[ZD_CHEST] = HintText::Exclude({ - //obscure text - Text{"fire #beyond a waterfall# reveals", /*french*/"du feu #derrière la cascade# éclaire", /*spanish*/"las #llamas tras una una cascada# revelan"}, - }); - - hintTable[GRAVEYARD_HOOKSHOT_CHEST] = HintText::Exclude({ - //obscure text - Text{"a chest hidden by a #speedy spectre# holds", /*french*/"le #coffre du rapide revenant# contient", /*spanish*/"un cofre custodiado por un #espectro veloz# contiene"}, - }, {}, - //clear text - Text{"#dead Dampé's first prize# is", /*french*/"la #première course d'Igor# donne", /*spanish*/"el primer premio de #la carrera de Dampé# se trata de"} - ); - - hintTable[GF_CHEST] = HintText::Exclude({ - //obscure text - Text{"on a #rooftop in the desert# lies", /*french*/"sur un #toit du désert# gît", /*spanish*/"en una #azotea del desierto# yace"}, - }); - - hintTable[KAK_REDEAD_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"#zombies beneath the earth# guard", /*french*/"les #revenants sous terre# protègent", /*spanish*/"unos #zombis subterráneos# esconden"}, - }); - - hintTable[SFM_WOLFOS_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"#wolves beneath the earth# guard", /*french*/"les #loups sous terre# protègent", /*spanish*/"unos #lobos subterráneos# esconden"}, - }); - - hintTable[HF_NEAR_MARKET_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #hole in a field near a drawbridge# holds", /*french*/"la #grotte près d'un pont# contient", /*spanish*/"bajo el #hoyo de una llanura cercano a un puente# yace"}, - }); - - hintTable[HF_SOUTHEAST_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #hole amongst trees in a field# holds", /*french*/"la #grotte près des arbres# contient", /*spanish*/"bajo el #hoyo de una llanura rodeado de árboles# yace"}, - }); - - hintTable[HF_OPEN_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"an #open hole in a field# holds", /*french*/"la #grotte dans les plaines# contient", /*spanish*/"bajo el #hoyo descubierto de una llanura# yace"}, - }); - - hintTable[KAK_OPEN_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"an #open hole in a town# holds", /*french*/"la #grotte dans le village# contient", /*spanish*/"bajo el #hoyo descubierto de un pueblo# yace"}, - }); - - hintTable[ZR_OPEN_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #hole along a river# holds", /*french*/"la #grotte près du fleuve# contient", /*spanish*/"bajo un #hoyo junto a un río# yace"}, - }); - - hintTable[KF_STORMS_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #hole in a forest village# holds", /*french*/"la #grotte inondée de pluie dans le Village Kokiri# révèle", /*spanish*/"bajo el #hoyo de una tribu del bosque# yace"}, - }); - - hintTable[LW_NEAR_SHORTCUTS_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #hole in a wooded maze# holds", /*french*/"la #grotte dans le labyrinthe sylvestre# contient", /*spanish*/"bajo un #hoyo de un laberinto forestal# yace"}, - }); - - hintTable[DMT_STORMS_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"#hole flooded with rain on a mountain# holds", /*french*/"la #grotte inondée de pluie sur la montagne# contient", /*spanish*/"bajo un #hoyo de una montaña inundado de lluvia# yace"}, - }); - - hintTable[DMC_UPPER_GROTTO_CHEST] = HintText::Exclude({ - //obscure text - Text{"a #hole in a volcano# holds", /*french*/"la #grotte dans le volcan# contient", /*spanish*/"bajo el #hoyo de un volcán# yace"}, - }); - - hintTable[TOT_MASTER_SWORD] = HintText::Exclude({ - //obscure text - Text{"a #pedestal in a temple# holds", /*french*/"un #piédestal dans un temple# contient", /*spanish*/"un #pedestal en un templo# sostiene"}, - }); - - hintTable[TOT_LIGHT_ARROWS_CUTSCENE] = HintText::Exclude({ - //obscure text - Text{"the #final gift of a princess# is", /*french*/"le #cadeau d'adieu de la princesse# est", /*spanish*/"el #obsequio final de la princesa# se trata de"}, - }); - - hintTable[LW_GIFT_FROM_SARIA] = HintText::Exclude({ - //obscure text - Text{"a #potato hoarder# holds", /*french*/"le #panini mélodieux# est en fait", /*spanish*/"cierta #jovencita verde# concede"}, - Text{"a rooty tooty #flutey cutey# gifts", /*french*/"la #patate musicale# est en fait", /*spanish*/"una #gran amiga# concede"}, - }, {}, - //clear text - Text{"#Saria's Gift# is", /*french*/"le #cadeau de Saria# est", /*spanish*/"el #regalo de Saria# se trata de"} - ); - - hintTable[ZF_GREAT_FAIRY_REWARD] = HintText::Exclude({ - //obscure text - Text{"the #fairy of winds# holds", /*french*/"la #fée du vent# a", /*spanish*/"el #hada del viento# brinda"}, - }); - - hintTable[HC_GREAT_FAIRY_REWARD] = HintText::Exclude({ - //obscure text - Text{"the #fairy of fire# holds", /*french*/"la #fée du feu# a", /*spanish*/"el #hada del fuego# brinda"}, - }); - - hintTable[COLOSSUS_GREAT_FAIRY_REWARD] = HintText::Exclude({ - //obscure text - Text{"the #fairy of love# holds", /*french*/"la #fée de l'amour# a", /*spanish*/"el #hada del amor# brinda"}, - }); - - hintTable[DMT_GREAT_FAIRY_REWARD] = HintText::Exclude({ - //obscure text - Text{"a #magical fairy# gifts", /*french*/"la #fée de la magie# a", /*spanish*/"un #hada mágica# brinda"}, - }); - - hintTable[DMC_GREAT_FAIRY_REWARD] = HintText::Exclude({ - //obscure text - Text{"a #magical fairy# gifts", /*french*/"la #fée de la magie# a", /*spanish*/"un #hada mágica# brinda"}, - }); - - hintTable[OGC_GREAT_FAIRY_REWARD] = HintText::Exclude({ - //obscure text - Text{"the #fairy of strength# holds", /*french*/"la #fée de la force# a", /*spanish*/"el #hada de la fuerza# brinda"}, - }); - - - hintTable[SONG_FROM_IMPA] = HintText::Exclude({ - //obscure text - Text{"#deep in a castle#, Impa teaches", /*french*/"#la gardienne de la princesse# donne", /*spanish*/"en el #jardín del castillo Impa enseña#"}, - }); - - hintTable[SONG_FROM_MALON] = HintText::Exclude({ - //obscure text - Text{"#a farm girl# sings", /*french*/"la #fillette de la ferme# donne", /*spanish*/"una #chica rupestre# canta"}, - }); - - hintTable[SONG_FROM_SARIA] = HintText::Exclude({ - //obscure text - Text{"#deep in the forest#, Saria teaches", /*french*/"la #fille de la forêt# donne", /*spanish*/"al #fondo del bosque# Saria enseña"}, - }); - - hintTable[SONG_FROM_WINDMILL] = HintText::Exclude({ - //obscure text - Text{"a man #in a windmill# is obsessed with", /*french*/"l'#homme du moulin# donne", /*spanish*/"el #hombre del molino# está obsesionado con"}, - }); - - - hintTable[HC_MALON_EGG] = HintText::Exclude({ - //obscure text - Text{"a #girl looking for her father# gives", /*french*/"la #fillette qui cherche son père# donne", /*spanish*/"una #chica en busca de su padre# otorga"}, - }); - - hintTable[HC_ZELDAS_LETTER] = HintText::Exclude({ - //obscure text - Text{"a #princess in a castle# gifts", /*french*/"la #princesse dans le château# donne", /*spanish*/"la #princesa de un castillo# otorga"}, - }); - - hintTable[ZD_DIVING_MINIGAME] = HintText::Exclude({ - //obscure text - Text{"an #unsustainable business model# gifts", /*french*/"le #mauvais modèle d'affaires# donne", /*spanish*/"un #mal modelo de negocio# premia con"}, - }, {}, - //clear text - Text{"those who #dive for Zora rupees# will find", /*french*/"ceux qui #plongent pour des rubis Zora# trouveront", /*spanish*/"aquellos que se #sumergan por las rupias zora# encontrarán"} - ); - - hintTable[LH_CHILD_FISHING] = HintText::Exclude({ - //obscure text - Text{"#fishing in youth# bestows", /*french*/"#pêcher dans sa jeunesse# promet", /*spanish*/"#pescar en la juventud# conduce a"}, - }); - - hintTable[LH_ADULT_FISHING] = HintText::Exclude({ - //obscure text - Text{"#fishing in maturity# bestows", /*french*/"#pêcher dans sa maturité# promet", /*spanish*/"#pescar en la madurez# conduce a"}, - }); - - hintTable[LH_LAB_DIVE] = HintText::Exclude({ - //obscure text - Text{"a #diving experiment# is rewarded with", /*french*/"l'#expérience de plongée# donne", /*spanish*/"#bucear para un experimento# se premia con"}, - }); - - hintTable[GC_ROLLING_GORON_AS_ADULT] = HintText::Exclude({ - //obscure text - Text{"#comforting yourself# provides", /*french*/"se #réconforter soi-même# donne", /*spanish*/"#confrontarte a ti mismo# otorga"}, - }, {}, - //clear text - Text{"#reassuring a young Goron# is rewarded with", /*french*/"#rassurer un jeune Goron# donne", /*spanish*/"#calmar a un joven Goron# otorga"} - ); - - hintTable[MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = HintText::Exclude({ - //obscure text - Text{"the #first explosive prize# is", /*french*/"le #premier prix explosif# est", /*spanish*/"el #primer premio explosivo# se trata de"}, - }); - - hintTable[MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = HintText::Exclude({ - //obscure text - Text{"the #second explosive prize# is", /*french*/"le #deuxième prix explosif# est", /*spanish*/"el #segundo premio explosivo# se trata de"}, - }); - - hintTable[MARKET_LOST_DOG] = HintText::Exclude({ - //obscure text - Text{"#puppy lovers# will find", /*french*/"les #amoureux canins# trouveront", /*spanish*/"los #amantes caninos# encontrarán"}, - }, {}, - //clear text - Text{"#rescuing Richard the Dog# is rewarded with", /*french*/"#retrouver Kiki le chien# promet", /*spanish*/"#rescatar al perrito Ricardo# conduce a"} - ); - - hintTable[LW_OCARINA_MEMORY_GAME] = HintText::Exclude({ - //obscure text - Text{"the prize for a #game of Simon Says# is", /*french*/"la #récompense de Jean Dit# est", /*spanish*/"#repetir ciertas melodías# otorga"}, - Text{"a #child sing-a-long# holds", /*french*/"les #jeunes flûtistes# donnent", /*spanish*/"#tocar junto a otros# otorga"}, - }, {}, - //clear text - Text{"#playing an Ocarina in Lost Woods# is rewarded with", /*french*/"#jouer l'ocarina dans les Bois Perdus# donne", /*spanish*/"#tocar la ocarina en el Bosque Perdido# otorga"} - ); - - hintTable[KAK_10_GOLD_SKULLTULA_REWARD] = HintText::Exclude({ - //obscure text - Text{"#10 bug badges# rewards", /*french*/"#10 écussons# donnent", /*spanish*/"#10 medallas de insectos# otorgan"}, - Text{"#10 spider souls# yields", /*french*/"#10 âmes# donnent", /*spanish*/"#10 almas de araña# otorgan"}, - Text{"#10 auriferous arachnids# lead to", /*french*/"#10 arachnides aurifères# donnent", /*spanish*/"#10 arácnidos auríferos# otorgan"}, - }, {}, - //clear text - Text{"slaying #10 Gold Skulltulas# reveals", /*french*/"détruire #10 Skulltulas d'or# donne", /*spanish*/"#exterminar 10 skulltulas doradas# revela"} - ); - - hintTable[KAK_MAN_ON_ROOF] = HintText::Exclude({ - //obscure text - Text{"a #rooftop wanderer# holds", /*french*/"une #rencontre sur un toit# donne", /*spanish*/"#alguien sobre un tejado# otorga"}, - }); - - hintTable[ZR_MAGIC_BEAN_SALESMAN] = HintText::Exclude({ - //obscure text - Text{"a seller of #colorful crops# has", /*french*/"le #marchand de légumes# vend", /*spanish*/"el vendedor de un #colorido cultivo# ofrece"}, - }, {}, - //clear text - Text{"a #bean seller# offers", /*french*/"le #marchand de haricots magiques# vend en fait", /*spanish*/"el #vendedor de judías# ofrece"} - ); - - hintTable[ZR_FROGS_IN_THE_RAIN] = HintText::Exclude({ - //obscure text - Text{"#frogs in a storm# gift", /*french*/"#des grenouilles mouillées# donnent", /*spanish*/"las #ancas bajo la tormenta# otorgan"}, - }); - hintTable[ZR_FROGS_ZELDAS_LULLABY] = HintText::Exclude( - { - // obscure text - Text{ "#sleepy frogs# gift", /*french*/ "#les grenouilles somnolentes# donnent", - /*spanish*/ "las #ranas somnolientas# regalan" }, - Text{ "#the Froggish Tenor in the back-left# gifts", - /*french*/ "#le ténor grenouillesque au fond à gauche# donne", - /*spanish*/ "el #Sapo Tenore al fondo, a la izquierda#, regala" }, - }, - {}, - // clear text - Text{ "after hearing #Zelda's Lullaby, the frogs# gift", - /*french*/ "à l'écoute de #la berceuse de Zelda, les grenouilles# donnent", - /*spanish*/ "después de escuchar #la Nana de Zelda, las ranas# regalan" }); - - hintTable[ZR_FROGS_EPONAS_SONG] = HintText::Exclude( - { - // obscure text - Text{ "#equine frogs# gift", /*french*/ "#les grenouilles équestres# donnent", - /*spanish*/ "las #ranas equinas# regalan" }, - Text{ "#the Froggish Tenor in the back-right# gifts", - /*french*/ "#le ténor grenouillesque au fond à droite# donne", - /*spanish*/ "el #Sapo Tenore al fondo, a la derecha#, regala" }, - }, - {}, - // clear text - Text{ "after hearing #Epona's Song, the frogs# gift", - /*french*/ "à l'écoute du #chant d'Epona, les grenouilles# donnent", - /*spanish*/ "después de escuchar #la Canción de Epona, las ranas# regalan" }); - - hintTable[ZR_FROGS_SARIAS_SONG] = HintText::Exclude( - { - // obscure text - Text{ "#sylvan frogs# gift", /*french*/ "#les grenouilles sylvestres# donnent", - /*spanish*/ "las #ranas silvestres# regalan" }, - Text{ "#the Froggish Tenor in the center# gifts", - /*french*/ "#le ténor grenouillesque dans le centre# donne", - /*spanish*/ "el #Sapo Tenore en el centro# regala" }, - }, - {}, - // clear text - Text{ "after hearing #Saria's Song, the frogs# gift", - /*french*/ "à l'écoute du #chant de Saria, les grenouilles# donnent", - /*spanish*/ "después de escuchar #la Canción de Saria, las ranas# regalan" }); - - hintTable[ZR_FROGS_SUNS_SONG] = HintText::Exclude( - { - // obscure text - Text{ "#enlightened frogs# gift", /*french*/ "#les grenouilles éclairées# donnent", - /*spanish*/ "las #ranas alumbradas# regalan" }, - Text{ "#the Froggish Tenor in the front-left# gifts", - /*french*/ "#le ténor grenouillesque à l'avant gauche# donne", - /*spanish*/ "el #Sapo Tenore al frente, a la izquierda#, regala" }, - }, - {}, - // clear text - Text{ "after hearing #the Sun's Song, the frogs# gift", - /*french*/ "à l'écoute du #chant du soleil, les grenouilles# donnent", - /*spanish*/ "después de escuchar #la Canción del Sol, las ranas# regalan" }); - - hintTable[ZR_FROGS_SONG_OF_TIME] = HintText::Exclude( - { - // obscure text - Text{ "#time-traveling frogs# gift", /*french*/ "#les grenouilles voyageuses dans le temps# donnent", - /*spanish*/ "las #ranas viajeras del tiempo# regalan" }, - Text{ "#the Froggish Tenor in the front-right# gifts", - /*french*/ "#le ténor grenouillesque à l'avant droite# donne", - /*spanish*/ "el #Sapo Tenore al frente, a la derecha#, regala" }, - }, - {}, - // clear text - Text{ "after hearing #the Song of Time, the frogs# gift", - /*french*/ "à l'écoute du #chant du temps, les grenouilles# donnent", - /*spanish*/ "después de escuchar #la Canción del tiempo, las ranas# regalan" }); - - hintTable[GF_HBA_1000_POINTS] = HintText::Exclude({ - //obscure text - Text{"scoring 1000 in #horseback archery# grants", /*french*/"obtenir 1000 points dans l'#archerie équestre# donne", /*spanish*/"conseguir 1000 puntos en el #tiro con arco a caballo# premia"}, - }); - - hintTable[MARKET_SHOOTING_GALLERY_REWARD] = HintText::Exclude({ - //obscure text - Text{"#shooting in youth# grants", /*french*/"#faire du tir dans sa jeunesse# donne", /*spanish*/"#disparar en la juventud# otorga"}, - }); - - hintTable[KAK_SHOOTING_GALLERY_REWARD] = HintText::Exclude({ - //obscure text - Text{"#shooting in maturity# grants", /*french*/"#faire du tir dans sa maturité# donne", /*spanish*/"#disparar en la madurez# otorga"}, - }); - - hintTable[LW_TARGET_IN_WOODS] = HintText::Exclude({ - //obscure text - Text{"shooting a #target in the woods# grants", /*french*/"#tirer une cible dans les bois# donne", /*spanish*/"disparar a un #blanco forestal# brinda"}, - }); - - hintTable[KAK_ANJU_AS_ADULT] = HintText::Exclude({ - //obscure text - Text{"a #chicken caretaker# offers adults", /*french*/"devenir un #éleveur de Cocottes# donne", /*spanish*/"una #cuidadora de emplumados# le ofrece a los mayores"}, - }); - - hintTable[LLR_TALONS_CHICKENS] = HintText::Exclude({ - //obscure text - Text{"#finding Super Cuccos# is rewarded with", /*french*/"#trouver des Super Cocottes# donne", /*spanish*/"#hallar los supercucos# conduce a"}, - }); - - hintTable[GC_ROLLING_GORON_AS_CHILD] = HintText::Exclude({ - //obscure text - Text{"the prize offered by a #large rolling Goron# is", /*french*/"la récompense d'un #gros Goron roulant# est", /*spanish*/"un #gran Goron rodante# otorga"}, - }); - - hintTable[LH_UNDERWATER_ITEM] = HintText::Exclude({ - //obscure text - Text{"the #sunken treasure in a lake# is", /*french*/"le #trésor au fond du lac# est", /*spanish*/"el #tesoro hundido del lago# se trata de"}, - }); - - hintTable[GF_GERUDO_MEMBERSHIP_CARD] = HintText::Exclude({ - //obscure text - Text{"#rescuing captured carpenters# is rewarded with", /*french*/"#secourir les charpentiers capturés# assure", /*spanish*/"#rescatar los apresados carpinteros# se premia con"}, - }); - - hintTable[WASTELAND_BOMBCHU_SALESMAN] = HintText::Exclude({ - //obscure text - Text{"a #carpet guru# sells", /*french*/"#un marchand du désert# vend", /*spanish*/"el #genio de una alfombra# vende"}, - }); - - hintTable[GC_MEDIGORON] = HintText::Exclude({ - //obscure text - Text{"#Medigoron# sells", /*french*/"#Medigoron# vend", /*spanish*/"#Medigoron# vende"}, - }); - - hintTable[KAK_GRANNYS_SHOP] = HintText::Exclude({ - // obscure text - Text{"the #potion shop lady# sells", /*french*/"la #dame du magasin de potion# vend", /*spanish*/"la #señora de la tienda de pociones# vende" }, - }); - - hintTable[KAK_IMPAS_HOUSE_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"#imprisoned in a house# lies", /*french*/"#encagé dans une maison# gît", /*spanish*/"#en una casa entre rejas# yace"}, - }); - - hintTable[HF_TEKTITE_GROTTO_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"#deep underwater in a hole# is", /*french*/"#dans les profondeurs d'une grotte# gît", /*spanish*/"#en lo hondo bajo un hoyo# yace"}, - }); - - hintTable[KAK_WINDMILL_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"on a #windmill ledge# lies", /*french*/"#haut perché dans le moulin# gît", /*spanish*/"al #borde de un molino# yace"}, - }); - - hintTable[GRAVEYARD_DAMPE_RACE_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"#racing a ghost# leads to", /*french*/"le défi du #revenant rapide# donne", /*spanish*/"#perseguir a un fantasma# conduce a"}, - }, {}, - //clear text - Text{"#dead Dampe's second# prize is", /*french*/"la #deuxième course d'Igor# donne", /*spanish*/"el segundo premio de #la carrera de Dampé# se trata de"} - ); - - hintTable[LLR_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"in a #ranch silo# lies", /*french*/"#dans l'entrepôt de la ferme# gît", /*spanish*/"en un #granero rupestre# yace"}, - }); - - hintTable[GRAVEYARD_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"a #crate in a graveyard# hides", /*french*/"#la boîte dans le Cimetière# contient", /*spanish*/"bajo la #caja de un cementerio# yace"}, - }); - - hintTable[GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = HintText::Exclude({ - //obscure text - Text{"a #gravekeeper digs up#", /*french*/"#le jeu du fossoyeur# cache", /*spanish*/"cierto #sepultero desentierra#"}, - }); - - hintTable[ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"on top of a #pillar in a river# lies", /*french*/"#sur un pilier au dessus du fleuve# gît", /*spanish*/"en lo alto del #pilar de un río# yace"}, - }); - - hintTable[ZR_NEAR_DOMAIN_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"on a #river ledge by a waterfall# lies", /*french*/"#sur la falaise au dessus du fleuve# gît", /*spanish*/"al borde de #la entrada a una cascada# yace"}, - }); - - hintTable[LH_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"high on a #lab rooftop# one can find", /*french*/"#la tour d'observation du lac# cache", /*spanish*/"en lo #alto de un laboratorio# yace"}, - }); - - hintTable[ZF_ICEBERG_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"#floating on ice# is", /*french*/"#gisant sur la glace# gît", /*spanish*/"#flotando sobre hielo# yace"}, - }); - - hintTable[GV_WATERFALL_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"behind a #valley waterfall# is", /*french*/"#derrière la cascade du désert# se cache", /*spanish*/"tras una #desierta cascada# yace"}, - }); - - hintTable[GV_CRATE_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"a #crate in a valley# hides", /*french*/"la #boîte dans la vallée# contient", /*spanish*/"bajo la #caja de un valle# yace"}, - }); - - hintTable[COLOSSUS_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"on top of an #arch of stone# lies", /*french*/"#gisant sur une arche de pierre# gît", /*spanish*/"en lo alto de un #arco de piedra# yace"}, - }); - - hintTable[DMT_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"above a #mountain cavern entrance# is", /*french*/"gisant #au dessus de la caverne montagneuse# gît", /*spanish*/"en lo alto de la #entrada de una cueva en la montaña# yace"}, - }); - - hintTable[DMC_WALL_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"nestled in a #volcanic wall# is", /*french*/"dans une #alcove volcanique# gît", /*spanish*/"entre unas #murallas volcánicas# yace"}, - }); - - hintTable[DMC_VOLCANO_FREESTANDING_POH] = HintText::Exclude({ - //obscure text - Text{"obscured by #volcanic ash# is", /*french*/"#recouvert de cendres volcaniques# gît", /*spanish*/"bajo la #ceniza volcánica# yace"}, - }); - - hintTable[GF_NORTH_F1_CARPENTER] = HintText::Exclude({ - //obscure text - Text{"#defeating Gerudo guards# reveals", /*french*/"les #geôliers Gerudo# détiennent", /*spanish*/"#derrotar a las guardas Gerudo# revela"}, - }); - - hintTable[GF_NORTH_F2_CARPENTER] = HintText::Exclude({ - //obscure text - Text{"#defeating Gerudo guards# reveals", /*french*/"les #geôliers Gerudo# détiennent", /*spanish*/"#derrotar a las guardas Gerudo# revela"}, - }); - - hintTable[GF_SOUTH_F1_CARPENTER] = HintText::Exclude({ - //obscure text - Text{"#defeating Gerudo guards# reveals", /*french*/"les #geôliers Gerudo# détiennent", /*spanish*/"#derrotar a las guardas Gerudo# revela"}, - }); - - hintTable[GF_SOUTH_F2_CARPENTER] = HintText::Exclude({ - //obscure text - Text{"#defeating Gerudo guards# reveals", /*french*/"les #geôliers Gerudo# détiennent", /*spanish*/"#derrotar a las guardas Gerudo# revela"}, - }); - - - hintTable[HF_GS_NEAR_KAK_GROTTO] = HintText::Exclude({ - //obscure text - Text{"a #spider-guarded spider in a hole# hoards", /*french*/"une #Skulltula dans un trou d'arachnides# a", /*spanish*/"una #Skulltula custodiada por otra# de un hoyo otorga"}, - }); - - - hintTable[LLR_GS_BACK_WALL] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider in a ranch# holding", /*french*/"une #Skulltula sur la façade de la ferme# a", /*spanish*/"la noche revela una #Skulltula del rancho# que otorga"}, - }); - - hintTable[LLR_GS_RAIN_SHED] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider in a ranch# holding", /*french*/"une #Skulltula sur le mur de l'enclos# a", /*spanish*/"la noche revela una #Skulltula del rancho# que otorga"}, - }); - - hintTable[LLR_GS_HOUSE_WINDOW] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider in a ranch# holding", /*french*/"une #Skulltula sur la maison de ferme# a", /*spanish*/"la noche revela una #Skulltula del rancho# que otorga"}, - }); - - hintTable[LLR_GS_TREE] = HintText::Exclude({ - //obscure text - Text{"a spider hiding in a #ranch tree# holds", /*french*/"une #Skulltula dans l'arbre de la ferme# a", /*spanish*/"una Skulltula escondida en el #árbol de un rancho# otorga"}, - }); - - - hintTable[KF_GS_BEAN_PATCH] = HintText::Exclude({ - //obscure text - Text{"a #spider buried in a forest# holds", /*french*/"une #Skulltula enterrée dans la forêt# a", /*spanish*/"una #Skulltula enterrada en un bosque# otorga"}, - }); - - hintTable[KF_GS_KNOW_IT_ALL_HOUSE] = HintText::Exclude({ - //obscure text - Text{"night in the past reveals a #spider in a forest# holding", /*french*/"une #Skulltula derrière une cabane de la forêt# a", /*spanish*/"la noche revela en el pasado una #Skulltula del bosque# que otorga"}, - }); - - hintTable[KF_GS_HOUSE_OF_TWINS] = HintText::Exclude({ - //obscure text - Text{"night in the future reveals a #spider in a forest# holding", /*french*/"une #Skulltula sur une cabane de la forêt# a", /*spanish*/"la noche revela en el futuro una #Skulltula del rancho# que otorga"}, - }); - - - hintTable[LW_GS_BEAN_PATCH_NEAR_BRIDGE] = HintText::Exclude({ - //obscure text - Text{"a #spider buried deep in a forest maze# holds", /*french*/"une #Skulltula enterrée dans les bois# a", /*spanish*/"una #Skulltula enterrada en un laberinto forestal# otorga"}, - }); - - hintTable[LW_GS_BEAN_PATCH_NEAR_THEATER] = HintText::Exclude({ - //obscure text - Text{"a #spider buried deep in a forest maze# holds", /*french*/"une #Skulltula enterrée dans les bois# a", /*spanish*/"una #Skulltula enterrada en un laberinto forestal# otorga"}, - }); - - hintTable[LW_GS_ABOVE_THEATER] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider deep in a forest maze# holding", /*french*/"une #Skulltula haut perchée dans les bois# a", /*spanish*/"la noche revela una #Skulltula del laberinto forestal# que otorga"}, - }); - - hintTable[SFM_GS] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider in a forest meadow# holding", /*french*/"une #Skulltula dans le sanctuaire des bois# a", /*spanish*/"la noche revela una #Skulltula de la pradera del bosque# que otorga"}, - }); - - - hintTable[OGC_GS] = HintText::Exclude({ - //obscure text - Text{"a #spider outside a tyrant's tower# holds", /*french*/"une #Skulltula parmi les ruines du château# a", /*spanish*/"una #Skulltula a las afueras de la torre de un tirano# otorga"}, - }); - - hintTable[HC_GS_TREE] = HintText::Exclude({ - //obscure text - Text{"a spider hiding in a #tree outside of a castle# holds", /*french*/"une #Skulltula dans l'arbre près du château# a", /*spanish*/"una Skulltula escondida en el #árbol de las afueras de un castillo# otorga"}, - }); - - hintTable[MARKET_GS_GUARD_HOUSE] = HintText::Exclude({ - //obscure text - Text{"a #spider in a guarded crate# holds", /*french*/"une #Skulltula dans une boîte en ville# a", /*spanish*/"una #Skulltula bajo una custodiada caja# otorga"}, - }); - - - hintTable[DMC_GS_BEAN_PATCH] = HintText::Exclude({ - //obscure text - Text{"a #spider buried in a volcano# holds", /*french*/"une #Skulltula enterrée dans un volcan# a", /*spanish*/"una #Skulltula enterrada en un volcán# otorga"}, - }); - - - hintTable[DMT_GS_BEAN_PATCH] = HintText::Exclude({ - //obscure text - Text{"a #spider buried outside a cavern# holds", /*french*/"une #Skulltula enterrée près d'une caverne# a", /*spanish*/"una #Skulltula enterrada a la entrada de una cueva# otorga"}, - }); - - hintTable[DMT_GS_NEAR_KAK] = HintText::Exclude({ - //obscure text - Text{"a #spider hidden in a mountain nook# holds", /*french*/"une #Skulltula cachée dans le flanc d'une montagne# a", /*spanish*/"una #Skulltula oculta en el rincón de la montaña# otorga"}, - }); - - hintTable[DMT_GS_ABOVE_DODONGOS_CAVERN] = HintText::Exclude({ - //obscure text - Text{"the hammer reveals a #spider on a mountain# holding", /*french*/"une #Skulltula derrière un rocher massif près d'une caverne# a", /*spanish*/"el martillo revela #una Skulltula de la montaña# que otorga"}, - }); - - hintTable[DMT_GS_FALLING_ROCKS_PATH] = HintText::Exclude({ - //obscure text - Text{"the hammer reveals a #spider on a mountain# holding", /*french*/"une #Skulltula derrière un rocher massif près du sommet d'un volcan# a", /*spanish*/"el martillo revela #una Skulltula de la montaña# que otorga"}, - }); - - - hintTable[GC_GS_CENTER_PLATFORM] = HintText::Exclude({ - //obscure text - Text{"a #suspended spider# in Goron City holds", /*french*/"une #Skulltula perchée dans le village Goron# a", /*spanish*/"una #Skulltula suspendida# en la Ciudad Goron otorga"}, - }); - - hintTable[GC_GS_BOULDER_MAZE] = HintText::Exclude({ - //obscure text - Text{"a spider in a #Goron City crate# holds", /*french*/"une #Skulltula dans une boîte du village Goron# a", /*spanish*/"una #Skulltula bajo una caja# de la Ciudad Goron otorga"}, - }); - - - hintTable[KAK_GS_HOUSE_UNDER_CONSTRUCTION] = HintText::Exclude({ - //obscure text - Text{"night in the past reveals a #spider in a town# holding", /*french*/"une #Skulltula dans le chantier de construction# a", /*spanish*/"la noche del pasado revela una #Skulltula del pueblo# que otorga"}, - }); - - hintTable[KAK_GS_SKULLTULA_HOUSE] = HintText::Exclude({ - //obscure text - Text{"night in the past reveals a #spider in a town# holding", /*french*/"une #Skulltula sur une maison maudite# a", /*spanish*/"la noche del pasado revela una #Skulltula del pueblo# que otorga"}, - }); - - hintTable[KAK_GS_GUARDS_HOUSE] = HintText::Exclude({ - //obscure text - Text{"night in the past reveals a #spider in a town# holding", /*french*/"une #Skulltula sur une maison de village# a", /*spanish*/"la noche del pasado revela una #Skulltula del pueblo# que otorga"}, - }); - - hintTable[KAK_GS_TREE] = HintText::Exclude({ - //obscure text - Text{"night in the past reveals a #spider in a town# holding", /*french*/"une #Skulltula dans un arbre de village# a", /*spanish*/"la noche del pasado revela una #Skulltula del pueblo# que otorga"}, - }); - - hintTable[KAK_GS_WATCHTOWER] = HintText::Exclude({ - //obscure text - Text{"night in the past reveals a #spider in a town# holding", /*french*/"une #Skulltula sur une échelle dans un village# a", /*spanish*/"la noche del pasado revela una #Skulltula del pueblo# que otorga"}, - }); - - hintTable[KAK_GS_ABOVE_IMPAS_HOUSE] = HintText::Exclude({ - //obscure text - Text{"night in the future reveals a #spider in a town# holding", /*french*/"une #Skulltula au dessus d'une grande maison# a", /*spanish*/"la noche del futuro revela una #Skulltula del pueblo# que otorga"}, - }); - - - hintTable[GRAVEYARD_GS_WALL] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider in a graveyard# holding", /*french*/"une #Skulltula sur une façade du Cimetière# a", /*spanish*/"la noche revela una #Skulltula del cementerio# que otorga"}, - }); - - hintTable[GRAVEYARD_GS_BEAN_PATCH] = HintText::Exclude({ - //obscure text - Text{"a #spider buried in a graveyard# holds", /*french*/"une #Skulltula enterrée dans le Cimetière# a", /*spanish*/"una #Skulltula enterrada en el cementerio# otorga"}, - }); - - - hintTable[ZR_GS_LADDER] = HintText::Exclude({ - //obscure text - Text{"night in the past reveals a #spider in a river# holding", /*french*/"une #Skulltula sur une échelle près d'une cascade# a", /*spanish*/"la noche del pasado revela una #Skulltula del río# que otorga"}, - }); - - hintTable[ZR_GS_TREE] = HintText::Exclude({ - //obscure text - Text{"a spider hiding in a #tree by a river# holds", /*french*/"une #Skulltula dans un arbre près du fleuve# a", /*spanish*/"una Skulltula escondida en el #árbol de un río# otorga"}, - }); - - hintTable[ZR_GS_ABOVE_BRIDGE] = HintText::Exclude({ - //obscure text - Text{"night in the future reveals a #spider in a river# holding", /*french*/"une #Skulltula sur une façade près d'une cascade# a", /*spanish*/"la noche del futuro revela una #Skulltula del río# que otorga"}, - }); - - hintTable[ZR_GS_NEAR_RAISED_GROTTOS] = HintText::Exclude({ - //obscure text - Text{"night in the future reveals a #spider in a river# holding", /*french*/"une #Skulltula sur une façade près d'une grotte du fleuve# a", /*spanish*/"la noche del futuro revela una #Skulltula del río# que otorga"}, - }); - - - hintTable[ZD_GS_FROZEN_WATERFALL] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider by a frozen waterfall# holding", /*french*/"une #Skulltula près d'une cascade gelée# a", /*spanish*/"la noche revela una #Skulltula junto a una congelada cascada# que otorga"}, - }); - - hintTable[ZF_GS_ABOVE_THE_LOG] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider near a deity# holding", /*french*/"une #Skulltula près du gardien aquatique# a", /*spanish*/"la noche revela una #Skulltula junto a cierta deidad# que otorga"}, - }); - - hintTable[ZF_GS_TREE] = HintText::Exclude({ - //obscure text - Text{"a spider hiding in a #tree near a deity# holds", /*french*/"une #Skulltula dans un arbre dans un réservoir# a", /*spanish*/"una Skulltula escondida en el #árbol junto a cierta deidad# otorga"}, - }); - - - hintTable[LH_GS_BEAN_PATCH] = HintText::Exclude({ - //obscure text - Text{"a #spider buried by a lake# holds", /*french*/"une #Skulltula enterrée près d'un lac# a", /*spanish*/"una #Skulltula enterrada junto a un lago# otorga"}, - }); - - hintTable[LH_GS_SMALL_ISLAND] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider by a lake# holding", /*french*/"une #Skulltula sur un îlot du lac# a", /*spanish*/"la noche revela una #Skulltula junto a un lago# que otorga"}, - }); - - hintTable[LH_GS_LAB_WALL] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider by a lake# holding", /*french*/"une #Skulltula sur le mur d'un centre de recherche# a", /*spanish*/"la noche revela una #Skulltula junto a un lago# que otorga"}, - }); - - hintTable[LH_GS_LAB_CRATE] = HintText::Exclude({ - //obscure text - Text{"a spider deed underwater in a #lab crate# holds", /*french*/"une #Skulltula dans une boîte au fond d'une cuve d'eau# a", /*spanish*/"una #Skulltula bajo la sumergida caja de un laboratorio# otorga"}, - }); - - hintTable[LH_GS_TREE] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider by a lake high in a tree# holding", /*french*/"une #Skulltula dans un grand arbre du lac# a", /*spanish*/"la noche revela #una Skulltula del lago sobre un árbol# que otorga"}, - }); - - - hintTable[GV_GS_BEAN_PATCH] = HintText::Exclude({ - //obscure text - Text{"a #spider buried in a valley# holds", /*french*/"une #Skulltula enterré dans une vallée# a", /*spanish*/"una #Skulltula enterrada en un valle# otorga"}, - }); - - hintTable[GV_GS_SMALL_BRIDGE] = HintText::Exclude({ - //obscure text - Text{"night in the past reveals a #spider in a valley# holding", /*french*/"une #Skulltula au dessus d'une petite cascade# a", /*spanish*/"la noche del pasado revela una #Skulltula del valle# que otorga"}, - }); - - hintTable[GV_GS_PILLAR] = HintText::Exclude({ - //obscure text - Text{"night in the future reveals a #spider in a valley# holding", /*french*/"une #Skulltula sur une arche de pierre dans une vallée# a", /*spanish*/"la noche del futuro revela una #Skulltula del valle# que otorga"}, - }); - - hintTable[GV_GS_BEHIND_TENT] = HintText::Exclude({ - //obscure text - Text{"night in the future reveals a #spider in a valley# holding", /*french*/"une #Skulltula derrière une tente# a", /*spanish*/"la noche del futuro revela una #Skulltula del valle# que otorga"}, - }); - - - hintTable[GF_GS_ARCHERY_RANGE] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider in a fortress# holding", /*french*/"une #Skulltula sur une cible de tir# a", /*spanish*/"la noche revela una #Skulltula de una fortaleza# que otorga"}, - }); - - hintTable[GF_GS_TOP_FLOOR] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider in a fortress# holding", /*french*/"une #Skulltula au sommet d'une forteresse# a", /*spanish*/"la noche revela una #Skulltula de una fortaleza# que otorga"}, - }); - - - hintTable[COLOSSUS_GS_BEAN_PATCH] = HintText::Exclude({ - //obscure text - Text{"a #spider buried in the desert# holds", /*french*/"une #Skulltula enterrée au pied du colosse# a", /*spanish*/"una #Skulltula enterrada en el desierto# otorga"}, - }); - - hintTable[COLOSSUS_GS_HILL] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider deep in the desert# holding", /*french*/"une #Skulltula sur une colline dans le désert# a", /*spanish*/"la noche revela una #Skulltula en las profundidades del desierto# que otorga"}, - }); - - hintTable[COLOSSUS_GS_TREE] = HintText::Exclude({ - //obscure text - Text{"night reveals a #spider deep in the desert# holding", /*french*/"une #Skulltula dans un arbre du désert# a", /*spanish*/"la noche revela una #Skulltula en las profundidades del desierto# que otorga"}, - }); - - - hintTable[KF_SHOP_ITEM_1] = HintText::Exclude({ - //obscure text - Text{"a #child shopkeeper# sells", /*french*/"la #boutique Kokiri# vend", /*spanish*/"un #joven dependiente# vende"}, - }); - - hintTable[KF_SHOP_ITEM_2] = HintText::Exclude({ - //obscure text - Text{"a #child shopkeeper# sells", /*french*/"la #boutique Kokiri# vend", /*spanish*/"un #joven dependiente# vende"}, - }); - - hintTable[KF_SHOP_ITEM_3] = HintText::Exclude({ - //obscure text - Text{"a #child shopkeeper# sells", /*french*/"la #boutique Kokiri# vend", /*spanish*/"un #joven dependiente# vende"}, - }); - - hintTable[KF_SHOP_ITEM_4] = HintText::Exclude({ - //obscure text - Text{"a #child shopkeeper# sells", /*french*/"la #boutique Kokiri# vend", /*spanish*/"un #joven dependiente# vende"}, - }); - - hintTable[KF_SHOP_ITEM_5] = HintText::Exclude({ - //obscure text - Text{"a #child shopkeeper# sells", /*french*/"la #boutique Kokiri# vend", /*spanish*/"un #joven dependiente# vende"}, - }); - - hintTable[KF_SHOP_ITEM_6] = HintText::Exclude({ - //obscure text - Text{"a #child shopkeeper# sells", /*french*/"la #boutique Kokiri# vend", /*spanish*/"un #joven dependiente# vende"}, - }); - - hintTable[KF_SHOP_ITEM_7] = HintText::Exclude({ - //obscure text - Text{"a #child shopkeeper# sells", /*french*/"la #boutique Kokiri# vend", /*spanish*/"un #joven dependiente# vende"}, - }); - - hintTable[KF_SHOP_ITEM_8] = HintText::Exclude({ - //obscure text - Text{"a #child shopkeeper# sells", /*french*/"la #boutique Kokiri# vend", /*spanish*/"un #joven dependiente# vende"}, - }); - - - hintTable[KAK_POTION_SHOP_ITEM_1] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Kakariko Potion Shop# offers", /*french*/"l'#apothicaire de Kakariko# vend", /*spanish*/"la #tienda de pociones de Kakariko# ofrece"} - ); - - hintTable[KAK_POTION_SHOP_ITEM_2] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Kakariko Potion Shop# offers", /*french*/"l'#apothicaire de Kakariko# vend", /*spanish*/"la #tienda de pociones de Kakariko# ofrece"} - ); - - hintTable[KAK_POTION_SHOP_ITEM_3] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Kakariko Potion Shop# offers", /*french*/"l'#apothicaire de Kakariko# vend", /*spanish*/"la #tienda de pociones de Kakariko# ofrece"} - ); - - hintTable[KAK_POTION_SHOP_ITEM_4] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Kakariko Potion Shop# offers", /*french*/"l'#apothicaire de Kakariko# vend", /*spanish*/"la #tienda de pociones de Kakariko# ofrece"} - ); - - hintTable[KAK_POTION_SHOP_ITEM_5] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Kakariko Potion Shop# offers", /*french*/"l'#apothicaire de Kakariko# vend", /*spanish*/"la #tienda de pociones de Kakariko# ofrece"} - ); - - hintTable[KAK_POTION_SHOP_ITEM_6] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Kakariko Potion Shop# offers", /*french*/"l'#apothicaire de Kakariko# vend", /*spanish*/"la #tienda de pociones de Kakariko# ofrece"} - ); - - hintTable[KAK_POTION_SHOP_ITEM_7] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Kakariko Potion Shop# offers", /*french*/"l'#apothicaire de Kakariko# vend", /*spanish*/"la #tienda de pociones de Kakariko# ofrece"} - ); - - hintTable[KAK_POTION_SHOP_ITEM_8] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Kakariko Potion Shop# offers", /*french*/"l'#apothicaire de Kakariko# vend", /*spanish*/"la #tienda de pociones de Kakariko# ofrece"} - ); - - - hintTable[MARKET_BOMBCHU_SHOP_ITEM_1] = HintText::Exclude({ - //obscure text - Text{"a #Bombchu merchant# sells", /*french*/"le #marchand de Missiles# vend", /*spanish*/"un #mercader de bombchus# vende"}, - }); - - hintTable[MARKET_BOMBCHU_SHOP_ITEM_2] = HintText::Exclude({ - //obscure text - Text{"a #Bombchu merchant# sells", /*french*/"le #marchand de Missiles# vend", /*spanish*/"un #mercader de bombchus# vende"}, - }); - - hintTable[MARKET_BOMBCHU_SHOP_ITEM_3] = HintText::Exclude({ - //obscure text - Text{"a #Bombchu merchant# sells", /*french*/"le #marchand de Missiles# vend", /*spanish*/"un #mercader de bombchus# vende"}, - }); - - hintTable[MARKET_BOMBCHU_SHOP_ITEM_4] = HintText::Exclude({ - //obscure text - Text{"a #Bombchu merchant# sells", /*french*/"le #marchand de Missiles# vend", /*spanish*/"un #mercader de bombchus# vende"}, - }); - - hintTable[MARKET_BOMBCHU_SHOP_ITEM_5] = HintText::Exclude({ - //obscure text - Text{"a #Bombchu merchant# sells", /*french*/"le #marchand de Missiles# vend", /*spanish*/"un #mercader de bombchus# vende"}, - }); - - hintTable[MARKET_BOMBCHU_SHOP_ITEM_6] = HintText::Exclude({ - //obscure text - Text{"a #Bombchu merchant# sells", /*french*/"le #marchand de Missiles# vend", /*spanish*/"un #mercader de bombchus# vende"}, - }); - - hintTable[MARKET_BOMBCHU_SHOP_ITEM_7] = HintText::Exclude({ - //obscure text - Text{"a #Bombchu merchant# sells", /*french*/"le #marchand de Missiles# vend", /*spanish*/"un #mercader de bombchus# vende"}, - }); - - hintTable[MARKET_BOMBCHU_SHOP_ITEM_8] = HintText::Exclude({ - //obscure text - Text{"a #Bombchu merchant# sells", /*french*/"le #marchand de Missiles# vend", /*spanish*/"un #mercader de bombchus# vende"}, - }); - - - hintTable[MARKET_POTION_SHOP_ITEM_1] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Market Potion Shop# offers", /*french*/"l'#apothicaire dans la Place du Marché# vend", /*spanish*/"la #tienda de pociones del mercado# ofrece"} - ); - - hintTable[MARKET_POTION_SHOP_ITEM_2] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Market Potion Shop# offers", /*french*/"l'#apothicaire dans la Place du Marché# vend", /*spanish*/"la #tienda de pociones del mercado# ofrece"} - ); - - hintTable[MARKET_POTION_SHOP_ITEM_3] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Market Potion Shop# offers", /*french*/"l'#apothicaire dans la Place du Marché# vend", /*spanish*/"la #tienda de pociones del mercado# ofrece"} - ); - - hintTable[MARKET_POTION_SHOP_ITEM_4] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Market Potion Shop# offers", /*french*/"l'#apothicaire dans la Place du Marché# vend", /*spanish*/"la #tienda de pociones del mercado# ofrece"} - ); - - hintTable[MARKET_POTION_SHOP_ITEM_5] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Market Potion Shop# offers", /*french*/"l'#apothicaire dans la Place du Marché# vend", /*spanish*/"la #tienda de pociones del mercado# ofrece"} - ); - - hintTable[MARKET_POTION_SHOP_ITEM_6] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Market Potion Shop# offers", /*french*/"l'#apothicaire dans la Place du Marché# vend", /*spanish*/"la #tienda de pociones del mercado# ofrece"} - ); - - hintTable[MARKET_POTION_SHOP_ITEM_7] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Market Potion Shop# offers", /*french*/"l'#apothicaire dans la Place du Marché# vend", /*spanish*/"la #tienda de pociones del mercado# ofrece"} - ); - - hintTable[MARKET_POTION_SHOP_ITEM_8] = HintText::Exclude({ - //obscure text - Text{"a #potion seller# offers", /*french*/"l'#apothicaire# vend", /*spanish*/"un #vendedor de pociones# ofrece"}, - }, {}, - //clear text - Text{"the #Market Potion Shop# offers", /*french*/"l'#apothicaire dans la Place du Marché# vend", /*spanish*/"la #tienda de pociones del mercado# ofrece"} - ); - - - hintTable[MARKET_BAZAAR_ITEM_1] = HintText::Exclude({ - //obscure text - Text{"the #Market Bazaar# offers", /*french*/"le #bazar de la Place du Marché# vend", /*spanish*/"el #bazar del mercado# ofrece"}, - }); - - hintTable[MARKET_BAZAAR_ITEM_2] = HintText::Exclude({ - //obscure text - Text{"the #Market Bazaar# offers", /*french*/"le #bazar de la Place du Marché# vend", /*spanish*/"el #bazar del mercado# ofrece"}, - }); - - hintTable[MARKET_BAZAAR_ITEM_3] = HintText::Exclude({ - //obscure text - Text{"the #Market Bazaar# offers", /*french*/"le #bazar de la Place du Marché# vend", /*spanish*/"el #bazar del mercado# ofrece"}, - }); - - hintTable[MARKET_BAZAAR_ITEM_4] = HintText::Exclude({ - //obscure text - Text{"the #Market Bazaar# offers", /*french*/"le #bazar de la Place du Marché# vend", /*spanish*/"el #bazar del mercado# ofrece"}, - }); - - hintTable[MARKET_BAZAAR_ITEM_5] = HintText::Exclude({ - //obscure text - Text{"the #Market Bazaar# offers", /*french*/"le #bazar de la Place du Marché# vend", /*spanish*/"el #bazar del mercado# ofrece"}, - }); - - hintTable[MARKET_BAZAAR_ITEM_6] = HintText::Exclude({ - //obscure text - Text{"the #Market Bazaar# offers", /*french*/"le #bazar de la Place du Marché# vend", /*spanish*/"el #bazar del mercado# ofrece"}, - }); - - hintTable[MARKET_BAZAAR_ITEM_7] = HintText::Exclude({ - //obscure text - Text{"the #Market Bazaar# offers", /*french*/"le #bazar de la Place du Marché# vend", /*spanish*/"el #bazar del mercado# ofrece"}, - }); - - hintTable[MARKET_BAZAAR_ITEM_8] = HintText::Exclude({ - //obscure text - Text{"the #Market Bazaar# offers", /*french*/"le #bazar de la Place du Marché# vend", /*spanish*/"el #bazar del mercado# ofrece"}, - }); - - - hintTable[KAK_BAZAAR_ITEM_1] = HintText::Exclude({ - //obscure text - Text{"the #Kakariko Bazaar# offers", /*french*/"le #bazar de Kakariko# vend", /*spanish*/"el #bazar de Kakariko# ofrece"}, - }); - - hintTable[KAK_BAZAAR_ITEM_2] = HintText::Exclude({ - //obscure text - Text{"the #Kakariko Bazaar# offers", /*french*/"le #bazar de Kakariko# vend", /*spanish*/"el #bazar de Kakariko# ofrece"}, - }); - - hintTable[KAK_BAZAAR_ITEM_3] = HintText::Exclude({ - //obscure text - Text{"the #Kakariko Bazaar# offers", /*french*/"le #bazar de Kakariko# vend", /*spanish*/"el #bazar de Kakariko# ofrece"}, - }); - - hintTable[KAK_BAZAAR_ITEM_4] = HintText::Exclude({ - //obscure text - Text{"the #Kakariko Bazaar# offers", /*french*/"le #bazar de Kakariko# vend", /*spanish*/"el #bazar de Kakariko# ofrece"}, - }); - - hintTable[KAK_BAZAAR_ITEM_5] = HintText::Exclude({ - //obscure text - Text{"the #Kakariko Bazaar# offers", /*french*/"le #bazar de Kakariko# vend", /*spanish*/"el #bazar de Kakariko# ofrece"}, - }); - - hintTable[KAK_BAZAAR_ITEM_6] = HintText::Exclude({ - //obscure text - Text{"the #Kakariko Bazaar# offers", /*french*/"le #bazar de Kakariko# vend", /*spanish*/"el #bazar de Kakariko# ofrece"}, - }); - - hintTable[KAK_BAZAAR_ITEM_7] = HintText::Exclude({ - //obscure text - Text{"the #Kakariko Bazaar# offers", /*french*/"le #bazar de Kakariko# vend", /*spanish*/"el #bazar de Kakariko# ofrece"}, - }); - - hintTable[KAK_BAZAAR_ITEM_8] = HintText::Exclude({ - //obscure text - Text{"the #Kakariko Bazaar# offers", /*french*/"le #bazar de Kakariko# vend", /*spanish*/"el #bazar de Kakariko# ofrece"}, - }); - - - hintTable[ZD_SHOP_ITEM_1] = HintText::Exclude({ - //obscure text - Text{"a #Zora shopkeeper# sells", /*french*/"la #boutique Zora# vend", /*spanish*/"el #dependiente Zora# vende"}, - }); - - hintTable[ZD_SHOP_ITEM_2] = HintText::Exclude({ - //obscure text - Text{"a #Zora shopkeeper# sells", /*french*/"la #boutique Zora# vend", /*spanish*/"el #dependiente Zora# vende"}, - }); - - hintTable[ZD_SHOP_ITEM_3] = HintText::Exclude({ - //obscure text - Text{"a #Zora shopkeeper# sells", /*french*/"la #boutique Zora# vend", /*spanish*/"el #dependiente Zora# vende"}, - }); - - hintTable[ZD_SHOP_ITEM_4] = HintText::Exclude({ - //obscure text - Text{"a #Zora shopkeeper# sells", /*french*/"la #boutique Zora# vend", /*spanish*/"el #dependiente Zora# vende"}, - }); - - hintTable[ZD_SHOP_ITEM_5] = HintText::Exclude({ - //obscure text - Text{"a #Zora shopkeeper# sells", /*french*/"la #boutique Zora# vend", /*spanish*/"el #dependiente Zora# vende"}, - }); - - hintTable[ZD_SHOP_ITEM_6] = HintText::Exclude({ - //obscure text - Text{"a #Zora shopkeeper# sells", /*french*/"la #boutique Zora# vend", /*spanish*/"el #dependiente Zora# vende"}, - }); - - hintTable[ZD_SHOP_ITEM_7] = HintText::Exclude({ - //obscure text - Text{"a #Zora shopkeeper# sells", /*french*/"la #boutique Zora# vend", /*spanish*/"el #dependiente Zora# vende"}, - }); - - hintTable[ZD_SHOP_ITEM_8] = HintText::Exclude({ - //obscure text - Text{"a #Zora shopkeeper# sells", /*french*/"la #boutique Zora# vend", /*spanish*/"el #dependiente Zora# vende"}, - }); - - - hintTable[GC_SHOP_ITEM_1] = HintText::Exclude({ - //obscure text - Text{"a #Goron shopkeeper# sells", /*french*/"la #boutique Goron# vend", /*spanish*/"el #dependiente Goron# vende"}, - }); - - hintTable[GC_SHOP_ITEM_2] = HintText::Exclude({ - //obscure text - Text{"a #Goron shopkeeper# sells", /*french*/"la #boutique Goron# vend", /*spanish*/"el #dependiente Goron# vende"}, - }); - - hintTable[GC_SHOP_ITEM_3] = HintText::Exclude({ - //obscure text - Text{"a #Goron shopkeeper# sells", /*french*/"la #boutique Goron# vend", /*spanish*/"el #dependiente Goron# vende"}, - }); - - hintTable[GC_SHOP_ITEM_4] = HintText::Exclude({ - //obscure text - Text{"a #Goron shopkeeper# sells", /*french*/"la #boutique Goron# vend", /*spanish*/"el #dependiente Goron# vende"}, - }); - - hintTable[GC_SHOP_ITEM_5] = HintText::Exclude({ - //obscure text - Text{"a #Goron shopkeeper# sells", /*french*/"la #boutique Goron# vend", /*spanish*/"el #dependiente Goron# vende"}, - }); - - hintTable[GC_SHOP_ITEM_6] = HintText::Exclude({ - //obscure text - Text{"a #Goron shopkeeper# sells", /*french*/"la #boutique Goron# vend", /*spanish*/"el #dependiente Goron# vende"}, - }); - - hintTable[GC_SHOP_ITEM_7] = HintText::Exclude({ - //obscure text - Text{"a #Goron shopkeeper# sells", /*french*/"la #boutique Goron# vend", /*spanish*/"el #dependiente Goron# vende"}, - }); - - hintTable[GC_SHOP_ITEM_8] = HintText::Exclude({ - //obscure text - Text{"a #Goron shopkeeper# sells", /*french*/"la #boutique Goron# vend", /*spanish*/"el #dependiente Goron# vende"}, - }); - - - hintTable[HF_DEKU_SCRUB_GROTTO] = HintText::Exclude({ - //obscure text - Text{"a lonely #scrub in a hole# sells", /*french*/"la #peste Mojo dans une grotte de la plaine# vend", /*spanish*/"un #singular deku bajo un hoyo# de la llanura vende"}, - }); - - hintTable[LLR_DEKU_SCRUB_GROTTO_LEFT] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo à la ferme# vend", /*spanish*/"un #trío de dekus# de una granja venden"}, - }); - - hintTable[LLR_DEKU_SCRUB_GROTTO_RIGHT] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo à la ferme# vend", /*spanish*/"un #trío de dekus# de una granja venden"}, - }); - - hintTable[LLR_DEKU_SCRUB_GROTTO_CENTER] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo à la ferme# vend", /*spanish*/"un #trío de dekus# de una granja venden"}, - }); - - - hintTable[LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = HintText::Exclude({ - //obscure text - Text{"a pair of #scrubs in the woods# sells", /*french*/"le #duo de peste Mojo près du théâtre# vend", /*spanish*/"un par de #dekus del bosque# venden"}, - }); - - hintTable[LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = HintText::Exclude({ - //obscure text - Text{"a pair of #scrubs in the woods# sells", /*french*/"le #duo de peste Mojo près du théâtre# vend", /*spanish*/"un par de #dekus del bosque# venden"}, - }); - - hintTable[LW_DEKU_SCRUB_NEAR_BRIDGE] = HintText::Exclude({ - //obscure text - Text{"a #scrub by a bridge# sells", /*french*/"la #peste Mojo près du pont dans les bois# vend", /*spanish*/"un #deku bajo un puente# del bosque venden"}, - }); - - hintTable[LW_DEKU_SCRUB_GROTTO_REAR] = HintText::Exclude({ - //obscure text - Text{"a #scrub underground duo# sells", /*french*/"le #duo de peste Mojo dans les sous-bois# vend", /*spanish*/"un #par de dekus subterráneos# del bosque venden"}, - }); - - hintTable[LW_DEKU_SCRUB_GROTTO_FRONT] = HintText::Exclude({ - //obscure text - Text{"a #scrub underground duo# sells", /*french*/"le #duo de peste Mojo dans les sous-bois# vend", /*spanish*/"un #par de dekus subterráneos# del bosque venden"}, - }); - - - hintTable[SFM_DEKU_SCRUB_GROTTO_REAR] = HintText::Exclude({ - //obscure text - Text{"a #scrub underground duo# sells", /*french*/"le #duo de peste Mojo au cœur du sanctuaire sylvestre# vend", /*spanish*/"un #par de dekus subterráneos# de la pradera sagrada venden"}, - }); - - hintTable[SFM_DEKU_SCRUB_GROTTO_FRONT] = HintText::Exclude({ - //obscure text - Text{"a #scrub underground duo# sells", /*french*/"le #duo de peste Mojo au cœur du sanctuaire sylvestre# vend", /*spanish*/"un #par de dekus subterráneos# de la pradera sagrada venden"}, - }); - - - hintTable[GC_DEKU_SCRUB_GROTTO_LEFT] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo dans le village Goron# vend", /*spanish*/"un #trío de dekus# de la Ciudad Goron venden"}, - }); - - hintTable[GC_DEKU_SCRUB_GROTTO_RIGHT] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo dans le village Goron# vend", /*spanish*/"un #trío de dekus# de la Ciudad Goron venden"}, - }); - - hintTable[GC_DEKU_SCRUB_GROTTO_CENTER] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo dans le village Goron# vend", /*spanish*/"un #trío de dekus# de la Ciudad Goron venden"}, - }); - - - hintTable[DMC_DEKU_SCRUB_GROTTO_LEFT] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo dans le volcan# vend", /*spanish*/"un #trío de dekus# del volcán venden"}, - }); - - hintTable[DMC_DEKU_SCRUB_GROTTO_RIGHT] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo dans le volcan# vend", /*spanish*/"un #trío de dekus# del volcán venden"}, - }); - - hintTable[DMC_DEKU_SCRUB_GROTTO_CENTER] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo dans le volcan# vend", /*spanish*/"un #trío de dekus# del volcán venden"}, - }); - - - hintTable[ZR_DEKU_SCRUB_GROTTO_REAR] = HintText::Exclude({ - //obscure text - Text{"a #scrub underground duo# sells", /*french*/"le #duo de peste Mojo près du fleuve# vend", /*spanish*/"un #par de dekus subterráneos# del río venden"}, - }); - - hintTable[ZR_DEKU_SCRUB_GROTTO_FRONT] = HintText::Exclude({ - //obscure text - Text{"a #scrub underground duo# sells", /*french*/"le #duo de peste Mojo près du fleuve# vend", /*spanish*/"un #par de dekus subterráneos# del río venden"}, - }); - - - hintTable[LH_DEKU_SCRUB_GROTTO_LEFT] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo près du lac# vend", /*spanish*/"un #trío de dekus# del lago venden"}, - }); - - hintTable[LH_DEKU_SCRUB_GROTTO_RIGHT] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo près du lac# vend", /*spanish*/"un #trío de dekus# del lago venden"}, - }); - - hintTable[LH_DEKU_SCRUB_GROTTO_CENTER] = HintText::Exclude({ - //obscure text - Text{"a #trio of scrubs# sells", /*french*/"le #trio de peste Mojo près du lac# vend", /*spanish*/"un #trío de dekus# del lago venden"}, - }); - - - hintTable[GV_DEKU_SCRUB_GROTTO_REAR] = HintText::Exclude({ - //obscure text - Text{"a #scrub underground duo# sells", /*french*/"le #duo de peste Mojo près de la vallée# vend", /*spanish*/"un #par de dekus subterráneos# del valle venden"}, - }); - - hintTable[GV_DEKU_SCRUB_GROTTO_FRONT] = HintText::Exclude({ - //obscure text - Text{"a #scrub underground duo# sells", /*french*/"le #duo de peste Mojo près de la vallée# vend", /*spanish*/"un #par de dekus subterráneos# del valle venden"}, - }); - - - hintTable[COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = HintText::Exclude({ - //obscure text - Text{"a #scrub underground duo# sells", /*french*/"le #duo de peste Mojo dans le désert# vend", /*spanish*/"un #par de dekus subterráneos# del desierto venden"}, - }); - - hintTable[COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = HintText::Exclude({ - //obscure text - Text{"a #scrub underground duo# sells", /*french*/"le #duo de peste Mojo dans le désert# vend", /*spanish*/"un #par de dekus subterráneos# del desierto venden"}, - }); - - - hintTable[LLR_STABLES_LEFT_COW] = HintText::Exclude({ - //obscure text - Text{"a #cow in a stable# gifts", /*french*/"la #vache dans l'étable# donne", /*spanish*/"una #vaca del establo# brinda"}, - }); - - hintTable[LLR_STABLES_RIGHT_COW] = HintText::Exclude({ - //obscure text - Text{"a #cow in a stable# gifts", /*french*/"la #vache dans l'étable# donne", /*spanish*/"una #vaca del establo# brinda"}, - }); - - hintTable[LLR_TOWER_RIGHT_COW] = HintText::Exclude({ - //obscure text - Text{"a #cow in a ranch silo# gifts", /*french*/"la #vache dans le silo de la ferme# donne", /*spanish*/"una #vaca del granero# brinda"}, - }); - - hintTable[LLR_TOWER_LEFT_COW] = HintText::Exclude({ - //obscure text - Text{"a #cow in a ranch silo# gifts", /*french*/"la #vache dans le silo de la ferme# donne", /*spanish*/"una #vaca del granero# brinda"}, - }); - - hintTable[KAK_IMPAS_HOUSE_COW] = HintText::Exclude({ - //obscure text - Text{"a #cow imprisoned in a house# protects", /*french*/"la #vache en cage# donne", /*spanish*/"una #vaca enjaulada de una casa# brinda"}, - }); - - hintTable[DMT_COW_GROTTO_COW] = HintText::Exclude({ - //obscure text - Text{"a #cow in a luxurious hole# offers", /*french*/"la #vache dans une grotte luxueuse# donne", /*spanish*/"una #vaca de un lujoso hoyo# brinda"}, - }); +#include "../../static_data.h" +#include "../hints.hpp" +#include "../../../custom-message/CustomMessageManager.h" + +namespace Rando { +void StaticData::HintTable_Init_Exclude_Overworld() { + + hintTextTable[RHT_KF_KOKIRI_SWORD_CHEST] = HintText(CustomMessage("They say that the #hidden treasure of the Kokiri# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #versteckte Schatz der Kokiri# #[[1]]# sei.", + /*french*/ "Selon moi, le #trésor des Kokiri# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #tesoro oculto de los Kokiri# esconde #[[1]]#. + + hintTextTable[RHT_KF_MIDOS_TOP_LEFT_CHEST] = HintText(CustomMessage("They say that #inside Mido's house# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #in Midos Haus# #[[1]]# sei.", + /*french*/ "Selon moi, #dans la maison de Mido# gît #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, en la #casa de Mido# yace #[[1]]#. + {}, { + CustomMessage("They say that the #leader of the Kokiri# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Anführer der Kokiri# #[[1]]# verstecke.", + /*french*/ "Selon moi, le #chef des Kokiri# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #líder de los Kokiri# esconde #[[1]]#. + + hintTextTable[RHT_KF_MIDOS_TOP_RIGHT_CHEST] = HintText(CustomMessage("They say that #inside Mido's house# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #in Midos Haus# #[[1]]# sei.", + /*french*/ "Selon moi, #dans la maison de Mido# gît #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, en la #casa de Mido# yace #[[1]]#. + {}, { + CustomMessage("They say that the #leader of the Kokiri# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Anführer der Kokiri# #[[1]]# verstecke.", + /*french*/ "Selon moi, le #chef des Kokiri# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #líder de los Kokiri# esconde #[[1]]#. + + hintTextTable[RHT_KF_MIDOS_BOTTOM_LEFT_CHEST] = HintText(CustomMessage("They say that #inside Mido's house# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #in Midos Haus# #[[1]]# sei.", + /*french*/ "Selon moi, #dans la maison de Mido# gît #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, en la #casa de Mido# yace #[[1]]#. + {}, { + CustomMessage("They say that the #leader of the Kokiri# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Anführer der Kokiri# #[[1]]# verstecke.", + /*french*/ "Selon moi, le #chef des Kokiri# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #líder de los Kokiri# esconde #[[1]]#. + + hintTextTable[RHT_KF_MIDOS_BOTTOM_RIGHT_CHEST] = HintText(CustomMessage("They say that #inside Mido's house# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #in Midos Haus# #[[1]]# sei.", + /*french*/ "Selon moi, #dans la maison de Mido# gît #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, en la #casa de Mido# yace #[[1]]#. + {}, { + CustomMessage("They say that the #leader of the Kokiri# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Anführer der Kokiri# #[[1]]# verstecke.", + /*french*/ "Selon moi, le #chef des Kokiri# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #líder de los Kokiri# esconde #[[1]]#. + + hintTextTable[RHT_GRAVEYARD_SHIELD_GRAVE_CHEST] = HintText(CustomMessage("They say that the #treasure of a fallen soldier# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Schatz eines gefallenen Soldaten# #[[1]]# sei.", + /*french*/ "Selon moi, le #trésor du soldat mort# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #tesoro de un soldado caído# esconde #[[1]]#. + + hintTextTable[RHT_DMT_CHEST] = HintText(CustomMessage("They say that hidden behind a wall on a #mountain trail# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß hinter einer Wand des #Gebirgspfads# #[[1]]# sei.", + /*french*/ "Selon moi, derrière une façade du #chemin montagneux# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, tras una pared del #sendero de la montaña# yace #[[1]]#. + + hintTextTable[RHT_GC_MAZE_RIGHT_CHEST] = HintText(CustomMessage("They say that in #Goron City# explosives unlock #[[1]]#.", + /*german*/ "Man erzählt sich, daß in #Goronia# Explosionen #[[1]]# freischalten würden.", + /*french*/ "Selon moi, des explosions dans le #village Goron# révèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en la #Ciudad Goron# unos explosivos desbloquean #[[1]]#. + + hintTextTable[RHT_GC_MAZE_CENTER_CHEST] = HintText(CustomMessage("They say that in #Goron City# explosives unlock #[[1]]#.", + /*german*/ "Man erzählt sich, daß in #Goronia# Explosionen #[[1]]# freischalten würden.", + /*french*/ "Selon moi, des explosions dans le #village Goron# révèlent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en la #Ciudad Goron# unos explosivos desbloquean #[[1]]#. + + hintTextTable[RHT_ZD_CHEST] = HintText(CustomMessage("They say that fire #beyond a waterfall# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß Feuer #hinter einem Wasserfall# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, du feu #derrière la cascade# éclaire #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #llamas tras una una cascada# revelan #[[1]]#. + + hintTextTable[RHT_GRAVEYARD_HOOKSHOT_CHEST] = HintText(CustomMessage("They say that #dead Dampé's first prize# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Igors erster Preis# #[[1]]# sei.", + /*french*/ "Selon moi, la #première course d'Igor# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, el primer premio de #la carrera de Dampé# se trata de #[[1]]#. + {}, { + CustomMessage("They say that a chest hidden by a #speedy spectre# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine von einem #schnellen Gespenst# versteckte Truhe #[[1]]# enthielte.", + /*french*/ "Selon moi, le #coffre du rapide revenant# contient #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un cofre custodiado por un #espectro veloz# contiene #[[1]]#. + + hintTextTable[RHT_GF_CHEST] = HintText(CustomMessage("They say that on a #rooftop in the desert# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf einem #Dach in der Wüste# #[[1]]# läge.", + /*french*/ "Selon moi, sur un #toit du désert# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en una #azotea del desierto# yace #[[1]]#. + + hintTextTable[RHT_KAK_REDEAD_GROTTO_CHEST] = HintText(CustomMessage("They say that #zombies beneath the earth# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Untoten unter der Erde# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #revenants sous terre# protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unos #zombis subterráneos# esconden #[[1]]#. + + hintTextTable[RHT_SFM_WOLFOS_GROTTO_CHEST] = HintText(CustomMessage("They say that #wolves beneath the earth# guard #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Wölfe unter der Erde# #[[1]]# bewachen würden.", + /*french*/ "Selon moi, les #loups sous terre# protègent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, unos #lobos subterráneos# esconden #[[1]]#. + + hintTextTable[RHT_HF_NEAR_MARKET_GROTTO_CHEST] = HintText(CustomMessage("They say that a #hole in a field near a drawbridge# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Loch in einem Feld nahe der Zugbrücke# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte près d'un pont# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo de una llanura cercano a un puente# yace #[[1]]#. + + hintTextTable[RHT_HF_NEAR_MARKET_GROTTO_FISH] = HintText(CustomMessage("They say that a #fish in a hole in a field near a drawbridge# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Fisch in einem Loch in einem Feld nahe der Zugbrücke# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte près d'un pont# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo de una llanura cercano a un puente# yace #[[1]]#. + + hintTextTable[RHT_HF_SOUTHEAST_GROTTO_CHEST] = HintText(CustomMessage("They say that a #hole amongst trees in a field# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Loch inmitten der Bäume in einem Feld# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte près des arbres# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo de una llanura rodeado de árboles# yace #[[1]]#. + + hintTextTable[RHT_HF_SOUTHEAST_GROTTO_FISH] = HintText(CustomMessage("They say that a #fish in a hole amongst trees in a field# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Fisch in einem Loch inmitten von Bäumen in einem Feld# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte près des arbres# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo de una llanura rodeado de árboles# yace #[[1]]#. + + hintTextTable[RHT_HF_OPEN_GROTTO_CHEST] = HintText(CustomMessage("They say that an #open hole in a field# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #offenes Loch in einem Feld# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte dans les plaines# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo descubierto de una llanura# yace #[[1]]#. + + hintTextTable[RHT_HF_OPEN_GROTTO_FISH] = HintText(CustomMessage("They say that a #fish in an open hole in a field# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Fisch in einem offenen Loch auf einem Feld# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte dans les plaines# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo descubierto de una llanura# yace #[[1]]#. + + hintTextTable[RHT_KAK_OPEN_GROTTO_CHEST] = HintText(CustomMessage("They say that an #open hole in a town# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #offenes Loch in einer Stadt# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte dans le village# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo descubierto de un pueblo# yace #[[1]]#. + + hintTextTable[RHT_KAK_OPEN_GROTTO_FISH] = HintText(CustomMessage("They say that a #fish in an open hole in a town# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Fisch in einem Loch in einer Stadt# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte dans le village# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo descubierto de un pueblo# yace #[[1]]#. + + hintTextTable[RHT_ZR_OPEN_GROTTO_CHEST] = HintText(CustomMessage("They say that a #hole along a river# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Loch entlang eines Flusses# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte près du fleuve# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo un #hoyo junto a un río# yace #[[1]]#. + + hintTextTable[RHT_ZR_OPEN_GROTTO_FISH] = HintText(CustomMessage("They say that a #fish in a hole along a river# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Fisch in einem Loch entlang eines Flusses# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte près du fleuve# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo un #hoyo junto a un río# yace #[[1]]#. + + hintTextTable[RHT_KF_STORMS_GROTTO_CHEST] = HintText(CustomMessage("They say that a #hole in a forest village# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Loch in einem Dorf des Waldes# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte inondée de pluie dans le Village Kokiri# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo de una tribu del bosque# yace #[[1]]#. + + hintTextTable[RHT_KF_STORMS_GROTTO_FISH] = HintText(CustomMessage("They say that a #fish in a hole in a forest village# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Fisch in einem Loch in einem Dorf des Waldes# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte inondée de pluie dans le Village Kokiri# révèle #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo de una tribu del bosque# yace #[[1]]#. + + hintTextTable[RHT_LW_NEAR_SHORTCUTS_GROTTO_CHEST] = HintText(CustomMessage("They say that a #hole in a wooded maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Loch in einem hölzernen Labyrinth# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte dans le labyrinthe sylvestre# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo un #hoyo de un laberinto forestal# yace #[[1]]#. + + hintTextTable[RHT_LW_NEAR_SHORTCUTS_GROTTO_FISH] = HintText(CustomMessage("They say that a #fish in a hole in a wooded maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Fisch in einem Loch in einem hölzernen Labyrinth# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte dans le labyrinthe sylvestre# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo un #hoyo de un laberinto forestal# yace #[[1]]#. + + hintTextTable[RHT_DMT_STORMS_GROTTO_CHEST] = HintText(CustomMessage("They say that #hole flooded with rain on a mountain# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #durch Regen geflutetes Loch auf einem Berg# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte inondée de pluie sur la montagne# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo un #hoyo de una montaña inundado de lluvia# yace #[[1]]#. + + hintTextTable[RHT_DMT_STORMS_GROTTO_FISH] = HintText(CustomMessage("They say that #fish in a hole flooded with rain on a mountain# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Fisch in einem durch Regen geflutetes Loch auf einem Berg# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte inondée de pluie sur la montagne# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo un #hoyo de una montaña inundado de lluvia# yace #[[1]]#. + + hintTextTable[RHT_DMC_UPPER_GROTTO_CHEST] = HintText(CustomMessage("They say that a #hole in a volcano# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Loch in einem Vulkan# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte dans le volcan# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo de un volcán# yace #[[1]]#. + + hintTextTable[RHT_DMC_UPPER_GROTTO_FISH] = HintText(CustomMessage("They say that a #fish in a hole in a volcano# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Fisch in einem Loch in einem Vulkan# #[[1]]# enthielte.", + /*french*/ "Selon moi, la #grotte dans le volcan# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo el #hoyo de un volcán# yace #[[1]]#. + + hintTextTable[RHT_TOT_MASTER_SWORD] = HintText(CustomMessage("They say that a #pedestal in a temple# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich auf einem #Podest in einem Tempel# #[[1]]# befände.", + /*french*/ "Selon moi, un #piédestal dans un temple# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #pedestal en un templo# sostiene #[[1]]#. + + hintTextTable[RHT_TOT_LIGHT_ARROWS_CUTSCENE] = HintText(CustomMessage("They say that the #final gift of a princess# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #letzte Geschenk einer Prinzessin# #[[1]]# sei.", + /*french*/ "Selon moi, le #cadeau d'adieu de la princesse# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #obsequio final de la princesa# se trata de #[[1]]#. + + hintTextTable[RHT_LW_GIFT_FROM_SARIA] = HintText(CustomMessage("They say that #Saria's Gift# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Salias Geschenk# #[[1]]# sei.", + /*french*/ "Selon moi, le #cadeau de Saria# est #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, el #regalo de Saria# se trata de #[[1]]#. + {}, { + CustomMessage("They say that a #potato hoarder# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Kartoffelhortender# #[[1]]# besäße.", + /*french*/ "Selon moi, le #panini mélodieux# est en fait #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, cierta #jovencita verde# concede #[[1]]#. + CustomMessage("They say that a rooty tooty #flutey cutey# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #musikalische Kartoffel# #[[1]]# schenke.", + /*french*/ "Selon moi, la #patate musicale# est en fait #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, una #gran amiga# concede #[[1]]#. + + hintTextTable[RHT_ZF_GREAT_FAIRY_REWARD] = HintText(CustomMessage("They say that the #fairy of winds# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Fee der Winde# #[[1]]# besäße.", + /*french*/ "Selon moi, la #fée du vent# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #hada del viento# brinda #[[1]]#. + + hintTextTable[RHT_HC_GREAT_FAIRY_REWARD] = HintText(CustomMessage("They say that the #fairy of fire# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Fee des Feuers# #[[1]]# besäße.", + /*french*/ "Selon moi, la #fée du feu# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #hada del fuego# brinda #[[1]]#. + + hintTextTable[RHT_COLOSSUS_GREAT_FAIRY_REWARD] = HintText(CustomMessage("They say that the #fairy of love# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Fee der Liebe# #[[1]]# besäße.", + /*french*/ "Selon moi, la #fée de l'amour# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #hada del amor# brinda #[[1]]#. + + hintTextTable[RHT_DMT_GREAT_FAIRY_REWARD] = HintText(CustomMessage("They say that a #magical fairy# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #magische Fee# #[[1]]# schenke.", + /*french*/ "Selon moi, la #fée de la magie# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #hada mágica# brinda #[[1]]#. + + hintTextTable[RHT_DMC_GREAT_FAIRY_REWARD] = HintText(CustomMessage("They say that a #magical fairy# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #magische Fee# #[[1]]# schenke.", + /*french*/ "Selon moi, la #fée de la magie# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #hada mágica# brinda #[[1]]#. + + hintTextTable[RHT_OGC_GREAT_FAIRY_REWARD] = HintText(CustomMessage("They say that the #fairy of strength# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Fee der Stärke# #[[1]]# besäße.", + /*french*/ "Selon moi, la #fée de la force# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #hada de la fuerza# brinda #[[1]]#. + + hintTextTable[RHT_SONG_FROM_IMPA] = HintText(CustomMessage("They say that #deep in a castle#, Impa teaches #[[1]]#.", + /*german*/ "Man erzählt sich, daß #tief in einem Schloß#, Impa #[[1]]# lehre.", + /*french*/ "Selon moi, #la gardienne de la princesse# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en el #jardín del castillo Impa enseña# #[[1]]#. + + hintTextTable[RHT_SONG_FROM_MALON] = HintText(CustomMessage("They say that #a farm girl# sings #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Mädchen des Landes# #[[1]]# singe.", + /*french*/ "Selon moi, la #fillette de la ferme# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #chica rupestre# canta #[[1]]#. + + hintTextTable[RHT_SONG_FROM_SARIA] = HintText(CustomMessage("They say that #deep in the forest#, Saria teaches #[[1]]#.", + /*german*/ "Man erzählt sich, daß #tief im Wald#, Salia #[[1]]# lehre.", + /*french*/ "Selon moi, la #fille de la forêt# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, al #fondo del bosque# Saria enseña #[[1]]#. + + hintTextTable[RHT_SONG_FROM_WINDMILL] = HintText(CustomMessage("They say that a man #in a windmill# is obsessed with #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein Mann #in einer Windmühle# von #[[1]]# besessen sei.", + /*french*/ "Selon moi, l'#homme du moulin# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #hombre del molino# está obsesionado con #[[1]]#. + + hintTextTable[RHT_HC_MALON_EGG] = HintText(CustomMessage("They say that a #girl looking for her father# gives #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #nach ihrem Vater suchenden Mädchen# #[[1]]# gäbe.", + /*french*/ "Selon moi, la #fillette qui cherche son père# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #chica en busca de su padre# otorga #[[1]]#. + + hintTextTable[RHT_HC_ZELDAS_LETTER] = HintText(CustomMessage("They say that a #princess in a castle# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Prinzessin in einem Schloß# #[[1]]# schenke.", + /*french*/ "Selon moi, la #princesse dans le château# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #princesa de un castillo# otorga #[[1]]#. + + hintTextTable[RHT_ZD_DIVING_MINIGAME] = HintText(CustomMessage("They say that those who #dive for Zora rupees# will find #[[1]]#.", + /*german*/ "Man erzählt sich, daß jene, welche nach den #Rubinen der Zora tauchen# #[[1]]# fänden.", + /*french*/ "Selon moi, ceux qui #plongent pour des rubis Zora# trouveront #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, aquellos que se #sumergan por las rupias zora# encontrarán #[[1]]#. + {}, { + CustomMessage("They say that an #unsustainable business model# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #unwirtschaftliches Geschäftsmodell# #[[1]]# schenke.", + /*french*/ "Selon moi, le #mauvais modèle d'affaires# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #mal modelo de negocio# premia con #[[1]]#. + + hintTextTable[RHT_LH_CHILD_FISHING] = HintText(CustomMessage("They say that #fishing in youth# bestows #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Fischen in der Jugend# #[[1]]# verleihe.", + /*french*/ "Selon moi, #pêcher dans sa jeunesse# promet #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #pescar en la juventud# conduce a #[[1]]#. + + hintTextTable[RHT_LH_POND_FISH] = HintText(CustomMessage("They say that #hitting the pond# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Fischen im Teich# #[[1]]# enthülle.", + /*french*/ "Selon moi, #[[1]]#.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LH_HYRULE_LOACH] = HintText(CustomMessage("They say that #fishing the hyrule loach# will give you #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Fischen der hylianischen Schmerle# #[[1]]# einbrächte.", + /*french*/ "Selon moi, !!! #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, si #pescas a la Locha de Hyrule# encontrarás #[[1]]#. + {}, { + CustomMessage("They say that #fishing the legend# bestows #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Fischen der Legende# #[[1]]# verleihe.", + /*french*/ "Selon moi, !!! #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, #pescar a la leyenda# conduce a #[[1]]#. + + hintTextTable[RHT_LH_ADULT_FISHING] = HintText(CustomMessage("They say that #fishing in maturity# bestows #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Fischen im Alter# #[[1]]# verleihe.", + /*french*/ "Selon moi, #pêcher dans sa maturité# promet #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #pescar en la madurez# conduce a #[[1]]#. + + hintTextTable[RHT_LH_LAB_DIVE] = HintText(CustomMessage("They say that a #diving experiment# is rewarded with #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Tauchexperiment# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, l'#expérience de plongée# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #bucear para un experimento# se premia con #[[1]]#. + // RANDOTODO: needs translation + hintTextTable[RHT_ZD_FISH] = HintText(CustomMessage("They say that a #fish by a waterfall# hoards #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Fisch nahe eines Wasserfalls# #[[1]]# horte.", + /*french*/ "Selon moi, #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #[[1]]#. + + + hintTextTable[RHT_GC_ROLLING_GORON_AS_ADULT] = HintText(CustomMessage("They say that #reassuring a young Goron# is rewarded with #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Beruhigen eines jungen Goronen# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #rassurer un jeune Goron# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #calmar a un joven Goron# otorga #[[1]]#. + {}, { + CustomMessage("They say that #comforting yourself# provides #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Ermutigung von einem Selbst# #[[1]]# einbrächte.", + /*french*/ "Selon moi, se #réconforter soi-même# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, #confrontarte a ti mismo# otorga #[[1]]#. + + hintTextTable[RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = HintText(CustomMessage("They say that the #first explosive prize# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #erste explosive Preis# #[[1]]# sei.", + /*french*/ "Selon moi, le #premier prix explosif# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #primer premio explosivo# se trata de #[[1]]#. + + hintTextTable[RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = HintText(CustomMessage("They say that the #second explosive prize# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #zweite explosive Preis# #[[1]]# sei.", + /*french*/ "Selon moi, le #deuxième prix explosif# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #segundo premio explosivo# se trata de #[[1]]#. + + hintTextTable[RHT_MARKET_LOST_DOG] = HintText(CustomMessage("They say that #rescuing Richard the Dog# is rewarded with #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Rettung des Hundes Richard# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #retrouver Kiki le chien# promet #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #rescatar al perrito Ricardo# conduce a #[[1]]#. + {}, { + CustomMessage("They say that #puppy lovers# will find #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Welpenliebhaber# #[[1]]# fänden.", + /*french*/ "Selon moi, les #amoureux canins# trouveront #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, los #amantes caninos# encontrarán #[[1]]#. + + hintTextTable[RHT_LW_OCARINA_MEMORY_GAME] = HintText(CustomMessage("They say that #playing an Ocarina in Lost Woods# is rewarded with #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Spielen der Okarina in den verlorenen Wäldern# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #jouer l'ocarina dans les Bois Perdus# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #tocar la ocarina en el Bosque Perdido# otorga #[[1]]#. + {}, { + CustomMessage("They say that the prize for a #game of Simon Says# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der Preis für eine Partie #Simon sagt# #[[1]]# sei.", + /*french*/ "Selon moi, la #récompense de Jean Dit# est #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #repetir ciertas melodías# otorga #[[1]]#. + CustomMessage("They say that a #child sing-a-long# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #jungen Flötisten# #[[1]]# besäßen.", + /*french*/ "Selon moi, les #jeunes flûtistes# donnent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, #tocar junto a otros# otorga #[[1]]#. + + hintTextTable[RHT_KAK_10_GOLD_SKULLTULA_REWARD] = HintText(CustomMessage("They say that slaying #10 Gold Skulltulas# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Besiegen von #10 Goldenen Skulltulas# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, détruire #10 Skulltulas d'or# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #exterminar 10 skulltulas doradas# revela #[[1]]#. + {}, { + CustomMessage("They say that #10 bug badges# rewards #[[1]]#.", + /*german*/ "Man erzählt sich, daß #10 Käferabzeichen# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #10 écussons# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #10 medallas de insectos# otorgan #[[1]]#. + CustomMessage("They say that #10 spider souls# yields #[[1]]#.", + /*german*/ "Man erzählt sich, daß #10 Spinnenseelen# #[[1]]# einbrächten.", + /*french*/ "Selon moi, #10 âmes# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, #10 almas de araña# otorgan #[[1]]#. + CustomMessage("They say that #10 auriferous arachnids# lead to #[[1]]#.", + /*german*/ "Man erzählt sich, daß #10 goldhaltige Arachniden# zu #[[1]]# führen würden.", + /*french*/ "Selon moi, #10 arachnides aurifères# donnent #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, #10 arácnidos auríferos# otorgan #[[1]]#. + + hintTextTable[RHT_KAK_MAN_ON_ROOF] = HintText(CustomMessage("They say that a #rooftop wanderer# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Dachwanderer# #[[1]]# besäße.", + /*french*/ "Selon moi, une #rencontre sur un toit# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #alguien sobre un tejado# otorga #[[1]]#. + + hintTextTable[RHT_ZR_MAGIC_BEAN_SALESMAN] = HintText(CustomMessage("They say that a #bean seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Bohnenverkäufer# #[[1]]# offeriere.", + /*french*/ "Selon moi, le #marchand de haricots magiques# vend en fait #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, el #vendedor de judías# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a seller of #colorful crops# has #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein Verkäufer #bunter Ernte# #[[1]]# besäße.", + /*french*/ "Selon moi, le #marchand de légumes# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el vendedor de un #colorido cultivo# ofrece #[[1]]#. + + hintTextTable[RHT_ZR_FROGS_IN_THE_RAIN] = HintText(CustomMessage("They say that #frogs in a storm# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Frösche im Sturm# #[[1]]# schenken würden.", + /*french*/ "Selon moi, #des grenouilles mouillées# donnent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, las #ancas bajo la tormenta# otorgan #[[1]]#. + + hintTextTable[RHT_ZR_FROGS_ZELDAS_LULLABY] = HintText(CustomMessage("They say that after hearing #Zelda's Lullaby, the frogs# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Frösche nach dem Hören von Zeldas Wiegenlied# #[[1]]# schenken würden.", + /*french*/ "Selon moi, à l'écoute de #la berceuse de Zelda, les grenouilles# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, después de escuchar #la Nana de Zelda, las ranas# regalan #[[1]]#. + {}, { + CustomMessage("They say that #sleepy frogs# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß #schläfrige Frösche# #[[1]]# schenken würden.", + /*french*/ "Selon moi, #les grenouilles somnolentes# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, las #ranas somnolientas# regalan #[[1]]#. + CustomMessage("They say that #the Froggish Tenor in the back-left# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß #der froschige Tenor hinten links# #[[1]]# schenke.", + /*french*/ "Selon moi, #le ténor grenouillesque au fond à gauche# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #Sapo Tenore al fondo, a la izquierda#, regala #[[1]]#. + + hintTextTable[RHT_ZR_FROGS_EPONAS_SONG] = HintText(CustomMessage("They say that after hearing #Epona's Song, the frogs# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Frösche nach dem Hören von Eponas Lied# #[[1]]# schenken würden.", + /*french*/ "Selon moi, à l'écoute du #chant d'Epona, les grenouilles# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, después de escuchar #la Canción de Epona, las ranas# regalan #[[1]]#. + {}, { + CustomMessage("They say that #equine frogs# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß #pferdeartige Frösche# #[[1]]# schenken würden.", + /*french*/ "Selon moi, #les grenouilles équestres# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, las #ranas equinas# regalan #[[1]]#. + CustomMessage("They say that #the Froggish Tenor in the back-right# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß #der froschige Tenor hinten rechts# #[[1]]# schenke.", + /*french*/ "Selon moi, #le ténor grenouillesque au fond à droite# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #Sapo Tenore al fondo, a la derecha#, regala #[[1]]#. + + hintTextTable[RHT_ZR_FROGS_SARIAS_SONG] = HintText(CustomMessage("They say that after hearing #Saria's Song, the frogs# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Frösche nach dem Hören von Salias Lied# #[[1]]# schenken würden.", + /*french*/ "Selon moi, à l'écoute du #chant de Saria, les grenouilles# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, después de escuchar #la Canción de Saria, las ranas# regalan #[[1]]#. + {}, { + CustomMessage("They say that #sylvan frogs# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß #waldige Frösche# #[[1]]# schenken würden.", + /*french*/ "Selon moi, #les grenouilles sylvestres# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, las #ranas silvestres# regalan #[[1]]#. + CustomMessage("They say that #the Froggish Tenor in the center# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß #der froschige Tenor im Zentrum# #[[1]]# schenke.", + /*french*/ "Selon moi, #le ténor grenouillesque dans le centre# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #Sapo Tenore en el centro# regala #[[1]]#. + + hintTextTable[RHT_ZR_FROGS_SUNS_SONG] = HintText(CustomMessage("They say that after hearing #the Sun's Song, the frogs# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Frösche nach dem Hören der Hymne der Sonne# #[[1]]# schenken würden.", + /*french*/ "Selon moi, à l'écoute du #chant du soleil, les grenouilles# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, después de escuchar #la Canción del Sol, las ranas# regalan #[[1]]#. + {}, { + CustomMessage("They say that #enlightened frogs# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß #erleuchtete Frösche# #[[1]]# schenken würden.", + /*french*/ "Selon moi, #les grenouilles éclairées# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, las #ranas alumbradas# regalan #[[1]]#. + CustomMessage("They say that #the Froggish Tenor in the front-left# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß #der froschige Tenor vorne links# #[[1]]# schenke.", + /*french*/ "Selon moi, #le ténor grenouillesque à l'avant gauche# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #Sapo Tenore al frente, a la izquierda#, regala #[[1]]#. + + hintTextTable[RHT_ZR_FROGS_SONG_OF_TIME] = HintText(CustomMessage("They say that after hearing #the Song of Time, the frogs# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Frösche nach dem Hören der Hymne der Zeit# #[[1]]# schenken würden.", + /*french*/ "Selon moi, à l'écoute du #chant du temps, les grenouilles# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, después de escuchar #la Canción del tiempo, las ranas# regalan #[[1]]#. + {}, { + CustomMessage("They say that #time-traveling frogs# gift #[[1]]#.", + /*german*/ "Man erzählt sich, daß #zeitreisende Frösche# #[[1]]# schenken würden.", + /*french*/ "Selon moi, #les grenouilles voyageuses dans le temps# donnent #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, las #ranas viajeras del tiempo# regalan #[[1]]#. + CustomMessage("They say that #the Froggish Tenor in the front-right# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß #der froschige Tenor vorne rechts# #[[1]]# schenke.", + /*french*/ "Selon moi, #le ténor grenouillesque à l'avant droite# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, el #Sapo Tenore al frente, a la derecha#, regala #[[1]]#. + + hintTextTable[RHT_GF_HBA_1000_POINTS] = HintText(CustomMessage("They say that scoring 1000 in #horseback archery# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Erzielen von 1000 Punkten beim #Pferdebogenschießen# #[[1]]# einbrächte.", + /*french*/ "Selon moi, obtenir 1000 points dans l'#archerie équestre# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, conseguir 1000 puntos en el #tiro con arco a caballo# premia #[[1]]#. + + hintTextTable[RHT_MARKET_SHOOTING_GALLERY_REWARD] = HintText(CustomMessage("They say that #shooting in youth# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Schießen in der Jugend# #[[1]]# einbrächte.", + /*french*/ "Selon moi, #faire du tir dans sa jeunesse# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #disparar en la juventud# otorga #[[1]]#. + + hintTextTable[RHT_KAK_SHOOTING_GALLERY_REWARD] = HintText(CustomMessage("They say that #shooting in maturity# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Schießen im Alter# #[[1]]# einbrächte.", + /*french*/ "Selon moi, #faire du tir dans sa maturité# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #disparar en la madurez# otorga #[[1]]#. + + hintTextTable[RHT_LW_TARGET_IN_WOODS] = HintText(CustomMessage("They say that shooting a #target in the woods# grants #[[1]]#.", + /*german*/ "Man erzählt sich, daß das Abschießen eines #Zieles in den Wäldern# #[[1]]# einbrächte.", + /*french*/ "Selon moi, #tirer une cible dans les bois# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, disparar a un #blanco forestal# brinda #[[1]]#. + + hintTextTable[RHT_KAK_ANJU_AS_ADULT] = HintText(CustomMessage("They say that a #chicken caretaker# offers adults #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Hühnchenpfleger# Erwachsenen #[[1]]# anböte.", + /*french*/ "Selon moi, devenir un #éleveur de Cocottes# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #cuidadora de emplumados# le ofrece a los mayores #[[1]]#. + + hintTextTable[RHT_LLR_TALONS_CHICKENS] = HintText(CustomMessage("They say that #finding Super Cuccos# is rewarded with #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Finden von Superhühnchen# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #trouver des Super Cocottes# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #hallar los supercucos# conduce a #[[1]]#. + + hintTextTable[RHT_GC_ROLLING_GORON_AS_CHILD] = HintText(CustomMessage("They say that the prize offered by a #large rolling Goron# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der angebotene Preis eines #großen rollenden Goronen# #[[1]]# sei.", + /*french*/ "Selon moi, la récompense d'un #gros Goron roulant# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #gran Goron rodante# otorga #[[1]]#. + + hintTextTable[RHT_LH_UNDERWATER_ITEM] = HintText(CustomMessage("They say that the #sunken treasure in a lake# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #versunkene Schatz in einem See# #[[1]]# sei.", + /*french*/ "Selon moi, le #trésor au fond du lac# est #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #tesoro hundido del lago# se trata de #[[1]]#. + + hintTextTable[RHT_GF_GERUDO_MEMBERSHIP_CARD] = HintText(CustomMessage("They say that #rescuing captured carpenters# is rewarded with #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Retten gefangener Zimmerleute# mit #[[1]]# belohnt würde.", + /*french*/ "Selon moi, #secourir les charpentiers capturés# assure #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #rescatar los apresados carpinteros# se premia con #[[1]]#. + + hintTextTable[RHT_WASTELAND_BOMBCHU_SALESMAN] = HintText(CustomMessage("They say that a #carpet guru# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Teppichguru# #[[1]]# verkaufe.", + /*french*/ "Selon moi, #un marchand du désert# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #genio de una alfombra# vende #[[1]]#. + + hintTextTable[RHT_GC_MEDIGORON] = HintText(CustomMessage("They say that #Medigoron# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Medigoron# #[[1]]# verkaufe.", + /*french*/ "Selon moi, #Medigoron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #Medigoron# vende #[[1]]#. + + hintTextTable[RHT_KAK_GRANNYS_SHOP] = HintText(CustomMessage("They say that the #potion shop lady# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Dame des Hexenladens# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #dame du magasin de potion# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la #señora de la tienda de pociones# vende #[[1]]#. + + hintTextTable[RHT_KAK_IMPAS_HOUSE_FREESTANDING_POH] = HintText(CustomMessage("They say that #imprisoned in a house# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß #eingesperrt in einem Haus# #[[1]]# läge.", + /*french*/ "Selon moi, #encagé dans une maison# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #en una casa entre rejas# yace #[[1]]#. + + hintTextTable[RHT_HF_TEKTITE_GROTTO_FREESTANDING_POH] = HintText(CustomMessage("They say that #deep underwater in a hole# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #tief unter Wasser in einem Loch# #[[1]]# sei.", + /*french*/ "Selon moi, #dans les profondeurs d'une grotte# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #en lo hondo bajo un hoyo# yace #[[1]]#. + + hintTextTable[RHT_KAK_WINDMILL_FREESTANDING_POH] = HintText(CustomMessage("They say that on a #windmill ledge# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf einem #Vorsprung in einer Windmühle# #[[1]]# läge.", + /*french*/ "Selon moi, #haut perché dans le moulin# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, al #borde de un molino# yace #[[1]]#. + + hintTextTable[RHT_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH] = HintText(CustomMessage("They say that #dead Dampe's second# prize is #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #zweite Preis des toten Boris# #[[1]]# sei.", + /*french*/ "Selon moi, la #deuxième course d'Igor# donne #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, el segundo premio de #la carrera de Dampé# se trata de #[[1]]#. + {}, { + CustomMessage("They say that #racing a ghost# leads to #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Rennen gegen einen Geist# zu #[[1]]# führen würde.", + /*french*/ "Selon moi, le défi du #revenant rapide# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, #perseguir a un fantasma# conduce a #[[1]]#. + + hintTextTable[RHT_LLR_FREESTANDING_POH] = HintText(CustomMessage("They say that in a #ranch silo# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß in einem #ländlichen Silo# #[[1]]# läge.", + /*french*/ "Selon moi, #dans l'entrepôt de la ferme# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en un #granero rupestre# yace #[[1]]#. + + hintTextTable[RHT_GRAVEYARD_FREESTANDING_POH] = HintText(CustomMessage("They say that a #crate in a graveyard# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Kiste auf einem Friedhof# #[[1]]# verberge.", + /*french*/ "Selon moi, #la boîte dans le Cimetière# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo la #caja de un cementerio# yace #[[1]]#. + + hintTextTable[RHT_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = HintText(CustomMessage("They say that a #gravekeeper digs up# #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Grabpfleger# #[[1]]# ausgrabe.", + /*french*/ "Selon moi, #le jeu du fossoyeur# cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, cierto #sepultero desentierra# #[[1]]#. + + hintTextTable[RHT_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = HintText(CustomMessage("They say that on top of a #pillar in a river# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf der Spitze einer #Säule in einem Fluß# #[[1]]# läge.", + /*french*/ "Selon moi, #sur un pilier au dessus du fleuve# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en lo alto del #pilar de un río# yace #[[1]]#. + + hintTextTable[RHT_ZR_NEAR_DOMAIN_FREESTANDING_POH] = HintText(CustomMessage("They say that on a #river ledge by a waterfall# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf einem #Vorsprung von einem Fluß nahe eines Wasserfalls# #[[1]]# läge.", + /*french*/ "Selon moi, #sur la falaise au dessus du fleuve# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, al borde de #la entrada a una cascada# yace #[[1]]#. + + hintTextTable[RHT_LH_FREESTANDING_POH] = HintText(CustomMessage("They say that high on a #lab rooftop# one can find #[[1]]#.", + /*german*/ "Man erzählt sich, daß man auf dem #Dach eines Laboratoriums# #[[1]]# finden könne.", + /*french*/ "Selon moi, #la tour d'observation du lac# cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en lo #alto de un laboratorio# yace #[[1]]#. + + hintTextTable[RHT_ZF_ICEBERG_FREESTANDING_POH] = HintText(CustomMessage("They say that #floating on ice# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß sich schwebend auf Eis #[[1]]# befände.", + /*french*/ "Selon moi, #gisant sur la glace# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #flotando sobre hielo# yace #[[1]]#. + + hintTextTable[RHT_GV_WATERFALL_FREESTANDING_POH] = HintText(CustomMessage("They say that behind a #valley waterfall# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß hinter einem #Wasserfall in einem Tal# #[[1]]# sei.", + /*french*/ "Selon moi, #derrière la cascade du désert# se cache #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, tras una #desierta cascada# yace #[[1]]#. + + hintTextTable[RHT_GV_CRATE_FREESTANDING_POH] = HintText(CustomMessage("They say that a #crate in a valley# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Kiste in einem Tal# #[[1]]# verberge.", + /*french*/ "Selon moi, la #boîte dans la vallée# contient #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo la #caja de un valle# yace #[[1]]#. + + hintTextTable[RHT_COLOSSUS_FREESTANDING_POH] = HintText(CustomMessage("They say that on top of an #arch of stone# lies #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf der Spitze eines #Steinbogens# #[[1]]# läge.", + /*french*/ "Selon moi, #gisant sur une arche de pierre# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en lo alto de un #arco de piedra# yace #[[1]]#. + + hintTextTable[RHT_DMT_FREESTANDING_POH] = HintText(CustomMessage("They say that above a #mountain cavern entrance# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß oberhalb eines #Berghöhleneingangs# #[[1]]# sei.", + /*french*/ "Selon moi, gisant #au dessus de la caverne montagneuse# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, en lo alto de la #entrada de una cueva en la montaña# yace #[[1]]#. + + hintTextTable[RHT_DMC_WALL_FREESTANDING_POH] = HintText(CustomMessage("They say that nestled in a #volcanic wall# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß in einem #vulkanischen Alkoven# #[[1]]# sei.", + /*french*/ "Selon moi, dans une #alcove volcanique# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, entre unas #murallas volcánicas# yace #[[1]]#. + + hintTextTable[RHT_DMC_VOLCANO_FREESTANDING_POH] = HintText(CustomMessage("They say that obscured by #volcanic ash# is #[[1]]#.", + /*german*/ "Man erzählt sich, daß #[[1]]# von #Vulkanasche# verdeckt sei.", + /*french*/ "Selon moi, #recouvert de cendres volcaniques# gît #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, bajo la #ceniza volcánica# yace #[[1]]#. + + hintTextTable[RHT_GF_NORTH_F1_CARPENTER] = HintText(CustomMessage("They say that #defeating Gerudo guards# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Besiegen der Gerudo-Wachen# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, les #geôliers Gerudo# détiennent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #derrotar a las guardas Gerudo# revela #[[1]]#. + + hintTextTable[RHT_GF_NORTH_F2_CARPENTER] = HintText(CustomMessage("They say that #defeating Gerudo guards# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Besiegen der Gerudo-Wachen# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, les #geôliers Gerudo# détiennent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #derrotar a las guardas Gerudo# revela #[[1]]#. + + hintTextTable[RHT_GF_SOUTH_F1_CARPENTER] = HintText(CustomMessage("They say that #defeating Gerudo guards# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Besiegen der Gerudo-Wachen# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, les #geôliers Gerudo# détiennent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #derrotar a las guardas Gerudo# revela #[[1]]#. + + hintTextTable[RHT_GF_SOUTH_F2_CARPENTER] = HintText(CustomMessage("They say that #defeating Gerudo guards# reveals #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Besiegen der Gerudo-Wachen# #[[1]]# enthüllen würde.", + /*french*/ "Selon moi, les #geôliers Gerudo# détiennent #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, #derrotar a las guardas Gerudo# revela #[[1]]#. + + hintTextTable[RHT_HF_GS_NEAR_KAK_GROTTO] = HintText(CustomMessage("They say that a #spider-guarded spider in a hole# hoards #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #spinnenbewachte Spinne in einem Loch #[[1]]# horte.", + /*french*/ "Selon moi, une #Skulltula dans un trou d'arachnides# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula custodiada por otra# de un hoyo otorga #[[1]]#. + + hintTextTable[RHT_LLR_GS_BACK_WALL] = HintText(CustomMessage("They say that night reveals a #spider in a ranch# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne auf einer Farm# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur la façade de la ferme# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula del rancho# que otorga #[[1]]#. + + hintTextTable[RHT_LLR_GS_RAIN_SHED] = HintText(CustomMessage("They say that night reveals a #spider in a ranch# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne auf einer Farm# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur le mur de l'enclos# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula del rancho# que otorga #[[1]]#. + + hintTextTable[RHT_LLR_GS_HOUSE_WINDOW] = HintText(CustomMessage("They say that night reveals a #spider in a ranch# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne auf einer Farm# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur la maison de ferme# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula del rancho# que otorga #[[1]]#. + + hintTextTable[RHT_LLR_GS_TREE] = HintText(CustomMessage("They say that a spider hiding in a #ranch tree# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine in einem #Baum auf einer Farm# versteckte Spinne #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans l'arbre de la ferme# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una Skulltula escondida en el #árbol de un rancho# otorga #[[1]]#. + + hintTextTable[RHT_KF_GS_BEAN_PATCH] = HintText(CustomMessage("They say that a #spider buried in a forest# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in einem Wald vergrabene Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula enterrée dans la forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula enterrada en un bosque# otorga #[[1]]#. + + hintTextTable[RHT_KF_GS_KNOW_IT_ALL_HOUSE] = HintText(CustomMessage("They say that night in the past reveals a #spider in a forest# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Vergangenheit eine #Spinne in einem Wald# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula derrière une cabane de la forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela en el pasado una #Skulltula del bosque# que otorga #[[1]]#. + + hintTextTable[RHT_KF_GS_HOUSE_OF_TWINS] = HintText(CustomMessage("They say that night in the future reveals a #spider in a forest# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Zukunft eine #Spinne in einem Wald# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une cabane de la forêt# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela en el futuro una #Skulltula del rancho# que otorga #[[1]]#. + + hintTextTable[RHT_LW_GS_BEAN_PATCH_NEAR_BRIDGE] = HintText(CustomMessage("They say that a #spider buried deep in a forest maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #tief in einem Waldlabyrinth vergrabene Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula enterrée dans les bois# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula enterrada en un laberinto forestal# otorga #[[1]]#. + + hintTextTable[RHT_LW_GS_BEAN_PATCH_NEAR_THEATER] = HintText(CustomMessage("They say that a #spider buried deep in a forest maze# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #tief in einem Waldlabyrinth vergrabene Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula enterrée dans les bois# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula enterrada en un laberinto forestal# otorga #[[1]]#. + + hintTextTable[RHT_LW_GS_ABOVE_THEATER] = HintText(CustomMessage("They say that night reveals a #spider deep in a forest maze# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne tief in einem Waldlabyrinth# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula haut perchée dans les bois# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula del laberinto forestal# que otorga #[[1]]#. + + hintTextTable[RHT_SFM_GS] = HintText(CustomMessage("They say that night reveals a #spider in a forest meadow# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne auf einer Waldwiese# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans le sanctuaire des bois# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula de la pradera del bosque# que otorga #[[1]]#. + + hintTextTable[RHT_OGC_GS] = HintText(CustomMessage("They say that a #spider outside a tyrant's tower# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne außerhalb eines Turms eines Tyrannen# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula parmi les ruines du château# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula a las afueras de la torre de un tirano# otorga #[[1]]#. + + hintTextTable[RHT_HC_GS_TREE] = HintText(CustomMessage("They say that a spider hiding in a #tree outside of a castle# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine in einem #Baum außerhalb von einem Schloß befindliche Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans l'arbre près du château# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una Skulltula escondida en el #árbol de las afueras de un castillo# otorga #[[1]]#. + + hintTextTable[RHT_MARKET_GS_GUARD_HOUSE] = HintText(CustomMessage("They say that a #spider in a guarded crate# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Spinne in einer bewachten Kiste# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans une boîte en ville# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula bajo una custodiada caja# otorga #[[1]]#. + + hintTextTable[RHT_DMC_GS_BEAN_PATCH] = HintText(CustomMessage("They say that a #spider buried in a volcano# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in einem Vulkan begrabene Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula enterrée dans un volcan# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula enterrada en un volcán# otorga #[[1]]#. + + hintTextTable[RHT_DMT_GS_BEAN_PATCH] = HintText(CustomMessage("They say that a #spider buried outside a cavern# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #außerhalb einer Höhle begrabene Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula enterrée près d'une caverne# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula enterrada a la entrada de una cueva# otorga #[[1]]#. + + hintTextTable[RHT_DMT_GS_NEAR_KAK] = HintText(CustomMessage("They say that a #spider hidden in a mountain nook# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in einem Bergwinkel versteckte Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula cachée dans le flanc d'une montagne# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula oculta en el rincón de la montaña# otorga #[[1]]#. + + hintTextTable[RHT_DMT_GS_ABOVE_DODONGOS_CAVERN] = HintText(CustomMessage("They say that the hammer reveals a #spider on a mountain# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß der Hammer eine #Spinne auf einem Berg# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula derrière un rocher massif près d'une caverne# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el martillo revela #una Skulltula de la montaña# que otorga #[[1]]#. + + hintTextTable[RHT_DMT_GS_FALLING_ROCKS_PATH] = HintText(CustomMessage("They say that the hammer reveals a #spider on a mountain# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß der Hammer eine #Spinne auf einem Berg# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula derrière un rocher massif près du sommet d'un volcan# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el martillo revela #una Skulltula de la montaña# que otorga #[[1]]#. + + hintTextTable[RHT_GC_GS_CENTER_PLATFORM] = HintText(CustomMessage("They say that a #suspended spider# in Goron City holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #hängende Spinne# in Goronia #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula perchée dans le village Goron# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula suspendida# en la Ciudad Goron otorga #[[1]]#. + + hintTextTable[RHT_GC_GS_BOULDER_MAZE] = HintText(CustomMessage("They say that a spider in a #Goron City crate# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine Spinne in einer #Kiste in Goronia# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans une boîte du village Goron# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula bajo una caja# de la Ciudad Goron otorga #[[1]]#. + + hintTextTable[RHT_KAK_GS_HOUSE_UNDER_CONSTRUCTION] = HintText(CustomMessage("They say that night in the past reveals a #spider in a town# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Vergangenheit eine #Spinne in einer Stadt# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans le chantier de construction# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del pasado revela una #Skulltula del pueblo# que otorga #[[1]]#. + + hintTextTable[RHT_KAK_GS_SKULLTULA_HOUSE] = HintText(CustomMessage("They say that night in the past reveals a #spider in a town# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Vergangenheit eine #Spinne in einer Stadt# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une maison maudite# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del pasado revela una #Skulltula del pueblo# que otorga #[[1]]#. + + hintTextTable[RHT_KAK_GS_GUARDS_HOUSE] = HintText(CustomMessage("They say that night in the past reveals a #spider in a town# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Vergangenheit eine #Spinne in einer Stadt# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une maison de village# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del pasado revela una #Skulltula del pueblo# que otorga #[[1]]#. + + hintTextTable[RHT_KAK_GS_TREE] = HintText(CustomMessage("They say that night in the past reveals a #spider in a town# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Vergangenheit eine #Spinne in einer Stadt# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans un arbre de village# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del pasado revela una #Skulltula del pueblo# que otorga #[[1]]#. + + hintTextTable[RHT_KAK_GS_WATCHTOWER] = HintText(CustomMessage("They say that night in the past reveals a #spider in a town# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Vergangenheit eine #Spinne in einer Stadt# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une échelle dans un village# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del pasado revela una #Skulltula del pueblo# que otorga #[[1]]#. + + hintTextTable[RHT_KAK_GS_ABOVE_IMPAS_HOUSE] = HintText(CustomMessage("They say that night in the future reveals a #spider in a town# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Zukunft eine #Spinne in einer Stadt# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au dessus d'une grande maison# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del futuro revela una #Skulltula del pueblo# que otorga #[[1]]#. + + hintTextTable[RHT_GRAVEYARD_GS_WALL] = HintText(CustomMessage("They say that night reveals a #spider in a graveyard# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne auf einem Friedhof# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une façade du Cimetière# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula del cementerio# que otorga #[[1]]#. + + hintTextTable[RHT_GRAVEYARD_GS_BEAN_PATCH] = HintText(CustomMessage("They say that a #spider buried in a graveyard# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #auf einem Friedhof begrabene Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula enterrée dans le Cimetière# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula enterrada en el cementerio# otorga #[[1]]#. + + hintTextTable[RHT_ZR_GS_LADDER] = HintText(CustomMessage("They say that night in the past reveals a #spider in a river# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Vergangenheit eine #Spinne in einem Fluß# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une échelle près d'une cascade# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del pasado revela una #Skulltula del río# que otorga #[[1]]#. + + hintTextTable[RHT_ZR_GS_TREE] = HintText(CustomMessage("They say that a spider hiding in a #tree by a river# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine in einem #Baum bei einem Fluß# versteckte Spinne #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans un arbre près du fleuve# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una Skulltula escondida en el #árbol de un río# otorga #[[1]]#. + + hintTextTable[RHT_ZR_GS_ABOVE_BRIDGE] = HintText(CustomMessage("They say that night in the future reveals a #spider in a river# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Zukunft eine #Spinne in einem Fluß# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une façade près d'une cascade# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del futuro revela una #Skulltula del río# que otorga #[[1]]#. + + hintTextTable[RHT_ZR_GS_NEAR_RAISED_GROTTOS] = HintText(CustomMessage("They say that night in the future reveals a #spider in a river# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Zukunft eine #Spinne in einem Fluß# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une façade près d'une grotte du fleuve# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del futuro revela una #Skulltula del río# que otorga #[[1]]#. + + hintTextTable[RHT_ZD_GS_FROZEN_WATERFALL] = HintText(CustomMessage("They say that night reveals a #spider by a frozen waterfall# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne bei einem gefrorenen Wasserfall# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula près d'une cascade gelée# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula junto a una congelada cascada# que otorga #[[1]]#. + + hintTextTable[RHT_ZF_GS_ABOVE_THE_LOG] = HintText(CustomMessage("They say that night reveals a #spider near a deity# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne in der Nähe einer Gottheit# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula près du gardien aquatique# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula junto a cierta deidad# que otorga #[[1]]#. + + hintTextTable[RHT_ZF_GS_TREE] = HintText(CustomMessage("They say that a spider hiding in a #tree near a deity# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine in einem #Baum in der Nähe einer Gottheit# versteckte Spinne #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans un arbre dans un réservoir# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una Skulltula escondida en el #árbol junto a cierta deidad# otorga #[[1]]#. + + hintTextTable[RHT_LH_GS_BEAN_PATCH] = HintText(CustomMessage("They say that a #spider buried by a lake# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #bei einem Fluß begrabene Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula enterrée près d'un lac# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula enterrada junto a un lago# otorga #[[1]]#. + + hintTextTable[RHT_LH_GS_SMALL_ISLAND] = HintText(CustomMessage("They say that night reveals a #spider by a lake# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne bei einem Fluß# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur un îlot du lac# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula junto a un lago# que otorga #[[1]]#. + + hintTextTable[RHT_LH_GS_LAB_WALL] = HintText(CustomMessage("They say that night reveals a #spider by a lake# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne bei einem Fluß# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur le mur d'un centre de recherche# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula junto a un lago# que otorga #[[1]]#. + + hintTextTable[RHT_LH_GS_LAB_CRATE] = HintText(CustomMessage("They say that a spider deed underwater in a #lab crate# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß einer Spinne in einer #Laborkiste# unter Wasser #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans une boîte au fond d'une cuve d'eau# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula bajo la sumergida caja de un laboratorio# otorga #[[1]]#. + + hintTextTable[RHT_LH_GS_TREE] = HintText(CustomMessage("They say that night reveals a #spider by a lake high in a tree# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne in einem Baum bei einem Fluß# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans un grand arbre du lac# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela #una Skulltula del lago sobre un árbol# que otorga #[[1]]#. + + hintTextTable[RHT_GV_GS_BEAN_PATCH] = HintText(CustomMessage("They say that a #spider buried in a valley# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in einem Tal begrabene Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula enterré dans une vallée# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula enterrada en un valle# otorga #[[1]]#. + + hintTextTable[RHT_GV_GS_SMALL_BRIDGE] = HintText(CustomMessage("They say that night in the past reveals a #spider in a valley# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Vergangenheit eine #Spinne in einem Tal# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au dessus d'une petite cascade# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del pasado revela una #Skulltula del valle# que otorga #[[1]]#. + + hintTextTable[RHT_GV_GS_PILLAR] = HintText(CustomMessage("They say that night in the future reveals a #spider in a valley# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Zukunft eine #Spinne in einem Tal# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une arche de pierre dans une vallée# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del futuro revela una #Skulltula del valle# que otorga #[[1]]#. + + hintTextTable[RHT_GV_GS_BEHIND_TENT] = HintText(CustomMessage("They say that night in the future reveals a #spider in a valley# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht in der Zukunft eine #Spinne in einem Tal# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula derrière une tente# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche del futuro revela una #Skulltula del valle# que otorga #[[1]]#. + + hintTextTable[RHT_GF_GS_ARCHERY_RANGE] = HintText(CustomMessage("They say that night reveals a #spider in a fortress# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne in einer Festung# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une cible de tir# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula de una fortaleza# que otorga #[[1]]#. + + hintTextTable[RHT_GF_GS_TOP_FLOOR] = HintText(CustomMessage("They say that night reveals a #spider in a fortress# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne in einer Festung# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula au sommet d'une forteresse# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula de una fortaleza# que otorga #[[1]]#. + + hintTextTable[RHT_COLOSSUS_GS_BEAN_PATCH] = HintText(CustomMessage("They say that a #spider buried in the desert# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in der Wüste begrabene Spinne# #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula enterrée au pied du colosse# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula enterrada en el desierto# otorga #[[1]]#. + + hintTextTable[RHT_COLOSSUS_GS_HILL] = HintText(CustomMessage("They say that night reveals a #spider deep in the desert# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne tief in der Wüste# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula sur une colline dans le désert# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula en las profundidades del desierto# que otorga #[[1]]#. + + hintTextTable[RHT_COLOSSUS_GS_TREE] = HintText(CustomMessage("They say that night reveals a #spider deep in the desert# holding #[[1]]#.", + /*german*/ "Man erzählt sich, daß die Nacht eine #Spinne tief in der Wüste# enthülle, welche #[[1]]# besäße.", + /*french*/ "Selon moi, une #Skulltula dans un arbre du désert# a #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, la noche revela una #Skulltula en las profundidades del desierto# que otorga #[[1]]#. + + hintTextTable[RHT_KF_SHOP_ITEM_1] = HintText(CustomMessage("They say that a #child shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Inhaber des Kokiri-Ladens# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #boutique Kokiri# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #joven dependiente# vende #[[1]]#. + + hintTextTable[RHT_KF_SHOP_ITEM_2] = HintText(CustomMessage("They say that a #child shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Inhaber des Kokiri-Ladens# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #boutique Kokiri# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #joven dependiente# vende #[[1]]#. + + hintTextTable[RHT_KF_SHOP_ITEM_3] = HintText(CustomMessage("They say that a #child shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Inhaber des Kokiri-Ladens# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #boutique Kokiri# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #joven dependiente# vende #[[1]]#. + + hintTextTable[RHT_KF_SHOP_ITEM_4] = HintText(CustomMessage("They say that a #child shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Inhaber des Kokiri-Ladens# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #boutique Kokiri# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #joven dependiente# vende #[[1]]#. + + hintTextTable[RHT_KF_SHOP_ITEM_5] = HintText(CustomMessage("They say that a #child shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Inhaber des Kokiri-Ladens# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #boutique Kokiri# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #joven dependiente# vende #[[1]]#. + + hintTextTable[RHT_KF_SHOP_ITEM_6] = HintText(CustomMessage("They say that a #child shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Inhaber des Kokiri-Ladens# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #boutique Kokiri# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #joven dependiente# vende #[[1]]#. + + hintTextTable[RHT_KF_SHOP_ITEM_7] = HintText(CustomMessage("They say that a #child shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Inhaber des Kokiri-Ladens# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #boutique Kokiri# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #joven dependiente# vende #[[1]]#. + + hintTextTable[RHT_KF_SHOP_ITEM_8] = HintText(CustomMessage("They say that a #child shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Inhaber des Kokiri-Ladens# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #boutique Kokiri# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #joven dependiente# vende #[[1]]#. + + hintTextTable[RHT_KAK_POTION_SHOP_ITEM_1] = HintText(CustomMessage("They say that the #Kakariko Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden in Kakariko# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones de Kakariko# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_POTION_SHOP_ITEM_2] = HintText(CustomMessage("They say that the #Kakariko Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden in Kakariko# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones de Kakariko# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_POTION_SHOP_ITEM_3] = HintText(CustomMessage("They say that the #Kakariko Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden in Kakariko# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones de Kakariko# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_POTION_SHOP_ITEM_4] = HintText(CustomMessage("They say that the #Kakariko Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden in Kakariko# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones de Kakariko# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_POTION_SHOP_ITEM_5] = HintText(CustomMessage("They say that the #Kakariko Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden in Kakariko# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones de Kakariko# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_POTION_SHOP_ITEM_6] = HintText(CustomMessage("They say that the #Kakariko Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden in Kakariko# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones de Kakariko# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_POTION_SHOP_ITEM_7] = HintText(CustomMessage("They say that the #Kakariko Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden in Kakariko# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones de Kakariko# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_POTION_SHOP_ITEM_8] = HintText(CustomMessage("They say that the #Kakariko Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden in Kakariko# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones de Kakariko# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_BOMBCHU_SHOP_ITEM_1] = HintText(CustomMessage("They say that a #Bombchu merchant# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Krabbelminenhändler# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #marchand de Missiles# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #mercader de bombchus# vende #[[1]]#. + + hintTextTable[RHT_MARKET_BOMBCHU_SHOP_ITEM_2] = HintText(CustomMessage("They say that a #Bombchu merchant# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Krabbelminenhändler# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #marchand de Missiles# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #mercader de bombchus# vende #[[1]]#. + + hintTextTable[RHT_MARKET_BOMBCHU_SHOP_ITEM_3] = HintText(CustomMessage("They say that a #Bombchu merchant# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Krabbelminenhändler# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #marchand de Missiles# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #mercader de bombchus# vende #[[1]]#. + + hintTextTable[RHT_MARKET_BOMBCHU_SHOP_ITEM_4] = HintText(CustomMessage("They say that a #Bombchu merchant# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Krabbelminenhändler# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #marchand de Missiles# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #mercader de bombchus# vende #[[1]]#. + + hintTextTable[RHT_MARKET_BOMBCHU_SHOP_ITEM_5] = HintText(CustomMessage("They say that a #Bombchu merchant# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Krabbelminenhändler# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #marchand de Missiles# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #mercader de bombchus# vende #[[1]]#. + + hintTextTable[RHT_MARKET_BOMBCHU_SHOP_ITEM_6] = HintText(CustomMessage("They say that a #Bombchu merchant# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Krabbelminenhändler# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #marchand de Missiles# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #mercader de bombchus# vende #[[1]]#. + + hintTextTable[RHT_MARKET_BOMBCHU_SHOP_ITEM_7] = HintText(CustomMessage("They say that a #Bombchu merchant# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Krabbelminenhändler# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #marchand de Missiles# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #mercader de bombchus# vende #[[1]]#. + + hintTextTable[RHT_MARKET_BOMBCHU_SHOP_ITEM_8] = HintText(CustomMessage("They say that a #Bombchu merchant# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Krabbelminenhändler# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #marchand de Missiles# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #mercader de bombchus# vende #[[1]]#. + + hintTextTable[RHT_MARKET_POTION_SHOP_ITEM_1] = HintText(CustomMessage("They say that the #Market Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden auf dem Markt# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire dans la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones del mercado# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_POTION_SHOP_ITEM_2] = HintText(CustomMessage("They say that the #Market Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden auf dem Markt# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire dans la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones del mercado# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_POTION_SHOP_ITEM_3] = HintText(CustomMessage("They say that the #Market Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden auf dem Markt# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire dans la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones del mercado# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_POTION_SHOP_ITEM_4] = HintText(CustomMessage("They say that the #Market Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden auf dem Markt# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire dans la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones del mercado# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_POTION_SHOP_ITEM_5] = HintText(CustomMessage("They say that the #Market Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden auf dem Markt# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire dans la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones del mercado# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_POTION_SHOP_ITEM_6] = HintText(CustomMessage("They say that the #Market Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden auf dem Markt# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire dans la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones del mercado# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_POTION_SHOP_ITEM_7] = HintText(CustomMessage("They say that the #Market Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden auf dem Markt# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire dans la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones del mercado# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_POTION_SHOP_ITEM_8] = HintText(CustomMessage("They say that the #Market Potion Shop# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Magie-Laden auf dem Markt# #[[1]]# offeriere.", + /*french*/ "Selon moi, l'#apothicaire dans la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/ Según dicen, la #tienda de pociones del mercado# ofrece #[[1]]#. + {}, { + CustomMessage("They say that a #potion seller# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Trankhändler# #[[1]]# anböte.", + /*french*/ "Selon moi, l'#apothicaire# vend #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/ Según dicen, un #vendedor de pociones# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_BAZAAR_ITEM_1] = HintText(CustomMessage("They say that the #Market Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Marktbasar# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar del mercado# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_BAZAAR_ITEM_2] = HintText(CustomMessage("They say that the #Market Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Marktbasar# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar del mercado# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_BAZAAR_ITEM_3] = HintText(CustomMessage("They say that the #Market Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Marktbasar# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar del mercado# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_BAZAAR_ITEM_4] = HintText(CustomMessage("They say that the #Market Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Marktbasar# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar del mercado# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_BAZAAR_ITEM_5] = HintText(CustomMessage("They say that the #Market Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Marktbasar# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar del mercado# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_BAZAAR_ITEM_6] = HintText(CustomMessage("They say that the #Market Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Marktbasar# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar del mercado# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_BAZAAR_ITEM_7] = HintText(CustomMessage("They say that the #Market Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Marktbasar# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar del mercado# ofrece #[[1]]#. + + hintTextTable[RHT_MARKET_BAZAAR_ITEM_8] = HintText(CustomMessage("They say that the #Market Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Marktbasar# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de la Place du Marché# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar del mercado# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_BAZAAR_ITEM_1] = HintText(CustomMessage("They say that the #Kakariko Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Basar in Kakariko# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar de Kakariko# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_BAZAAR_ITEM_2] = HintText(CustomMessage("They say that the #Kakariko Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Basar in Kakariko# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar de Kakariko# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_BAZAAR_ITEM_3] = HintText(CustomMessage("They say that the #Kakariko Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Basar in Kakariko# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar de Kakariko# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_BAZAAR_ITEM_4] = HintText(CustomMessage("They say that the #Kakariko Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Basar in Kakariko# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar de Kakariko# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_BAZAAR_ITEM_5] = HintText(CustomMessage("They say that the #Kakariko Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Basar in Kakariko# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar de Kakariko# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_BAZAAR_ITEM_6] = HintText(CustomMessage("They say that the #Kakariko Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Basar in Kakariko# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar de Kakariko# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_BAZAAR_ITEM_7] = HintText(CustomMessage("They say that the #Kakariko Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Basar in Kakariko# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar de Kakariko# ofrece #[[1]]#. + + hintTextTable[RHT_KAK_BAZAAR_ITEM_8] = HintText(CustomMessage("They say that the #Kakariko Bazaar# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß auf dem #Basar in Kakariko# #[[1]]# angeboten würde.", + /*french*/ "Selon moi, le #bazar de Kakariko# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #bazar de Kakariko# ofrece #[[1]]#. + + hintTextTable[RHT_ZD_SHOP_ITEM_1] = HintText(CustomMessage("They say that a #Zora shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Zora# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Zora# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Zora# vende #[[1]]#. + + hintTextTable[RHT_ZD_SHOP_ITEM_2] = HintText(CustomMessage("They say that a #Zora shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Zora# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Zora# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Zora# vende #[[1]]#. + + hintTextTable[RHT_ZD_SHOP_ITEM_3] = HintText(CustomMessage("They say that a #Zora shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Zora# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Zora# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Zora# vende #[[1]]#. + + hintTextTable[RHT_ZD_SHOP_ITEM_4] = HintText(CustomMessage("They say that a #Zora shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Zora# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Zora# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Zora# vende #[[1]]#. + + hintTextTable[RHT_ZD_SHOP_ITEM_5] = HintText(CustomMessage("They say that a #Zora shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Zora# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Zora# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Zora# vende #[[1]]#. + + hintTextTable[RHT_ZD_SHOP_ITEM_6] = HintText(CustomMessage("They say that a #Zora shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Zora# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Zora# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Zora# vende #[[1]]#. + + hintTextTable[RHT_ZD_SHOP_ITEM_7] = HintText(CustomMessage("They say that a #Zora shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Zora# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Zora# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Zora# vende #[[1]]#. + + hintTextTable[RHT_ZD_SHOP_ITEM_8] = HintText(CustomMessage("They say that a #Zora shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Zora# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Zora# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Zora# vende #[[1]]#. + + hintTextTable[RHT_GC_SHOP_ITEM_1] = HintText(CustomMessage("They say that a #Goron shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Goronen# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Goron# vende #[[1]]#. + + hintTextTable[RHT_GC_SHOP_ITEM_2] = HintText(CustomMessage("They say that a #Goron shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Goronen# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Goron# vende #[[1]]#. + + hintTextTable[RHT_GC_SHOP_ITEM_3] = HintText(CustomMessage("They say that a #Goron shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Goronen# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Goron# vende #[[1]]#. + + hintTextTable[RHT_GC_SHOP_ITEM_4] = HintText(CustomMessage("They say that a #Goron shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Goronen# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Goron# vende #[[1]]#. + + hintTextTable[RHT_GC_SHOP_ITEM_5] = HintText(CustomMessage("They say that a #Goron shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Goronen# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Goron# vende #[[1]]#. + + hintTextTable[RHT_GC_SHOP_ITEM_6] = HintText(CustomMessage("They say that a #Goron shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Goronen# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Goron# vende #[[1]]#. + + hintTextTable[RHT_GC_SHOP_ITEM_7] = HintText(CustomMessage("They say that a #Goron shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Goronen# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Goron# vende #[[1]]#. + + hintTextTable[RHT_GC_SHOP_ITEM_8] = HintText(CustomMessage("They say that a #Goron shopkeeper# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Händler der Goronen# #[[1]]# verkaufen würde.", + /*french*/ "Selon moi, la #boutique Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, el #dependiente Goron# vende #[[1]]#. + + hintTextTable[RHT_HF_DEKU_SCRUB_GROTTO] = HintText(CustomMessage("They say that a lonely #scrub in a hole# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #einsamer Deku in einem Loch# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #peste Mojo dans une grotte de la plaine# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #singular deku bajo un hoyo# de la llanura vende #[[1]]#. + + hintTextTable[RHT_LLR_DEKU_SCRUB_GROTTO_LEFT] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo à la ferme# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# de una granja venden #[[1]]#. + + hintTextTable[RHT_LLR_DEKU_SCRUB_GROTTO_RIGHT] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo à la ferme# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# de una granja venden #[[1]]#. + + hintTextTable[RHT_LLR_DEKU_SCRUB_GROTTO_CENTER] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo à la ferme# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# de una granja venden #[[1]]#. + + hintTextTable[RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = HintText(CustomMessage("They say that a pair of #scrubs in the woods# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar in den Wäldern# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo près du théâtre# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un par de #dekus del bosque# venden #[[1]]#. + + hintTextTable[RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = HintText(CustomMessage("They say that a pair of #scrubs in the woods# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar in den Wäldern# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo près du théâtre# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un par de #dekus del bosque# venden #[[1]]#. + + hintTextTable[RHT_LW_DEKU_SCRUB_NEAR_BRIDGE] = HintText(CustomMessage("They say that a #scrub by a bridge# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku bei einer Brücke# #[[1]]# verkaufe.", + /*french*/ "Selon moi, la #peste Mojo près du pont dans les bois# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #deku bajo un puente# del bosque venden #[[1]]#. + + hintTextTable[RHT_LW_DEKU_SCRUB_GROTTO_REAR] = HintText(CustomMessage("They say that a #scrub underground duo# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar im Untergrund# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo dans les sous-bois# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus subterráneos# del bosque venden #[[1]]#. + + hintTextTable[RHT_LW_DEKU_SCRUB_GROTTO_FRONT] = HintText(CustomMessage("They say that a #scrub underground duo# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar im Untergrund# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo dans les sous-bois# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus subterráneos# del bosque venden #[[1]]#. + + hintTextTable[RHT_SFM_DEKU_SCRUB_GROTTO_REAR] = HintText(CustomMessage("They say that a #scrub underground duo# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar im Untergrund# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo au cœur du sanctuaire sylvestre# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus subterráneos# de la pradera sagrada venden #[[1]]#. + + hintTextTable[RHT_SFM_DEKU_SCRUB_GROTTO_FRONT] = HintText(CustomMessage("They say that a #scrub underground duo# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar im Untergrund# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo au cœur du sanctuaire sylvestre# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus subterráneos# de la pradera sagrada venden #[[1]]#. + + hintTextTable[RHT_GC_DEKU_SCRUB_GROTTO_LEFT] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo dans le village Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# de la Ciudad Goron venden #[[1]]#. + + hintTextTable[RHT_GC_DEKU_SCRUB_GROTTO_RIGHT] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo dans le village Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# de la Ciudad Goron venden #[[1]]#. + + hintTextTable[RHT_GC_DEKU_SCRUB_GROTTO_CENTER] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo dans le village Goron# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# de la Ciudad Goron venden #[[1]]#. + + hintTextTable[RHT_DMC_DEKU_SCRUB_GROTTO_LEFT] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo dans le volcan# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# del volcán venden #[[1]]#. + + hintTextTable[RHT_DMC_DEKU_SCRUB_GROTTO_RIGHT] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo dans le volcan# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# del volcán venden #[[1]]#. + + hintTextTable[RHT_DMC_DEKU_SCRUB_GROTTO_CENTER] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo dans le volcan# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# del volcán venden #[[1]]#. + + hintTextTable[RHT_ZR_DEKU_SCRUB_GROTTO_REAR] = HintText(CustomMessage("They say that a #scrub underground duo# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar im Untergrund# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo près du fleuve# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus subterráneos# del río venden #[[1]]#. + + hintTextTable[RHT_ZR_DEKU_SCRUB_GROTTO_FRONT] = HintText(CustomMessage("They say that a #scrub underground duo# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar im Untergrund# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo près du fleuve# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus subterráneos# del río venden #[[1]]#. + + hintTextTable[RHT_LH_DEKU_SCRUB_GROTTO_LEFT] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo près du lac# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# del lago venden #[[1]]#. + + hintTextTable[RHT_LH_DEKU_SCRUB_GROTTO_RIGHT] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo près du lac# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# del lago venden #[[1]]#. + + hintTextTable[RHT_LH_DEKU_SCRUB_GROTTO_CENTER] = HintText(CustomMessage("They say that a #trio of scrubs# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Trio# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #trio de peste Mojo près du lac# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #trío de dekus# del lago venden #[[1]]#. + + hintTextTable[RHT_GV_DEKU_SCRUB_GROTTO_REAR] = HintText(CustomMessage("They say that a #scrub underground duo# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar im Untergrund# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo près de la vallée# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus subterráneos# del valle venden #[[1]]#. + + hintTextTable[RHT_GV_DEKU_SCRUB_GROTTO_FRONT] = HintText(CustomMessage("They say that a #scrub underground duo# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar im Untergrund# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo près de la vallée# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus subterráneos# del valle venden #[[1]]#. + + hintTextTable[RHT_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = HintText(CustomMessage("They say that a #scrub underground duo# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar im Untergrund# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo dans le désert# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus subterráneos# del desierto venden #[[1]]#. + + hintTextTable[RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = HintText(CustomMessage("They say that a #scrub underground duo# sells #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Deku-Paar im Untergrund# #[[1]]# verkaufe.", + /*french*/ "Selon moi, le #duo de peste Mojo dans le désert# vend #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, un #par de dekus subterráneos# del desierto venden #[[1]]#. + + hintTextTable[RHT_LLR_STABLES_LEFT_COW] = HintText(CustomMessage("They say that a #cow in a stable# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Kuh in einem Stall# #[[1]]# schenke.", + /*french*/ "Selon moi, la #vache dans l'étable# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #vaca del establo# brinda #[[1]]#. + + hintTextTable[RHT_LLR_STABLES_RIGHT_COW] = HintText(CustomMessage("They say that a #cow in a stable# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Kuh in einem Stall# #[[1]]# schenke.", + /*french*/ "Selon moi, la #vache dans l'étable# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #vaca del establo# brinda #[[1]]#. + + hintTextTable[RHT_LLR_TOWER_RIGHT_COW] = HintText(CustomMessage("They say that a #cow in a ranch silo# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Kuh in einem Silo# #[[1]]# schenke.", + /*french*/ "Selon moi, la #vache dans le silo de la ferme# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #vaca del granero# brinda #[[1]]#. + + hintTextTable[RHT_LLR_TOWER_LEFT_COW] = HintText(CustomMessage("They say that a #cow in a ranch silo# gifts #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Kuh in einem Silo# #[[1]]# schenke.", + /*french*/ "Selon moi, la #vache dans le silo de la ferme# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #vaca del granero# brinda #[[1]]#. + + hintTextTable[RHT_KAK_IMPAS_HOUSE_COW] = HintText(CustomMessage("They say that a #cow imprisoned in a house# protects #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #in einem Haus gefangene Kuh# #[[1]]# schütze.", + /*french*/ "Selon moi, la #vache en cage# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #vaca enjaulada de una casa# brinda #[[1]]#. + + hintTextTable[RHT_DMT_COW_GROTTO_COW] = HintText(CustomMessage("They say that a #cow in a luxurious hole# offers #[[1]]#.", + /*german*/ "Man erzählt sich, daß eine #Kuh in einem luxuriösen Loch# #[[1]]# offeriere.", + /*french*/ "Selon moi, la #vache dans une grotte luxueuse# donne #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #vaca de un lujoso hoyo# brinda #[[1]]#. + + hintTextTable[RHT_BEEHIVE_CHEST_GROTTO] = HintText(CustomMessage("They say that a #beehive above a chest# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Bienenstock oberhalb einer Truhe# #[[1]]# verberge.", + /*french*/ "Selon moi, #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #colmena sobre un cofre# esconde #[[1]]#. + + hintTextTable[RHT_BEEHIVE_LONELY_SCRUB_GROTTO] = HintText(CustomMessage("They say that a #beehive above a lonely scrub# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Bienenstock oberhalb eines einsamen Deku# #[[1]]# verberge.", + /*french*/ "Selon moi, #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #colmena sobre un deku solitario# esconde #[[1]]#. + + hintTextTable[RHT_BEEHIVE_SCRUB_PAIR_GROTTO] = HintText(CustomMessage("They say that a #beehive above a pair of scrubs# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Bienenstock oberhalb eines Deku-Paars# #[[1]]# verberge.", + /*french*/ "Selon moi, #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #colmena sobre un par de dekus# esconde #[[1]]#. + + hintTextTable[RHT_BEEHIVE_SCRUB_TRIO_GROTTO] = HintText(CustomMessage("They say that a #beehive above a trio of scrubs# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Bienenstock oberhalb eines Deku-Trios# #[[1]]# verberge.", + /*french*/ "Selon moi, #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #colmena sobre un trío de dekus# esconde #[[1]]#. + + hintTextTable[RHT_BEEHIVE_COW_GROTTO] = HintText(CustomMessage("They say that a #beehive above a cow# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Bienenstock oberhalb einer Kuh# #[[1]]# verberge.", + /*french*/ "Selon moi, #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #colmena sobre una vaca# esconde #[[1]]#. + + hintTextTable[RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA] = HintText(CustomMessage("They say that a #beehive in front of the king of the zoras# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Bienenstock vor dem Zora-König# #[[1]]# verberge.", + /*french*/ "Selon moi, #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #colmena delante del rey de los zoras# esconde #[[1]]#. + + hintTextTable[RHT_BEEHIVE_BEHIND_KING_ZORA] = HintText(CustomMessage("They say that a #beehive behind the king of the zoras# hides #[[1]]#.", + /*german*/ "Man erzählt sich, daß ein #Bienenstock hinter dem Zora-König# #[[1]]# verberge.", + /*french*/ "Selon moi, #[[1]]#.", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #colmena detrás del rey de los zoras# esconde #[[1]]#. +} } diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index 9b9913c8c4a..60464746c43 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -1,1964 +1,2135 @@ -#include "../hint_list.hpp" - -void HintTable_Init_Item() { - hintTable[KOKIRI_SWORD] = HintText::Item({ - //obscure text - Text{"a butter knife", /*french*/"un couteau à beurre", /*spanish*/"un ágil puñal"}, - Text{"a starter slasher", /*french*/"une arme de débutant", /*spanish*/"una hoja de principiantes"}, - Text{"a switchblade", /*french*/"un canif", /*spanish*/"una navaja"}, - }, { - //ambiguous text - Text{"a sword", /*french*/"une épée", /*spanish*/"una espada"}, - }, - //clear text - Text{"the Kokiri Sword", /*french*/"l'Épée Kokiri", /*spanish*/"la Espada Kokiri"} - ); - - hintTable[MASTER_SWORD] = HintText::Item({ - //obscure text - Text{"evil's bane", /*french*/"le fléau du mal", /*spanish*/"la destructora del mal"}, - Text{"a seven year limbo", /*french*/"une stase de sept ans", /*spanish*/"unos siete años de espera"}, - }, { - //ambiguous text - Text{"a sword", /*french*/"une épée", /*spanish*/"una espada"}, - }, - //clear text - Text{"the Master Sword", /*french*/"l'Épée de Légende", /*spanish*/"la Espada Maestra"} - ); - - hintTable[GIANTS_KNIFE] = HintText::Item({ - //obscure text - Text{"a fragile blade", /*french*/"une lame fragile", /*spanish*/"una frágil hoja"}, - Text{"a breakable cleaver", /*french*/"un espadon de verre", /*spanish*/"un rompible acero"}, - }, { - //ambiguous text - Text{"a sword", /*french*/"une épée", /*spanish*/"una espada"}, - }, - //clear text - Text{"the Giant's Knife", /*french*/"la Lame des Géants", /*spanish*/"la daga gigante"} - ); - - hintTable[BIGGORON_SWORD] = HintText::Item({ - //obscure text - Text{"the biggest blade", /*french*/"une lame gigantesque", /*spanish*/"el mayor mandoble"}, - Text{"a colossal cleaver", /*french*/"un espadon colossal", /*spanish*/"un estoque colosal"}, - }, { - //ambiguous text - Text{"a sword", /*french*/"une épée", /*spanish*/"una espada"}, - }, - //clear text - Text{"the Biggoron Sword", /*french*/"l'Épée de Biggoron", /*spanish*/"la Espada de Biggoron"} - ); - - hintTable[DEKU_SHIELD] = HintText::Item({ - //obscure text - Text{"a wooden ward", /*french*/"un écu d'écorce", /*spanish*/"una protección del bosque"}, - Text{"a burnable barrier", /*french*/"une protection inflammable", /*spanish*/"una barrera quemable"}, - }, { - //ambiguous text - Text{"a shield", /*french*/"un bouclier", /*spanish*/"un escudo"}, - }, - //clear text - Text{"a Deku Shield", /*french*/"un Bouclier Mojo", /*spanish*/"un escudo deku"} - ); - - hintTable[HYLIAN_SHIELD] = HintText::Item({ - //obscure text - Text{"a steel safeguard", /*french*/"une carapace d'acier", /*spanish*/"una protección de acero"}, - Text{"Like Like's metal meal", /*french*/"un amuse-gueule de Pudding", /*spanish*/"un alimento de Like Like"}, - }, { - //ambiguous text - Text{"a shield", /*french*/"un bouclier", /*spanish*/"un escudo"}, - }, - //clear text - Text{"a Hylian Shield", /*french*/"un Bouclier Hylien", /*spanish*/"un escudo hyliano"} - ); - - hintTable[MIRROR_SHIELD] = HintText::Item({ - //obscure text - Text{"a reflective rampart", /*french*/"un capteur de lumière", /*spanish*/"una muralla reflectora"}, - Text{"Medusa's weakness", /*french*/"la faiblesse de Méduse", /*spanish*/"la debilidad de Medusa"}, - Text{"a silvered surface", /*french*/"une surface argentée", /*spanish*/"una superficie plateada"}, - }, { - //ambiguous text - Text{"a shield", /*french*/"un bouclier", /*spanish*/"un escudo"}, - }, - //clear text - Text{"the Mirror Shield", /*french*/"le Bouclier Miroir", /*spanish*/"el escudo espejo"} - ); - - hintTable[GORON_TUNIC] = HintText::Item({ - //obscure text - Text{"ruby robes", /*french*/"un pigment rouge", /*spanish*/"una vestimenta rubí"}, - Text{"fireproof fabric", /*french*/"un trésor anti-flamme", /*spanish*/"una ignífuga prenda"}, - Text{"cooking clothes", /*french*/"une tenue de cuisine", /*spanish*/"unos abrasantes ropajes"}, - }, { - //ambiguous text - Text{"a tunic", /*french*/"une tunique", /*spanish*/"un sayo"}, - }, - //clear text - Text{"a Goron Tunic", /*french*/"une Tunique Goron", /*spanish*/"un sayo goron"} - ); - - hintTable[ZORA_TUNIC] = HintText::Item({ - //obscure text - Text{"a sapphire suit", /*french*/"un pigment bleuté", /*spanish*/"una vestidura zafiro"}, - Text{"scuba gear", /*french*/"un habit de plongée", /*spanish*/"un traje impermeable"}, - Text{"a swimsuit", /*french*/"un costume de baignade", /*spanish*/"unos ropajes sumergibles"}, - }, { - //ambiguous text - Text{"a tunic", /*french*/"une tunique", /*spanish*/"un sayo"}, - Text{"something expensive", /*french*/"une chose dispendieuse", /*spanish*/"algo caro"}, - }, - //clear text - Text{"a Zora Tunic", /*french*/"une Tunique Zora", /*spanish*/"un sayo zora"} - ); - - hintTable[IRON_BOOTS] = HintText::Item({ - //obscure text - Text{"sink shoes", /*french*/"un boulet de fer", /*spanish*/"un calzado de las profundidades"}, - Text{"clank cleats", /*french*/"une paire de talons bruyants", /*spanish*/"unas suelas férreas"}, - }, { - //ambiguous text - Text{"some boots", /*french*/"une paire de bottes", /*spanish*/"un par de botas"}, - Text{"a feature of the Water Temple", /*french*/"une particularité du Temple de l'Eau", /*spanish*/"algo particular del Templo del Agua"}, - Text{"something heavy", /*french*/"une chose pesante", /*spanish*/"algo de lo más pesado"}, - }, - //clear text - Text{"the Iron Boots", /*french*/"une paire de Bottes de plomb", /*spanish*/"las botas de hierro"} - ); - - hintTable[HOVER_BOOTS] = HintText::Item({ - //obscure text - Text{"butter boots", /*french*/"une paire de patins de beurre", /*spanish*/"unas suelas resvaladizas"}, - Text{"sacred slippers", /*french*/"une paire de pantoufles sacrées", /*spanish*/"unos escurridizos botines"}, - Text{"spacewalkers", /*french*/"une paire de bottes spatiales", /*spanish*/"un calzado antigravitatorio"}, - }, { - //ambiguous text - Text{"some boots", /*french*/"une paire de bottes", /*spanish*/"un par de botas"}, - }, - //clear text - Text{"the Hover Boots", /*french*/"une paire de Bottes des airs", /*spanish*/"las botas voladoras"} - ); - - - hintTable[ZELDAS_LETTER] = HintText::Item({ - //obscure text - Text{"an autograph", /*french*/"un autographe", /*spanish*/"un autógrafo"}, - Text{"royal stationery", /*french*/"du papier royal", /*spanish*/"un escrito real"}, - Text{"royal snail mail", /*french*/"une enveloppe royale", /*spanish*/"correo de la realeza"}, - }, {}, - //clear text - Text{"Zelda's Letter", /*french*/"la Lettre de Zelda", /*spanish*/"la carta de Zelda"} - ); - - hintTable[WEIRD_EGG] = HintText::Item({ - //obscure text - Text{"a chicken dilemma", /*french*/"un drôle d'ovale", /*spanish*/"el dilema de la gallina"}, - }, { - //ambiguous text - Text{"an egg", /*french*/"un oeuf", /*spanish*/"un huevo"}, - }, - //clear text - Text{"the Weird Egg", /*french*/"l'Oeuf Curieux", /*spanish*/"el huevo extraño"} - ); - - hintTable[BOOMERANG] = HintText::Item({ - //obscure text - Text{"a banana", /*french*/"une banane", /*spanish*/"un plátano"}, - Text{"a stun stick", /*french*/"un bâton étourdissant", /*spanish*/"un palo aturdidor"}, - Text{"a yellow angle", /*french*/"un angle jaune", /*spanish*/"un ángulo amarillo"}, - }, { - //ambiguous text - Text{"something that can grab things", /*french*/"une chose qui peut attraper", /*spanish*/"algo que pueda agarrar cosas"}, - Text{"something that can stun", /*french*/"une chose qui peut paralyser", /*spanish*/"algo que pueda paralizar"}, - }, - //clear text - Text{"the Boomerang", /*french*/"le Boomerang", /*spanish*/"el bumerán"} - ); - - hintTable[LENS_OF_TRUTH] = HintText::Item({ - //obscure text - Text{"a lie detector", /*french*/"un détecteur de mensonges", /*spanish*/"el detector de ilusiones"}, - Text{"a ghost tracker", /*french*/"un trouve-fantôme", /*spanish*/"el rastreador paranormal"}, - Text{"true sight", /*french*/"le troisième œil", /*spanish*/"el ojo que todo ve"}, - Text{"a detective's tool", /*french*/"un trésor Sheikah", /*spanish*/"la revelación verdadera"}, - }, { - //ambiguous text - Text{"a secret-finding tool", /*french*/"un cherche-secrets", /*spanish*/"un instrumento para hallar objetos"}, - }, - //clear text - Text{"the Lens of Truth", /*french*/"le Monocle de Vérité", /*spanish*/"la Lupa de la Verdad"} - ); - - hintTable[MEGATON_HAMMER] = HintText::Item({ - //obscure text - Text{"the dragon smasher", /*french*/"le tueur de dragons", /*spanish*/"un destructor de dragones"}, - Text{"the metal mallet", /*french*/"un outil de construction", /*spanish*/"un mazo de metal"}, - Text{"the heavy hitter", /*french*/"un poids lourd", /*spanish*/"un machacador"}, - }, { - //ambiguous text - Text{"something that can remove boulders", /*french*/"une chose qui enlève les rochers", /*spanish*/"algo que pueda quitar rocas"}, - }, - //clear text - Text{"the Megaton Hammer", /*french*/"la Masse des Titans", /*spanish*/"el martillo Megatón"} - ); - - hintTable[STONE_OF_AGONY] = HintText::Item({ - //obscure text - Text{"the shake stone", /*french*/"le fragment vibrant", /*spanish*/"el fragmento tintineante"}, - Text{"a gray alarm", /*french*/"une alerte bleue", /*spanish*/"una azul alarma"}, - }, { - //ambiguous text - Text{"a prize of the House of Skulltulas", /*french*/"un prix de la maison des Skulltulas", /*spanish*/"un obsequio de la Casa Skulltula"}, - Text{"a secret-finding tool", /*french*/"un cherche-secrets", /*spanish*/"un instrumento para hallar objetos"}, - }, - //clear text - Text{"the Stone of Agony", /*french*/"la Pierre de Souffrance", /*spanish*/"la Piedra de la Agonía"} - ); - - hintTable[DINS_FIRE] = HintText::Item({ - //obscure text - Text{"an inferno", /*french*/"un brasier", /*spanish*/"un incendio"}, - Text{"a heat wave", /*french*/"une vague de chaleur", /*spanish*/"una onda de calor"}, - Text{"a red ball", /*french*/"une explosion de flammes", /*spanish*/"una roja esfera"}, - }, { - //ambiguous text - Text{"a Great Fairy's power", /*french*/"le pouvoir d'une grande fée", /*spanish*/"el poder de una Gran Hada"}, - }, - //clear text - Text{"Din's Fire", /*french*/"le Feu de Din", /*spanish*/"el Fuego de Din"} - ); - - hintTable[FARORES_WIND] = HintText::Item({ - //obscure text - Text{"teleportation", /*french*/"la téléportation", /*spanish*/"un teletransportador"}, - Text{"a relocation rune", /*french*/"une rune de relocation", /*spanish*/"una runa de transporte"}, - Text{"a green ball", /*french*/"une boule verte", /*spanish*/"una verde esfera"}, - }, { - //ambiguous text - Text{"a Great Fairy's power", /*french*/"le pouvoir d'une grande fée", /*spanish*/"el poder de una Gran Hada"}, - }, - //clear text - Text{"Farore's Wind", /*french*/"le Vent de Farore", /*spanish*/"el Viento de Farore"} - ); - - hintTable[NAYRUS_LOVE] = HintText::Item({ - //obscure text - Text{"a safe space", /*french*/"une bulle de cristal", /*spanish*/"una seguridad temporal"}, - Text{"an impregnable aura", /*french*/"un aura impénétrable", /*spanish*/"un aura impenetrable"}, - Text{"a blue barrier", /*french*/"une toison bleu", /*spanish*/"una barrera azul"}, - }, { - //ambiguous text - Text{"a Great Fairy's power", /*french*/"le pouvoir d'une grande fée", /*spanish*/"el poder de una Gran Hada"}, - }, - //clear text - Text{"Nayru's Love", /*french*/"l'Amour de Nayru", /*spanish*/"el Amor de Nayru"} - ); - - hintTable[FIRE_ARROWS] = HintText::Item({ - //obscure text - Text{"the furnace firearm" , /*french*/"une fusée solaire", /*spanish*/"el ardiente aguijón"}, - Text{"the burning bolts", /*french*/"un obus enflammé", /*spanish*/"las puntas ígneas"}, - Text{"a magma missile", /*french*/"un missile volcanique", /*spanish*/"el misil abrasador"}, - }, { - //ambiguous text - Text{"a magic arrow", /*french*/"une flèche magique", /*spanish*/"una flecha mágica"}, - }, - //clear text - Text{"the Fire Arrows", /*french*/"les Flèches de Feu", /*spanish*/"la flecha de fuego"} - ); - - hintTable[ICE_ARROWS] = HintText::Item({ - //obscure text - Text{"the refrigerator rocket", /*french*/"un missile pétrifiant", /*spanish*/"el misil congelador"}, - Text{"the frostbite bolts", /*french*/"un froid mordant", /*spanish*/"las puntas gélidas"}, - Text{"an iceberg maker", /*french*/"une aiguille glaciale", /*spanish*/"el control de escarcha"}, - }, { - //ambiguous text - Text{"a magic arrow", /*french*/"une flèche magique", /*spanish*/"una flecha mágica"}, - Text{"something that can stun", /*french*/"une chose qui peut paralyser", /*spanish*/"algo que pueda paralizar"}, - }, - //clear text - Text{"the Ice Arrows", /*french*/"les Flèches de Glace", /*spanish*/"la flecha de hielo"} - ); - - hintTable[LIGHT_ARROWS] = HintText::Item({ - //obscure text - Text{"the shining shot", /*french*/"l'arme brillante", /*spanish*/"el haz de luz"}, - Text{"the luminous launcher", /*french*/"un jet de lumière", /*spanish*/"el disparo luminoso"}, - Text{"Ganondorf's bane", /*french*/"le fléau de Ganondorf", /*spanish*/"la perdición de Ganondorf"}, - Text{"the lighting bolts", /*french*/"l'éclair sacré", /*spanish*/"las puntas resplandecientes"}, - }, { - //ambiguous text - Text{"a magic arrow", /*french*/"une flèche magique", /*spanish*/"una flecha mágica"}, - }, - //clear text - Text{"the Light Arrows", /*french*/"les Flèches de Lumière", /*spanish*/"la flecha de luz"} - ); - - hintTable[GERUDO_MEMBERSHIP_CARD] = HintText::Item({ - //obscure text - Text{"a girl club membership", /*french*/"une carte de membre", /*spanish*/"una fémina membresía"}, - Text{"a desert tribe's pass", /*french*/"un laissez-passer", /*spanish*/"el vale del desierto"}, - }, { - Text{"a token of recognition", /*french*/"une preuve de reconnaissance", /*spanish*/"una prueba de reconocimiento"}, - }, - //clear text - Text{"the Gerudo Membership Card", /*french*/"la Carte Gerudo", /*spanish*/"el pase de socio gerudo"} - ); - - hintTable[MAGIC_BEAN] = HintText::Item({ - //obscure text - Text{"a wizardly legume", /*french*/"un légume ensorcelé", /*spanish*/"una legumbre hechizada"}, - }, { - //ambiguous text - Text{"something sometimes buried", /*french*/"une chose parfois enterrée", /*spanish*/"algo a veces enterrado"}, - }, - //clear text - Text{"a Magic Bean", /*french*/"un Haricot Magique", /*spanish*/"una judía mágica"} - ); - - hintTable[MAGIC_BEAN_PACK] = HintText::Item({ - //obscure text - Text{"wizardly legumes", /*french*/"un paquet de légumes ensorcelés", /*spanish*/"unas legumbres hechizadas"}, - }, { - //ambiguous text - Text{"something sometimes buried", /*french*/"une chose parfois enterrée", /*spanish*/"algo a veces enterrado"}, - }, - //clear text - Text{"Magic Beans", /*french*/"un Paquet de Haricots Magiques", /*spanish*/"unas judías mágicas"} - ); - - hintTable[DOUBLE_DEFENSE] = HintText::Item({ - //obscure text - Text{"a white outline", /*french*/"un rebord blanc", /*spanish*/"un contorno blanco"}, - Text{"damage decrease", /*french*/"une protection supplémentaire", /*spanish*/"una reducción de daño"}, - Text{"strengthened love", /*french*/"un amour coriace", /*spanish*/"un amor fortalecido"}, - }, { - //ambiguous text - Text{"a Great Fairy's power", /*french*/"le pouvoir d'une grande fée", /*spanish*/"el poder de una Gran Hada"}, - Text{"something heart-shaped", /*french*/"une chose en forme de coeur", /*spanish*/"algo con forma de corazón"}, - }, - //clear text - Text{"Double Defense", /*french*/"la Double Défence", /*spanish*/"la doble defensa"} - ); - - hintTable[GOLD_SKULLTULA_TOKEN] = HintText::Item({ - //obscure text - Text{"proof of destruction", /*french*/"un certificat d'élimination", /*spanish*/"una prueba de la destrucción"}, - Text{"an arachnid chip", /*french*/"un symbole cranien", /*spanish*/"una figura arácnida"}, - Text{"spider remains", /*french*/"une dépouille dorée", /*spanish*/"unos restos dorados"}, - Text{"one percent of a curse", /*french*/"un centième de malédiction", /*spanish*/"una centésima de una maldición"}, - }, { - //ambiguous text - Text{"a token of recognition", /*french*/"une preuve de reconnaissance", /*spanish*/"una prueba de reconocimiento"}, - Text{"something sometimes buried", /*french*/"une chose parfois enterrée", /*spanish*/"algo a veces enterrado"}, - }, - //clear text - Text{"a Gold Skulltula Token", /*french*/"un Symbole de Skulltula d'or", /*spanish*/"un símbolo de skulltula dorada"} - ); - - hintTable[POCKET_EGG] = HintText::Item({ - //obscure text - Text{"a Cucco container", /*french*/"un réservoir à Cocotte", /*spanish*/"cuco contenido"}, - Text{"a Cucco, eventually", /*french*/"un poussin éventuel", /*spanish*/"un futuro cuco"}, - Text{"a fowl youth", /*french*/"une omelette crue", /*spanish*/"una dulce juventud"}, - }, { - //ambiguous text - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - Text{"an egg", /*french*/"un oeuf", /*spanish*/"un huevo"}, - }, - //clear text - Text{"the Pocket Egg", /*french*/"l'Oeuf de Poche", /*spanish*/"el huevo de bolsillo"} - ); - - hintTable[POCKET_CUCCO] = HintText::Item({ - //obscure text - Text{"a little clucker", /*french*/"un petit glousseur", /*spanish*/"un pollito chiquito"}, - }, { - //ambiguous text - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - }, - //clear text - Text{"the Pocket Cucco", /*french*/"la Cocotte de Poche", /*spanish*/"el cuco de bolsillo"} - ); - - hintTable[COJIRO] = HintText::Item({ - //obscure text - Text{"a cerulean capon", /*french*/"un paon azur", /*spanish*/"un cerúleo capón"}, - }, { - //ambiguous text - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - }, - //clear text - Text{"Cojiro", /*french*/"le p'tit poulet", /*spanish*/"a Cojiro"} - ); - - hintTable[ODD_MUSHROOM] = HintText::Item({ - //obscure text - Text{"a powder ingredient", /*french*/"un ingrédient à poudre", /*spanish*/"un oloroso ingrediente"}, - }, { - //ambiguous text - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - }, - //clear text - Text{"an Odd Mushroom", /*french*/"un Champignon Suspect", /*spanish*/"un champiñón extraño"} - ); - - hintTable[ODD_POTION] = HintText::Item({ - //obscure text - Text{"Granny's goodies", /*french*/"la confiserie de mamie", /*spanish*/"la especialidad de la abuela"}, - }, { - //ambiguous text - Text{"something that contains medicine", /*french*/"une chose médicamenteuse", /*spanish*/"algo que contenga medicina"}, - Text{"something with a strange smell", /*french*/"une chose qui sent bizarre", /*spanish*/"algo con un olor extraño"}, - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - }, - //clear text - Text{"an Odd Potion", /*french*/"une Mixture Suspecte", /*spanish*/"una medicina rara"} - ); - - hintTable[POACHERS_SAW] = HintText::Item({ - //obscure text - Text{"a tree killer", /*french*/"un coupeur d'arbres", /*spanish*/"un destructor de árboles"}, - }, { - //ambiguous text - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - }, - //clear text - Text{"the Poacher's Saw", /*french*/"la Scie du Chasseur", /*spanish*/"la sierra del furtivo"} - ); - - hintTable[BROKEN_SWORD] = HintText::Item({ - //obscure text - Text{"a shattered slicer", /*french*/"une arme cassée", /*spanish*/"una rebanadora rota"}, - }, { - //ambiguous text - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - Text{"a sword", /*french*/"une épée", /*spanish*/"una espada"}, - }, - //clear text - Text{"the Broken Goron's Sword", /*french*/"l'Épée Brisée de Goron", /*spanish*/"la espada goron rota"} - ); - - hintTable[PRESCRIPTION] = HintText::Item({ - //obscure text - Text{"a pill pamphlet", /*french*/"un document urgent", /*spanish*/"un instructivo medicinal"}, - Text{"a doctor's note", /*french*/"un papier médical", /*spanish*/"unas notas del doctor"}, - }, { - //ambiguous text - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - }, - //clear text - Text{"the Prescription", /*french*/"une Ordonnance", /*spanish*/"la receta"} - ); - - hintTable[EYEBALL_FROG] = HintText::Item({ - //obscure text - Text{"a perceiving polliwog", /*french*/"un amphibien", /*spanish*/"un variopinto batracio"}, - }, { - //ambiguous text - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - }, - //clear text - Text{"the Eyeball Frog", /*french*/"le Crapaud-qui-louche", /*spanish*/"la rana de ojos saltones"} - ); - - hintTable[EYEDROPS] = HintText::Item({ - //obscure text - Text{"a vision vial", /*french*/"une solution oculaire", /*spanish*/"un remedio para la vista"}, - }, { - //ambiguous text - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - }, - //clear text - Text{"the Eyedrops", /*french*/"une phiole de Super-Gouttes", /*spanish*/"las supergotas oculares"} - ); - - hintTable[CLAIM_CHECK] = HintText::Item({ - //obscure text - Text{"a three day wait", /*french*/"un rendez-vous dans trois jours", /*spanish*/"unos tres días de espera"}, - }, { - //ambiguous text - Text{"a trade quest item", /*french*/"un objet de quête d'échanges", /*spanish*/"un objeto de una misión secundaria"}, - }, - //clear text - Text{"the Claim Check", /*french*/"un Certificat", /*spanish*/"el recibo"} - ); - - hintTable[PROGRESSIVE_HOOKSHOT] = HintText::Item({ - //obscure text - Text{"Dampé's keepsake", /*french*/"l'héritage d'Igor", /*spanish*/"un recuerdo de Dampé"}, - Text{"the Grapple Beam", /*french*/"le rayon grippeur", /*spanish*/"una garra metálica"}, - Text{"the BOING! chain", /*french*/"la chaîne de BOING!", /*spanish*/"una cadena retráctil"}, - }, { - //ambiguous text - Text{"something that can grab things", /*french*/"une chose qui peut attraper", /*spanish*/"algo que pueda agarrar cosas"}, - Text{"something that can stun", /*french*/"une chose qui peut paralyser", /*spanish*/"algo que pueda paralizar"}, - }, - //clear text - Text{"a Hookshot", /*french*/"un Grappin", /*spanish*/"un gancho"} - ); - - hintTable[PROGRESSIVE_STRENGTH] = HintText::Item({ - //obscure text - Text{"power gloves", /*french*/"une paire de gants de travail", /*spanish*/"unos poderosos guanteletes"}, - Text{"metal mittens", /*french*/"une paire de mitaines", /*spanish*/"unas manoplas metálicas"}, - Text{"the heavy lifty", /*french*/"la puissance de dix hommes", /*spanish*/"un levantamiento pesado"}, - }, { - //ambiguous text - Text{"something that can remove boulders", /*french*/"une chose qui enlève les rochers", /*spanish*/"algo que pueda quitar rocas"}, - }, - //clear text - Text{"a Strength Upgrade", /*french*/"une Amélioration de Force", /*spanish*/"un aumento de fuerza"} - ); - - hintTable[PROGRESSIVE_BOMB_BAG] = HintText::Item({ - //obscure text - Text{"an explosive container", /*french*/"un porte-grenade", /*spanish*/"un recipiente explosivo"}, - Text{"a blast bag", /*french*/"un estomac de Dodongo", /*spanish*/"un zurrón de estallidos"}, - }, { - //ambiguous text - Text{"explosives", /*french*/"un paquet d'explosifs", /*spanish*/"un montón de explosivos"}, - Text{"something that can remove boulders", /*french*/"une chose qui enlève les rochers", /*spanish*/"algo que pueda quitar rocas"}, - }, - //clear text - Text{"a Bomb Bag", /*french*/"un Sac de Bombes", /*spanish*/"un saco de bombas"} - ); - - hintTable[PROGRESSIVE_BOW] = HintText::Item({ - //obscure text - Text{"an archery enabler", /*french*/"un facilitateur de tir", /*spanish*/"un tiro al blanco"}, - Text{"a danger dart launcher", /*french*/"un tire-fléchette", /*spanish*/"un peligroso lanzadardos"}, - }, { - //ambiguous text - Text{"a projectile shooter", /*french*/"un tire-projectile", /*spanish*/"un arma de proyectil"}, - }, - //clear text - Text{"a Bow", /*french*/"l'Arc des Fées", /*spanish*/"un arco de las hadas"} - ); - - hintTable[PROGRESSIVE_SLINGSHOT] = HintText::Item({ - //obscure text - Text{"a seed shooter", /*french*/"un lance-noix", /*spanish*/"un lanzasemillas"}, - Text{"a rubberband", /*french*/"un élastique", /*spanish*/"un tirachinas"}, - Text{"a child's catapult", /*french*/"un jouet d'enfant", /*spanish*/"una catapulta infantil"}, - }, { - //ambiguous text - Text{"a projectile shooter", /*french*/"un tire-projectile", /*spanish*/"un arma de proyectil"}, - }, - //clear text - Text{"a Slingshot", /*french*/"un Lance-Pierre", /*spanish*/"una resortera de las hadas"} - ); - - hintTable[PROGRESSIVE_WALLET] = HintText::Item({ - //obscure text - Text{"a mo' money holder", /*french*/"un sac à sous", /*spanish*/"una cartera de dinero"}, - Text{"a gem purse", /*french*/"une sacoche", /*spanish*/"un zurrón de gemas"}, - Text{"a portable bank", /*french*/"une petite banque", /*spanish*/"un banco portable"}, - }, { - //ambiguous text - Text{"a prize of the House of Skulltulas", /*french*/"un prix de la maison des Skulltulas", /*spanish*/"un obsequio de la Casa Skulltula"}, - }, - //clear text - Text{"a Wallet", /*french*/"une Bourse", /*spanish*/"una bolsa de rupias"} - ); - - hintTable[PROGRESSIVE_SCALE] = HintText::Item({ - //obscure text - Text{"a deeper dive", /*french*/"une bulle de plongée", /*spanish*/"un profundo buceo"}, - Text{"a piece of Zora", /*french*/"un morceau de Zora", /*spanish*/"un fragmento de Zora"}, - }, { - //ambiguous text - Text{"a diving tool", /*french*/"un outil de plongée", /*spanish*/"un instrumento de buceo"}, - }, - //clear text - Text{"a Zora Scale", /*french*/"une Écaille Zora", /*spanish*/"una escama Zora"} - ); - - hintTable[PROGRESSIVE_NUT_UPGRADE] = HintText::Item({ - //obscure text - Text{"more nuts", /*french*/"ecnore plus de noix", /*spanish*/"más semillas de nogal"}, - Text{"flashbang storage", /*french*/"un sac à noix", /*spanish*/"más frutos aturdidores"}, - }, { - //ambiguous text - Text{"some Deku munitions", /*french*/"un paquet de munitions Mojo", /*spanish*/"un montón de municiones Deku"}, - Text{"something that can stun", /*french*/"une chose qui peut paralyser", /*spanish*/"algo que pueda paralizar"}, - }, - //clear text - Text{"Deku Nut Capacity", /*french*/"une Augmentation de Noix Mojo", /*spanish*/"un aumento de nueces deku"} - ); - - hintTable[PROGRESSIVE_STICK_UPGRADE] = HintText::Item({ - //obscure text - Text{"a lumber rack", /*french*/"un paquet de bois", /*spanish*/"más bastones"}, - Text{"more flammable twigs", /*french*/"beaucoup de branches", /*spanish*/"más varas"}, - }, { - //ambiguous text - Text{"some Deku munitions", /*french*/"un paquet de munitions Mojo", /*spanish*/"un montón de municiones Deku"}, - }, - //clear text - Text{"Deku Stick Capacity", /*french*/"une augmentation de bâtons Mojo", /*spanish*/"un aumento de palos deku"} - ); - - hintTable[PROGRESSIVE_MAGIC_METER] = HintText::Item({ - //obscure text - Text{"mystic training", /*french*/"un potentiel magique", /*spanish*/"una maestría mística"}, - Text{"pixie dust", /*french*/"de la poudre de fée", /*spanish*/"un polvo de hada"}, - Text{"a green rectangle", /*french*/"un rectangle vert", /*spanish*/"una verduzca barra"}, - }, { - //ambiguous text - Text{"a Great Fairy's power", /*french*/"le pouvoir d'une grande fée", /*spanish*/"el poder de una Gran Hada"}, - }, - //clear text - Text{"a Magic Meter", /*french*/"une Jauge de Magie", /*spanish*/"un aumento de poder mágico"} - ); - - hintTable[PROGRESSIVE_OCARINA] = HintText::Item({ - //obscure text - Text{"a flute", /*french*/"un bec musical", /*spanish*/"un utensilio musical"}, - Text{"a music maker", /*french*/"un porteur de chansons", /*spanish*/"un instrumento"}, - }, { - //ambiguous text - Text{"something given by Saria", /*french*/"un cadeau de Saria", /*spanish*/"un obsequio de Saria"}, - Text{"something kept by the royal family", /*french*/"une chose qui paralyse", /*spanish*/"algo guardado por la familia real"}, - }, - //clear text - Text{"an Ocarina", /*french*/"un ocarina", /*spanish*/"una ocarina"} - ); - - hintTable[PROGRESSIVE_BOMBCHUS] = HintText::Item({ - //obscure text - Text{"mice bombs", /*french*/"un adorable explosif", /*spanish*/"unas bombas roedoras"}, - Text{"proximity mice", /*french*/"une mine anti-rongeur", /*spanish*/"unos explosivos ratoncitos"}, - Text{"wall crawlers", /*french*/"un rapide grimpeur", /*spanish*/"unos trepaparedes"}, - Text{"trail blazers", /*french*/"un zigzag éclatant", /*spanish*/"unas ratas propulsadas"}, - }, { - //ambiguous text - Text{"a prize of the House of Skulltulas", /*french*/"un prix de la maison des Skulltulas", /*spanish*/"un obsequio de la Casa Skulltula"}, - Text{"explosives", /*french*/"un paquet d'explosifs", /*spanish*/"un montón de explosivos"}, - }, - //clear text - Text{"Bombchus", /*french*/"un paquet de Missiles", /*spanish*/"unos bombchus"} - ); - - hintTable[PROGRESSIVE_GORONSWORD] = HintText::Item({ - //obscure text - Text{"a long blade", /*french*/"une longue lame", /*spanish*/"una gran hoja"}, - Text{"a Goron weapon", /*french*/"une arme Goron", /*spanish*/"un arma goron"}, - }, { - //ambiguous text - Text{"a sword", /*french*/"une épée", /*spanish*/"una espada"}, - }, - //clear text - Text{"a Goron Sword", /*french*/"une épée Goron", /*spanish*/"una espada goron"} - ); - - hintTable[EMPTY_BOTTLE] = HintText::Item({ - //obscure text - Text{"a glass container", /*french*/"un cylindre de cristal", /*spanish*/"un recipiente de cristal"}, - Text{"an empty jar", /*french*/"une jarre incassable", /*spanish*/"un frasco vacío"}, - Text{"encased air", /*french*/"un bocal d'air", /*spanish*/"aire a presión"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Bottle", /*french*/"un flacon vide", /*spanish*/"una botella"} - ); - - hintTable[BOTTLE_WITH_MILK] = HintText::Item({ - //obscure text - Text{"cow juice", /*french*/"une source de calcium", /*spanish*/"una fuente de calcio"}, - Text{"a white liquid", /*french*/"un liquide blanc", /*spanish*/"una bebida nutritiva"}, - Text{"a baby's breakfast", /*french*/"du jus pour bébé", /*spanish*/"un trago para bebés"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Milk Bottle", /*french*/"un flacon de lait", /*spanish*/"una botella de leche"} - ); - - hintTable[BOTTLE_WITH_RED_POTION] = HintText::Item({ - //obscure text - Text{"a vitality vial", /*french*/"un mélange de vitalité", /*spanish*/"una pócima vitalicia"}, - Text{"a red liquid", /*french*/"un liquide rouge", /*spanish*/"un remedio rojizo"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Red Potion Bottle", /*french*/"un flacon de potion rouge", /*spanish*/"una botella de poción roja"} - ); - - hintTable[BOTTLE_WITH_GREEN_POTION] = HintText::Item({ - //obscure text - Text{"a magic mixture", /*french*/"une réserve magique", /*spanish*/"un potingue mágico"}, - Text{"a green liquid", /*french*/"un liquide vert", /*spanish*/"un remedio verduzco"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Green Potion Bottle", /*french*/"un flacon de potion verte", /*spanish*/"una botella de poción verde"} - ); - - hintTable[BOTTLE_WITH_BLUE_POTION] = HintText::Item({ - //obscure text - Text{"an ailment antidote", /*french*/"l'élixir ultime", /*spanish*/"un antídoto para el dolor"}, - Text{"a blue liquid", /*french*/"un liquide bleu", /*spanish*/"un remedio índigo"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Blue Potion Bottle", /*french*/"un flacon de potion bleue", /*spanish*/"una botella de poción azul"} - ); - - hintTable[BOTTLE_WITH_FAIRY] = HintText::Item({ - //obscure text - Text{"an imprisoned fairy", /*french*/"une fée emprisonnée", /*spanish*/"un hada atrapada"}, - Text{"an extra life", /*french*/"une vie de rechange", /*spanish*/"una oportunidad más"}, - Text{"Navi's cousin", /*french*/"le cousin de Navi", /*spanish*/"una prima de Navi"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Fairy Bottle", /*french*/"une fée en flacon", /*spanish*/"un hada en una botella"} - ); - - hintTable[BOTTLE_WITH_FISH] = HintText::Item({ - //obscure text - Text{"an aquarium", /*french*/"un aquarium", /*spanish*/"un escamado ser"}, - Text{"a deity's snack", /*french*/"le repas d'un dieu marin", /*spanish*/"un tentempié de cierta deidad"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Fish Bottle", /*french*/"un poisson en flacon", /*spanish*/"un pez en una botella"} - ); - - hintTable[BOTTLE_WITH_BLUE_FIRE] = HintText::Item({ - //obscure text - Text{"a conflagration canteen", /*french*/"une mystérieuse flamme", /*spanish*/"un incendio retenido"}, - Text{"an icemelt jar", /*french*/"un brasier glacial", /*spanish*/"unas brasas enfrascadas"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Blue Fire Bottle", /*french*/"une flamme bleue en flacon", /*spanish*/"una botella de fuego azul"} - ); - - hintTable[BOTTLE_WITH_BUGS] = HintText::Item({ - //obscure text - Text{"an insectarium", /*french*/"un insectarium", /*spanish*/"unos invertebrados seres"}, - Text{"Skulltula finders", /*french*/"une poignée de trouve-Skulltula", /*spanish*/"unos rastreadores de skulltulas"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Bug Bottle", /*french*/"un insecte en flacon", /*spanish*/"unos insectos en una botella"} - ); - - hintTable[BOTTLE_WITH_POE] = HintText::Item({ - //obscure text - Text{"a spooky ghost", /*french*/"un effroyable fantôme", /*spanish*/"un espantoso espectro"}, - Text{"a face in the jar", /*french*/"un visage dans un bocal", /*spanish*/"una expresión enfrascada"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Poe Bottle", /*french*/"un Esprit en flacon", /*spanish*/"un Poe en una botella"} - ); - - hintTable[BOTTLE_WITH_BIG_POE] = HintText::Item({ - //obscure text - Text{"the spookiest ghost", /*french*/"un épouvantable spectre", /*spanish*/"el espectro más espeluznante"}, - Text{"a sidequest spirit", /*french*/"un précieux esprit", /*spanish*/"un buen valorado espíritu"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"a Big Poe Bottle", /*french*/"une Ame en flacon", /*spanish*/"un Gran Poe en una botella"} - ); - - hintTable[RUTOS_LETTER] = HintText::Item({ - //obscure text - Text{"a call for help", /*french*/"un appel au secours", /*spanish*/"una llamada de auxilio"}, - Text{"the note that Mweeps", /*french*/"un message qui fait mwip", /*spanish*/"un escrito mweep"}, - Text{"an SOS call", /*french*/"un signal SOS", /*spanish*/"una nota de socorro"}, - Text{"a fishy stationery", /*french*/"un papier mouillé", /*spanish*/"un mensaje de ayuda"}, - }, { - //ambiguous text - Text{"a bottle", /*french*/"un flacon", /*spanish*/"una botella"}, - }, - //clear text - Text{"Ruto's Letter", /*french*/"la lettre de Ruto", /*spanish*/"la carta de Ruto"} - ); - - hintTable[ZELDAS_LULLABY] = HintText::Item({ - //obscure text - Text{"a song of royal slumber", /*french*/"une chanson royale", /*spanish*/"la canción real"}, - Text{"a triforce tune", /*french*/"la musique sacrée", /*spanish*/"la melodía de la trifuerza"}, - }, { - //ambiguous text - Text{"a regular song", /*french*/"une chanson normale", /*spanish*/"una cancion normal"}, - Text{"something kept by the royal family", /*french*/"une chose qui paralyse", /*spanish*/"algo guardado por la familia real"}, - }, - //clear text - Text{"Zelda's Lullaby", /*french*/"la berceuse de Zelda", /*spanish*/"la Nana de Zelda"} - ); - - hintTable[EPONAS_SONG] = HintText::Item({ - //obscure text - Text{"an equestrian etude", /*french*/"une hymne équestre", /*spanish*/"una copla ecuestre"}, - Text{"Malon's melody", /*french*/"la mélodie des vaches", /*spanish*/"la sonata de Malon"}, - Text{"a ranch song", /*french*/"le chant des champs", /*spanish*/"un canto rupestre"}, - }, { - //ambiguous text - Text{"a regular song", /*french*/"une chanson normale", /*spanish*/"una cancion normal"}, - }, - //clear text - Text{"Epona's Song", /*french*/"le chant d'Epona", /*spanish*/"la Canción de Epona"} - ); - - hintTable[SARIAS_SONG] = HintText::Item({ - //obscure text - Text{"a song of dancing Gorons", /*french*/"une chanson danceuse", /*spanish*/"un pegadizo tono goron"}, - Text{"Saria's phone number", /*french*/"le téléphone d'une amie", /*spanish*/"una consulta de asistencia"}, - }, { - //ambiguous text - Text{"a regular song", /*french*/"une chanson normale", /*spanish*/"una cancion normal"}, - Text{"something given by Saria", /*french*/"un cadeau de Saria", /*spanish*/"un obsequio de Saria"}, - }, - //clear text - Text{"Saria's Song", /*french*/"le chant de Saria", /*spanish*/"la Canción de Saria"} - ); - - hintTable[SUNS_SONG] = HintText::Item({ - //obscure text - Text{"Sunny Day", /*french*/"Zénith", /*spanish*/"un día soleado"}, - Text{"the ReDead's bane", /*french*/"le fléau des Éffrois", /*spanish*/"la destructora de Redeads"}, - Text{"the Gibdo's bane", /*french*/"le fléau des Gibdo", /*spanish*/"la destructora de Gibdos"}, - }, { - //ambiguous text - Text{"a regular song", /*french*/"une chanson normale", /*spanish*/"una cancion normal"}, - Text{"something that can stun", /*french*/"une chose qui peut paralyser", /*spanish*/"algo que pueda paralizar"}, - }, - //clear text - Text{"the Sun's Song", /*french*/"le chant du soleil", /*spanish*/"la Canción del Sol"} - ); - - hintTable[SONG_OF_TIME] = HintText::Item({ - //obscure text - Text{"a song 7 years long", /*french*/"le flot du temps", /*spanish*/"la setenada canción"}, - Text{"the tune of ages", /*french*/"le Chant des Âges", /*spanish*/"la melodía eónica"}, - }, { - //ambiguous text - Text{"a regular song", /*french*/"une chanson normale", /*spanish*/"una cancion normal"}, - }, - //clear text - Text{"the Song of Time", /*french*/"le chant du temps", /*spanish*/"la Canción del tiempo"} - ); - - hintTable[SONG_OF_STORMS] = HintText::Item({ - //obscure text - Text{"Rain Dance", /*french*/"Danse Pluie", /*spanish*/"la danza de la lluvia"}, - Text{"a thunderstorm tune", /*french*/"une hymne foudroyante", /*spanish*/"una sonata tormentosa"}, - Text{"windmill acceleration", /*french*/"l'accélérateur de moulins", /*spanish*/"el arranque de molinos"}, - }, { - //ambiguous text - Text{"a regular song", /*french*/"une chanson normale", /*spanish*/"una cancion normal"}, - }, - //clear text - Text{"the Song of Storms", /*french*/"le chant des tempêtes", /*spanish*/"la Canción de la Tormenta"} - ); - - hintTable[MINUET_OF_FOREST] = HintText::Item({ - //obscure text - Text{"the song of tall trees", /*french*/"le bruit des arbres", /*spanish*/"la canción de las copas"}, - Text{"an arboreal anthem", /*french*/"l'hymne sylvestre", /*spanish*/"el himno forestal"}, - Text{"a green spark trail", /*french*/"une comète verte", /*spanish*/"el sendero esmeralda"}, - }, { - //ambiguous text - Text{"a warp song", /*french*/"une chanson de téléportation", /*spanish*/"una canción de teletransportación"}, - }, - //clear text - Text{"the Minuet of Forest", /*french*/"le menuet de la forêt", /*spanish*/"el Minueto del bosque"} - ); - - hintTable[BOLERO_OF_FIRE] = HintText::Item({ - //obscure text - Text{"a song of lethal lava", /*french*/"une musique enflammée", /*spanish*/"la canción de la lava"}, - Text{"a red spark trail", /*french*/"une comète rouge", /*spanish*/"el sendero rubí"}, - Text{"a volcanic verse", /*french*/"le souffle du volcan", /*spanish*/"el verso volcánico"}, - }, { - //ambiguous text - Text{"a warp song", /*french*/"une chanson de téléportation", /*spanish*/"una canción de teletransportación"}, - }, - //clear text - Text{"the Bolero of Fire", /*french*/"le boléro du feu", /*spanish*/"el Bolero del fuego"} - ); - - hintTable[SERENADE_OF_WATER] = HintText::Item({ - //obscure text - Text{"a song of a damp ditch", /*french*/"le calme de l'eau", /*spanish*/"la canción del estanque"}, - Text{"a blue spark trail", /*french*/"une comète bleue", /*spanish*/"el sendero zafiro"}, - Text{"the lake's lyric", /*french*/"la voix du lac", /*spanish*/"la letra del lago"}, - }, { - //ambiguous text - Text{"a warp song", /*french*/"une chanson de téléportation", /*spanish*/"una canción de teletransportación"}, - }, - //clear text - Text{"the Serenade of Water", /*french*/"la sérénade de l'eau", /*spanish*/"la Serenata del agua"} - ); - - hintTable[REQUIEM_OF_SPIRIT] = HintText::Item({ - //obscure text - Text{"a song of sandy statues", /*french*/"la mélodie d'une grande statue", /*spanish*/"la canción de la gran estatua"}, - Text{"an orange spark trail", /*french*/"une comète orange", /*spanish*/"el sendero ámbar"}, - Text{"the desert ditty", /*french*/"le vent du désert", /*spanish*/"la estrofa del desierto"}, - }, { - //ambiguous text - Text{"a warp song", /*french*/"une chanson de téléportation", /*spanish*/"una canción de teletransportación"}, - }, - //clear text - Text{"the Requiem of Spirit", /*french*/"le requiem des esprits", /*spanish*/"el Réquiem del espíritu"} - ); - - hintTable[NOCTURNE_OF_SHADOW] = HintText::Item({ - //obscure text - Text{"a song of spooky spirits", /*french*/"une hymne de chair de poule", /*spanish*/"la canción de los espectros"}, - Text{"a graveyard boogie", /*french*/"un boogie de fantômes", /*spanish*/"una honra fúnebre"}, - Text{"a haunted hymn", /*french*/"une chanson lugubre", /*spanish*/"una estrofa encantada"}, - Text{"a purple spark trail", /*french*/"une comète mauve", /*spanish*/"el sendero malva"}, - }, { - //ambiguous text - Text{"a warp song", /*french*/"une chanson de téléportation", /*spanish*/"una canción de teletransportación"}, - }, - //clear text - Text{"the Nocturne of Shadow", /*french*/"le nocturne de l'ombre", /*spanish*/"el Nocturno de la sombra"} - ); - - hintTable[PRELUDE_OF_LIGHT] = HintText::Item({ - //obscure text - Text{"a luminous prologue melody", /*french*/"une matine illuminée", /*spanish*/"la melodía refulgente"}, - Text{"a yellow spark trail", /*french*/"une comète jaune", /*spanish*/"el sendero resplandeciente"}, - Text{"the temple traveler", /*french*/"un chant de sanctuaire", /*spanish*/"la ruta del templo"}, - }, { - //ambiguous text - Text{"a warp song", /*french*/"une chanson de téléportation", /*spanish*/"una canción de teletransportación"}, - }, - //clear text - Text{"the Prelude of Light", /*french*/"le prélude de la lumière", /*spanish*/"el Preludio de la luz"} - ); - hintTable[DEKU_TREE_MAP] = HintText::Item({ - //obscure text - Text{"a mossy atlas", /*french*/"un atlas boisé", /*spanish*/"un atlas musgoso"}, - Text{"some mossy blueprints", /*french*/"un plan boisé", /*spanish*/"unos planos musgosos"}, - }, { - //ambiguous text - Text{"a dungeon map", /*french*/"une carte", /*spanish*/"un mapa"}, - }, - //clear text - Text{"the Deku Tree Map", /*french*/"la carte de l'Arbre Mojo", /*spanish*/"el mapa del Gran Árbol Deku"} - ); - hintTable[DODONGOS_CAVERN_MAP] = HintText::Item({ - //obscure text - Text{"a rocky atlas", /*french*/"un atlas rocheux", /*spanish*/"un atlas rocoso"}, - Text{"some rocky blueprints", /*french*/"un plan rocheux", /*spanish*/"unos planos rocosos"}, - }, { - //ambiguous text - Text{"a dungeon map", /*french*/"une carte", /*spanish*/"un mapa"}, - }, - //clear text - Text{"the Dodongo's Cavern Map", /*french*/"la carte de la Caverne Dodongo", /*spanish*/"el mapa de la Cueva de los Dodongos"} - ); - hintTable[JABU_JABUS_BELLY_MAP] = HintText::Item({ - //obscure text - Text{"a fishy atlas", /*french*/"un atlas digéré", /*spanish*/"un atlas digesto"}, - Text{"some fishy blueprints", /*french*/"un plan digéré", /*spanish*/"unos planos digestos"}, - }, { - //ambiguous text - Text{"a dungeon map", /*french*/"une carte", /*spanish*/"un mapa"}, - }, - //clear text - Text{"the Jabu-Jabu's Belly Map", /*french*/"la carte de Jabu-Jabu", /*spanish*/"el mapa de la Tripa de Jabu-Jabu"} - ); - hintTable[FOREST_TEMPLE_MAP] = HintText::Item({ - //obscure text - Text{"a sylvan atlas", /*french*/"un atlas sylvestre", /*spanish*/"un atlas enselvado"}, - Text{"some sylvan blueprints", /*french*/"un plan sylvestre", /*spanish*/"unos planos enselvados"}, - }, { - //ambiguous text - Text{"a dungeon map", /*french*/"une carte", /*spanish*/"un mapa"}, - }, - //clear text - Text{"the Forest Temple Map", /*french*/"la carte du Temple de la Forêt", /*spanish*/"el mapa del Templo del Bosque"} - ); - hintTable[FIRE_TEMPLE_MAP] = HintText::Item({ - //obscure text - Text{"a molten atlas", /*french*/"un atlas fondu", /*spanish*/"un atlas fundido"}, - Text{"some molten blueprints", /*french*/"un plan fondu", /*spanish*/"unos planos fundidos"}, - }, { - //ambiguous text - Text{"a dungeon map", /*french*/"une carte", /*spanish*/"un mapa"}, - }, - //clear text - Text{"the Fire Temple Map", /*french*/"la carte du Temple du Feu", /*spanish*/"el mapa del Templo del Fuego"} - ); - hintTable[WATER_TEMPLE_MAP] = HintText::Item({ - //obscure text - Text{"a wet atlas", /*french*/"un atlas humide", /*spanish*/"un atlas mojado"}, - Text{"some wet blueprints", /*french*/"un plan humide", /*spanish*/"unos planos mojados"}, - }, { - //ambiguous text - Text{"a dungeon map", /*french*/"une carte", /*spanish*/"un mapa"}, - }, - //clear text - Text{"the Water Temple Map", /*french*/"la carte du Temple de l'Eau", /*spanish*/"el mapa del Templo del Agua"} - ); - hintTable[SPIRIT_TEMPLE_MAP] = HintText::Item({ - //obscure text - Text{"a sandy atlas", /*french*/"un atlas sableux", /*spanish*/"un atlas arenoso"}, - Text{"some sandy blueprints", /*french*/"un plan sableux", /*spanish*/"unos planos arenosos"}, - }, { - //ambiguous text - Text{"a dungeon map", /*french*/"une carte", /*spanish*/"un mapa"}, - }, - //clear text - Text{"the Spirit Temple Map", /*french*/"la carte du Temple de l'Esprit", /*spanish*/"el mapa del Templo del Espíritu"} - ); - hintTable[SHADOW_TEMPLE_MAP] = HintText::Item({ - //obscure text - Text{"a creepy atlas", /*french*/"un atlas sinistre", /*spanish*/"un atlas siniestra"}, - Text{"some creepy blueprints", /*french*/"un plan sinistre", /*spanish*/"unos planos siniestras"}, - }, { - //ambiguous text - Text{"a dungeon map", /*french*/"une carte", /*spanish*/"un mapa"}, - }, - //clear text - Text{"the Shadow Temple Map", /*french*/"la carte du Temple de l'Ombre", /*spanish*/"el mapa del Templo de las Sombras"} - ); - hintTable[BOTTOM_OF_THE_WELL_MAP] = HintText::Item({ - //obscure text - Text{"a moldy atlas", /*french*/"un atlas moisi", /*spanish*/"un atlas mohoso"}, - Text{"some moldy blueprints", /*french*/"un plan moisi", /*spanish*/"unos planos mohosos"}, - }, { - //ambiguous text - Text{"a dungeon map", /*french*/"une carte", /*spanish*/"un mapa"}, - }, - //clear text - Text{"the Bottom of the Well Map", /*french*/"la carte du fond du Puits", /*spanish*/"el mapa del Fondo del pozo"} - ); - hintTable[ICE_CAVERN_MAP] = HintText::Item({ - //obscure text - Text{"a polar atlas", /*french*/"un atlas polaire", /*spanish*/"un atlas polar"}, - Text{"some polar blueprints", /*french*/"un plan polaire", /*spanish*/"unos planos polars"}, - }, { - //ambiguous text - Text{"a dungeon map", /*french*/"une carte", /*spanish*/"un mapa"}, - }, - //clear text - Text{"the Ice Cavern Map", /*french*/"la carte de la Caverne Polaire", /*spanish*/"el mapa de la Caverna de hielo"} - ); - hintTable[DEKU_TREE_COMPASS] = HintText::Item({ - //obscure text - Text{"a mossy treasure tracker", /*french*/"un cherche-trésor boisé", /*spanish*/"un zahorí musgoso"}, - Text{"a mossy magnetic needle", /*french*/"une aimant boisée", /*spanish*/"un imán musgoso"}, - }, { - //ambiguous text - Text{"a compass", /*french*/"une boussole", /*spanish*/"una brújula"}, - }, - //clear text - Text{"the Deku Tree Compass", /*french*/"la boussole de l'Arbre Mojo", /*spanish*/"la brújula del Gran Árbol Deku"} - ); - hintTable[DODONGOS_CAVERN_COMPASS] = HintText::Item({ - //obscure text - Text{"a rocky treasure tracker", /*french*/"un cherche-trésor rocheux", /*spanish*/"un zahorí rocoso"}, - Text{"a rocky magnetic needle", /*french*/"une aimant rocheux", /*spanish*/"un imán rocoso"}, - }, { - //ambiguous text - Text{"a compass", /*french*/"une boussole", /*spanish*/"una brújula"}, - }, - //clear text - Text{"the Dodongo's Cavern Compass", /*french*/"la boussole de la Caverne Dodongo", /*spanish*/"la brújula de la Cueva de los Dodongos"} - ); - hintTable[JABU_JABUS_BELLY_COMPASS] = HintText::Item({ - //obscure text - Text{"a fishy treasure tracker", /*french*/"un cherche-trésor digéré", /*spanish*/"un zahorí digesto"}, - Text{"a fishy magnetic needle", /*french*/"une aimant digéré", /*spanish*/"un imán digesto"}, - }, { - //ambiguous text - Text{"a compass", /*french*/"une boussole", /*spanish*/"una brújula"}, - }, - //clear text - Text{"the Jabu-Jabu's Belly Compass", /*french*/"la boussole de Jabu-Jabu", /*spanish*/"la brújula de la Tripa de Jabu-Jabu"} - ); - hintTable[FOREST_TEMPLE_COMPASS] = HintText::Item({ - //obscure text - Text{"a sylvan treasure tracker", /*french*/"un cherche-trésor sylvestre", /*spanish*/"un zahorí enselvado"}, - Text{"a sylvan magnetic needle", /*french*/"une aimant sylvestre", /*spanish*/"un imán enselvado"}, - }, { - //ambiguous text - Text{"a compass", /*french*/"une boussole", /*spanish*/"una brújula"}, - }, - //clear text - Text{"the Forest Temple Compass", /*french*/"la boussole du Temple de la Forêt", /*spanish*/"la brújula del Templo del Bosque"} - ); - hintTable[FIRE_TEMPLE_COMPASS] = HintText::Item({ - //obscure text - Text{"a molten treasure tracker", /*french*/"un cherche-trésor fondu", /*spanish*/"un zahorí fundido"}, - Text{"a molten magnetic needle", /*french*/"une aimant fondu", /*spanish*/"un imán fundido"}, - }, { - //ambiguous text - Text{"a compass", /*french*/"une boussole", /*spanish*/"una brújula"}, - }, - //clear text - Text{"the Fire Temple Compass", /*french*/"la boussole du Temple du Feu", /*spanish*/"la brújula del Templo del Fuego"} - ); - hintTable[WATER_TEMPLE_COMPASS] = HintText::Item({ - //obscure text - Text{"a wet treasure tracker", /*french*/"un cherche-trésor humide", /*spanish*/"un zahorí mojado"}, - Text{"a wet magnetic needle", /*french*/"une aimant humide", /*spanish*/"un imán mojado"}, - }, { - //ambiguous text - Text{"a compass", /*french*/"une boussole", /*spanish*/"una brújula"}, - }, - //clear text - Text{"the Water Temple Compass", /*french*/"la boussole du Temple de l'Eau", /*spanish*/"la brújula del Templo del Agua"} - ); - hintTable[SPIRIT_TEMPLE_COMPASS] = HintText::Item({ - //obscure text - Text{"a sandy treasure tracker", /*french*/"un cherche-trésor sableux", /*spanish*/"un zahorí arenoso"}, - Text{"a sandy magnetic needle", /*french*/"une aimant sableux", /*spanish*/"un imán arenoso"}, - }, { - //ambiguous text - Text{"a compass", /*french*/"une boussole", /*spanish*/"una brújula"}, - }, - //clear text - Text{"the Spirit Temple Compass", /*french*/"la boussole du Temple de l'Esprit", /*spanish*/"la brújula del Templo del Espíritu"} - ); - hintTable[SHADOW_TEMPLE_COMPASS] = HintText::Item({ - //obscure text - Text{"a creepy treasure tracker", /*french*/"un cherche-trésor sinistre", /*spanish*/"un zahorí siniestra"}, - Text{"a creepy magnetic needle", /*french*/"une aimant sinistre", /*spanish*/"un imán siniestra"}, - }, { - //ambiguous text - Text{"a compass", /*french*/"une boussole", /*spanish*/"una brújula"}, - }, - //clear text - Text{"the Shadow Temple Compass", /*french*/"la boussole du Temple de l'Ombre", /*spanish*/"la brújula del Templo de las Sombras"} - ); - hintTable[BOTTOM_OF_THE_WELL_COMPASS] = HintText::Item({ - //obscure text - Text{"a dank treasure tracker", /*french*/"un cherche-trésor moisi", /*spanish*/"un zahorí mohoso"}, - Text{"a dank magnetic needle", /*french*/"une aimant moisi", /*spanish*/"un imán mohoso"}, - }, { - //ambiguous text - Text{"a compass", /*french*/"une boussole", /*spanish*/"una brújula"}, - }, - //clear text - Text{"the Bottom of the Well Compass", /*french*/"la boussole du fond du Puits", /*spanish*/"la brújula del Fondo del pozo"} - ); - hintTable[ICE_CAVERN_COMPASS] = HintText::Item({ - //obscure text - Text{"a polar treasure tracker", /*french*/"un cherche-trésor polaire", /*spanish*/"un zahorí polar"}, - Text{"a polar magnetic needle", /*french*/"une aimant polaire", /*spanish*/"un imán polar"}, - }, { - //ambiguous text - Text{"a compass", /*french*/"une boussole", /*spanish*/"una brújula"}, - }, - //clear text - Text{"the Ice Cavern Compass", /*french*/"la Boussole de la Caverne Polaire", /*spanish*/"la brújula de la Caverna de hielo"} - ); - hintTable[FOREST_TEMPLE_BOSS_KEY] = HintText::Item({ - //obscure text - Text{"a sylvan master of unlocking", /*french*/"un anti-grosse porte sylvestre", /*spanish*/"la clave enselvada de un jefe"}, - Text{"a sylvan dungeon's master pass", /*french*/"une clé maléfique sylvestree", /*spanish*/"el pase maestro enselvado"}, - }, { - //ambiguous text - Text{"a boss key", /*french*/"une Clé d'Or", /*spanish*/"una gran llave"}, - }, - //clear text - Text{"the Forest Temple Boss Key", /*french*/"la Clé d'Or du Temple de la Forêt", /*spanish*/"la gran llave del Templo del Bosque"} - ); - hintTable[FIRE_TEMPLE_BOSS_KEY] = HintText::Item({ - //obscure text - Text{"a molten master of unlocking", /*french*/"un anti-grosse porte fondu", /*spanish*/"la clave fundido de un jefe"}, - Text{"a molten dungeon's master pass", /*french*/"une clé maléfique fondu", /*spanish*/"el pase maestro fundido"}, - }, { - //ambiguous text - Text{"a boss key", /*french*/"une Clé d'Or", /*spanish*/"una gran llave"}, - }, - //clear text - Text{"the Fire Temple Boss Key", /*french*/"la Clé d'Or du Temple du Feu", /*spanish*/"la gran llave del Templo del Fuego"} - ); - hintTable[WATER_TEMPLE_BOSS_KEY] = HintText::Item({ - //obscure text - Text{"a wet master of unlocking", /*french*/"un anti-grosse porte humide", /*spanish*/"la clave mojado de un jefe"}, - Text{"a wet dungeon's master pass", /*french*/"une clé maléfique humide", /*spanish*/"el pase maestro mojado"}, - }, { - //ambiguous text - Text{"a boss key", /*french*/"une Clé d'Or", /*spanish*/"una gran llave"}, - }, - //clear text - Text{"the Water Temple Boss Key", /*french*/"la Clé d'Or du Temple de l'Eau", /*spanish*/"la gran llave del Templo del Agua"} - ); - hintTable[SPIRIT_TEMPLE_BOSS_KEY] = HintText::Item({ - //obscure text - Text{"a sandy master of unlocking", /*french*/"un anti-grosse porte sableux", /*spanish*/"la clave arenoso de un jefe"}, - Text{"a sandy dungeon's master pass", /*french*/"une clé maléfique sableux", /*spanish*/"el pase maestro arenoso"}, - }, { - //ambiguous text - Text{"a boss key", /*french*/"une Clé d'Or", /*spanish*/"una gran llave"}, - }, - //clear text - Text{"the Spirit Temple Boss Key", /*french*/"la Clé d'Or du Temple de l'Esprit", /*spanish*/"la gran llave del Templo del Espíritu"} - ); - hintTable[SHADOW_TEMPLE_BOSS_KEY] = HintText::Item({ - //obscure text - Text{"a creepy master of unlocking", /*french*/"un anti-grosse porte sinistre", /*spanish*/"la clave siniestra de un jefe"}, - Text{"a creepy dungeon's master pass", /*french*/"une clé maléfique sinistre", /*spanish*/"el pase maestro siniestra"}, - }, { - //ambiguous text - Text{"a boss key", /*french*/"une Clé d'Or", /*spanish*/"una gran llave"}, - }, - //clear text - Text{"the Shadow Temple Boss Key", /*french*/"la Clé d'Or du Temple de l'Ombre", /*spanish*/"la gran llave del Templo de las Sombras"} - ); - hintTable[GANONS_CASTLE_BOSS_KEY] = HintText::Item({ - //obscure text - Text{"a final master of unlocking", /*french*/"un anti-grosse porte final", /*spanish*/"la clave final de un jefe"}, - Text{"a final dungeon's master pass", /*french*/"une clé maléfique final", /*spanish*/"el pase maestro final"}, - }, { - //ambiguous text - Text{"a boss key", /*french*/"une Clé d'Or", /*spanish*/"una gran llave"}, - }, - //clear text - Text{"the Ganon's Castle Boss Key", /*french*/"la Clé d'Or du Château de Ganon", /*spanish*/"la gran llave del Castillo de Ganon"} - ); - hintTable[FOREST_TEMPLE_SMALL_KEY] = HintText::Item({ - //obscure text - Text{"a sylvan tool for unlocking", /*french*/"un anti-porte sylvestre", /*spanish*/"una clave de una entrada enselvada"}, - Text{"a sylvan dungeon pass", /*french*/"le rêve sylvestre d'un prisonnier", /*spanish*/"un pase de una mazmorra enselvada"}, - Text{"a sylvan lock remover", /*french*/"un efface-serrure sylvestre", /*spanish*/"un destructor de cerraduras enselvada"}, - Text{"a sylvan lockpick", /*french*/"un crochet à porte sylvestre", /*spanish*/"una apertura portentosa enselvada"}, - }, { - //ambiguous text - Text{"a small key", /*french*/"une petite clé", /*spanish*/"una llave pequeña"}, - }, - //clear text - Text{"a Forest Temple Small Key", /*french*/"une petite clé du Temple de la Forêt", /*spanish*/"una llave pequeña del Templo del Bosque"} - ); - hintTable[FIRE_TEMPLE_SMALL_KEY] = HintText::Item({ - //obscure text - Text{"a molten tool for unlocking", /*french*/"un anti-porte fondu", /*spanish*/"una clave de una entrada fundida"}, - Text{"a molten dungeon pass", /*french*/"le rêve fondu d'un prisonnier", /*spanish*/"un pase de una mazmorra fundida"}, - Text{"a molten lock remover", /*french*/"un efface-serrure fondu", /*spanish*/"un destructor de cerraduras fundida"}, - Text{"a molten lockpick", /*french*/"un crochet à porte fondu", /*spanish*/"una apertura portentosa fundida"}, - }, { - //ambiguous text - Text{"a small key", /*french*/"une petite clé", /*spanish*/"una llave pequeña"}, - }, - //clear text - Text{"a Fire Temple Small Key", /*french*/"une petite clé du Temple du Feu", /*spanish*/"una llave pequeña del Templo del Fuego"} - ); - hintTable[WATER_TEMPLE_SMALL_KEY] = HintText::Item({ - //obscure text - Text{"a wet tool for unlocking", /*french*/"un anti-porte humide", /*spanish*/"una clave de una entrada mojada"}, - Text{"a wet dungeon pass", /*french*/"le rêve humide d'un prisonnier", /*spanish*/"un pase de una mazmorra mojada"}, - Text{"a wet lock remover", /*french*/"un efface-serrure humide", /*spanish*/"un destructor de cerraduras mojada"}, - Text{"a wet lockpick", /*french*/"un crochet à porte humide", /*spanish*/"una apertura portentosa mojada"}, - }, { - //ambiguous text - Text{"a small key", /*french*/"une petite clé", /*spanish*/"una llave pequeña"}, - }, - //clear text - Text{"a Water Temple Small Key", /*french*/"une petite clé du Temple de l'Eau", /*spanish*/"una llave pequeña del Templo del Agua"} - ); - hintTable[SPIRIT_TEMPLE_SMALL_KEY] = HintText::Item({ - //obscure text - Text{"a sandy tool for unlocking", /*french*/"un anti-porte sableux", /*spanish*/"una clave de una entrada arenosa"}, - Text{"a sandy dungeon pass", /*french*/"le rêve sableux d'un prisonnier", /*spanish*/"un pase de una mazmorra arenosa"}, - Text{"a sandy lock remover", /*french*/"un efface-serrure sableux", /*spanish*/"un destructor de cerraduras arenosa"}, - Text{"a sandy lockpick", /*french*/"un crochet à porte sableux", /*spanish*/"una apertura portentosa arenosa"}, - }, { - //ambiguous text - Text{"a small key", /*french*/"une petite clé", /*spanish*/"una llave pequeña"}, - }, - //clear text - Text{"a Spirit Temple Small Key", /*french*/"une petite clé du Temple de l'Esprit", /*spanish*/"una llave pequeña del Templo del Espíritu"} - ); - hintTable[SHADOW_TEMPLE_SMALL_KEY] = HintText::Item({ - //obscure text - Text{"a creepy tool for unlocking", /*french*/"un anti-porte sinistre", /*spanish*/"una clave de una entrada siniestra:a"}, - Text{"a creepy dungeon pass", /*french*/"le rêve sinistre d'un prisonnier", /*spanish*/"un pase de una mazmorra siniestra:a"}, - Text{"a creepy lock remover", /*french*/"un efface-serrure sinistre", /*spanish*/"un destructor de cerraduras siniestra:a"}, - Text{"a creepy lockpick", /*french*/"un crochet à porte sinistre", /*spanish*/"una apertura portentosa siniestra:a"}, - }, { - //ambiguous text - Text{"a small key", /*french*/"une petite clé", /*spanish*/"una llave pequeña"}, - }, - //clear text - Text{"a Shadow Temple Small Key", /*french*/"une petite clé du Temple de l'Ombre", /*spanish*/"una llave pequeña del Templo de las Sombras"} - ); - hintTable[GERUDO_TRAINING_GROUNDS_SMALL_KEY] = HintText::Item({ - //obscure text - Text{"a labyrinthian tool for unlocking", /*french*/"un anti-porte labyrinthique", /*spanish*/"una clave de una entrada laberíntica"}, - Text{"a labyrinthian dungeon pass", /*french*/"le rêve labyrinthique d'un prisonnier", /*spanish*/"un pase de una mazmorra laberíntica"}, - Text{"a labyrinthian lock remover", /*french*/"un efface-serrure labyrinthique", /*spanish*/"un destructor de cerraduras laberíntica"}, - Text{"a labyrinthian lockpick", /*french*/"un crochet à porte labyrinthique", /*spanish*/"una apertura portentosa laberíntica"}, - }, { - //ambiguous text - Text{"a small key", /*french*/"une petite clé", /*spanish*/"una llave pequeña"}, - }, - //clear text - Text{"a Gerudo Training Ground Small Key", /*french*/"une petite clé du Gymnase Gerudo", /*spanish*/"una llave pequeña del Centro de Instrucción Gerudo"} - ); - hintTable[GERUDO_FORTRESS_SMALL_KEY] = HintText::Item({ - //obscure text - Text{"an imprisoned tool for unlocking", /*french*/"un anti-porte emprisonné", /*spanish*/"una clave de una entrada encarcelada"}, - Text{"an imprisoned dungeon pass", /*french*/"le rêve emprisonné d'un prisonnier", /*spanish*/"un pase de una mazmorra encarcelada"}, - Text{"an imprisoned lock remover", /*french*/"un efface-serrure emprisonné", /*spanish*/"un destructor de cerraduras encarcelada"}, - Text{"an imprisoned lockpick", /*french*/"un crochet à porte emprisonné", /*spanish*/"una apertura portentosa encarcelada"}, - }, { - //ambiguous text - Text{"a small key", /*french*/"une petite clé", /*spanish*/"una llave pequeña"}, - }, - //clear text - Text{"a Gerudo Fortress Small Key", /*french*/"une petite clé de la Repaire des Voleurs", /*spanish*/"una llave pequeña de la Fortaleza Gerudo"} - ); - hintTable[BOTTOM_OF_THE_WELL_SMALL_KEY] = HintText::Item({ - //obscure text - Text{"a moldy tool for unlocking", /*french*/"un anti-porte moisi", /*spanish*/"una clave de una entrada mohosa"}, - Text{"a moldy dungeon pass", /*french*/"le rêve moisi d'un prisonnier", /*spanish*/"un pase de una mazmorra mohosa"}, - Text{"a moldy lock remover", /*french*/"un efface-serrure moisi", /*spanish*/"un destructor de cerraduras mohosa"}, - Text{"a moldy lockpick", /*french*/"un crochet à porte moisi", /*spanish*/"una apertura portentosa mohosa"}, - }, { - //ambiguous text - Text{"a small key", /*french*/"une petite clé", /*spanish*/"una llave pequeña"}, - }, - //clear text - Text{"a Bottom of the Well Small Key", /*french*/"une petite clé du fond du Puits", /*spanish*/"una llave pequeña del Fondo del pozo"} - ); - hintTable[GANONS_CASTLE_SMALL_KEY] = HintText::Item({ - //obscure text - Text{"a final tool for unlocking", /*french*/"un anti-porte final", /*spanish*/"una clave de una entrada final"}, - Text{"a final dungeon pass", /*french*/"le rêve final d'un prisonnier", /*spanish*/"un pase de una mazmorra final"}, - Text{"a final lock remover", /*french*/"un efface-serrure final", /*spanish*/"un destructor de cerraduras final"}, - Text{"a final lockpick", /*french*/"un crochet à porte final", /*spanish*/"una apertura portentosa final"}, - }, { - //ambiguous text - Text{"a small key", /*french*/"une petite clé", /*spanish*/"una llave pequeña"}, - }, - //clear text - Text{"a Ganon's Castle Small Key", /*french*/"une petite clé du Château de Ganon", /*spanish*/"una llave pequeña del Castillo de Ganon"} - ); - hintTable[FOREST_TEMPLE_KEY_RING] = HintText::Item({ - //obscure text - Text{"a sylvan toolbox for unlocking", /*french*/"des anti-portes sylvestres", /*spanish*/"un conjunto silvestre de cerrajero"}, - Text{"a sylvan dungeon season pass", /*french*/"les rêves sylvestres d'un prisonnier", /*spanish*/"un pase vip de mazmorras silvestre"}, - Text{"a sylvan jingling ring", /*french*/"des efface-serrures sylvestres", /*spanish*/"una cadena multiusos silvestre"}, - Text{"a sylvan skeleton key", /*french*/"des crochets à porte sylvestres", /*spanish*/"un anillo silvestre contra cerrojos"}, - }, { - //ambiguous text - Text{"a key ring", /*french*/"un trousseau de clés", /*spanish*/"un llavero"}, - }, - //clear text - Text{"a Forest Temple Key Ring", /*french*/"un trousseau de clés du Temple de la Forêt", /*spanish*/"un llavero del Templo del Bosque"} - ); - hintTable[FIRE_TEMPLE_KEY_RING] = HintText::Item({ - //obscure text - Text{"a molten toolbox for unlocking", /*french*/"des anti-portes fondus", /*spanish*/"un conjunto fundido de cerrajero"}, - Text{"a molten dungeon season pass", /*french*/"les rêves fondus d'un prisonnier", /*spanish*/"un pase vip de mazmorras fundido"}, - Text{"a molten jingling ring", /*french*/"des efface-serrures fondus", /*spanish*/"una cadena multiusos fundida"}, - Text{"a molten skeleton key", /*french*/"des crochets à porte fondus", /*spanish*/"un anillo fundido contra cerrojos"}, - }, { - //ambiguous text - Text{"a key ring", /*french*/"un trousseau de clés", /*spanish*/"un llavero"}, - }, - //clear text - Text{"a Fire Temple Key Ring", /*french*/"un trousseau de clés du Temple du Feu", /*spanish*/"un llavero del Templo del Fuego"} - ); - hintTable[WATER_TEMPLE_KEY_RING] = HintText::Item({ - //obscure text - Text{"a wet toolbox for unlocking", /*french*/"des anti-portes humides", /*spanish*/"un conjunto abisal de cerrajero"}, - Text{"a wet dungeon season pass", /*french*/"les rêves humides d'un prisonnier", /*spanish*/"un pase vip de mazmorras abisal"}, - Text{"a wet jingling ring", /*french*/"des efface-serrures humides", /*spanish*/"una cadena multiusos abisal"}, - Text{"a wet skeleton key", /*french*/"des crochets à porte humides", /*spanish*/"un anillo abisal contra cerrojos"}, - }, { - //ambiguous text - Text{"a key ring", /*french*/"un trousseau de clés", /*spanish*/"un llavero"}, - }, - //clear text - Text{"a Water Temple Key Ring", /*french*/"un trousseau de clés du Temple de l'Eau", /*spanish*/"un llavero del Templo del Agua"} - ); - hintTable[SPIRIT_TEMPLE_KEY_RING] = HintText::Item({ - //obscure text - Text{"a sandy toolbox for unlocking", /*french*/"des anti-portes sableux", /*spanish*/"un conjunto arenoso de cerrajero"}, - Text{"a sandy dungeon season pass", /*french*/"les rêves sableux d'un prisonnier", /*spanish*/"un pase vip de mazmorras arenoso"}, - Text{"a sandy jingling ring", /*french*/"des efface-serrures sableux", /*spanish*/"una cadena multiusos arenosa"}, - Text{"a sandy skeleton key", /*french*/"des crochets à porte sableux", /*spanish*/"un anillo arenoso contra cerrojos"}, - }, { - //ambiguous text - Text{"a key ring", /*french*/"un trousseau de clés", /*spanish*/"un llavero"}, - }, - //clear text - Text{"a Spirit Temple Key Ring", /*french*/"un trousseau de clés du Temple de l'Esprit", /*spanish*/"un llavero del Templo del Espíritu"} - ); - hintTable[SHADOW_TEMPLE_KEY_RING] = HintText::Item({ - //obscure text - Text{"a creepy toolbox for unlocking", /*french*/"des anti-portes sinistres", /*spanish*/"un conjunto tenebroso de cerrajero"}, - Text{"a creepy dungeon season pass", /*french*/"les rêves sinistres d'un prisonnier", /*spanish*/"un pase vip de mazmorras tenebroso"}, - Text{"a creepy jingling ring", /*french*/"des efface-serrures sinistres", /*spanish*/"una cadena multiusos tenebrosa"}, - Text{"a creepy skeleton key", /*french*/"des crochets à porte sinistres", /*spanish*/"un anillo tenebroso contra cerrojos"}, - }, { - //ambiguous text - Text{"a key ring", /*french*/"un trousseau de clés", /*spanish*/"un llavero"}, - }, - //clear text - Text{"a Shadow Temple Key Ring", /*french*/"un trousseau de clés du Temple de l'Ombre", /*spanish*/"un llavero del Templo de las Sombras"} - ); - hintTable[GERUDO_TRAINING_GROUNDS_KEY_RING] = HintText::Item({ - //obscure text - Text{"a labyrinthian toolbox for unlocking", /*french*/"des anti-portes labyrinthiques", /*spanish*/"un conjunto laberíntico de cerrajero"}, - Text{"a labyrinthian dungeon season pass", /*french*/"les rêves labyrinthiques d'un prisonnier", /*spanish*/"un pase vip de mazmorras laberíntico"}, - Text{"a labyrinthian jingling ring", /*french*/"des efface-serrures labyrinthiques", /*spanish*/"una cadena multiusos laberíntica"}, - Text{"a labyrinthian skeleton key", /*french*/"des crochets à porte labyrinthiques", /*spanish*/"un anillo laberíntico contra cerrojos"}, - }, { - //ambiguous text - Text{"a key ring", /*french*/"un trousseau de clés", /*spanish*/"un llavero"}, - }, - //clear text - Text{"a Gerudo Training Ground Key Ring", /*french*/"un trousseau de clés du Gymnase Gerudo", /*spanish*/"un llavero del Centro de Instrucción Gerudo"} - ); - hintTable[GERUDO_FORTRESS_KEY_RING] = HintText::Item({ - //obscure text - Text{"an imprisoned toolbox for unlocking", /*french*/"des anti-portes emprisonnés", /*spanish*/"un conjunto enjaulado de cerrajero"}, - Text{"an imprisoned dungeon season pass", /*french*/"les rêves emprisonnés d'un prisonnier", /*spanish*/"un pase vip de una mazmorra enjaulado"}, - Text{"an imprisoned jingling ring", /*french*/"des efface-serrures emprisonnés", /*spanish*/"una cadena multiusos enjaulada"}, - Text{"an imprisoned skeleton key", /*french*/"des crochets à porte emprisonnés", /*spanish*/"un anillo enjaulado contra cerrojos"}, - }, { - //ambiguous text - Text{"a key ring", /*french*/"un trousseau de clés", /*spanish*/"un llavero"}, - }, - //clear text - Text{"a Gerudo Fortress Key Ring", /*french*/"un trousseau de clés de la Repaire des Voleurs", /*spanish*/"un llavero de la Fortaleza Gerudo"} - ); - hintTable[BOTTOM_OF_THE_WELL_KEY_RING] = HintText::Item({ - //obscure text - Text{"a moldy toolbox for unlocking", /*french*/"des anti-portes moisis", /*spanish*/"un conjunto subterráneo de cerrajero"}, - Text{"a moldy dungeon season pass", /*french*/"les rêves moisis d'un prisonnier", /*spanish*/"un pase vip de una mazmorra subterráneo"}, - Text{"a moldy jingling ring", /*french*/"des efface-serrures moisis", /*spanish*/"una cadena multiusos subterránea"}, - Text{"a moldy skeleton key", /*french*/"des crochets à porte moisis", /*spanish*/"un anillo subterráneo contra cerrojos"}, - }, { - //ambiguous text - Text{"a key ring", /*french*/"un trousseau de clés", /*spanish*/"un llavero"}, - }, - //clear text - Text{"a Bottom of the Well Key Ring", /*french*/"un trousseau de clés du fond du Puits", /*spanish*/"un llavero del Fondo del pozo"} - ); - hintTable[GANONS_CASTLE_KEY_RING] = HintText::Item({ - //obscure text - Text{"a final toolbox for unlocking", /*french*/"des anti-portes finaux", /*spanish*/"un conjunto decisivo de cerrajero"}, - Text{"a final dungeon season pass", /*french*/"les rêves finaux d'un prisonnier", /*spanish*/"un pase vip de una mazmorra decisivo"}, - Text{"a final jingling ring", /*french*/"des efface-serrures finaux", /*spanish*/"una cadena multiusos decisiva"}, - Text{"a final skeleton key", /*french*/"des crochets à porte finaux", /*spanish*/"un anillo decisivo multiusos"}, - }, { - //ambiguous text - Text{"a key ring", /*french*/"un trousseau de clés", /*spanish*/"un llavero"}, - }, - //clear text - Text{"a Ganon's Castle Key Ring", /*french*/"un trousseau de clés du Château de Ganon", /*spanish*/"un llavero del Castillo de Ganon"} - ); - - hintTable[TREASURE_GAME_SMALL_KEY] = HintText::Item({ - //obscure text - Text{"a gambler's tool for unlocking", /*french*/"un anti-porte de parieur", /*spanish*/"una clave de un juego de azar"}, - Text{"a gambler's dungeon pass", /*french*/"le rêve d'un prisonnier parieur", /*spanish*/"un pase de un juego de azar"}, - Text{"a gambler's lock remover", /*french*/"un efface-serrure de parieur", /*spanish*/"un destructor de cerraduras del juego de azar"}, - Text{"a gambler's lockpick", /*french*/"un crochet à serrure de parieur", /*spanish*/"una apertura portentosa del juego de azar"}, - }, { - //ambiguous text - Text{"a small key", /*french*/"une petite clé", /*spanish*/"una llave pequeña"}, - }, - //clear text - Text{"a Treasure Chest Shop Small Key", /*french*/"une petite clé de la chasse aux trésors", /*spanish*/"una llave pequeña del Cofre del Tesoro"} - ); - - hintTable[KOKIRI_EMERALD] = HintText::Item({ - //obscure text - Text{"a green stone", /*french*/"une pierre verte", /*spanish*/"una piedra verde"}, - Text{"a gift before death", /*french*/"le dernier souffle d'un arbre", /*spanish*/"un obsequio testamentario"}, - }, { - //ambiguous text - Text{"a spiritual stone", /*french*/"une Pierre Ancestrale", /*spanish*/"una piedra espiritual"}, - }, - //clear text - Text{"the Kokiri Emerald", /*french*/"l'Émeraude Kokiri", /*spanish*/"la Esmeralda de los Kokiri"} - ); - - hintTable[GORON_RUBY] = HintText::Item({ - //obscure text - Text{"a red stone", /*french*/"une pierre rouge", /*spanish*/"una piedra carmín"}, - Text{"sworn brotherhood", /*french*/"un serment de fraternité", /*spanish*/"el juramento de hermanos de sangre"}, - }, { - //ambiguous text - Text{"a spiritual stone", /*french*/"une Pierre Ancestrale", /*spanish*/"una piedra espiritual"}, - }, - //clear text - Text{"the Goron Ruby", /*french*/"le Rubis Goron", /*spanish*/"el Rubí de los Goron"} - ); - - hintTable[ZORA_SAPPHIRE] = HintText::Item({ - //obscure text - Text{"a blue stone", /*french*/"une pierre bleue", /*spanish*/"una piedra celeste"}, - Text{"an engagement gift", /*french*/"un cadeau de mariage", /*spanish*/"un regalo de compromiso"}, - }, { - //ambiguous text - Text{"a spiritual stone", /*french*/"une Pierre Ancestrale", /*spanish*/"una piedra espiritual"}, - }, - //clear text - Text{"the Zora Sapphire", /*french*/"le Saphir Zora", /*spanish*/"el Zafiro de los Zora"} - ); - - hintTable[FOREST_MEDALLION] = HintText::Item({ - //obscure text - Text{"a green coin", /*french*/"une pièce verte", /*spanish*/"una moneda esmeralda"}, - Text{"Saria's friendship", /*french*/"l'amitié de Saria", /*spanish*/"la amistad de Saria"}, - }, { - //ambiguous text - Text{"a medallion", /*french*/"un médaillon", /*spanish*/"un medallón"}, - }, - //clear text - Text{"the Forest Medallion", /*french*/"le Médaillon de la Forêt", /*spanish*/"el Medallón del Bosque"} - ); - - hintTable[FIRE_MEDALLION] = HintText::Item({ - //obscure text - Text{"a red coin", /*french*/"une pièce rouge", /*spanish*/"una moneda rubí"}, - Text{"Darunia's power", /*french*/"la fraternité de Darunia", /*spanish*/"la fraternidad de Darunia"}, - }, { - //ambiguous text - Text{"a medallion", /*french*/"un médaillon", /*spanish*/"un medallón"}, - }, - //clear text - Text{"the Fire Medallion", /*french*/"le Médaillon du Feu", /*spanish*/"el Medallón del Fuego"} - ); - - hintTable[WATER_MEDALLION] = HintText::Item({ - //obscure text - Text{"a blue coin", /*french*/"une pièce bleue", /*spanish*/"una moneda zafiro"}, - Text{"Ruto's power", /*french*/"l'amour de Ruto", /*spanish*/"el amor de Ruto"}, - }, { - //ambiguous text - Text{"a medallion", /*french*/"un médaillon", /*spanish*/"un medallón"}, - }, - //clear text - Text{"the Water Medallion", /*french*/"le Médaillon de l'Eau", /*spanish*/"el Medallón del Agua"} - ); - - hintTable[SPIRIT_MEDALLION] = HintText::Item({ - //obscure text - Text{"an orange coin", /*french*/"une pièce orange", /*spanish*/"una moneda ámbar"}, - Text{"Nabooru's power", /*french*/"le respect de Nabooru", /*spanish*/"el respeto de Nabooru"}, - }, { - //ambiguous text - Text{"a medallion", /*french*/"un médaillon", /*spanish*/"un medallón"}, - }, - //clear text - Text{"the Spirit Medallion", /*french*/"le Médaillon de l'Esprit", /*spanish*/"el Medallón del Espíritu"} - ); - - hintTable[SHADOW_MEDALLION] = HintText::Item({ - //obscure text - Text{"a purple coin", /*french*/"une pièce pourpre", /*spanish*/"una moneda malva"}, - Text{"Impa's power", /*french*/"la confiance d'Impa", /*spanish*/"la confianza de Impa"}, - }, { - //ambiguous text - Text{"a medallion", /*french*/"un médaillon", /*spanish*/"un medallón"}, - }, - //clear text - Text{"the Shadow Medallion", /*french*/"le Médaillon de l'Ombre", /*spanish*/"el Medallón de la Sombra"} - ); - - hintTable[LIGHT_MEDALLION] = HintText::Item({ - //obscure text - Text{"a yellow coin", /*french*/"une pièce jaune", /*spanish*/"una moneda resplandeciente"}, - Text{"Rauru's power", /*french*/"la foi de Rauru", /*spanish*/"la fe de Rauru"}, - }, { - //ambiguous text - Text{"a medallion", /*french*/"un médaillon", /*spanish*/"un medallón"}, - }, - //clear text - Text{"the Light Medallion", /*french*/"le Médaillon de la Lumière", /*spanish*/"el Medallón de la Luz"} - ); - - hintTable[RECOVERY_HEART] = HintText::Item({ - //obscure text - Text{"a free heal", /*french*/"un bec-au-bobo", /*spanish*/"una cura de regalo"}, - Text{"a hearty meal", /*french*/"un petit amour", /*spanish*/"una sanación romántica"}, - Text{"a Band-Aid", /*french*/"un diachylon", /*spanish*/"un corazoncito sanador"}, - }, { - //ambiguous text - Text{"something heart-shaped", /*french*/"une chose en forme de coeur", /*spanish*/"algo con forma de corazón"}, - }, - //clear text - Text{"a Recovery Heart", /*french*/"un coeur de vie", /*spanish*/"un corazón"} - ); - - hintTable[GREEN_RUPEE] = HintText::Item({ - //obscure text - Text{"a unique coin", /*french*/"un rubis bien mérité", /*spanish*/"una singular moneda"}, - Text{"a penny", /*french*/"un sou", /*spanish*/"un peso hyliano"}, - Text{"a green gem", /*french*/"un joyau vert", /*spanish*/"una gema verde"}, - }, { - //ambiguous text - Text{"some rupees", /*french*/"une quantité de rubis", /*spanish*/"una cantidad de rupias"}, - }, - //clear text - Text{"a Green Rupee", /*french*/"un rubis vert", /*spanish*/"una rupia verde"} - ); - - hintTable[GREG_RUPEE] = HintText::Item({ - //obscure text - Text{"an old friend", /*french*/"Greg", /*spanish*/"Greg"}, - Text{"a glorious gem", /*french*/"Greg", /*spanish*/"Greg"}, - }, { - //ambiguous text - Text{"a Green Rupee", /*french*/"un rubis vert", /*spanish*/"una rupia verde"} - }, - //clear text - Text{"Greg", /*french*/"Greg", /*spanish*/"Greg"} - ); - - hintTable[BLUE_RUPEE] = HintText::Item({ - //obscure text - Text{"a common coin", /*french*/"quelques sous", /*spanish*/"una moneda usual"}, - Text{"a blue gem", /*french*/"un joyau bleu", /*spanish*/"una gema azul"}, - }, { - //ambiguous text - Text{"some rupees", /*french*/"une quantité de rubis", /*spanish*/"una cantidad de rupias"}, - }, - //clear text - Text{"a Blue Rupee", /*french*/"un rubis bleu", /*spanish*/"una rupia azul"} - ); - - hintTable[RED_RUPEE] = HintText::Item({ - //obscure text - Text{"couch cash", /*french*/"un peu de fric", /*spanish*/"una buena moneda"}, - Text{"a red gem", /*french*/"un joyau rouge", /*spanish*/"una gema roja"}, - }, { - //ambiguous text - Text{"some rupees", /*french*/"une quantité de rubis", /*spanish*/"una cantidad de rupias"}, - }, - //clear text - Text{"a Red Rupee", /*french*/"un rubis rouge", /*spanish*/"una rupia roja"} - ); - - hintTable[PURPLE_RUPEE] = HintText::Item({ - //obscure text - Text{"big bucks", /*french*/"plein de fric", /*spanish*/"plata de calidad"}, - Text{"a purple gem", /*french*/"un joyau mauve", /*spanish*/"una gema morada"}, - Text{"wealth", /*french*/"la richesse", /*spanish*/"una buena riqueza"}, - }, { - //ambiguous text - Text{"some rupees", /*french*/"une quantité de rubis", /*spanish*/"una cantidad de rupias"}, - }, - //clear text - Text{"a Purple Rupee", /*french*/"un rubis pourpre", /*spanish*/"una rupia morada"} - ); - - hintTable[HUGE_RUPEE] = HintText::Item({ - //obscure text - Text{"a juicy jackpot", /*french*/"le jackpot", /*spanish*/"el premio gordo"}, - Text{"a yellow gem", /*french*/"un joyau doré", /*spanish*/"una gema amarilla"}, - Text{"a giant gem", /*french*/"un gros joyau", /*spanish*/"una gema descomunal"}, - Text{"great wealth", /*french*/"l'aisance financière", /*spanish*/"dinero a caudales"}, - }, { - //ambiguous text - Text{"some rupees", /*french*/"une quantité de rubis", /*spanish*/"una cantidad de rupias"}, - }, - //clear text - Text{"a Huge Rupee", /*french*/"un énorme rubis", /*spanish*/"una rupia gigante"} - ); - - hintTable[PIECE_OF_HEART] = HintText::Item({ - //obscure text - Text{"a little love", /*french*/"un peu plus d'amour", /*spanish*/"un cuarto de amor"}, - Text{"a broken heart", /*french*/"un coeur brisé", /*spanish*/"un corazón roto"}, - }, { - //ambiguous text - Text{"something heart-shaped", /*french*/"une chose en forme de coeur", /*spanish*/"algo con forma de corazón"}, - }, - //clear text - Text{"a Piece of Heart", /*french*/"un Quart de Coeur", /*spanish*/"una pieza de corazón"} - ); - - hintTable[HEART_CONTAINER] = HintText::Item({ - //obscure text - Text{"a lot of love", /*french*/"le grand amour", /*spanish*/"amor por doquier"}, - Text{"a Valentine's gift", /*french*/"un cadeau de Saint-Valentin", /*spanish*/"un contenedor de afección"}, - Text{"a boss's organ", /*french*/"un organe de monstre", /*spanish*/"los órganos de un jefe"}, - }, { - //ambiguous text - Text{"something heart-shaped", /*french*/"une chose en forme de coeur", /*spanish*/"algo con forma de corazón"}, - }, - //clear text - Text{"a Heart Container", /*french*/"un Réceptacle de Coeur", /*spanish*/"un contenedor de corazón"} - ); - - hintTable[ICE_TRAP] = HintText::Item({ - //obscure text - Text{"a gift from Ganon", /*french*/"un cadeau de Ganon", /*spanish*/"un regalo de Ganon"}, - Text{"a chilling discovery", /*french*/"une frissonante découverte", /*spanish*/"un escalofriante hallazgo"}, - Text{"frosty fun", /*french*/"une engelure", /*spanish*/"una gélida diversión"}, - }, { - //ambiguous text - Text{"a Great Fairy's power", /*french*/"le pouvoir d'une grande fée", /*spanish*/"el poder de una Gran Hada"}, - Text{"a magic arrow", /*french*/"une flèche magique", /*spanish*/"una flecha mágica"}, - Text{"a medallion", /*french*/"un médaillon", /*spanish*/"un medallón"}, - Text{"a spiritual stone", /*french*/"une Pierre Ancestrale", /*spanish*/"una piedra espiritual"}, - Text{"something that can stun", /*french*/"une chose qui peut paralyser", /*spanish*/"algo que pueda paralizar"}, - }, - //clear text - Text{"an Ice Trap", /*french*/"un Piège de Glace", /*spanish*/"una trampa de hielo"} - ); - - //MILK - - hintTable[BOMBS_5] = HintText::Item({ - //obscure text - Text{"a few explosives", /*french*/"une poignée de pétards", /*spanish*/"un par de explosivos"}, - Text{"a few blast balls", /*french*/"une poignée de boules bleues", /*spanish*/"un par de estallidos"}, - }, { - //ambiguous text - Text{"explosives", /*french*/"un paquet d'explosifs", /*spanish*/"un montón de explosivos"}, - }, - //clear text - Text{"Bombs (5 pieces)", /*french*/"une demi-dizaine de bombes", /*spanish*/"unas (5) bombas"} - ); - - hintTable[BOMBS_10] = HintText::Item({ - //obscure text - Text{"some explosives", /*french*/"un paquet de pétards", /*spanish*/"unos cuantos explosivos"}, - Text{"some blast balls", /*french*/"un paquet de boules bleues", /*spanish*/"unos cuantos estallidos"}, - }, { - //ambiguous text - Text{"explosives", /*french*/"un paquet d'explosifs", /*spanish*/"un montón de explosivos"}, - }, - //clear text - Text{"Bombs (10 pieces)", /*french*/"une dizaine de bombes", /*spanish*/"unas (10) bombas"} - ); - - hintTable[BOMBS_20] = HintText::Item({ - //obscure text - Text{"lots-o-explosives", /*french*/"une abondance de pétards", /*spanish*/"un puñado de explosivos"}, - Text{"plenty of blast balls", /*french*/"une abondance de boules bleues", /*spanish*/"bastantes estallidos"}, - }, { - //ambiguous text - Text{"explosives", /*french*/"un paquet d'explosifs", /*spanish*/"un montón de explosivos"}, - }, - //clear text - Text{"Bombs (20 pieces)", /*french*/"une vingtaine de bombes", /*spanish*/"unas (20) bombas"} - ); - - hintTable[BOMBCHU_5] = HintText::Item({ - //obscure text - Text{"a few mice bombs", /*french*/"une poignée de mignons explosifs", /*spanish*/"un par de bombas roedoras"}, - Text{"a few proximity mice", /*french*/"une poignée de jouets à remonter", /*spanish*/"un par de explosivos ratoncitos"}, - Text{"a few wall crawlers", /*french*/"une poignée de rapides grimpeurs", /*spanish*/"un par de trepaparedes"}, - Text{"a few trail blazers", /*french*/"une poignée de zigzags éclatants", /*spanish*/"un par de ratas propulsadas"}, - }, { - //ambiguous text - Text{"a prize of the House of Skulltulas", /*french*/"un prix de la maison des Skulltulas", /*spanish*/"un obsequio de la Casa Skulltula"}, - Text{"explosives", /*french*/"un paquet d'explosifs", /*spanish*/"un montón de explosivos"}, - }, - //clear text - Text{"Bombchus (5 pieces)", /*french*/"une demi-dizaine de Missiles", /*spanish*/"unos (5) bombchus"} - ); - - hintTable[BOMBCHU_10] = HintText::Item({ - //obscure text - Text{"some mice bombs", /*french*/"un paquet de mignons explosifs", /*spanish*/"unas cuantas bombas roedoras"}, - Text{"some proximity mice", /*french*/"un paquet de jouets à remonter", /*spanish*/"unos cuantos explosivos ratoncitos"}, - Text{"some wall crawlers", /*french*/"un paquet de rapides grimpeurs", /*spanish*/"unos cuantos trepaparedes"}, - Text{"some trail blazers", /*french*/"un paquet de zigzags éclatants", /*spanish*/"unas cuantas ratas propulsadas"}, - }, { - //ambiguous text - Text{"a prize of the House of Skulltulas", /*french*/"un prix de la maison des Skulltulas", /*spanish*/"un obsequio de la Casa Skulltula"}, - Text{"explosives", /*french*/"un paquet d'explosifs", /*spanish*/"un montón de explosivos"}, - }, - //clear text - Text{"Bombchus (10 pieces)", /*french*/"une dizaine de Missiles", /*spanish*/"unos (10) bombchus"} - ); - - hintTable[BOMBCHU_20] = HintText::Item({ - //obscure text - Text{"plenty of mice bombs", /*french*/"une abondance de mignons explosifs", /*spanish*/"bastantes bombas roedoras"}, - Text{"plenty of proximity mice", /*french*/"une abondance de jouets à remonter", /*spanish*/"bastantes explosivos ratoncitos"}, - Text{"plenty of wall crawlers", /*french*/"une abondance de rapides grimpeurs", /*spanish*/"bastantes trepaparedes"}, - Text{"plenty of trail blazers", /*french*/"une abondance de zigzags éclatants", /*spanish*/"bastantes ratas propulsadas"}, - }, { - //ambiguous text - Text{"a prize of the House of Skulltulas", /*french*/"un prix de la maison des Skulltulas", /*spanish*/"un obsequio de la Casa Skulltula"}, - Text{"explosives", /*french*/"un paquet d'explosifs", /*spanish*/"un montón de explosivos"}, - }, - //clear text - Text{"Bombchus (20 pieces)", /*french*/"une vingtaine de Missiles", /*spanish*/"unos (20) bombchus"} - ); - - //BOMBCHU_DROP - - hintTable[ARROWS_5] = HintText::Item({ - //obscure text - Text{"a few danger darts", /*french*/"une poignée d'obus", /*spanish*/"un par de peligrosos dardos"}, - Text{"a few sharp shafts", /*french*/"une poignée de piquets", /*spanish*/"un par de puntas afiladas"}, - }, { - //ambiguous text - Text{"a projectile", /*french*/"un projectile", /*spanish*/"un proyectil"}, - }, - //clear text - Text{"Arrows (5 pieces)", /*french*/"une demi-dizaine de flèches", /*spanish*/"unas (5) flechas"} - ); - - hintTable[ARROWS_10] = HintText::Item({ - //obscure text - Text{"some danger darts", /*french*/"un paquet d'obus", /*spanish*/"unos cuantos peligrosos dardos"}, - Text{"some sharp shafts", /*french*/"un paquet de piquets", /*spanish*/"unas cuantas puntas afiladas"}, - }, { - //ambiguous text - Text{"a projectile", /*french*/"un projectile", /*spanish*/"un proyectil"}, - }, - //clear text - Text{"Arrows (10 pieces)", /*french*/"une dizaine de flèches", /*spanish*/"unas (10) flechas"} - ); - - hintTable[ARROWS_30] = HintText::Item({ - //obscure text - Text{"plenty of danger darts", /*french*/"une abondance d'obus", /*spanish*/"bastantes peligrosos dardos"}, - Text{"plenty of sharp shafts", /*french*/"une abondance de piquets", /*spanish*/"bastantes puntas afiladas"}, - }, { - //ambiguous text - Text{"a projectile", /*french*/"un projectile", /*spanish*/"un proyectil"}, - }, - //clear text - Text{"Arrows (30 pieces)", /*french*/"une trentaine de flèches", /*spanish*/"unas (30) flechas"} - ); - - hintTable[DEKU_NUTS_5] = HintText::Item({ - //obscure text - Text{"some nuts", /*french*/"une poignée de noisettes", /*spanish*/"un par de nueces"}, - Text{"some flashbangs", /*french*/"une poignée d'éclats", /*spanish*/"un par de semillas aturdidoras"}, - Text{"some scrub spit", /*french*/"une poignée de crachats Mojo", /*spanish*/"un par de escupitajos deku"}, - }, { - //ambiguous text - Text{"some Deku munitions", /*french*/"un paquet de munitions Mojo", /*spanish*/"un montón de municiones Deku"}, - Text{"something that can stun", /*french*/"une chose qui peut paralyser", /*spanish*/"algo que pueda paralizar"}, - }, - //clear text - Text{"Deku Nuts (5 pieces)", /*french*/"une demi-dizaine de noix Mojo", /*spanish*/"unas (5) nueces deku"} - ); - - hintTable[DEKU_NUTS_10] = HintText::Item({ - //obscure text - Text{"lots-o-nuts", /*french*/"un paquet de noisettes", /*spanish*/"un puñado de nueces"}, - Text{"plenty of flashbangs", /*french*/"un paquet d'éclats", /*spanish*/"unas cuantas semillas aturdidoras"}, - Text{"plenty of scrub spit", /*french*/"un paquet de crachats Mojo", /*spanish*/"unos cuantos escupitajos deku"}, - }, { - //ambiguous text - Text{"some Deku munitions", /*french*/"un paquet de munitions Mojo", /*spanish*/"un montón de municiones Deku"}, - Text{"something that can stun", /*french*/"une chose qui peut paralyser", /*spanish*/"algo que pueda paralizar"}, - }, - //clear text - Text{"Deku Nuts (10 pieces)", /*french*/"une dizaine de noix Mojo", /*spanish*/"unas (10) nueces deku"} - ); - - hintTable[DEKU_SEEDS_30] = HintText::Item({ - //obscure text - Text{"catapult ammo", /*french*/"un paquet de délicieuses munitions", /*spanish*/"un par de munición infantil"}, - Text{"lots-o-seeds", /*french*/"un paquet de germes séchés", /*spanish*/"un puñado de semillas"}, - }, { - //ambiguous text - Text{"a projectile", /*french*/"un projectile", /*spanish*/"un proyectil"}, - Text{"some Deku munitions", /*french*/"un paquet de munitions Mojo", /*spanish*/"un montón de municiones Deku"}, - }, - //clear text - Text{"Deku Seeds (30 pieces)", /*french*/"une trentaine de graines Mojo", /*spanish*/"unas (30) semillas deku"} - ); - - hintTable[DEKU_STICK_1] = HintText::Item({ - //obscure text - Text{"a breakable branch", /*french*/"un bout de bois", /*spanish*/"un pequeño báculo"}, - }, { - //ambiguous text - Text{"some Deku munitions", /*french*/"un paquet de munitions Mojo", /*spanish*/"un montón de municiones Deku"}, - }, - //clear text - Text{"a Deku Stick", /*french*/"un bâton Mojo", /*spanish*/"un palo deku"} - ); - - hintTable[TREASURE_GAME_HEART] = HintText::Item({ - //obscure text - Text{"a victory valentine", /*french*/"un amour gagnant", /*spanish*/"el amor victorioso"}, - }, { - //ambiguous text - Text{"something heart-shaped", /*french*/"une chose en forme de coeur", /*spanish*/"algo con forma de corazón"}, - }, - //clear text - Text{"a Piece of Heart", /*french*/"un Quart de Coeur", /*spanish*/"el amor de la victoria"} - ); - - hintTable[TREASURE_GAME_GREEN_RUPEE] = HintText::Item({ - //obscure text - Text{"the dollar of defeat", /*french*/"le rubis de la défaite", /*spanish*/"el peso de la derrota"}, - }, { - //ambiguous text - Text{"some rupees", /*french*/"une quantité de rubis", /*spanish*/"una cantidad de rupias"}, - }, - //clear text - Text{"a Green Rupee", /*french*/"un rubis vert", /*spanish*/"una rupia verde"} - ); - - hintTable[TRIFORCE_PIECE] = HintText::Item({ - //obscure text - Text{"a triumph fork", /*french*/"la Tribosse", /*spanish*/"un trígono del triunfo"}, - Text{"cheese", /*french*/"du fromage", /*spanish*/"un porción de queso"}, - Text{"a gold fragment", /*french*/"un fragment d'or", /*spanish*/"un fragmento dorado"}, - }, {}, - //clear text - Text{"a Piece of the Triforce", /*french*/"un fragment de la Triforce", /*spanish*/"un fragmento de la Trifuerza"} - ); - - hintTable[EPONA] = HintText::Item({ - //obscure text - Text{"a horse", /*french*/"un fidèle destrier", /*spanish*/"una yegua"}, - Text{"a four legged friend", /*french*/"un puissant animal", /*spanish*/"una amiga cuadrúpeda"}, - }, { - //ambiguous text - Text{"something from Malon", /*french*/"un cadeau de Malon", /*spanish*/"un obsequio de Malon"}, - Text{"a song sung by frogs", /*french*/"une chanson aimée des grenouilles", /*spanish*/"una melodía de ranas"}, - Text{"something to cross a broken bridge", /*french*/"une chose pour traverser un pont brisé", /*spanish*/"algo para cruzar un puente roto"}, - }, - //clear text - Text{"Epona", /*french*/"Epona", /*spanish*/"a Epona"} - ); - - // [HINT_ERROR] = HintText::Item({ - // //obscure text - // Text{"something mysterious", /*french*/"un sacré mystère", /*spanish*/"algo misterioso"}, - // Text{"an unknown treasure", /*french*/"un trésor inconnu", /*spanish*/"un desconocido tesoro"}, - // }, - // //clear text - // Text{"An Error (Please Report This)", /*french*/"une erreur (signaler S.V.P.)", /*spanish*/"un error (repórtelo si es posible)"} - // ); +#include "../../static_data.h" +#include "../hints.hpp" +#include "../../../custom-message/CustomMessageManager.h" + +namespace Rando { + +void StaticData::HintTable_Init_Item() { + + hintTextTable[RHT_KOKIRI_SWORD] = HintText(CustomMessage("the Kokiri Sword", /*german*/"das Kokiri-Schwert", /*french*/"l'Épée Kokiri"), + // /*spanish*/la Espada Kokiri + { + CustomMessage("a sword", /*german*/"ein Schwert", /*french*/"une épée") + // /*spanish*/una espada + }, { + CustomMessage("a butter knife", /*german*/"ein Buttermesser", /*french*/"un couteau à beurre"), + // /*spanish*/un ágil puñal + CustomMessage("a starter slasher", /*german*/"ein Anfängerschwert", /*french*/"une arme de débutant"), + // /*spanish*/una hoja de principiantes + CustomMessage("a switchblade", /*german*/"ein Stellmesser", /*french*/"un canif")}); + // /*spanish*/una navaja + + hintTextTable[RHT_MASTER_SWORD] = HintText(CustomMessage("the Master Sword", /*german*/"das Master-Schwert", /*french*/"l'Épée de Légende"), + // /*spanish*/la Espada Maestra + { + CustomMessage("a sword", /*german*/"ein Schwert", /*french*/"une épée") + // /*spanish*/una espada + }, { + CustomMessage("evil's bane", /*german*/"der böse Fluch", /*french*/"le fléau du mal"), + // /*spanish*/la destructora del mal + CustomMessage("a seven year limbo", /*german*/"eine siebenjährige Erwartung", /*french*/"une stase de sept ans")}); + // /*spanish*/unos siete años de espera + + hintTextTable[RHT_GIANTS_KNIFE] = HintText(CustomMessage("the Giant's Knife", /*german*/"das Langschwert", /*french*/"la Lame des Géants"), + // /*spanish*/la daga gigante + { + CustomMessage("a sword", /*german*/"ein Schwert", /*french*/"une épée") + // /*spanish*/una espada + }, { + CustomMessage("a fragile blade", /*german*/"ein fragiles Schwert", /*french*/"une lame fragile"), + // /*spanish*/una frágil hoja + CustomMessage("a breakable cleaver", /*german*/"ein brüchiger Spalter", /*french*/"un espadon de verre")}); + // /*spanish*/un rompible acero + + hintTextTable[RHT_BIGGORON_SWORD] = HintText(CustomMessage("the Biggoron Sword", /*german*/"das Biggoron-Schwert", /*french*/"l'Épée de Biggoron"), + // /*spanish*/la Espada de Biggoron + { + CustomMessage("a sword", /*german*/"ein Schwert", /*french*/"une épée") + // /*spanish*/una espada + }, { + CustomMessage("the biggest blade", /*german*/"das größte Schwert", /*french*/"une lame gigantesque"), + // /*spanish*/el mayor mandoble + CustomMessage("a colossal cleaver", /*german*/"ein kolossaler Spalter", /*french*/"un espadon colossal")}); + // /*spanish*/un estoque colosal + + hintTextTable[RHT_DEKU_SHIELD] = HintText(CustomMessage("a Deku Shield", /*german*/"ein Deku-Schild", /*french*/"un Bouclier Mojo"), + // /*spanish*/un escudo deku + { + CustomMessage("a shield", /*german*/"ein Schild", /*french*/"un bouclier") + // /*spanish*/un escudo + }, { + CustomMessage("a wooden ward", /*german*/"eine hölzerne Abwehr", /*french*/"un écu d'écorce"), + // /*spanish*/una protección del bosque + CustomMessage("a burnable barrier", /*german*/"eine brennbare Barriere", /*french*/"une protection inflammable")}); + // /*spanish*/una barrera quemable + + hintTextTable[RHT_HYLIAN_SHIELD] = HintText(CustomMessage("a Hylian Shield", /*german*/"ein Hylia-Schild", /*french*/"un Bouclier Hylien"), + // /*spanish*/un escudo hyliano + { + CustomMessage("a shield", /*german*/"ein Schild", /*french*/"un bouclier") + // /*spanish*/un escudo + }, { + CustomMessage("a steel safeguard", /*german*/"ein eiserner Schutz", /*french*/"une carapace d'acier"), + // /*spanish*/una protección de acero + CustomMessage("Like Like's metal meal", /*german*/"Raubschleims Metallmahlzeit", /*french*/"un amuse-gueule de Pudding")}); + // /*spanish*/un alimento de Like Like + + hintTextTable[RHT_MIRROR_SHIELD] = HintText(CustomMessage("the Mirror Shield", /*german*/"das Spiegelschild", /*french*/"le Bouclier Miroir"), + // /*spanish*/el escudo espejo + { + CustomMessage("a shield", /*german*/"ein Schild", /*french*/"un bouclier") + // /*spanish*/un escudo + }, { + CustomMessage("a reflective rampart", /*german*/"ein reflektierender Schutzwall", /*french*/"un capteur de lumière"), + // /*spanish*/una muralla reflectora + CustomMessage("Medusa's weakness", /*german*/"Medusas Schwäche", /*french*/"la faiblesse de Méduse"), + // /*spanish*/la debilidad de Medusa + CustomMessage("a silvered surface", /*german*/"eine silberne Oberfläche", /*french*/"une surface argentée")}); + // /*spanish*/una superficie plateada + + hintTextTable[RHT_GORON_TUNIC] = HintText(CustomMessage("a Goron Tunic", /*german*/"eine Goronen-Tunika", /*french*/"une Tunique Goron"), + // /*spanish*/un sayo goron + { + CustomMessage("a tunic", /*german*/"eine Tunika", /*french*/"une tunique") + // /*spanish*/un sayo + }, { + CustomMessage("ruby robes", /*german*/"Rubinroben", /*french*/"un pigment rouge"), + // /*spanish*/una vestimenta rubí + CustomMessage("fireproof fabric", /*german*/"feuerfestes Gewebe", /*french*/"un trésor anti-flamme"), + // /*spanish*/una ignífuga prenda + CustomMessage("cooking clothes", /*german*/"Kochschürze", /*french*/"une tenue de cuisine")}); + // /*spanish*/unos abrasantes ropajes + + hintTextTable[RHT_ZORA_TUNIC] = HintText(CustomMessage("a Zora Tunic", /*german*/"eine Zora-Tunika", /*french*/"une Tunique Zora"), + // /*spanish*/un sayo zora + { + CustomMessage("a tunic", /*german*/"eine Tunika", /*french*/"une tunique"), + // /*spanish*/un sayo + CustomMessage("something expensive", /*german*/"etwas Teures", /*french*/"une chose dispendieuse") + // /*spanish*/algo caro + }, { + CustomMessage("a sapphire suit", /*german*/"ein Saphiranzug", /*french*/"un pigment bleuté"), + // /*spanish*/una vestidura zafiro + CustomMessage("scuba gear", /*german*/"eine Taucherausrüstung", /*french*/"un habit de plongée"), + // /*spanish*/un traje impermeable + CustomMessage("a swimsuit", /*german*/"ein Badeanzug", /*french*/"un costume de baignade")}); + // /*spanish*/unos ropajes sumergibles + + hintTextTable[RHT_IRON_BOOTS] = HintText(CustomMessage("the Iron Boots", /*german*/"die Eisenstiefel", /*french*/"une paire de Bottes de plomb"), + // /*spanish*/las botas de hierro + { + CustomMessage("some boots", /*german*/"ein paar Stiefel", /*french*/"une paire de bottes"), + // /*spanish*/un par de botas + CustomMessage("a feature of the Water Temple", /*german*/"ein Merkmal des Wassertempels", /*french*/"une particularité du Temple de l'Eau"), + // /*spanish*/algo particular del Templo del Agua + CustomMessage("something heavy", /*german*/"etwas Schweres", /*french*/"une chose pesante") + // /*spanish*/algo de lo más pesado + }, { + CustomMessage("sink shoes", /*german*/"Sinkschuhe", /*french*/"un boulet de fer"), + // /*spanish*/un calzado de las profundidades + CustomMessage("clank cleats", /*german*/"klirrende Knacken", /*french*/"une paire de talons bruyants")}); + // /*spanish*/unas suelas férreas + + hintTextTable[RHT_HOVER_BOOTS] = HintText(CustomMessage("the Hover Boots", /*german*/"die Gleitstiefel", /*french*/"une paire de Bottes des airs"), + // /*spanish*/las botas voladoras + { + CustomMessage("some boots", /*german*/"ein paar Stiefel", /*french*/"une paire de bottes") + // /*spanish*/un par de botas + }, { + CustomMessage("butter boots", /*german*/"Butterstiefel", /*french*/"une paire de patins de beurre"), + // /*spanish*/unas suelas resvaladizas + CustomMessage("sacred slippers", /*german*/"heilige Pantoffeln", /*french*/"une paire de pantoufles sacrées"), + // /*spanish*/unos escurridizos botines + CustomMessage("spacewalkers", /*german*/"Weltraumstiefel", /*french*/"une paire de bottes spatiales")}); + // /*spanish*/un calzado antigravitatorio + + hintTextTable[RHT_ZELDAS_LETTER] = HintText(CustomMessage("Zelda's Letter", /*german*/"Zeldas Brief", /*french*/"la Lettre de Zelda"), + // /*spanish*/la carta de Zelda + {}, { + CustomMessage("an autograph", /*german*/"ein Autograph", /*french*/"un autographe"), + // /*spanish*/un autógrafo + CustomMessage("royal stationery", /*german*/"royales Briefpapier", /*french*/"du papier royal"), + // /*spanish*/un escrito real + CustomMessage("royal snail mail", /*german*/"ein royaler Umschlag", /*french*/"une enveloppe royale")}); + // /*spanish*/correo de la realeza + + hintTextTable[RHT_WEIRD_EGG] = HintText(CustomMessage("the Weird Egg", /*german*/"ein seltsames Ei", /*french*/"l'Oeuf Curieux"), + // /*spanish*/el huevo extraño + { + CustomMessage("an egg", /*german*/"ein Ei", /*french*/"un oeuf") + // /*spanish*/un huevo + }, { + CustomMessage("a chicken dilemma", /*german*/"ein Hühnerdilemma", /*french*/"un drôle d'ovale")}); + // /*spanish*/el dilema de la gallina + + hintTextTable[RHT_BOOMERANG] = HintText(CustomMessage("the Boomerang", /*german*/"ein Bumerang", /*french*/"le Boomerang"), + // /*spanish*/el bumerán + { + CustomMessage("something that can grab things", /*german*/"etwas, das Dinge greifen kann", /*french*/"une chose qui peut attraper"), + // /*spanish*/algo que pueda agarrar cosas + CustomMessage("something that can stun", /*german*/"etwas, das paralysieren kann", /*french*/"une chose qui peut paralyser") + // /*spanish*/algo que pueda paralizar + }, { + CustomMessage("a banana", /*german*/"eine Banane", /*french*/"une banane"), + // /*spanish*/un plátano + CustomMessage("a stun stick", /*german*/"ein paralysierender Stab", /*french*/"un bâton étourdissant"), + // /*spanish*/un palo aturdidor + CustomMessage("a yellow angle", /*german*/"ein gelber Winkel", /*french*/"un angle jaune")}); + // /*spanish*/un ángulo amarillo + + hintTextTable[RHT_LENS_OF_TRUTH] = HintText(CustomMessage("the Lens of Truth", /*german*/"das Auge der Wahrheit", /*french*/"le Monocle de Vérité"), + // /*spanish*/la Lupa de la Verdad + { + CustomMessage("a secret-finding tool", /*german*/"ein geheimnisfindendes Werkzeug", /*french*/"un cherche-secrets") + // /*spanish*/un instrumento para hallar objetos + }, { + CustomMessage("a lie detector", /*german*/"ein Lügendetektor", /*french*/"un détecteur de mensonges"), + // /*spanish*/el detector de ilusiones + CustomMessage("a ghost tracker", /*german*/"ein Geisterfinder", /*french*/"un trouve-fantôme"), + // /*spanish*/el rastreador paranormal + CustomMessage("true sight", /*german*/"wahre Sicht", /*french*/"le troisième œil"), + // /*spanish*/el ojo que todo ve + CustomMessage("a detective's tool", /*german*/"ein Detektivwerkzeug", /*french*/"un trésor Sheikah")}); + // /*spanish*/la revelación verdadera + + hintTextTable[RHT_MEGATON_HAMMER] = HintText(CustomMessage("the Megaton Hammer", /*german*/"der Stahlhammer", /*french*/"la Masse des Titans"), + // /*spanish*/el martillo Megatón + { + CustomMessage("something that can remove boulders", /*german*/"etwas, das Geröll entfernen kann", /*french*/"une chose qui enlève les rochers") + // /*spanish*/algo que pueda quitar rocas + }, { + CustomMessage("the dragon smasher", /*german*/"ein Drachenschläger", /*french*/"le tueur de dragons"), + // /*spanish*/un destructor de dragones + CustomMessage("the metal mallet", /*german*/"ein stählerner Schlägel", /*french*/"un outil de construction"), + // /*spanish*/un mazo de metal + CustomMessage("the heavy hitter", /*german*/"ein schwerer Schläger", /*french*/"un poids lourd")}); + // /*spanish*/un machacador + + hintTextTable[RHT_STONE_OF_AGONY] = HintText(CustomMessage("the Stone of Agony", /*german*/"der Stein des Wissens", /*french*/"la Pierre de Souffrance"), + // /*spanish*/la Piedra de la Agonía + { + CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"), + // /*spanish*/un obsequio de la Casa Skulltula + CustomMessage("a secret-finding tool", /*german*/"ein geheimnisfindendes Werkzeug", /*french*/"un cherche-secrets") + // /*spanish*/un instrumento para hallar objetos + }, { + CustomMessage("the shake stone", /*german*/"der Schüttelstein", /*french*/"le fragment vibrant"), + // /*spanish*/el fragmento tintineante + CustomMessage("a gray alarm", /*german*/"der graue Alarm", /*french*/"une alerte bleue")}); + // /*spanish*/una azul alarma + + hintTextTable[RHT_DINS_FIRE] = HintText(CustomMessage("Din's Fire", /*german*/"Dins Feuerinferno", /*french*/"le Feu de Din"), + // /*spanish*/el Fuego de Din + { + CustomMessage("a Great Fairy's power", /*german*/"eine Kraft einer großen Fee", /*french*/"le pouvoir d'une grande fée") + // /*spanish*/el poder de una Gran Hada + }, { + CustomMessage("an inferno", /*german*/"ein Inferno", /*french*/"un brasier"), + // /*spanish*/un incendio + CustomMessage("a heat wave", /*german*/"eine Hitzewelle", /*french*/"une vague de chaleur"), + // /*spanish*/una onda de calor + CustomMessage("a red ball", /*german*/"ein roter Ball", /*french*/"une explosion de flammes")}); + // /*spanish*/una roja esfera + + hintTextTable[RHT_FARORES_WIND] = HintText(CustomMessage("Farore's Wind", /*german*/"Farores Donnersturm", /*french*/"le Vent de Farore"), + // /*spanish*/el Viento de Farore + { + CustomMessage("a Great Fairy's power", /*german*/"eine Kraft einer großen Fee", /*french*/"le pouvoir d'une grande fée") + // /*spanish*/el poder de una Gran Hada + }, { + CustomMessage("teleportation", /*german*/"ein Teleportierer", /*french*/"la téléportation"), + // /*spanish*/un teletransportador + CustomMessage("a relocation rune", /*german*/"eine Umzugsrune", /*french*/"une rune de relocation"), + // /*spanish*/una runa de transporte + CustomMessage("a green ball", /*german*/"ein grüner Ball", /*french*/"une boule verte")}); + // /*spanish*/una verde esfera + + hintTextTable[RHT_NAYRUS_LOVE] = HintText(CustomMessage("Nayru's Love", /*german*/"Nayrus Umarmung", /*french*/"l'Amour de Nayru"), + // /*spanish*/el Amor de Nayru + { + CustomMessage("a Great Fairy's power", /*german*/"eine Kraft einer großen Fee", /*french*/"le pouvoir d'une grande fée") + // /*spanish*/el poder de una Gran Hada + }, { + CustomMessage("a safe space", /*german*/"ein sicherer Raum", /*french*/"une bulle de cristal"), + // /*spanish*/una seguridad temporal + CustomMessage("an impregnable aura", /*german*/"eine undurchdringliche Aura", /*french*/"un aura impénétrable"), + // /*spanish*/un aura impenetrable + CustomMessage("a blue barrier", /*german*/"eine blaue Barriere", /*french*/"une toison bleu")}); + // /*spanish*/una barrera azul + + hintTextTable[RHT_FIRE_ARROWS] = HintText(CustomMessage("the Fire Arrows", /*german*/"die Feuerpfeile", /*french*/"les Flèches de Feu"), + // /*spanish*/la flecha de fuego + { + CustomMessage("a magic arrow", /*german*/"ein magischer Pfeil", /*french*/"une flèche magique") + // /*spanish*/una flecha mágica + }, { + CustomMessage("the furnace firearm", /*german*/"die Ofenwaffe", /*french*/"une fusée solaire"), + // /*spanish*/el ardiente aguijón + CustomMessage("the burning bolts", /*german*/"die Brennstifte", /*french*/"un obus enflammé"), + // /*spanish*/las puntas ígneas + CustomMessage("a magma missile", /*german*/"eine vulkanische Rakete", /*french*/"un missile volcanique")}); + // /*spanish*/el misil abrasador + + hintTextTable[RHT_ICE_ARROWS] = HintText(CustomMessage("the Ice Arrows", /*german*/"die Eispfeile", /*french*/"les Flèches de Glace"), + // /*spanish*/la flecha de hielo + { + CustomMessage("a magic arrow", /*german*/"ein magischer Pfeil", /*french*/"une flèche magique"), + // /*spanish*/una flecha mágica + CustomMessage("something that can stun", /*german*/"etwas, das paralysieren kann", /*french*/"une chose qui peut paralyser") + // /*spanish*/algo que pueda paralizar + }, { + CustomMessage("the refrigerator rocket", /*german*/"die Kühlschrankrakete", /*french*/"un missile pétrifiant"), + // /*spanish*/el misil congelador + CustomMessage("the frostbite bolts", /*german*/"die Froststifte", /*french*/"un froid mordant"), + // /*spanish*/las puntas gélidas + CustomMessage("an iceberg maker", /*german*/"ein Eisbergmacher", /*french*/"une aiguille glaciale")}); + // /*spanish*/el control de escarcha + + hintTextTable[RHT_LIGHT_ARROWS] = HintText(CustomMessage("the Light Arrows", /*german*/"die Lichtpfeile", /*french*/"les Flèches de Lumière"), + // /*spanish*/la flecha de luz + { + CustomMessage("a magic arrow", /*german*/"ein magischer Pfeil", /*french*/"une flèche magique") + // /*spanish*/una flecha mágica + }, { + CustomMessage("the shining shot", /*german*/"der strahlende Schuss", /*french*/"l'arme brillante"), + // /*spanish*/el haz de luz + CustomMessage("the luminous launcher", /*german*/"der leuchtende Werfer", /*french*/"un jet de lumière"), + // /*spanish*/el disparo luminoso + CustomMessage("Ganondorf's bane", /*german*/"Ganondorfs Verderben", /*french*/"le fléau de Ganondorf"), + // /*spanish*/la perdición de Ganondorf + CustomMessage("the lighting bolts", /*german*/"die Lichtstifte", /*french*/"l'éclair sacré")}); + // /*spanish*/las puntas resplandecientes + + hintTextTable[RHT_GERUDO_MEMBERSHIP_CARD] = HintText(CustomMessage("the Gerudo Membership Card", /*german*/"der Gerudo-Pass", /*french*/"la Carte Gerudo"), + // /*spanish*/el pase de socio gerudo + { + CustomMessage("a token of recognition", /*german*/"ein Zeichen der Anerkennung", /*french*/"une preuve de reconnaissance") + // /*spanish*/una prueba de reconocimiento + }, { + CustomMessage("a girl club membership", /*german*/"eine Mitgliedskarte", /*french*/"une carte de membre"), + // /*spanish*/una fémina membresía + CustomMessage("a desert tribe's pass", /*german*/"ein Pass eines Wüstenstammes", /*french*/"un laissez-passer")}); + // /*spanish*/el vale del desierto + + hintTextTable[RHT_MAGIC_BEAN] = HintText(CustomMessage("a Magic Bean", /*german*/"eine Wundererbse", /*french*/"un Haricot Magique"), + // /*spanish*/una judía mágica + { + CustomMessage("something sometimes buried", /*german*/"etwas, das manchmal begraben ist", /*french*/"une chose parfois enterrée") + // /*spanish*/algo a veces enterrado + }, { + CustomMessage("a wizardly legume", /*german*/"eine zauberhafte Hülse", /*french*/"un légume ensorcelé")}); + // /*spanish*/una legumbre hechizada + + hintTextTable[RHT_MAGIC_BEAN_PACK] = HintText(CustomMessage("Magic Beans", /*german*/"Wundererbsen", /*french*/"un Paquet de Haricots Magiques"), + // /*spanish*/unas judías mágicas + { + CustomMessage("something sometimes buried", /*german*/"etwas, das manchmal begraben ist", /*french*/"une chose parfois enterrée") + // /*spanish*/algo a veces enterrado + }, { + CustomMessage("wizardly legumes", /*german*/"zauberhafte Hülsen", /*french*/"un paquet de légumes ensorcelés")}); + // /*spanish*/unas legumbres hechizadas + + hintTextTable[RHT_DOUBLE_DEFENSE] = HintText(CustomMessage("Double Defense", /*german*/"Doppelte Verteidigung", /*french*/"la Double Défence"), + // /*spanish*/la doble defensa + { + CustomMessage("a Great Fairy's power", /*german*/"eine Kraft einer großen Fee", /*french*/"le pouvoir d'une grande fée"), + // /*spanish*/el poder de una Gran Hada + CustomMessage("something heart-shaped", /*german*/"etwas Herzförmiges", /*french*/"une chose en forme de coeur") + // /*spanish*/algo con forma de corazón + }, { + CustomMessage("a white outline", /*german*/"ein weißes Profil", /*french*/"un rebord blanc"), + // /*spanish*/un contorno blanco + CustomMessage("damage decrease", /*german*/"Schadensverringerung", /*french*/"une protection supplémentaire"), + // /*spanish*/una reducción de daño + CustomMessage("strengthened love", /*german*/"gestärkte Liebe", /*french*/"un amour coriace")}); + // /*spanish*/un amor fortalecido + + hintTextTable[RHT_GOLD_SKULLTULA_TOKEN] = HintText(CustomMessage("a Gold Skulltula Token", /*german*/"ein goldenes Skulltula-Symbol", /*french*/"un Symbole de Skulltula d'or"), + // /*spanish*/un símbolo de skulltula dorada + { + CustomMessage("a token of recognition", /*german*/"ein Zeichen der Anerkennung", /*french*/"une preuve de reconnaissance"), + // /*spanish*/una prueba de reconocimiento + CustomMessage("something sometimes buried", /*german*/"etwas, das manchmal begraben ist", /*french*/"une chose parfois enterrée") + // /*spanish*/algo a veces enterrado + }, { + CustomMessage("proof of destruction", /*german*/"Nachweis der Zerstörung", /*french*/"un certificat d'élimination"), + // /*spanish*/una prueba de la destrucción + CustomMessage("an arachnid chip", /*german*/"ein spinnenartiges Symbol", /*french*/"un symbole cranien"), + // /*spanish*/una figura arácnida + CustomMessage("spider remains", /*german*/"Spinnenüberreste", /*french*/"une dépouille dorée"), + // /*spanish*/unos restos dorados + CustomMessage("one percent of a curse", /*german*/"ein Prozent eines Fluchs", /*french*/"un centième de malédiction")}); + // /*spanish*/una centésima de una maldición + + hintTextTable[RHT_POCKET_EGG] = HintText(CustomMessage("the Pocket Egg", /*german*/"das Ei", /*french*/"l'Oeuf de Poche"), + // /*spanish*/el huevo de bolsillo + { + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges"), + // /*spanish*/un objeto de una misión secundaria + CustomMessage("an egg", /*german*/"ein Ei", /*french*/"un oeuf") + // /*spanish*/un huevo + }, { + CustomMessage("a Cucco container", /*german*/"ein Hühnerbehälter", /*french*/"un réservoir à Cocotte"), + // /*spanish*/cuco contenido + CustomMessage("a Cucco, eventually", /*german*/"schlussendlich ein Huhn", /*french*/"un poussin éventuel"), + // /*spanish*/un futuro cuco + CustomMessage("a fowl youth", /*german*/"ein junges Geflügel", /*french*/"une omelette crue")}); + // /*spanish*/una dulce juventud + + hintTextTable[RHT_POCKET_CUCCO] = HintText(CustomMessage("the Pocket Cucco", /*german*/"Kiki", /*french*/"la Cocotte de Poche"), + // /*spanish*/el cuco de bolsillo + { + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges") + // /*spanish*/un objeto de una misión secundaria + }, { + CustomMessage("a little clucker", /*german*/"ein kleiner Gackerer", /*french*/"un petit glousseur")}); + // /*spanish*/un pollito chiquito + + hintTextTable[RHT_COJIRO] = HintText(CustomMessage("Cojiro", /*german*/"Henni", /*french*/"le p'tit poulet"), + // /*spanish*/a Cojiro + { + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges") + // /*spanish*/un objeto de una misión secundaria + }, { + CustomMessage("a cerulean capon", /*german*/"ein coelinblaues Kapaun", /*french*/"un paon azur")}); + // /*spanish*/un cerúleo capón + + hintTextTable[RHT_ODD_MUSHROOM] = HintText(CustomMessage("an Odd Mushroom", /*german*/"ein Schimmelpilz", /*french*/"un Champignon Suspect"), + // /*spanish*/un champiñón extraño + { + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges") + // /*spanish*/un objeto de una misión secundaria + }, { + CustomMessage("a powder ingredient", /*german*/"eine Puderingredienz", /*french*/"un ingrédient à poudre")}); + // /*spanish*/un oloroso ingrediente + + hintTextTable[RHT_ODD_POTION] = HintText(CustomMessage("an Odd Potion", /*german*/"ein Modertrank", /*french*/"une Mixture Suspecte"), + // /*spanish*/una medicina rara + { + CustomMessage("something that contains medicine", /*german*/"etwas, das Medizin enthält", /*french*/"une chose médicamenteuse"), + // /*spanish*/algo que contenga medicina + CustomMessage("something with a strange smell", /*german*/"etwas, das streng riecht", /*french*/"une chose qui sent bizarre"), + // /*spanish*/algo con un olor extraño + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges") + // /*spanish*/un objeto de una misión secundaria + }, { + CustomMessage("Granny's goodies", /*german*/"Omas Zuckerwerk", /*french*/"la confiserie de mamie")}); + // /*spanish*/la especialidad de la abuela + + hintTextTable[RHT_POACHERS_SAW] = HintText(CustomMessage("the Poacher's Saw", /*german*/"eine Säge", /*french*/"la Scie du Chasseur"), + // /*spanish*/la sierra del furtivo + { + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges") + // /*spanish*/un objeto de una misión secundaria + }, { + CustomMessage("a tree killer", /*german*/"ein Baumtöter", /*french*/"un coupeur d'arbres")}); + // /*spanish*/un destructor de árboles + + hintTextTable[RHT_BROKEN_SWORD] = HintText(CustomMessage("the Broken Goron's Sword", /*german*/"das zerbrochene Goronen-Schwert", /*french*/"l'Épée Brisée de Goron"), + // /*spanish*/la espada goron rota + { + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges"), + // /*spanish*/un objeto de una misión secundaria + CustomMessage("a sword", /*german*/"ein Schwert", /*french*/"une épée") + // /*spanish*/una espada + }, { + CustomMessage("a shattered slicer", /*german*/"ein zersplitterter Schneider", /*french*/"une arme cassée")}); + // /*spanish*/una rebanadora rota + + hintTextTable[RHT_PRESCRIPTION] = HintText(CustomMessage("the Prescription", /*german*/"ein Rezept", /*french*/"une Ordonnance"), + // /*spanish*/la receta + { + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges") + // /*spanish*/un objeto de una misión secundaria + }, { + CustomMessage("a pill pamphlet", /*german*/"ein Pillenpamphlet", /*french*/"un document urgent"), + // /*spanish*/un instructivo medicinal + CustomMessage("a doctor's note", /*german*/"eine Notiz eines Doktors", /*french*/"un papier médical")}); + // /*spanish*/unas notas del doctor + + hintTextTable[RHT_EYEBALL_FROG] = HintText(CustomMessage("the Eyeball Frog", /*german*/"der Glotzfrosch", /*french*/"le Crapaud-qui-louche"), + // /*spanish*/la rana de ojos saltones + { + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges") + // /*spanish*/un objeto de una misión secundaria + }, { + CustomMessage("a perceiving polliwog", /*german*/"eine wahrnehmende Kaulquappe", /*french*/"un amphibien")}); + // /*spanish*/un variopinto batracio + + hintTextTable[RHT_EYEDROPS] = HintText(CustomMessage("the Eyedrops", /*german*/"die Augentropfen", /*french*/"une phiole de Super-Gouttes"), + // /*spanish*/las supergotas oculares + { + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges") + // /*spanish*/un objeto de una misión secundaria + }, { + CustomMessage("a vision vial", /*german*/"eine Sichtphiole", /*french*/"une solution oculaire")}); + // /*spanish*/un remedio para la vista + + hintTextTable[RHT_CLAIM_CHECK] = HintText(CustomMessage("the Claim Check", /*german*/"ein Zertifikat", /*french*/"un Certificat"), + // /*spanish*/el recibo + { + CustomMessage("a trade quest item", /*german*/"ein Gegenstand einer Handelsmission", /*french*/"un objet de quête d'échanges") + // /*spanish*/un objeto de una misión secundaria + }, { + CustomMessage("a three day wait", /*german*/"eine dreitägige Erwartung", /*french*/"un rendez-vous dans trois jours")}); + // /*spanish*/unos tres días de espera + + hintTextTable[RHT_PROGRESSIVE_HOOKSHOT] = HintText(CustomMessage("a Hookshot", /*german*/"ein Enterhaken", /*french*/"un Grappin"), + // /*spanish*/un gancho + { + CustomMessage("something that can grab things", /*german*/"etwas, das Dinge greifen kann", /*french*/"une chose qui peut attraper"), + // /*spanish*/algo que pueda agarrar cosas + CustomMessage("something that can stun", /*german*/"etwas, das paralysieren kann", /*french*/"une chose qui peut paralyser") + // /*spanish*/algo que pueda paralizar + }, { + CustomMessage("Dampé's keepsake", /*german*/"Dampés Andenken", /*french*/"l'héritage d'Igor"), + // /*spanish*/un recuerdo de Dampé + CustomMessage("the Grapple Beam", /*german*/"der Greifstrahl", /*french*/"le rayon grippeur"), + // /*spanish*/una garra metálica + CustomMessage("the RHT_BOING! chain", /*german*/"die Kette des RHT_BOING!", /*french*/"la chaîne de RHT_BOING!")}); + // /*spanish*/una cadena retráctil + + hintTextTable[RHT_PROGRESSIVE_STRENGTH] = HintText(CustomMessage("a Strength Upgrade", /*german*/"eine Stärkeverbesserung", /*french*/"une Amélioration de Force"), + // /*spanish*/un aumento de fuerza + { + CustomMessage("something that can remove boulders", /*german*/"etwas, das Geröll entfernen kann", /*french*/"une chose qui enlève les rochers") + // /*spanish*/algo que pueda quitar rocas + }, { + CustomMessage("power gloves", /*german*/"Krafthandschuhe", /*french*/"une paire de gants de travail"), + // /*spanish*/unos poderosos guanteletes + CustomMessage("metal mittens", /*german*/"Metallfäustlinge", /*french*/"une paire de mitaines"), + // /*spanish*/unas manoplas metálicas + CustomMessage("the heavy lifty", /*german*/"der Schwerlastheber", /*french*/"la puissance de dix hommes")}); + // /*spanish*/un levantamiento pesado + + hintTextTable[RHT_PROGRESSIVE_BOMB_BAG] = HintText(CustomMessage("a Bomb Bag", /*german*/"ein Bombenbeutel", /*french*/"un Sac de Bombes"), + // /*spanish*/un saco de bombas + { + CustomMessage("explosives", /*german*/"ein Explosivpaket", /*french*/"un paquet d'explosifs"), + // /*spanish*/un montón de explosivos + CustomMessage("something that can remove boulders", /*german*/"etwas, das Geröll entfernen kann", /*french*/"une chose qui enlève les rochers") + // /*spanish*/algo que pueda quitar rocas + }, { + CustomMessage("an explosive container", /*german*/"ein Explosivbehälter", /*french*/"un porte-grenade"), + // /*spanish*/un recipiente explosivo + CustomMessage("a blast bag", /*german*/"ein Dodongomagen", /*french*/"un estomac de Dodongo")}); + // /*spanish*/un zurrón de estallidos + + hintTextTable[RHT_PROGRESSIVE_BOW] = HintText(CustomMessage("a Fairy Bow", /*german*/"ein Feen-Bogen", /*french*/"l'Arc des Fées"), + // /*spanish*/un arco de las hadas + { + CustomMessage("a projectile shooter", /*german*/"ein Projektilwerfer", /*french*/"un tire-projectile") + // /*spanish*/un arma de proyectil + }, { + CustomMessage("an archery enabler", /*german*/"ein Bogenschussermöglicher", /*french*/"un facilitateur de tir"), + // /*spanish*/un tiro al blanco + CustomMessage("a danger dart launcher", /*german*/"ein Pfeilwerfer", /*french*/"un tire-fléchette")}); + // /*spanish*/un peligroso lanzadardos + + hintTextTable[RHT_PROGRESSIVE_SLINGSHOT] = HintText(CustomMessage("a Slingshot", /*german*/"eine Schleuder", /*french*/"un Lance-Pierre"), + // /*spanish*/una resortera de las hadas + { + CustomMessage("a projectile shooter", /*german*/"ein Projektilwerfer", /*french*/"un tire-projectile") + // /*spanish*/un arma de proyectil + }, { + CustomMessage("a seed shooter", /*german*/"ein Nusswerfer", /*french*/"un lance-noix"), + // /*spanish*/un lanzasemillas + CustomMessage("a rubberband", /*german*/"ein Gummiband", /*french*/"un élastique"), + // /*spanish*/un tirachinas + CustomMessage("a child's catapult", /*german*/"ein Kinderkatapult", /*french*/"un jouet d'enfant")}); + // /*spanish*/una catapulta infantil + + hintTextTable[RHT_PROGRESSIVE_WALLET] = HintText(CustomMessage("a Wallet", /*german*/"eine Börse", /*french*/"une Bourse"), + // /*spanish*/una bolsa de rupias + { + CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas") + // /*spanish*/un obsequio de la Casa Skulltula + }, { + CustomMessage("a mo' money holder", /*german*/"ein Geldhalter", /*french*/"un sac à sous"), + // /*spanish*/una cartera de dinero + CustomMessage("a gem purse", /*german*/"ein Edelsteinportemonnaie", /*french*/"une sacoche"), + // /*spanish*/un zurrón de gemas + CustomMessage("a portable bank", /*german*/"eine tragbare Bank", /*french*/"une petite banque")}); + // /*spanish*/un banco portable + + hintTextTable[RHT_PROGRESSIVE_SCALE] = HintText(CustomMessage("a Zora Scale", /*german*/"eine Zora-Schuppe", /*french*/"une Écaille Zora"), + // /*spanish*/una escama Zora + { + CustomMessage("a diving tool", /*german*/"ein Tauchwerkzeug", /*french*/"un outil de plongée") + // /*spanish*/un instrumento de buceo + }, { + CustomMessage("a deeper dive", /*german*/"eine Tauchblase", /*french*/"une bulle de plongée"), + // /*spanish*/un profundo buceo + CustomMessage("a piece of Zora", /*german*/"ein Zora-Fragment", /*french*/"un morceau de Zora")}); + // /*spanish*/un fragmento de Zora + + hintTextTable[RHT_PROGRESSIVE_NUT_UPGRADE] = HintText(CustomMessage("Deku Nut Capacity", /*german*/"Deku-Nuß-Kapazität", /*french*/"une Augmentation de Noix Mojo"), + // /*spanish*/un aumento de nueces deku + { + CustomMessage("some Deku munitions", /*german*/"etwas Deku-Munition", /*french*/"un paquet de munitions Mojo"), + // /*spanish*/un montón de municiones Deku + CustomMessage("something that can stun", /*german*/"etwas, das paralysieren kann", /*french*/"une chose qui peut paralyser") + // /*spanish*/algo que pueda paralizar + }, { + CustomMessage("more nuts", /*german*/"mehr Nüsse", /*french*/"encore plus de noix"), + // /*spanish*/más semillas de nogal + CustomMessage("flashbang storage", /*german*/"Blendgranatenvorrat", /*french*/"un sac à noix")}); + // /*spanish*/más frutos aturdidores + + hintTextTable[RHT_PROGRESSIVE_STICK_UPGRADE] = HintText(CustomMessage("Deku Stick Capacity", /*german*/"Deku-Stab-Kapazität", /*french*/"une augmentation de bâtons Mojo"), + // /*spanish*/un aumento de palos deku + { + CustomMessage("some Deku munitions", /*german*/"etwas Deku-Munition", /*french*/"un paquet de munitions Mojo") + // /*spanish*/un montón de municiones Deku + }, { + CustomMessage("lumber racks", /*german*/"Holzgestelle", /*french*/"un paquet de bois"), + // /*spanish*/más bastones + CustomMessage("more flammable twigs", /*german*/"mehr entflammbare Zweige", /*french*/"beaucoup de branches")}); + // /*spanish*/más varas + + hintTextTable[RHT_PROGRESSIVE_MAGIC_METER] = HintText(CustomMessage("a Magic Meter", /*german*/"ein Magieabmaß", /*french*/"une Jauge de Magie"), + // /*spanish*/un aumento de poder mágico + { + CustomMessage("a Great Fairy's power", /*german*/"eine Kraft einer großen Fee", /*french*/"le pouvoir d'une grande fée") + // /*spanish*/el poder de una Gran Hada + }, { + CustomMessage("mystic training", /*german*/"mystisches Training", /*french*/"un potentiel magique"), + // /*spanish*/una maestría mística + CustomMessage("pixie dust", /*german*/"Feenstaub", /*french*/"de la poudre de fée"), + // /*spanish*/un polvo de hada + CustomMessage("a green rectangle", /*german*/"ein grünes Rechteck", /*french*/"un rectangle vert")}); + // /*spanish*/una verduzca barra + + hintTextTable[RHT_PROGRESSIVE_OCARINA] = HintText(CustomMessage("an Ocarina", /*german*/"eine Okarina", /*french*/"un ocarina"), + // /*spanish*/una ocarina + { + CustomMessage("something given by Saria", /*german*/"ein Geschenk von Salia", /*french*/"un cadeau de Saria"), + // /*spanish*/un obsequio de Saria + CustomMessage("something kept by the royal family", /*german*/"etwas, das von der royalen Familie bewahrt wird", /*french*/"une chose qui paralyse") + // /*spanish*/algo guardado por la familia real + }, { + CustomMessage("a flute", /*german*/"eine Flöte", /*french*/"un bec musical"), + // /*spanish*/un utensilio musical + CustomMessage("a music maker", /*german*/"ein Musikmacher", /*french*/"un porteur de chansons")}); + // /*spanish*/un instrumento + + hintTextTable[RHT_PROGRESSIVE_BOMBCHUS] = HintText(CustomMessage("Bombchus", /*german*/"Krabbelminen", /*french*/"un paquet de Missiles"), + // /*spanish*/unos bombchus + { + CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"), + // /*spanish*/un obsequio de la Casa Skulltula + CustomMessage("explosives", /*german*/"ein Explosivpaket", /*french*/"un paquet d'explosifs") + // /*spanish*/un montón de explosivos + }, { + CustomMessage("mice bombs", /*german*/"Mäusebomben", /*french*/"un adorable explosif"), + // /*spanish*/unas bombas roedoras + CustomMessage("proximity mice", /*german*/"Näherungsmäuse", /*french*/"une mine anti-rongeur"), + // /*spanish*/unos explosivos ratoncitos + CustomMessage("wall crawlers", /*german*/"Wandkrabbler", /*french*/"un rapide grimpeur"), + // /*spanish*/unos trepaparedes + CustomMessage("trail blazers", /*german*/"Vorreiter", /*french*/"un zigzag éclatant")}); + // /*spanish*/unas ratas propulsadas + + hintTextTable[RHT_PROGRESSIVE_GORONSWORD] = HintText(CustomMessage("a Goron Sword", /*german*/"ein Goronen-Schwert", /*french*/"une épée Goron"), + // /*spanish*/una espada goron + { + CustomMessage("a sword", /*german*/"ein Schwert", /*french*/"une épée") + // /*spanish*/una espada + }, { + CustomMessage("a long blade", /*german*/"eine lange Klinge", /*french*/"une longue lame"), + // /*spanish*/una gran hoja + CustomMessage("a Goron weapon", /*german*/"eine Goronenwaffe", /*french*/"une arme Goron")}); + // /*spanish*/un arma goron + + hintTextTable[RHT_EMPTY_BOTTLE] = HintText(CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon vide"), + // /*spanish*/una botella + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("a glass container", /*german*/"ein Glasbehälter", /*french*/"un cylindre de cristal"), + // /*spanish*/un recipiente de cristal + CustomMessage("an empty jar", /*german*/"ein leerer Krug", /*french*/"une jarre incassable"), + // /*spanish*/un frasco vacío + CustomMessage("encased air", /*german*/"eingeschlossene Luft", /*french*/"un bocal d'air")}); + // /*spanish*/aire a presión + + hintTextTable[RHT_BOTTLE_WITH_MILK] = HintText(CustomMessage("a Milk Bottle", /*german*/"eine Milchflasche", /*french*/"un flacon de lait"), + // /*spanish*/una botella de leche + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("cow juice", /*german*/"Kuhsaft", /*french*/"une source de calcium"), + // /*spanish*/una fuente de calcio + CustomMessage("a white liquid", /*german*/"eine weiße Flüssigkeit", /*french*/"un liquide blanc"), + // /*spanish*/una bebida nutritiva + CustomMessage("a baby's breakfast", /*german*/"ein Babyfrühstück", /*french*/"du jus pour bébé")}); + // /*spanish*/un trago para bebés + + hintTextTable[RHT_BOTTLE_WITH_RED_POTION] = HintText(CustomMessage("a Red Potion Bottle", /*german*/"eine Flasche mit rotem Elixier", /*french*/"un flacon de potion rouge"), + // /*spanish*/una botella de poción roja + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("a vitality vial", /*german*/"eine Vitalitätsphiole", /*french*/"un mélange de vitalité"), + // /*spanish*/una pócima vitalicia + CustomMessage("a red liquid", /*german*/"eine rote Flüssigkeit", /*french*/"un liquide rouge")}); + // /*spanish*/un remedio rojizo + + hintTextTable[RHT_BOTTLE_WITH_GREEN_POTION] = HintText(CustomMessage("a Green Potion Bottle", /*german*/"eine Flasche mit grünem Elixier", /*french*/"un flacon de potion verte"), + // /*spanish*/una botella de poción verde + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("a magic mixture", /*german*/"eine magische Mixtur", /*french*/"une réserve magique"), + // /*spanish*/un potingue mágico + CustomMessage("a green liquid", /*german*/"eine grüne Flüssigkeit", /*french*/"un liquide vert")}); + // /*spanish*/un remedio verduzco + + hintTextTable[RHT_BOTTLE_WITH_BLUE_POTION] = HintText(CustomMessage("a Blue Potion Bottle", /*german*/"eine Flasche mit blauem Elixier", /*french*/"un flacon de potion bleue"), + // /*spanish*/una botella de poción azul + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("an ailment antidote", /*german*/"ein Krankheitsantidot", /*french*/"l'élixir ultime"), + // /*spanish*/un antídoto para el dolor + CustomMessage("a blue liquid", /*german*/"eine blaue Flüssigkeit", /*french*/"un liquide bleu")}); + // /*spanish*/un remedio índigo + + hintTextTable[RHT_BOTTLE_WITH_FAIRY] = HintText(CustomMessage("a Fairy Bottle", /*german*/"eine Feenflasche", /*french*/"une fée en flacon"), + // /*spanish*/un hada en una botella + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("an imprisoned fairy", /*german*/"eine gefangene Fee", /*french*/"une fée emprisonnée"), + // /*spanish*/un hada atrapada + CustomMessage("an extra life", /*german*/"ein Extraleben", /*french*/"une vie de rechange"), + // /*spanish*/una oportunidad más + CustomMessage("Navi's cousin", /*german*/"Navis Vetter", /*french*/"le cousin de Navi")}); + // /*spanish*/una prima de Navi + + hintTextTable[RHT_BOTTLE_WITH_FISH] = HintText(CustomMessage("a Fish Bottle", /*german*/"eine Fischflasche", /*french*/"un poisson en flacon"), + // /*spanish*/un pez en una botella + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("an aquarium", /*german*/"ein Aquarium", /*french*/"un aquarium"), + // /*spanish*/un escamado ser + CustomMessage("a deity's snack", /*german*/"ein Gottheitssnack", /*french*/"le repas d'un dieu marin")}); + // /*spanish*/un tentempié de cierta deidad + + hintTextTable[RHT_BOTTLE_WITH_BLUE_FIRE] = HintText(CustomMessage("a Blue Fire Bottle", /*german*/"eine Flasche mit blauem Feuer", /*french*/"une flamme bleue en flacon"), + // /*spanish*/una botella de fuego azul + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("a conflagration canteen", /*german*/"eine Brandfeldflasche", /*french*/"une mystérieuse flamme"), + // /*spanish*/un incendio retenido + CustomMessage("an icemelt jar", /*german*/"ein eisschmelzender Krug", /*french*/"un brasier glacial")}); + // /*spanish*/unas brasas enfrascadas + + hintTextTable[RHT_BOTTLE_WITH_BUGS] = HintText(CustomMessage("a Bug Bottle", /*german*/"eine Wanzenflasche", /*french*/"un insecte en flacon"), + // /*spanish*/unos insectos en una botella + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("an insectarium", /*german*/"ein Insektarium", /*french*/"un insectarium"), + // /*spanish*/unos invertebrados seres + CustomMessage("Skulltula finders", /*german*/"Skulltula-Finder", /*french*/"une poignée de trouve-Skulltula")}); + // /*spanish*/unos rastreadores de skulltulas + + hintTextTable[RHT_BOTTLE_WITH_POE] = HintText(CustomMessage("a Poe Bottle", /*german*/"eine Irrlichtflasche", /*french*/"un Esprit en flacon"), + // /*spanish*/un Poe en una botella + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("a spooky ghost", /*german*/"ein spukhafter Geist", /*french*/"un effroyable fantôme"), + // /*spanish*/un espantoso espectro + CustomMessage("a face in the jar", /*german*/"ein Gesicht im Krug", /*french*/"un visage dans un bocal")}); + // /*spanish*/una expresión enfrascada + + hintTextTable[RHT_BOTTLE_WITH_BIG_POE] = HintText(CustomMessage("a Big Poe Bottle", /*german*/"eine Nachtschwärmerflasche", /*french*/"une Ame en flacon"), + // /*spanish*/un Gran Poe en una botella + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("the spookiest ghost", /*german*/"der spukhafteste Geist", /*french*/"un épouvantable spectre"), + // /*spanish*/el espectro más espeluznante + CustomMessage("a sidequest spirit", /*german*/"ein Nebenmissionsgeist", /*french*/"un précieux esprit")}); + // /*spanish*/un buen valorado espíritu + + hintTextTable[RHT_RUTOS_LETTER] = HintText(CustomMessage("Ruto's Letter", /*german*/"Rutos Brief", /*french*/"la lettre de Ruto"), + // /*spanish*/la carta de Ruto + { + CustomMessage("a bottle", /*german*/"eine Flasche", /*french*/"un flacon") + // /*spanish*/una botella + }, { + CustomMessage("a call for help", /*german*/"ein Hilferuf", /*french*/"un appel au secours"), + // /*spanish*/una llamada de auxilio + CustomMessage("the note that Mweeps", /*german*/"eine Notiz, die Mweeps", /*french*/"un message qui fait mwip"), + // /*spanish*/un escrito mweep + CustomMessage("an RHT_SOS call", /*german*/"ein RHT_SOS Signal", /*french*/"un signal RHT_SOS"), + // /*spanish*/una nota de socorro + CustomMessage("a fishy stationery", /*german*/"ein nasses Papier", /*french*/"un papier mouillé")}); + // /*spanish*/un mensaje de ayuda + + hintTextTable[RHT_ZELDAS_LULLABY] = HintText(CustomMessage("Zelda's Lullaby", /*german*/"Zeldas Wiegenlied", /*french*/"la berceuse de Zelda"), + // /*spanish*/la Nana de Zelda + { + CustomMessage("a regular song", /*german*/"ein normales Lied", /*french*/"une chanson normale"), + // /*spanish*/una cancion normal + CustomMessage("something kept by the royal family", /*german*/"etwas, das von der royalen Familie bewahrt wird", /*french*/"une chose qui paralyse") + // /*spanish*/algo guardado por la familia real + }, { + CustomMessage("a song of royal slumber", /*german*/"ein royales Lied", /*french*/"une chanson royale"), + // /*spanish*/la canción real + CustomMessage("a triforce tune", /*german*/"eine heilige Musik", /*french*/"la musique sacrée")}); + // /*spanish*/la melodía de la trifuerza + + hintTextTable[RHT_EPONAS_SONG] = HintText(CustomMessage("Epona's Song", /*german*/"Eponas Lied", /*french*/"le chant d'Epona"), + // /*spanish*/la Canción de Epona + { + CustomMessage("a regular song", /*german*/"ein normales Lied", /*french*/"une chanson normale") + // /*spanish*/una cancion normal + }, { + CustomMessage("an equestrian etude", /*german*/"eine Reiterhymne", /*french*/"une hymne équestre"), + // /*spanish*/una copla ecuestre + CustomMessage("Malon's melody", /*german*/"Malons Melodie", /*french*/"la mélodie des vaches"), + // /*spanish*/la sonata de Malon + CustomMessage("a ranch song", /*german*/"ein Lied des Ackers", /*french*/"le chant des champs")}); + // /*spanish*/un canto rupestre + + hintTextTable[RHT_SARIAS_SONG] = HintText(CustomMessage("Saria's Song", /*german*/"Salias Lied", /*french*/"le chant de Saria"), + // /*spanish*/la Canción de Saria + { + CustomMessage("a regular song", /*german*/"ein normales Lied", /*french*/"une chanson normale"), + // /*spanish*/una cancion normal + CustomMessage("something given by Saria", /*german*/"ein Geschenk von Salia", /*french*/"un cadeau de Saria") + // /*spanish*/un obsequio de Saria + }, { + CustomMessage("a song of dancing Gorons", /*german*/"ein Lied der tanzenden Goronen", /*french*/"une chanson danceuse"), + // /*spanish*/un pegadizo tono goron + CustomMessage("Saria's phone number", /*german*/"Salias Telefonnummer", /*french*/"le téléphone d'une amie")}); + // /*spanish*/una consulta de asistencia + + hintTextTable[RHT_SUNS_SONG] = HintText(CustomMessage("the Sun's Song", /*german*/"Hymne der Sonne", /*french*/"le chant du soleil"), + // /*spanish*/la Canción del Sol + { + CustomMessage("a regular song", /*german*/"ein normales Lied", /*french*/"une chanson normale"), + // /*spanish*/una cancion normal + CustomMessage("something that can stun", /*german*/"etwas, das paralysieren kann", /*french*/"une chose qui peut paralyser") + // /*spanish*/algo que pueda paralizar + }, { + CustomMessage("Sunny Day", /*german*/"sonniger Tag", /*french*/"Zénith"), + // /*spanish*/un día soleado + CustomMessage("the ReDead's bane", /*german*/"das Verderben der Remorts", /*french*/"le fléau des Éffrois"), + // /*spanish*/la destructora de Redeads + CustomMessage("the Gibdo's bane", /*german*/"das Verderben der Gibdos", /*french*/"le fléau des Gibdo")}); + // /*spanish*/la destructora de Gibdos + + hintTextTable[RHT_SONG_OF_TIME] = HintText(CustomMessage("the Song of Time", /*german*/"Hymne der Zeit", /*french*/"le chant du temps"), + // /*spanish*/la Canción del tiempo + { + CustomMessage("a regular song", /*german*/"ein normales Lied", /*french*/"une chanson normale") + // /*spanish*/una cancion normal + }, { + CustomMessage("a song 7 years long", /*german*/"ein sieben Jahre langes Lied", /*french*/"le flot du temps"), + // /*spanish*/la setenada canción + CustomMessage("the tune of ages", /*german*/"Hymne des Äons", /*french*/"le Chant des Âges")}); + // /*spanish*/la melodía eónica + + hintTextTable[RHT_SONG_OF_STORMS] = HintText(CustomMessage("the Song of Storms", /*german*/"Hymne des Sturms", /*french*/"le chant des tempêtes"), + // /*spanish*/la Canción de la Tormenta + { + CustomMessage("a regular song", /*german*/"ein normales Lied", /*french*/"une chanson normale") + // /*spanish*/una cancion normal + }, { + CustomMessage("Rain Dance", /*german*/"Regentanz", /*french*/"Danse Pluie"), + // /*spanish*/la danza de la lluvia + CustomMessage("a thunderstorm tune", /*german*/"eine Gewitterhymne", /*french*/"une hymne foudroyante"), + // /*spanish*/una sonata tormentosa + CustomMessage("windmill acceleration", /*german*/"Windmühlenbeschleunigung", /*french*/"l'accélérateur de moulins")}); + // /*spanish*/el arranque de molinos + + hintTextTable[RHT_MINUET_OF_FOREST] = HintText(CustomMessage("the Minuet of Forest", /*german*/"Menuett des Waldes", /*french*/"le menuet de la forêt"), + // /*spanish*/el Minueto del bosque + { + CustomMessage("a warp song", /*german*/"ein Teleportationslied", /*french*/"une chanson de téléportation") + // /*spanish*/una canción de teletransportación + }, { + CustomMessage("the song of tall trees", /*german*/"Lied der großen Bäume", /*french*/"le bruit des arbres"), + // /*spanish*/la canción de las copas + CustomMessage("an arboreal anthem", /*german*/"eine baumartige Hymne", /*french*/"l'hymne sylvestre"), + // /*spanish*/el himno forestal + CustomMessage("a green spark trail", /*german*/"ein grüner Komet", /*french*/"une comète verte")}); + // /*spanish*/el sendero esmeralda + + hintTextTable[RHT_BOLERO_OF_FIRE] = HintText(CustomMessage("the Bolero of Fire", /*german*/"Bolero des Feuers", /*french*/"le boléro du feu"), + // /*spanish*/el Bolero del fuego + { + CustomMessage("a warp song", /*german*/"ein Teleportationslied", /*french*/"une chanson de téléportation") + // /*spanish*/una canción de teletransportación + }, { + CustomMessage("a song of lethal lava", /*german*/"Lied der tödlichen Lava", /*french*/"une musique enflammée"), + // /*spanish*/la canción de la lava + CustomMessage("a red spark trail", /*german*/"ein roter Komet", /*french*/"une comète rouge"), + // /*spanish*/el sendero rubí + CustomMessage("a volcanic verse", /*german*/"ein vulkanischer Vers", /*french*/"le souffle du volcan")}); + // /*spanish*/el verso volcánico + + hintTextTable[RHT_SERENADE_OF_WATER] = HintText(CustomMessage("the Serenade of Water", /*german*/"Serenade des Wassers", /*french*/"la sérénade de l'eau"), + // /*spanish*/la Serenata del agua + { + CustomMessage("a warp song", /*german*/"ein Teleportationslied", /*french*/"une chanson de téléportation") + // /*spanish*/una canción de teletransportación + }, { + CustomMessage("a song of a damp ditch", /*german*/"die Stille des Wassers", /*french*/"le calme de l'eau"), + // /*spanish*/la canción del estanque + CustomMessage("a blue spark trail", /*german*/"ein blauer Komet", /*french*/"une comète bleue"), + // /*spanish*/el sendero zafiro + CustomMessage("the lake's lyric", /*german*/"die Lyrik des Sees", /*french*/"la voix du lac")}); + // /*spanish*/la letra del lago + + hintTextTable[RHT_REQUIEM_OF_SPIRIT] = HintText(CustomMessage("the Requiem of Spirit", /*german*/"Requiem der Geister", /*french*/"le requiem des esprits"), + // /*spanish*/el Réquiem del espíritu + { + CustomMessage("a warp song", /*german*/"ein Teleportationslied", /*french*/"une chanson de téléportation") + // /*spanish*/una canción de teletransportación + }, { + CustomMessage("a song of sandy statues", /*german*/"Lied der sandigen Statuen", /*french*/"la mélodie d'une grande statue"), + // /*spanish*/la canción de la gran estatua + CustomMessage("an orange spark trail", /*german*/"ein oranger Komet", /*french*/"une comète orange"), + // /*spanish*/el sendero ámbar + CustomMessage("the desert ditty", /*german*/"der Wind der Wüste", /*french*/"le vent du désert")}); + // /*spanish*/la estrofa del desierto + + hintTextTable[RHT_NOCTURNE_OF_SHADOW] = HintText(CustomMessage("the Nocturne of Shadow", /*german*/"Nocturne des Schattens", /*french*/"le nocturne de l'ombre"), + // /*spanish*/el Nocturno de la sombra + { + CustomMessage("a warp song", /*german*/"ein Teleportationslied", /*french*/"une chanson de téléportation") + // /*spanish*/una canción de teletransportación + }, { + CustomMessage("a song of spooky spirits", /*german*/"Lied der spukhaften Geister", /*french*/"une hymne de chair de poule"), + // /*spanish*/la canción de los espectros + CustomMessage("a graveyard boogie", /*german*/"ein Friedhofsboogie", /*french*/"un boogie de fantômes"), + // /*spanish*/una honra fúnebre + CustomMessage("a haunted hymn", /*german*/"eine Spukhymne", /*french*/"une chanson lugubre"), + // /*spanish*/una estrofa encantada + CustomMessage("a purple spark trail", /*german*/"ein violetter Komet", /*french*/"une comète mauve")}); + // /*spanish*/el sendero malva + + hintTextTable[RHT_PRELUDE_OF_LIGHT] = HintText(CustomMessage("the Prelude of Light", /*german*/"Kantate des Lichts", /*french*/"le prélude de la lumière"), + // /*spanish*/el Preludio de la luz + { + CustomMessage("a warp song", /*german*/"ein Teleportationslied", /*french*/"une chanson de téléportation") + // /*spanish*/una canción de teletransportación + }, { + CustomMessage("a luminous prologue melody", /*german*/"eine leuchtende Melodie", /*french*/"une matine illuminée"), + // /*spanish*/la melodía refulgente + CustomMessage("a yellow spark trail", /*german*/"ein gelber Komet", /*french*/"une comète jaune"), + // /*spanish*/el sendero resplandeciente + CustomMessage("the temple traveler", /*german*/"ein Tempelreisender", /*french*/"un chant de sanctuaire")}); + // /*spanish*/la ruta del templo + + hintTextTable[RHT_DEKU_TREE_MAP] = HintText(CustomMessage("the Deku Tree Map", /*german*/"die Karte des Deku-Baums", /*french*/"la carte de l'Arbre Mojo"), + // /*spanish*/el mapa del Gran Árbol Deku + { + CustomMessage("a dungeon map", /*german*/"eine Karte", /*french*/"une carte") + // /*spanish*/un mapa + }, { + CustomMessage("a mossy atlas", /*german*/"ein moosiger Atlas", /*french*/"un atlas boisé"), + // /*spanish*/un atlas musgoso + CustomMessage("some mossy blueprints", /*german*/"einige moosige Blaupausen", /*french*/"un plan boisé")}); + // /*spanish*/unos planos musgosos + + hintTextTable[RHT_DODONGOS_CAVERN_MAP] = HintText(CustomMessage("the Dodongo's Cavern Map", /*german*/"die Karte der Dodongo-Höhle", /*french*/"la carte de la Caverne Dodongo"), + // /*spanish*/el mapa de la Cueva de los Dodongos + { + CustomMessage("a dungeon map", /*german*/"eine Karte", /*french*/"une carte") + // /*spanish*/un mapa + }, { + CustomMessage("a rocky atlas", /*german*/"eine felsiger Atlas", /*french*/"un atlas rocheux"), + // /*spanish*/un atlas rocoso + CustomMessage("some rocky blueprints", /*german*/"einige felsige Blaupausen", /*french*/"un plan rocheux")}); + // /*spanish*/unos planos rocosos + + hintTextTable[RHT_JABU_JABUS_BELLY_MAP] = HintText(CustomMessage("the Jabu-Jabu's Belly Map", /*german*/"die Karte des Jabu-Jabu-Bauchs", /*french*/"la carte de Jabu-Jabu"), + // /*spanish*/el mapa de la Tripa de Jabu-Jabu + { + CustomMessage("a dungeon map", /*german*/"eine Karte", /*french*/"une carte") + // /*spanish*/un mapa + }, { + CustomMessage("a fishy atlas", /*german*/"ein fischiger Atlas", /*french*/"un atlas digéré"), + // /*spanish*/un atlas digesto + CustomMessage("some fishy blueprints", /*german*/"einige fischige Blaupausen", /*french*/"un plan digéré")}); + // /*spanish*/unos planos digestos + + hintTextTable[RHT_FOREST_TEMPLE_MAP] = HintText(CustomMessage("the Forest Temple Map", /*german*/"die Karte des Waldtempels", /*french*/"la carte du Temple de la Forêt"), + // /*spanish*/el mapa del Templo del Bosque + { + CustomMessage("a dungeon map", /*german*/"eine Karte", /*french*/"une carte") + // /*spanish*/un mapa + }, { + CustomMessage("a sylvan atlas", /*german*/"ein waldiger Atlas", /*french*/"un atlas sylvestre"), + // /*spanish*/un atlas enselvado + CustomMessage("some sylvan blueprints", /*german*/"einige waldige Blaupausen", /*french*/"un plan sylvestre")}); + // /*spanish*/unos planos enselvados + + hintTextTable[RHT_FIRE_TEMPLE_MAP] = HintText(CustomMessage("the Fire Temple Map", /*german*/"die Karte des Feuertempels", /*french*/"la carte du Temple du Feu"), + // /*spanish*/el mapa del Templo del Fuego + { + CustomMessage("a dungeon map", /*german*/"eine Karte", /*french*/"une carte") + // /*spanish*/un mapa + }, { + CustomMessage("a molten atlas", /*german*/"ein geschmolzener Atlas", /*french*/"un atlas fondu"), + // /*spanish*/un atlas fundido + CustomMessage("some molten blueprints", /*german*/"einige geschmolzene Blaupausen", /*french*/"un plan fondu")}); + // /*spanish*/unos planos fundidos + + hintTextTable[RHT_WATER_TEMPLE_MAP] = HintText(CustomMessage("the Water Temple Map", /*german*/"die Karte des Wassertempels", /*french*/"la carte du Temple de l'Eau"), + // /*spanish*/el mapa del Templo del Agua + { + CustomMessage("a dungeon map", /*german*/"eine Karte", /*french*/"une carte") + // /*spanish*/un mapa + }, { + CustomMessage("a wet atlas", /*german*/"ein nasser Atlas", /*french*/"un atlas humide"), + // /*spanish*/un atlas mojado + CustomMessage("some wet blueprints", /*german*/"einige nasse Blaupausen", /*french*/"un plan humide")}); + // /*spanish*/unos planos mojados + + hintTextTable[RHT_SPIRIT_TEMPLE_MAP] = HintText(CustomMessage("the Spirit Temple Map", /*german*/"die Karte des Geistertempels", /*french*/"la carte du Temple de l'Esprit"), + // /*spanish*/el mapa del Templo del Espíritu + { + CustomMessage("a dungeon map", /*german*/"eine Karte", /*french*/"une carte") + // /*spanish*/un mapa + }, { + CustomMessage("a sandy atlas", /*german*/"ein sandiger Atlas", /*french*/"un atlas sableux"), + // /*spanish*/un atlas arenoso + CustomMessage("some sandy blueprints", /*german*/"einige sandige Blaupausen", /*french*/"un plan sableux")}); + // /*spanish*/unos planos arenosos + + hintTextTable[RHT_SHADOW_TEMPLE_MAP] = HintText(CustomMessage("the Shadow Temple Map", /*german*/"die Karte des Schattentempels", /*french*/"la carte du Temple de l'Ombre"), + // /*spanish*/el mapa del Templo de las Sombras + { + CustomMessage("a dungeon map", /*german*/"eine Karte", /*french*/"une carte") + // /*spanish*/un mapa + }, { + CustomMessage("a creepy atlas", /*german*/"eine gruseliger Atlas", /*french*/"un atlas sinistre"), + // /*spanish*/un atlas siniestra + CustomMessage("some creepy blueprints", /*german*/"einige gruselige Blaupausen", /*french*/"un plan sinistre")}); + // /*spanish*/unos planos siniestras + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MAP] = HintText(CustomMessage("the Bottom of the Well Map", /*german*/"die Karte des Grund des Brunnens", /*french*/"la carte du fond du Puits"), + // /*spanish*/el mapa del Fondo del pozo + { + CustomMessage("a dungeon map", /*german*/"eine Karte", /*french*/"une carte") + // /*spanish*/un mapa + }, { + CustomMessage("a moldy atlas", /*german*/"ein schimmeliger Atlas", /*french*/"un atlas moisi"), + // /*spanish*/un atlas mohoso + CustomMessage("some moldy blueprints", /*german*/"einige schimmelige Blaupausen", /*french*/"un plan moisi")}); + // /*spanish*/unos planos mohosos + + hintTextTable[RHT_ICE_CAVERN_MAP] = HintText(CustomMessage("the Ice Cavern Map", /*german*/"die Karte der Eishöhle", /*french*/"la carte de la Caverne Polaire"), + // /*spanish*/el mapa de la Caverna de hielo + { + CustomMessage("a dungeon map", /*german*/"eine Karte", /*french*/"une carte") + // /*spanish*/un mapa + }, { + CustomMessage("a polar atlas", /*german*/"ein polarer Atlas", /*french*/"un atlas polaire"), + // /*spanish*/un atlas polar + CustomMessage("some polar blueprints", /*german*/"einige polare Blaupausen", /*french*/"un plan polaire")}); + // /*spanish*/unos planos polars + + hintTextTable[RHT_DEKU_TREE_COMPASS] = HintText(CustomMessage("the Deku Tree Compass", /*german*/"der Kompaß des Deku-Baums", /*french*/"la boussole de l'Arbre Mojo"), + // /*spanish*/la brújula del Gran Árbol Deku + { + CustomMessage("a compass", /*german*/"ein Kompaß", /*french*/"une boussole") + // /*spanish*/una brújula + }, { + CustomMessage("a mossy treasure tracker", /*german*/"ein moosiger Schatzfinder", /*french*/"un cherche-trésor boisé"), + // /*spanish*/un zahorí musgoso + CustomMessage("a mossy magnetic needle", /*german*/"eine moosige Magnetnadel", /*french*/"une aimant boisée")}); + // /*spanish*/un imán musgoso + + hintTextTable[RHT_DODONGOS_CAVERN_COMPASS] = HintText(CustomMessage("the Dodongo's Cavern Compass", /*german*/"der Kompaß der Dodongo-Höhle", /*french*/"la boussole de la Caverne Dodongo"), + // /*spanish*/la brújula de la Cueva de los Dodongos + { + CustomMessage("a compass", /*german*/"ein Kompaß", /*french*/"une boussole") + // /*spanish*/una brújula + }, { + CustomMessage("a rocky treasure tracker", /*german*/"ein felsiger Schatzfinder", /*french*/"un cherche-trésor rocheux"), + // /*spanish*/un zahorí rocoso + CustomMessage("a rocky magnetic needle", /*german*/"eine felsige Magnetnadel", /*french*/"une aimant rocheux")}); + // /*spanish*/un imán rocoso + + hintTextTable[RHT_JABU_JABUS_BELLY_COMPASS] = HintText(CustomMessage("the Jabu-Jabu's Belly Compass", /*german*/"der Kompaß des Jabu-Jabu-Bauchs", /*french*/"la boussole de Jabu-Jabu"), + // /*spanish*/la brújula de la Tripa de Jabu-Jabu + { + CustomMessage("a compass", /*german*/"ein Kompaß", /*french*/"une boussole") + // /*spanish*/una brújula + }, { + CustomMessage("a fishy treasure tracker", /*german*/"ein fischiger Schatzfinder", /*french*/"un cherche-trésor digéré"), + // /*spanish*/un zahorí digesto + CustomMessage("a fishy magnetic needle", /*german*/"eine fischige Magnetnadel", /*french*/"une aimant digéré")}); + // /*spanish*/un imán digesto + + hintTextTable[RHT_FOREST_TEMPLE_COMPASS] = HintText(CustomMessage("the Forest Temple Compass", /*german*/"der Kompaß des Waldtempels", /*french*/"la boussole du Temple de la Forêt"), + // /*spanish*/la brújula del Templo del Bosque + { + CustomMessage("a compass", /*german*/"ein Kompaß", /*french*/"une boussole") + // /*spanish*/una brújula + }, { + CustomMessage("a sylvan treasure tracker", /*german*/"ein waldiger Schatzfinder", /*french*/"un cherche-trésor sylvestre"), + // /*spanish*/un zahorí enselvado + CustomMessage("a sylvan magnetic needle", /*german*/"eine waldige Magnetnadel", /*french*/"une aimant sylvestre")}); + // /*spanish*/un imán enselvado + + hintTextTable[RHT_FIRE_TEMPLE_COMPASS] = HintText(CustomMessage("the Fire Temple Compass", /*german*/"der Kompaß des Feuertempels", /*french*/"la boussole du Temple du Feu"), + // /*spanish*/la brújula del Templo del Fuego + { + CustomMessage("a compass", /*german*/"ein Kompaß", /*french*/"une boussole") + // /*spanish*/una brújula + }, { + CustomMessage("a molten treasure tracker", /*german*/"ein geschmolzener Schatzfinder", /*french*/"un cherche-trésor fondu"), + // /*spanish*/un zahorí fundido + CustomMessage("a molten magnetic needle", /*german*/"eine geschmolzene Magnetnadel", /*french*/"une aimant fondu")}); + // /*spanish*/un imán fundido + + hintTextTable[RHT_WATER_TEMPLE_COMPASS] = HintText(CustomMessage("the Water Temple Compass", /*german*/"der Kompaß des Wassertempels", /*french*/"la boussole du Temple de l'Eau"), + // /*spanish*/la brújula del Templo del Agua + { + CustomMessage("a compass", /*german*/"ein Kompaß", /*french*/"une boussole") + // /*spanish*/una brújula + }, { + CustomMessage("a wet treasure tracker", /*german*/"ein nasser Schatzfinder", /*french*/"un cherche-trésor humide"), + // /*spanish*/un zahorí mojado + CustomMessage("a wet magnetic needle", /*german*/"eine nasse Magnetnadel", /*french*/"une aimant humide")}); + // /*spanish*/un imán mojado + + hintTextTable[RHT_SPIRIT_TEMPLE_COMPASS] = HintText(CustomMessage("the Spirit Temple Compass", /*german*/"der Kompaß des Geistertempels", /*french*/"la boussole du Temple de l'Esprit"), + // /*spanish*/la brújula del Templo del Espíritu + { + CustomMessage("a compass", /*german*/"ein Kompaß", /*french*/"une boussole") + // /*spanish*/una brújula + }, { + CustomMessage("a sandy treasure tracker", /*german*/"ein sandiger Schatzfinder", /*french*/"un cherche-trésor sableux"), + // /*spanish*/un zahorí arenoso + CustomMessage("a sandy magnetic needle", /*german*/"eine sandige Magnetnadel", /*french*/"une aimant sableux")}); + // /*spanish*/un imán arenoso + + hintTextTable[RHT_SHADOW_TEMPLE_COMPASS] = HintText(CustomMessage("the Shadow Temple Compass", /*german*/"der Kompaß des Schattentempels", /*french*/"la boussole du Temple de l'Ombre"), + // /*spanish*/la brújula del Templo de las Sombras + { + CustomMessage("a compass", /*german*/"ein Kompaß", /*french*/"une boussole") + // /*spanish*/una brújula + }, { + CustomMessage("a creepy treasure tracker", /*german*/"ein gruseliger Schatzfinder", /*french*/"un cherche-trésor sinistre"), + // /*spanish*/un zahorí siniestra + CustomMessage("a creepy magnetic needle", /*german*/"eine gruselige Magnetnadel", /*french*/"une aimant sinistre")}); + // /*spanish*/un imán siniestra + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_COMPASS] = HintText(CustomMessage("the Bottom of the Well Compass", /*german*/"der Kompaß des Grund des Brunnens", /*french*/"la boussole du fond du Puits"), + // /*spanish*/la brújula del Fondo del pozo + { + CustomMessage("a compass", /*german*/"ein Kompaß", /*french*/"une boussole") + // /*spanish*/una brújula + }, { + CustomMessage("a dank treasure tracker", /*german*/"ein feuchter Schatzfinder", /*french*/"un cherche-trésor moisi"), + // /*spanish*/un zahorí mohoso + CustomMessage("a dank magnetic needle", /*german*/"eine feuchte Magnetnadel", /*french*/"une aimant moisi")}); + // /*spanish*/un imán mohoso + + hintTextTable[RHT_ICE_CAVERN_COMPASS] = HintText(CustomMessage("the Ice Cavern Compass", /*german*/"der Kompaß der Eishöhle", /*french*/"la Boussole de la Caverne Polaire"), + // /*spanish*/la brújula de la Caverna de hielo + { + CustomMessage("a compass", /*german*/"ein Kompaß", /*french*/"une boussole") + // /*spanish*/una brújula + }, { + CustomMessage("a polar treasure tracker", /*german*/"ein polarer Schatzfinder", /*french*/"un cherche-trésor polaire"), + // /*spanish*/un zahorí polar + CustomMessage("a polar magnetic needle", /*german*/"eine polare Magnetnadel", /*french*/"une aimant polaire")}); + // /*spanish*/un imán polar + + hintTextTable[RHT_FOREST_TEMPLE_BOSS_KEY] = HintText(CustomMessage("the Forest Temple Boss Key", /*german*/"der Waldtempel-Master-Schlüssel", /*french*/"la Clé d'Or du Temple de la Forêt"), + // /*spanish*/la gran llave del Templo del Bosque + { + CustomMessage("a boss key", /*german*/"ein Master-Schlüssel", /*french*/"une Clé d'Or") + // /*spanish*/una gran llave + }, { + CustomMessage("a sylvan master of unlocking", /*german*/"ein waldiger Meister des Entschlüsselns", /*french*/"un anti-grosse porte sylvestre"), + // /*spanish*/la clave enselvada de un jefe + CustomMessage("a sylvan dungeon's master pass", /*german*/"ein waldiger Dungeon-Meisterpass", /*french*/"une clé maléfique sylvestre")}); + // /*spanish*/el pase maestro enselvado + + hintTextTable[RHT_FIRE_TEMPLE_BOSS_KEY] = HintText(CustomMessage("the Fire Temple Boss Key", /*german*/"der Feuertempel-Master-Schlüssel", /*french*/"la Clé d'Or du Temple du Feu"), + // /*spanish*/la gran llave del Templo del Fuego + { + CustomMessage("a boss key", /*german*/"ein Master-Schlüssel", /*french*/"une Clé d'Or") + // /*spanish*/una gran llave + }, { + CustomMessage("a molten master of unlocking", /*german*/"ein geschmolzener Meister des Entschlüsselns", /*french*/"un anti-grosse porte fondu"), + // /*spanish*/la clave fundido de un jefe + CustomMessage("a molten dungeon's master pass", /*german*/"ein geschmolzener Dungeon-Meisterpass", /*french*/"une clé maléfique fondu")}); + // /*spanish*/el pase maestro fundido + + hintTextTable[RHT_WATER_TEMPLE_BOSS_KEY] = HintText(CustomMessage("the Water Temple Boss Key", /*german*/"der Wassertempel-Master-Schlüssel", /*french*/"la Clé d'Or du Temple de l'Eau"), + // /*spanish*/la gran llave del Templo del Agua + { + CustomMessage("a boss key", /*german*/"ein Master-Schlüssel", /*french*/"une Clé d'Or") + // /*spanish*/una gran llave + }, { + CustomMessage("a wet master of unlocking", /*german*/"ein nasser Meister des Entschlüsselns", /*french*/"un anti-grosse porte humide"), + // /*spanish*/la clave mojado de un jefe + CustomMessage("a wet dungeon's master pass", /*german*/"ein nasser Dungeon-Meisterpass", /*french*/"une clé maléfique humide")}); + // /*spanish*/el pase maestro mojado + + hintTextTable[RHT_SPIRIT_TEMPLE_BOSS_KEY] = HintText(CustomMessage("the Spirit Temple Boss Key", /*german*/"der Geistertempel-Master-Schlüssel", /*french*/"la Clé d'Or du Temple de l'Esprit"), + // /*spanish*/la gran llave del Templo del Espíritu + { + CustomMessage("a boss key", /*german*/"ein Master-Schlüssel", /*french*/"une Clé d'Or") + // /*spanish*/una gran llave + }, { + CustomMessage("a sandy master of unlocking", /*german*/"ein sandiger Meister des Entschlüsselns", /*french*/"un anti-grosse porte sableux"), + // /*spanish*/la clave arenoso de un jefe + CustomMessage("a sandy dungeon's master pass", /*german*/"ein sandiger Dungeon-Meisterpass", /*french*/"une clé maléfique sableux")}); + // /*spanish*/el pase maestro arenoso + + hintTextTable[RHT_SHADOW_TEMPLE_BOSS_KEY] = HintText(CustomMessage("the Shadow Temple Boss Key", /*german*/"der Schattentempel-Master-Schlüssel", /*french*/"la Clé d'Or du Temple de l'Ombre"), + // /*spanish*/la gran llave del Templo de las Sombras + { + CustomMessage("a boss key", /*german*/"ein Master-Schlüssel", /*french*/"une Clé d'Or") + // /*spanish*/una gran llave + }, { + CustomMessage("a creepy master of unlocking", /*german*/"ein gruseliger Meister des Entschlüsselns", /*french*/"un anti-grosse porte sinistre"), + // /*spanish*/la clave siniestra de un jefe + CustomMessage("a creepy dungeon's master pass", /*german*/"ein gruseliger Dungeon-Meisterpass", /*french*/"une clé maléfique sinistre")}); + // /*spanish*/el pase maestro siniestra + + hintTextTable[RHT_GANONS_CASTLE_BOSS_KEY] = HintText(CustomMessage("the Ganon's Castle Boss Key", /*german*/"der Master-Schlüssel für Ganons Schloß", /*french*/"la Clé d'Or du Château de Ganon"), + // /*spanish*/la gran llave del Castillo de Ganon + { + CustomMessage("a boss key", /*german*/"ein Master-Schlüssel", /*french*/"une Clé d'Or") + // /*spanish*/una gran llave + }, { + CustomMessage("a final master of unlocking", /*german*/"ein finaler Meister des Entschlüsselns", /*french*/"un anti-grosse porte final"), + // /*spanish*/la clave final de un jefe + CustomMessage("a final dungeon's master pass", /*german*/"ein finaler Dungeon-Meisterpass", /*french*/"une clé maléfique final")}); + // /*spanish*/el pase maestro final + + hintTextTable[RHT_FOREST_TEMPLE_SMALL_KEY] = HintText(CustomMessage("a Forest Temple Small Key", /*german*/"ein kleiner Waldtempel-Schlüssel", /*french*/"une petite clé du Temple de la Forêt"), + // /*spanish*/una llave pequeña del Templo del Bosque + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave pequeña + }, { + CustomMessage("a sylvan tool for unlocking", /*german*/"ein waldiges Werkzeug zur Entschlüsselung", /*french*/"un anti-porte sylvestre"), + // /*spanish*/una clave de una entrada enselvada + CustomMessage("a sylvan dungeon pass", /*german*/"ein waldiger Dungeon-Pass", /*french*/"le rêve sylvestre d'un prisonnier"), + // /*spanish*/un pase de una mazmorra enselvada + CustomMessage("a sylvan lock remover", /*german*/"ein waldiger Schlossentferner", /*french*/"un efface-serrure sylvestre"), + // /*spanish*/un destructor de cerraduras enselvada + CustomMessage("a sylvan lockpick", /*german*/"ein waldiger Dietrich", /*french*/"un crochet à porte sylvestre")}); + // /*spanish*/una apertura portentosa enselvada + + hintTextTable[RHT_FIRE_TEMPLE_SMALL_KEY] = HintText(CustomMessage("a Fire Temple Small Key", /*german*/"ein kleiner Feuertempel-Schlüssel", /*french*/"une petite clé du Temple du Feu"), + // /*spanish*/una llave pequeña del Templo del Fuego + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave pequeña + }, { + CustomMessage("a molten tool for unlocking", /*german*/"ein geschmolzenes Werkzeug zur Entschlüsselung", /*french*/"un anti-porte fondu"), + // /*spanish*/una clave de una entrada fundida + CustomMessage("a molten dungeon pass", /*german*/"ein geschmolzener Dungeon-Pass", /*french*/"le rêve fondu d'un prisonnier"), + // /*spanish*/un pase de una mazmorra fundida + CustomMessage("a molten lock remover", /*german*/"ein geschmolzener Schlossentferner", /*french*/"un efface-serrure fondu"), + // /*spanish*/un destructor de cerraduras fundida + CustomMessage("a molten lockpick", /*german*/"ein geschmolzener Dietrich", /*french*/"un crochet à porte fondu")}); + // /*spanish*/una apertura portentosa fundida + + hintTextTable[RHT_WATER_TEMPLE_SMALL_KEY] = HintText(CustomMessage("a Water Temple Small Key", /*german*/"ein kleiner Wassertempel-Schlüssel", /*french*/"une petite clé du Temple de l'Eau"), + // /*spanish*/una llave pequeña del Templo del Agua + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave pequeña + }, { + CustomMessage("a wet tool for unlocking", /*german*/"ein nasses Werkzeug zur Entschlüsselung", /*french*/"un anti-porte humide"), + // /*spanish*/una clave de una entrada mojada + CustomMessage("a wet dungeon pass", /*german*/"ein nasser Dungeon-Pass", /*french*/"le rêve humide d'un prisonnier"), + // /*spanish*/un pase de una mazmorra mojada + CustomMessage("a wet lock remover", /*german*/"ein nasser Schlossentferner", /*french*/"un efface-serrure humide"), + // /*spanish*/un destructor de cerraduras mojada + CustomMessage("a wet lockpick", /*german*/"ein nasser Dietrich", /*french*/"un crochet à porte humide")}); + // /*spanish*/una apertura portentosa mojada + + hintTextTable[RHT_SPIRIT_TEMPLE_SMALL_KEY] = HintText(CustomMessage("a Spirit Temple Small Key", /*german*/"ein kleiner Geistertempel-Schlüssel", /*french*/"une petite clé du Temple de l'Esprit"), + // /*spanish*/una llave pequeña del Templo del Espíritu + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave pequeña + }, { + CustomMessage("a sandy tool for unlocking", /*german*/"ein sandiges Werkzeug zur Entschlüsselung", /*french*/"un anti-porte sableux"), + // /*spanish*/una clave de una entrada arenosa + CustomMessage("a sandy dungeon pass", /*german*/"ein sandiger Dungeon-Pass", /*french*/"le rêve sableux d'un prisonnier"), + // /*spanish*/un pase de una mazmorra arenosa + CustomMessage("a sandy lock remover", /*german*/"ein sandiger Schlossentferner", /*french*/"un efface-serrure sableux"), + // /*spanish*/un destructor de cerraduras arenosa + CustomMessage("a sandy lockpick", /*german*/"ein sandiger Dietrich", /*french*/"un crochet à porte sableux")}); + // /*spanish*/una apertura portentosa arenosa + + hintTextTable[RHT_SHADOW_TEMPLE_SMALL_KEY] = HintText(CustomMessage("a Shadow Temple Small Key", /*german*/"ein kleiner Schattentempel-Schlüssel", /*french*/"une petite clé du Temple de l'Ombre"), + // /*spanish*/una llave pequeña del Templo de las Sombras + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave pequeña + }, { + CustomMessage("a creepy tool for unlocking", /*german*/"ein gruseliges Werkzeug zur Entschlüsselung", /*french*/"un anti-porte sinistre"), + // /*spanish*/una clave de una entrada siniestra:a + CustomMessage("a creepy dungeon pass", /*german*/"ein gruseliger Dungeon-Pass", /*french*/"le rêve sinistre d'un prisonnier"), + // /*spanish*/un pase de una mazmorra siniestra:a + CustomMessage("a creepy lock remover", /*german*/"ein gruseliger Schlossentferner", /*french*/"un efface-serrure sinistre"), + // /*spanish*/un destructor de cerraduras siniestra:a + CustomMessage("a creepy lockpick", /*german*/"ein gruseliger Dietrich", /*french*/"un crochet à porte sinistre")}); + // /*spanish*/una apertura portentosa siniestra:a + + hintTextTable[RHT_GERUDO_TRAINING_GROUNDS_SMALL_KEY] = HintText(CustomMessage("a Gerudo Training Ground Small Key", /*german*/"ein kleiner Schlüssel des Gerudo-Trainingsgeländes", /*french*/"une petite clé du Gymnase Gerudo"), + // /*spanish*/una llave pequeña del Centro de Instrucción Gerudo + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave pequeña + }, { + CustomMessage("a labyrinthian tool for unlocking", /*german*/"ein labyrinthisches Werkzeug zur Entschlüsselung", /*french*/"un anti-porte labyrinthique"), + // /*spanish*/una clave de una entrada laberíntica + CustomMessage("a labyrinthian dungeon pass", /*german*/"ein labyrinthischer Dungeon-Pass", /*french*/"le rêve labyrinthique d'un prisonnier"), + // /*spanish*/un pase de una mazmorra laberíntica + CustomMessage("a labyrinthian lock remover", /*german*/"ein labyrinthischer Schlossentferner", /*french*/"un efface-serrure labyrinthique"), + // /*spanish*/un destructor de cerraduras laberíntica + CustomMessage("a labyrinthian lockpick", /*german*/"ein labyrinthischer Dietrich", /*french*/"un crochet à porte labyrinthique")}); + // /*spanish*/una apertura portentosa laberíntica + + hintTextTable[RHT_GERUDO_FORTRESS_SMALL_KEY] = HintText(CustomMessage("a Gerudo Fortress Small Key", /*german*/"ein kleiner Schlüssel für die Gerudo-Festung", /*french*/"une petite clé de la Repaire des Voleurs"), + // /*spanish*/una llave pequeña de la Fortaleza Gerudo + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave pequeña + }, { + CustomMessage("an imprisoned tool for unlocking", /*german*/"ein gefangenes Werkzeug zur Entschlüsselung", /*french*/"un anti-porte emprisonné"), + // /*spanish*/una clave de una entrada encarcelada + CustomMessage("an imprisoned dungeon pass", /*german*/"ein gefangener Dungeon-Pass", /*french*/"le rêve emprisonné d'un prisonnier"), + // /*spanish*/un pase de una mazmorra encarcelada + CustomMessage("an imprisoned lock remover", /*german*/"ein gefangener Schlossentferner", /*french*/"un efface-serrure emprisonné"), + // /*spanish*/un destructor de cerraduras encarcelada + CustomMessage("an imprisoned lockpick", /*german*/"ein gefangener Dietrich", /*french*/"un crochet à porte emprisonné")}); + // /*spanish*/una apertura portentosa encarcelada + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_SMALL_KEY] = HintText(CustomMessage("a Bottom of the Well Small Key", /*german*/"ein kleiner Schlüssel des Grund des Brunnens", /*french*/"une petite clé du fond du Puits"), + // /*spanish*/una llave pequeña del Fondo del pozo + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave pequeña + }, { + CustomMessage("a moldy tool for unlocking", /*german*/"ein schimmeliges Werkzeug zur Entschlüsselung", /*french*/"un anti-porte moisi"), + // /*spanish*/una clave de una entrada mohosa + CustomMessage("a moldy dungeon pass", /*german*/"ein schimmeliger Dungeon-Pass", /*french*/"le rêve moisi d'un prisonnier"), + // /*spanish*/un pase de una mazmorra mohosa + CustomMessage("a moldy lock remover", /*german*/"ein schimmeliger Schlossentferner", /*french*/"un efface-serrure moisi"), + // /*spanish*/un destructor de cerraduras mohosa + CustomMessage("a moldy lockpick", /*german*/"ein schimmeliger Dietrich", /*french*/"un crochet à porte moisi")}); + // /*spanish*/una apertura portentosa mohosa + + hintTextTable[RHT_GANONS_CASTLE_SMALL_KEY] = HintText(CustomMessage("a Ganon's Castle Small Key", /*german*/"ein kleiner Schlüssel für Ganons Schloß", /*french*/"une petite clé du Château de Ganon"), + // /*spanish*/una llave pequeña del Castillo de Ganon + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave pequeña + }, { + CustomMessage("a final tool for unlocking", /*german*/"ein finales Werkzeug zur Entschlüsselung", /*french*/"un anti-porte final"), + // /*spanish*/una clave de una entrada final + CustomMessage("a final dungeon pass", /*german*/"ein finaler Dungeon-Pass", /*french*/"le rêve final d'un prisonnier"), + // /*spanish*/un pase de una mazmorra final + CustomMessage("a final lock remover", /*german*/"ein finaler Schlossentferner", /*french*/"un efface-serrure final"), + // /*spanish*/un destructor de cerraduras final + CustomMessage("a final lockpick", /*german*/"ein finaler Dietrich", /*french*/"un crochet à porte final")}); + // /*spanish*/una apertura portentosa final + + hintTextTable[RHT_FOREST_TEMPLE_KEY_RING] = HintText(CustomMessage("a Forest Temple Key Ring", /*german*/"ein Schlüsselbund des Waldtempels", /*french*/"un trousseau de clés du Temple de la Forêt"), + // /*spanish*/un llavero del Templo del Bosque + { + CustomMessage("a key ring", /*german*/"ein Schlüsselbund", /*french*/"un trousseau de clés") + // /*spanish*/un llavero + }, { + CustomMessage("a sylvan toolbox for unlocking", /*german*/"eine waldige Werkzeugkiste zur Entschlüsselung", /*french*/"des anti-portes sylvestres"), + // /*spanish*/un conjunto silvestre de cerrajero + CustomMessage("a sylvan dungeon season pass", /*german*/"ein waldiger Dungeon-Season-Pass", /*french*/"les rêves sylvestres d'un prisonnier"), + // /*spanish*/un pase vip de mazmorras silvestre + CustomMessage("a sylvan jingling ring", /*german*/"ein waldiger Multifunktionsschlüssel", /*french*/"des efface-serrures sylvestres"), + // /*spanish*/una cadena multiusos silvestre + CustomMessage("a sylvan skeleton key", /*german*/"ein waldiger Skelettschlüssel", /*french*/"des crochets à porte sylvestres")}); + // /*spanish*/un anillo silvestre contra cerrojos + + hintTextTable[RHT_FIRE_TEMPLE_KEY_RING] = HintText(CustomMessage("a Fire Temple Key Ring", /*german*/"ein Schlüsselbund des Feuertempels", /*french*/"un trousseau de clés du Temple du Feu"), + // /*spanish*/un llavero del Templo del Fuego + { + CustomMessage("a key ring", /*german*/"ein Schlüsselbund", /*french*/"un trousseau de clés") + // /*spanish*/un llavero + }, { + CustomMessage("a molten toolbox for unlocking", /*german*/"eine geschmolzene Werkzeugkiste zur Entschlüsselung", /*french*/"des anti-portes fondus"), + // /*spanish*/un conjunto fundido de cerrajero + CustomMessage("a molten dungeon season pass", /*german*/"ein geschmolzener Dungeon-Season-Pass", /*french*/"les rêves fondus d'un prisonnier"), + // /*spanish*/un pase vip de mazmorras fundido + CustomMessage("a molten jingling ring", /*german*/"ein geschmolzener Multifunktionsschlüssel", /*french*/"des efface-serrures fondus"), + // /*spanish*/una cadena multiusos fundida + CustomMessage("a molten skeleton key", /*german*/"ein geschmolzener Skelettschlüssel", /*french*/"des crochets à porte fondus")}); + // /*spanish*/un anillo fundido contra cerrojos + + hintTextTable[RHT_WATER_TEMPLE_KEY_RING] = HintText(CustomMessage("a Water Temple Key Ring", /*german*/"ein Schlüsselbund des Wassertempels", /*french*/"un trousseau de clés du Temple de l'Eau"), + // /*spanish*/un llavero del Templo del Agua + { + CustomMessage("a key ring", /*german*/"ein Schlüsselbund", /*french*/"un trousseau de clés") + // /*spanish*/un llavero + }, { + CustomMessage("a wet toolbox for unlocking", /*german*/"eine nasse Werkzeugkiste zur Entschlüsselung", /*french*/"des anti-portes humides"), + // /*spanish*/un conjunto abisal de cerrajero + CustomMessage("a wet dungeon season pass", /*german*/"ein nasser Dungeon-Season-Pass", /*french*/"les rêves humides d'un prisonnier"), + // /*spanish*/un pase vip de mazmorras abisal + CustomMessage("a wet jingling ring", /*german*/"ein nasser Multifunktionsschlüssel", /*french*/"des efface-serrures humides"), + // /*spanish*/una cadena multiusos abisal + CustomMessage("a wet skeleton key", /*german*/"ein nasser Skelettschlüssel", /*french*/"des crochets à porte humides")}); + // /*spanish*/un anillo abisal contra cerrojos + + hintTextTable[RHT_SPIRIT_TEMPLE_KEY_RING] = HintText(CustomMessage("a Spirit Temple Key Ring", /*german*/"ein Schlüsselbund des Geistertempels", /*french*/"un trousseau de clés du Temple de l'Esprit"), + // /*spanish*/un llavero del Templo del Espíritu + { + CustomMessage("a key ring", /*german*/"ein Schlüsselbund", /*french*/"un trousseau de clés") + // /*spanish*/un llavero + }, { + CustomMessage("a sandy toolbox for unlocking", /*german*/"eine sandige Werkzeugkiste zur Entschlüsselung", /*french*/"des anti-portes sableux"), + // /*spanish*/un conjunto arenoso de cerrajero + CustomMessage("a sandy dungeon season pass", /*german*/"ein sandiger Dungeon-Season-Pass", /*french*/"les rêves sableux d'un prisonnier"), + // /*spanish*/un pase vip de mazmorras arenoso + CustomMessage("a sandy jingling ring", /*german*/"ein sandiger Multifunktionsschlüssel", /*french*/"des efface-serrures sableux"), + // /*spanish*/una cadena multiusos arenosa + CustomMessage("a sandy skeleton key", /*german*/"ein sandiger Skelettschlüssel", /*french*/"des crochets à porte sableux")}); + // /*spanish*/un anillo arenoso contra cerrojos + + hintTextTable[RHT_SHADOW_TEMPLE_KEY_RING] = HintText(CustomMessage("a Shadow Temple Key Ring", /*german*/"ein Schlüsselbund des Schattentempels", /*french*/"un trousseau de clés du Temple de l'Ombre"), + // /*spanish*/un llavero del Templo de las Sombras + { + CustomMessage("a key ring", /*german*/"ein Schlüsselbund", /*french*/"un trousseau de clés") + // /*spanish*/un llavero + }, { + CustomMessage("a creepy toolbox for unlocking", /*german*/"eine gruselige Werkzeugkiste zur Entschlüsselung", /*french*/"des anti-portes sinistres"), + // /*spanish*/un conjunto tenebroso de cerrajero + CustomMessage("a creepy dungeon season pass", /*german*/"ein gruseliger Dungeon-Season-Pass", /*french*/"les rêves sinistres d'un prisonnier"), + // /*spanish*/un pase vip de mazmorras tenebroso + CustomMessage("a creepy jingling ring", /*german*/"ein gruseliger Multifunktionsschlüssel", /*french*/"des efface-serrures sinistres"), + // /*spanish*/una cadena multiusos tenebrosa + CustomMessage("a creepy skeleton key", /*german*/"ein gruseliger Skelettschlüssel", /*french*/"des crochets à porte sinistres")}); + // /*spanish*/un anillo tenebroso contra cerrojos + + hintTextTable[RHT_GERUDO_TRAINING_GROUNDS_KEY_RING] = HintText(CustomMessage("a Gerudo Training Ground Key Ring", /*german*/"ein Schlüsselbund des Gerudo-Trainingsgeländes", /*french*/"un trousseau de clés du Gymnase Gerudo"), + // /*spanish*/un llavero del Centro de Instrucción Gerudo + { + CustomMessage("a key ring", /*german*/"ein Schlüsselbund", /*french*/"un trousseau de clés") + // /*spanish*/un llavero + }, { + CustomMessage("a labyrinthian toolbox for unlocking", /*german*/"eine labyrinthische Werkzeugkiste zur Entschlüsselung", /*french*/"des anti-portes labyrinthiques"), + // /*spanish*/un conjunto laberíntico de cerrajero + CustomMessage("a labyrinthian dungeon season pass", /*german*/"ein labyrinthischer Dungeon-Season-Pass", /*french*/"les rêves labyrinthiques d'un prisonnier"), + // /*spanish*/un pase vip de mazmorras laberíntico + CustomMessage("a labyrinthian jingling ring", /*german*/"ein labyrinthischer Multifunktionsschlüssel", /*french*/"des efface-serrures labyrinthiques"), + // /*spanish*/una cadena multiusos laberíntica + CustomMessage("a labyrinthian skeleton key", /*german*/"ein labyrinthischer Skelettschlüssel", /*french*/"des crochets à porte labyrinthiques")}); + // /*spanish*/un anillo laberíntico contra cerrojos + + hintTextTable[RHT_GERUDO_FORTRESS_KEY_RING] = HintText(CustomMessage("a Gerudo Fortress Key Ring", /*german*/"ein Schlüsselbund der Gerudo-Festung", /*french*/"un trousseau de clés de la Repaire des Voleurs"), + // /*spanish*/un llavero de la Fortaleza Gerudo + { + CustomMessage("a key ring", /*german*/"ein Schlüsselbund", /*french*/"un trousseau de clés") + // /*spanish*/un llavero + }, { + CustomMessage("an imprisoned toolbox for unlocking", /*german*/"eine gefangene Werkzeugkiste zur Entschlüsselung", /*french*/"des anti-portes emprisonnés"), + // /*spanish*/un conjunto enjaulado de cerrajero + CustomMessage("an imprisoned dungeon season pass", /*german*/"ein gefangener Dungeon-Season-Pass", /*french*/"les rêves emprisonnés d'un prisonnier"), + // /*spanish*/un pase vip de una mazmorra enjaulado + CustomMessage("an imprisoned jingling ring", /*german*/"ein gefangener Multifunktionsschlüssel", /*french*/"des efface-serrures emprisonnés"), + // /*spanish*/una cadena multiusos enjaulada + CustomMessage("an imprisoned skeleton key", /*german*/"ein gefangener Skelettschlüssel", /*french*/"des crochets à porte emprisonnés")}); + // /*spanish*/un anillo enjaulado contra cerrojos + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_KEY_RING] = HintText(CustomMessage("a Bottom of the Well Key Ring", /*german*/"ein Schlüsselbund des Grund des Brunnens", /*french*/"un trousseau de clés du fond du Puits"), + // /*spanish*/un llavero del Fondo del pozo + { + CustomMessage("a key ring", /*german*/"ein Schlüsselbund", /*french*/"un trousseau de clés") + // /*spanish*/un llavero + }, { + CustomMessage("a moldy toolbox for unlocking", /*german*/"eine schimmelige Werkzeugkiste zur Entschlüsselung", /*french*/"des anti-portes moisis"), + // /*spanish*/un conjunto subterráneo de cerrajero + CustomMessage("a moldy dungeon season pass", /*german*/"ein schimmeliger Dungeon-Season-Pass", /*french*/"les rêves moisis d'un prisonnier"), + // /*spanish*/un pase vip de una mazmorra subterráneo + CustomMessage("a moldy jingling ring", /*german*/"ein schimmeliger Multifunktionsschlüssel", /*french*/"des efface-serrures moisis"), + // /*spanish*/una cadena multiusos subterránea + CustomMessage("a moldy skeleton key", /*german*/"ein schimmeliger Skelettschlüssel", /*french*/"des crochets à porte moisis")}); + // /*spanish*/un anillo subterráneo contra cerrojos + + hintTextTable[RHT_GANONS_CASTLE_KEY_RING] = HintText(CustomMessage("a Ganon's Castle Key Ring", /*german*/"ein Schlüsselbund von Ganons Schloß", /*french*/"un trousseau de clés du Château de Ganon"), + // /*spanish*/un llavero del Castillo de Ganon + { + CustomMessage("a key ring", /*german*/"ein Schlüsselbund", /*french*/"un trousseau de clés") + // /*spanish*/un llavero + }, { + CustomMessage("a final toolbox for unlocking", /*german*/"eine finale Werkzeugkiste zur Entschlüsselung", /*french*/"des anti-portes finaux"), + // /*spanish*/un conjunto decisivo de cerrajero + CustomMessage("a final dungeon season pass", /*german*/"ein finaler Dungeon-Season-Pass", /*french*/"les rêves finaux d'un prisonnier"), + // /*spanish*/un pase vip de una mazmorra decisivo + CustomMessage("a final jingling ring", /*german*/"ein finaler Multifunktionsschlüssel", /*french*/"des efface-serrures finaux"), + // /*spanish*/una cadena multiusos decisiva + CustomMessage("a final skeleton key", /*german*/"ein finaler Skelettschlüssel", /*french*/"des crochets à porte finaux")}); + // /*spanish*/un anillo decisivo multiusos + + hintTextTable[RHT_TREASURE_GAME_SMALL_KEY] = HintText(CustomMessage("a Treasure Chest Shop Small Key", /*german*/"ein kleiner Schlüssel des Schatztruhenladens", /*french*/"une petite clé de la chasse aux trésors"), + // /*spanish*/una llave pequeña del Cofre del Tesoro + { + CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé") + // /*spanish*/una llave pequeña + }, { + CustomMessage("a gambler's tool for unlocking", /*german*/"ein Spieler-Werkzeug zur Entschlüsselung", /*french*/"un anti-porte de parieur"), + // /*spanish*/una clave de un juego de azar + CustomMessage("a gambler's dungeon pass", /*german*/"ein Spieler-Dungeon-Pass", /*french*/"le rêve d'un prisonnier parieur"), + // /*spanish*/un pase de un juego de azar + CustomMessage("a gambler's lock remover", /*german*/"ein Spieler-Schlossentferner", /*french*/"un efface-serrure de parieur"), + // /*spanish*/un destructor de cerraduras del juego de azar + CustomMessage("a gambler's lockpick", /*german*/"ein Spieler-Dietrich", /*french*/"un crochet à serrure de parieur")}); + // /*spanish*/una apertura portentosa del juego de azar + + hintTextTable[RHT_KOKIRI_EMERALD] = HintText(CustomMessage("the Kokiri Emerald", /*german*/"der Kokiri-Smaragd", /*french*/"l'Émeraude Kokiri"), + // /*spanish*/la Esmeralda de los Kokiri + { + CustomMessage("a spiritual stone", /*german*/"ein spiritueller Stein", /*french*/"une Pierre Ancestrale") + // /*spanish*/una piedra espiritual + }, { + CustomMessage("a green stone", /*german*/"ein grüner Stein", /*french*/"une pierre verte"), + // /*spanish*/una piedra verde + CustomMessage("a gift before death", /*german*/"ein Geschenk vor dem Tod", /*french*/"le dernier souffle d'un arbre")}); + // /*spanish*/un obsequio testamentario + + hintTextTable[RHT_GORON_RUBY] = HintText(CustomMessage("the Goron Ruby", /*german*/"der Goronen-Rubin", /*french*/"le Rubis Goron"), + // /*spanish*/el Rubí de los Goron + { + CustomMessage("a spiritual stone", /*german*/"ein spiritueller Stein", /*french*/"une Pierre Ancestrale") + // /*spanish*/una piedra espiritual + }, { + CustomMessage("a red stone", /*german*/"ein roter Stein", /*french*/"une pierre rouge"), + // /*spanish*/una piedra carmín + CustomMessage("sworn brotherhood", /*german*/"verschworene Bruderschaft", /*french*/"un serment de fraternité")}); + // /*spanish*/el juramento de hermanos de sangre + + hintTextTable[RHT_ZORA_SAPPHIRE] = HintText(CustomMessage("the Zora Sapphire", /*german*/"der Zora-Saphir", /*french*/"le Saphir Zora"), + // /*spanish*/el Zafiro de los Zora + { + CustomMessage("a spiritual stone", /*german*/"ein spiritueller Stein", /*french*/"une Pierre Ancestrale") + // /*spanish*/una piedra espiritual + }, { + CustomMessage("a blue stone", /*german*/"ein blauer Stein", /*french*/"une pierre bleue"), + // /*spanish*/una piedra celeste + CustomMessage("an engagement gift", /*german*/"ein Verlobungsgeschenk", /*french*/"un cadeau de mariage")}); + // /*spanish*/un regalo de compromiso + + hintTextTable[RHT_FOREST_MEDALLION] = HintText(CustomMessage("the Forest Medallion", /*german*/"Amulett des Waldes", /*french*/"le Médaillon de la Forêt"), + // /*spanish*/el Medallón del Bosque + { + CustomMessage("a medallion", /*german*/"ein Amulett", /*french*/"un médaillon") + // /*spanish*/un medallón + }, { + CustomMessage("a green coin", /*german*/"eine grüne Münze", /*french*/"une pièce verte"), + // /*spanish*/una moneda esmeralda + CustomMessage("Saria's friendship", /*german*/"Salias Freundschaft", /*french*/"l'amitié de Saria")}); + // /*spanish*/la amistad de Saria + + hintTextTable[RHT_FIRE_MEDALLION] = HintText(CustomMessage("the Fire Medallion", /*german*/"Amulett des Feuers", /*french*/"le Médaillon du Feu"), + // /*spanish*/el Medallón del Fuego + { + CustomMessage("a medallion", /*german*/"ein Amulett", /*french*/"un médaillon") + // /*spanish*/un medallón + }, { + CustomMessage("a red coin", /*german*/"eine rote Münze", /*french*/"une pièce rouge"), + // /*spanish*/una moneda rubí + CustomMessage("Darunia's power", /*german*/"Darunias Kraft", /*french*/"la fraternité de Darunia")}); + // /*spanish*/la fraternidad de Darunia + + hintTextTable[RHT_WATER_MEDALLION] = HintText(CustomMessage("the Water Medallion", /*german*/"Amulett des Wassers", /*french*/"le Médaillon de l'Eau"), + // /*spanish*/el Medallón del Agua + { + CustomMessage("a medallion", /*german*/"ein Amulett", /*french*/"un médaillon") + // /*spanish*/un medallón + }, { + CustomMessage("a blue coin", /*german*/"eine blaue Münze", /*french*/"une pièce bleue"), + // /*spanish*/una moneda zafiro + CustomMessage("Ruto's power", /*german*/"Rutos Macht", /*french*/"l'amour de Ruto")}); + // /*spanish*/el amor de Ruto + + hintTextTable[RHT_SPIRIT_MEDALLION] = HintText(CustomMessage("the Spirit Medallion", /*german*/"Amulett der Geister", /*french*/"le Médaillon de l'Esprit"), + // /*spanish*/el Medallón del Espíritu + { + CustomMessage("a medallion", /*german*/"ein Amulett", /*french*/"un médaillon") + // /*spanish*/un medallón + }, { + CustomMessage("an orange coin", /*german*/"eine orange Münze", /*french*/"une pièce orange"), + // /*spanish*/una moneda ámbar + CustomMessage("Nabooru's power", /*german*/"Naborus Macht", /*french*/"le respect de Nabooru")}); + // /*spanish*/el respeto de Nabooru + + hintTextTable[RHT_SHADOW_MEDALLION] = HintText(CustomMessage("the Shadow Medallion", /*german*/"Amulett des Schattens", /*french*/"le Médaillon de l'Ombre"), + // /*spanish*/el Medallón de la Sombra + { + CustomMessage("a medallion", /*german*/"ein Amulett", /*french*/"un médaillon") + // /*spanish*/un medallón + }, { + CustomMessage("a purple coin", /*german*/"eine violette Münze", /*french*/"une pièce pourpre"), + // /*spanish*/una moneda malva + CustomMessage("Impa's power", /*german*/"Impas Macht", /*french*/"la confiance d'Impa")}); + // /*spanish*/la confianza de Impa + + hintTextTable[RHT_LIGHT_MEDALLION] = HintText(CustomMessage("the Light Medallion", /*german*/"Amulett des Lichts", /*french*/"le Médaillon de la Lumière"), + // /*spanish*/el Medallón de la Luz + { + CustomMessage("a medallion", /*german*/"ein Amulett", /*french*/"un médaillon") + // /*spanish*/un medallón + }, { + CustomMessage("a yellow coin", /*german*/"eine gelbe Münze", /*french*/"une pièce jaune"), + // /*spanish*/una moneda resplandeciente + CustomMessage("Rauru's power", /*german*/"Raurus Macht", /*french*/"la foi de Rauru")}); + // /*spanish*/la fe de Rauru + + hintTextTable[RHT_RECOVERY_HEART] = HintText(CustomMessage("a Recovery Heart", /*german*/"ein Herz", /*french*/"un coeur de vie"), + // /*spanish*/un corazón + { + CustomMessage("something heart-shaped", /*german*/"etwas Herzförmiges", /*french*/"une chose en forme de coeur") + // /*spanish*/algo con forma de corazón + }, { + CustomMessage("a free heal", /*german*/"eine kostenlose Heilung", /*french*/"un bec-au-bobo"), + // /*spanish*/una cura de regalo + CustomMessage("a hearty meal", /*german*/"ein herzhaftes Mahl", /*french*/"un petit amour"), + // /*spanish*/una sanación romántica + CustomMessage("a Band-Aid", /*german*/"ein Wundpflaster", /*french*/"un diachylon")}); + // /*spanish*/un corazoncito sanador + + hintTextTable[RHT_GREEN_RUPEE] = HintText(CustomMessage("a Green Rupee", /*german*/"ein grüner Rubin", /*french*/"un rubis vert"), + // /*spanish*/una rupia verde + { + CustomMessage("some rupees", /*german*/"einige Rubine", /*french*/"une quantité de rubis") + // /*spanish*/una cantidad de rupias + }, { + CustomMessage("a unique coin", /*german*/"eine einzigartige Münze", /*french*/"un rubis bien mérité"), + // /*spanish*/una singular moneda + CustomMessage("a penny", /*german*/"ein Pfennig", /*french*/"un sou"), + // /*spanish*/un peso hyliano + CustomMessage("a green gem", /*german*/"ein grüner Edelstein", /*french*/"un joyau vert")}); + // /*spanish*/una gema verde + + hintTextTable[RHT_GREG_RUPEE] = HintText(CustomMessage("Greg", /*german*/"Greg", /*french*/"Greg"), + // /*spanish*/Greg + { + CustomMessage("a Green Rupee", /*german*/"ein grüner Rubin", /*french*/"un rubis vert") + // /*spanish*/una rupia verde + }, { + CustomMessage("an old friend", /*german*/"ein alter Freund", /*french*/"Greg"), + // /*spanish*/Greg + CustomMessage("a glorious gem", /*german*/"ein glorioser Edelstein", /*french*/"Greg")}); + // /*spanish*/Greg + + hintTextTable[RHT_BLUE_RUPEE] = HintText(CustomMessage("a Blue Rupee", /*german*/"ein blauer Rubin", /*french*/"un rubis bleu"), + // /*spanish*/una rupia azul + { + CustomMessage("some rupees", /*german*/"einige Rubine", /*french*/"une quantité de rubis") + // /*spanish*/una cantidad de rupias + }, { + CustomMessage("a common coin", /*german*/"eine gewöhnliche Münze", /*french*/"quelques sous"), + // /*spanish*/una moneda usual + CustomMessage("a blue gem", /*german*/"ein blauer Edelstein", /*french*/"un joyau bleu")}); + // /*spanish*/una gema azul + + hintTextTable[RHT_RED_RUPEE] = HintText(CustomMessage("a Red Rupee", /*german*/"ein roter Rubin", /*french*/"un rubis rouge"), + // /*spanish*/una rupia roja + { + CustomMessage("some rupees", /*german*/"einige Rubine", /*french*/"une quantité de rubis") + // /*spanish*/una cantidad de rupias + }, { + CustomMessage("couch cash", /*german*/"ein wenig Zaster", /*french*/"un peu de fric"), + // /*spanish*/una buena moneda + CustomMessage("a red gem", /*german*/"ein roter Edelstein", /*french*/"un joyau rouge")}); + // /*spanish*/una gema roja + + hintTextTable[RHT_PURPLE_RUPEE] = HintText(CustomMessage("a Purple Rupee", /*german*/"ein violetter Rubin", /*french*/"un rubis pourpre"), + // /*spanish*/una rupia morada + { + CustomMessage("some rupees", /*german*/"einige Rubine", /*french*/"une quantité de rubis") + // /*spanish*/una cantidad de rupias + }, { + CustomMessage("big bucks", /*german*/"ordentlich Zaster", /*french*/"plein de fric"), + // /*spanish*/plata de calidad + CustomMessage("a purple gem", /*german*/"ein violetter Edelstein", /*french*/"un joyau mauve"), + // /*spanish*/una gema morada + CustomMessage("wealth", /*german*/"Wohlstand", /*french*/"la richesse")}); + // /*spanish*/una buena riqueza + + hintTextTable[RHT_HUGE_RUPEE] = HintText(CustomMessage("a Huge Rupee", /*german*/"ein riesiger Rubin", /*french*/"un énorme rubis"), + // /*spanish*/una rupia gigante + { + CustomMessage("some rupees", /*german*/"einige Rubine", /*french*/"une quantité de rubis") + // /*spanish*/una cantidad de rupias + }, { + CustomMessage("a juicy jackpot", /*german*/"ein saftiger Jackpot", /*french*/"le jackpot"), + // /*spanish*/el premio gordo + CustomMessage("a yellow gem", /*german*/"ein gelber Edelstein", /*french*/"un joyau doré"), + // /*spanish*/una gema amarilla + CustomMessage("a giant gem", /*german*/"ein riesiger Edelstein", /*french*/"un gros joyau"), + // /*spanish*/una gema descomunal + CustomMessage("great wealth", /*german*/"großer Wohlstand", /*french*/"l'aisance financière")}); + // /*spanish*/dinero a caudales + + hintTextTable[RHT_PIECE_OF_HEART] = HintText(CustomMessage("a Piece of Heart", /*german*/"ein Herzteil", /*french*/"un Quart de Coeur"), + // /*spanish*/una pieza de corazón + { + CustomMessage("something heart-shaped", /*german*/"etwas Herzförmiges", /*french*/"une chose en forme de coeur") + // /*spanish*/algo con forma de corazón + }, { + CustomMessage("a little love", /*german*/"ein wenig Liebe", /*french*/"un peu plus d'amour"), + // /*spanish*/un cuarto de amor + CustomMessage("a broken heart", /*german*/"ein gebrochenes Herz", /*french*/"un coeur brisé")}); + // /*spanish*/un corazón roto + + hintTextTable[RHT_HEART_CONTAINER] = HintText(CustomMessage("a Heart Container", /*german*/"ein Herzcontainer", /*french*/"un Réceptacle de Coeur"), + // /*spanish*/un contenedor de corazón + { + CustomMessage("something heart-shaped", /*german*/"etwas Herzförmiges", /*french*/"une chose en forme de coeur") + // /*spanish*/algo con forma de corazón + }, { + CustomMessage("a lot of love", /*german*/"eine Menge Liebe", /*french*/"le grand amour"), + // /*spanish*/amor por doquier + CustomMessage("a Valentine's gift", /*german*/"ein Valentinsgeschenk", /*french*/"un cadeau de Saint-Valentin"), + // /*spanish*/un contenedor de afección + CustomMessage("a boss's organ", /*german*/"ein monströses Organ", /*french*/"un organe de monstre")}); + // /*spanish*/los órganos de un jefe + + hintTextTable[RHT_ICE_TRAP] = HintText(CustomMessage("an Ice Trap", /*german*/"eine Eisfalle", /*french*/"un Piège de Glace"), + // /*spanish*/una trampa de hielo + { + CustomMessage("a Great Fairy's power", /*german*/"eine Kraft einer großen Fee", /*french*/"le pouvoir d'une grande fée"), + // /*spanish*/el poder de una Gran Hada + CustomMessage("a magic arrow", /*german*/"ein magischer Pfeil", /*french*/"une flèche magique"), + // /*spanish*/una flecha mágica + CustomMessage("a medallion", /*german*/"ein Amulett", /*french*/"un médaillon"), + // /*spanish*/un medallón + CustomMessage("a spiritual stone", /*german*/"ein spiritueller Stein", /*french*/"une Pierre Ancestrale"), + // /*spanish*/una piedra espiritual + CustomMessage("something that can stun", /*german*/"etwas, das paralysieren kann", /*french*/"une chose qui peut paralyser") + // /*spanish*/algo que pueda paralizar + }, { + CustomMessage("a gift from Ganon", /*german*/"ein Geschenk von Ganon", /*french*/"un cadeau de Ganon"), + // /*spanish*/un regalo de Ganon + CustomMessage("a chilling discovery", /*german*/"eine fröstelnde Entdeckung", /*french*/"une frissonante découverte"), + // /*spanish*/un escalofriante hallazgo + CustomMessage("frosty fun", /*german*/"frostiger Spaß", /*french*/"une engelure")}); + // /*spanish*/una gélida diversión + + hintTextTable[RHT_BOMBS_5] = HintText(CustomMessage("Bombs (5 pieces)", /*german*/"Bomben (5 Stück)", /*french*/"une demi-dizaine de bombes"), + // /*spanish*/unas (5) bombas + { + CustomMessage("explosives", /*german*/"Explosivpakete", /*french*/"un paquet d'explosifs") + // /*spanish*/un montón de explosivos + }, { + CustomMessage("a few explosives", /*german*/"ein paar Explosivbehälter", /*french*/"une poignée de pétards"), + // /*spanish*/un par de explosivos + CustomMessage("a few blast balls", /*german*/"ein paar Explosionsbälle", /*french*/"une poignée de boules bleues")}); + // /*spanish*/un par de estallidos + + hintTextTable[RHT_BOMBS_10] = HintText(CustomMessage("Bombs (10 pieces)", /*german*/"Bomben (10 Stück)", /*french*/"une dizaine de bombes"), + // /*spanish*/unas (10) bombas + { + CustomMessage("explosives", /*german*/"Explosivpakete", /*french*/"un paquet d'explosifs") + // /*spanish*/un montón de explosivos + }, { + CustomMessage("some explosives", /*german*/"einige Explosivbehälter", /*french*/"un paquet de pétards"), + // /*spanish*/unos cuantos explosivos + CustomMessage("some blast balls", /*german*/"einige Explosionsbälle", /*french*/"un paquet de boules bleues")}); + // /*spanish*/unos cuantos estallidos + + hintTextTable[RHT_BOMBS_20] = HintText(CustomMessage("Bombs (20 pieces)", /*german*/"Bomben (20 Stück)", /*french*/"une vingtaine de bombes"), + // /*spanish*/unas (20) bombas + { + CustomMessage("explosives", /*german*/"Explosivpakete", /*french*/"un paquet d'explosifs") + // /*spanish*/un montón de explosivos + }, { + CustomMessage("lots-o-explosives", /*german*/"viele Explosivbehälter", /*french*/"une abondance de pétards"), + // /*spanish*/un puñado de explosivos + CustomMessage("plenty of blast balls", /*german*/"viele Explosionsbälle", /*french*/"une abondance de boules bleues")}); + // /*spanish*/bastantes estallidos + + hintTextTable[RHT_BOMBCHUS_5] = HintText(CustomMessage("Bombchus (5 pieces)", /*german*/"Krabbelminen (5 Stück)", /*french*/"une demi-dizaine de Missiles"), + // /*spanish*/unos (5) bombchus + { + CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"), + // /*spanish*/un obsequio de la Casa Skulltula + CustomMessage("explosives", /*german*/"Explosivpakete", /*french*/"un paquet d'explosifs") + // /*spanish*/un montón de explosivos + }, { + CustomMessage("a few mice bombs", /*german*/"ein paar Mäusebomben", /*french*/"une poignée de mignons explosifs"), + // /*spanish*/un par de bombas roedoras + CustomMessage("a few proximity mice", /*german*/"ein paar Näherungsmäuse", /*french*/"une poignée de jouets à remonter"), + // /*spanish*/un par de explosivos ratoncitos + CustomMessage("a few wall crawlers", /*german*/"ein paar Wandkrabbler", /*french*/"une poignée de rapides grimpeurs"), + // /*spanish*/un par de trepaparedes + CustomMessage("a few trail blazers", /*german*/"ein paar Vorreiter", /*french*/"une poignée de zigzags éclatants")}); + // /*spanish*/un par de ratas propulsadas + + hintTextTable[RHT_BOMBCHUS_10] = HintText(CustomMessage("Bombchus (10 pieces)", /*german*/"Krabbelminen (10 Stück)", /*french*/"une dizaine de Missiles"), + // /*spanish*/unos (10) bombchus + { + CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"), + // /*spanish*/un obsequio de la Casa Skulltula + CustomMessage("explosives", /*german*/"Explosivpakete", /*french*/"un paquet d'explosifs") + // /*spanish*/un montón de explosivos + }, { + CustomMessage("some mice bombs", /*german*/"einige Mäusebomben", /*french*/"un paquet de mignons explosifs"), + // /*spanish*/unas cuantas bombas roedoras + CustomMessage("some proximity mice", /*german*/"einige Näherungsmäuse", /*french*/"un paquet de jouets à remonter"), + // /*spanish*/unos cuantos explosivos ratoncitos + CustomMessage("some wall crawlers", /*german*/"einige Wandkrabbler", /*french*/"un paquet de rapides grimpeurs"), + // /*spanish*/unos cuantos trepaparedes + CustomMessage("some trail blazers", /*german*/"einige Vorreiter", /*french*/"un paquet de zigzags éclatants")}); + // /*spanish*/unas cuantas ratas propulsadas + + hintTextTable[RHT_BOMBCHUS_20] = HintText(CustomMessage("Bombchus (20 pieces)", /*german*/"Krabbelminen (20 Stück)", /*french*/"une vingtaine de Missiles"), + // /*spanish*/unos (20) bombchus + { + CustomMessage("a prize of the House of Skulltulas", /*german*/"ein Preis des Skulltula-Hauses", /*french*/"un prix de la maison des Skulltulas"), + // /*spanish*/un obsequio de la Casa Skulltula + CustomMessage("explosives", /*german*/"Explosivpakete", /*french*/"un paquet d'explosifs") + // /*spanish*/un montón de explosivos + }, { + CustomMessage("plenty of mice bombs", /*german*/"viele Mäusebomben", /*french*/"une abondance de mignons explosifs"), + // /*spanish*/bastantes bombas roedoras + CustomMessage("plenty of proximity mice", /*german*/"viele Näherungsmäuse", /*french*/"une abondance de jouets à remonter"), + // /*spanish*/bastantes explosivos ratoncitos + CustomMessage("plenty of wall crawlers", /*german*/"viele Wandkrabbler", /*french*/"une abondance de rapides grimpeurs"), + // /*spanish*/bastantes trepaparedes + CustomMessage("plenty of trail blazers", /*german*/"viele Vorreiter", /*french*/"une abondance de zigzags éclatants")}); + // /*spanish*/bastantes ratas propulsadas + + hintTextTable[RHT_ARROWS_5] = HintText(CustomMessage("Arrows (5 pieces)", /*german*/"Pfeile (5 Stück)", /*french*/"une demi-dizaine de flèches"), + // /*spanish*/unas (5) flechas + { + CustomMessage("a projectile", /*german*/"ein Projektil", /*french*/"un projectile") + // /*spanish*/un proyectil + }, { + CustomMessage("a few danger darts", /*german*/"ein paar gefährliche Spitzen", /*french*/"une poignée d'obus"), + // /*spanish*/un par de peligrosos dardos + CustomMessage("a few sharp shafts", /*german*/"ein paar scharfe Stifte", /*french*/"une poignée de piquets")}); + // /*spanish*/un par de puntas afiladas + + hintTextTable[RHT_ARROWS_10] = HintText(CustomMessage("Arrows (10 pieces)", /*german*/"Pfeile (10 Stück)", /*french*/"une dizaine de flèches"), + // /*spanish*/unas (10) flechas + { + CustomMessage("a projectile", /*german*/"ein Projektil", /*french*/"un projectile") + // /*spanish*/un proyectil + }, { + CustomMessage("some danger darts", /*german*/"einige gefährliche Spitzen", /*french*/"un paquet d'obus"), + // /*spanish*/unos cuantos peligrosos dardos + CustomMessage("some sharp shafts", /*german*/"einige scharfe Stifte", /*french*/"un paquet de piquets")}); + // /*spanish*/unas cuantas puntas afiladas + + hintTextTable[RHT_ARROWS_30] = HintText(CustomMessage("Arrows (30 pieces)", /*german*/"Pfeile (30 Stück)", /*french*/"une trentaine de flèches"), + // /*spanish*/unas (30) flechas + { + CustomMessage("a projectile", /*german*/"ein Projektil", /*french*/"un projectile") + // /*spanish*/un proyectil + }, { + CustomMessage("plenty of danger darts", /*german*/"viele gefährliche Spitzen", /*french*/"une abondance d'obus"), + // /*spanish*/bastantes peligrosos dardos + CustomMessage("plenty of sharp shafts", /*german*/"viele scharfe Stifte", /*french*/"une abondance de piquets")}); + // /*spanish*/bastantes puntas afiladas + + hintTextTable[RHT_DEKU_NUTS_5] = HintText(CustomMessage("Deku Nuts (5 pieces)", /*german*/"Deku-Nüsse (5 Stück)", /*french*/"une demi-dizaine de noix Mojo"), + // /*spanish*/unas (5) nueces deku + { + CustomMessage("some Deku munitions", /*german*/"ein wenig Deku-Munition", /*french*/"un paquet de munitions Mojo"), + // /*spanish*/un montón de municiones Deku + CustomMessage("something that can stun", /*german*/"etwas, das paralysieren kann", /*french*/"une chose qui peut paralyser") + // /*spanish*/algo que pueda paralizar + }, { + CustomMessage("some nuts", /*german*/"ein paar Nüsse", /*french*/"une poignée de noisettes"), + // /*spanish*/un par de nueces + CustomMessage("some flashbangs", /*german*/"ein paar Blendgranaten", /*french*/"une poignée d'éclats"), + // /*spanish*/un par de semillas aturdidoras + CustomMessage("some scrub spit", /*german*/"ein wenig Buschspucke", /*french*/"une poignée de crachats Mojo")}); + // /*spanish*/un par de escupitajos deku + + hintTextTable[RHT_DEKU_NUTS_10] = HintText(CustomMessage("Deku Nuts (10 pieces)", /*german*/"Deku-Nüsse (10 Stück)", /*french*/"une dizaine de noix Mojo"), + // /*spanish*/unas (10) nueces deku + { + CustomMessage("some Deku munitions", /*german*/"etwas Deku-Munition", /*french*/"un paquet de munitions Mojo"), + // /*spanish*/un montón de municiones Deku + CustomMessage("something that can stun", /*german*/"etwas, das paralysieren kann", /*french*/"une chose qui peut paralyser") + // /*spanish*/algo que pueda paralizar + }, { + CustomMessage("lots-o-nuts", /*german*/"einige Nüsse", /*french*/"un paquet de noisettes"), + // /*spanish*/un puñado de nueces + CustomMessage("plenty of flashbangs", /*german*/"einige Blendgranaten", /*french*/"un paquet d'éclats"), + // /*spanish*/unas cuantas semillas aturdidoras + CustomMessage("plenty of scrub spit", /*german*/"einige Buschspucke", /*french*/"un paquet de crachats Mojo")}); + // /*spanish*/unos cuantos escupitajos deku + + hintTextTable[RHT_DEKU_SEEDS_30] = HintText(CustomMessage("Deku Seeds (30 pieces)", /*german*/"Deku-Samen (30 Stück)", /*french*/"une trentaine de graines Mojo"), + // /*spanish*/unas (30) semillas deku + { + CustomMessage("a projectile", /*german*/"ein Projektil", /*french*/"un projectile"), + // /*spanish*/un proyectil + CustomMessage("some Deku munitions", /*german*/"viel Deku-Munition", /*french*/"un paquet de munitions Mojo") + // /*spanish*/un montón de municiones Deku + }, { + CustomMessage("catapult ammo", /*german*/"Katapultmunition", /*french*/"un paquet de délicieuses munitions"), + // /*spanish*/un par de munición infantil + CustomMessage("lots-o-seeds", /*german*/"viele Samen", /*french*/"un paquet de germes séchés")}); + // /*spanish*/un puñado de semillas + + hintTextTable[RHT_DEKU_STICK_1] = HintText(CustomMessage("a Deku Stick", /*german*/"ein Deku-Stab", /*french*/"un bâton Mojo"), + // /*spanish*/un palo deku + { + CustomMessage("some Deku munitions", /*german*/"ein wenig Deku-Munition", /*french*/"un paquet de munitions Mojo") + // /*spanish*/un montón de municiones Deku + }, { + CustomMessage("a breakable branch", /*german*/"ein brüchiger Zweig", /*french*/"un bout de bois")}); + // /*spanish*/un pequeño báculo + + hintTextTable[RHT_TREASURE_GAME_HEART] = HintText(CustomMessage("a Piece of Heart", /*german*/"ein Herzteil", /*french*/"un Quart de Coeur"), + // /*spanish*/el amor de la victoria + { + CustomMessage("something heart-shaped", /*german*/"etwas Herzförmiges", /*french*/"une chose en forme de coeur") + // /*spanish*/algo con forma de corazón + }, { + CustomMessage("a victory valentine", /*german*/"ein siegreicher Valentin", /*french*/"un amour gagnant")}); + // /*spanish*/el amor victorioso + + hintTextTable[RHT_TREASURE_GAME_GREEN_RUPEE] = HintText(CustomMessage("a Green Rupee", /*german*/"ein grüner Rubin", /*french*/"un rubis vert"), + // /*spanish*/una rupia verde + { + CustomMessage("some rupees", /*german*/"einige Rubine", /*french*/"une quantité de rubis") + // /*spanish*/una cantidad de rupias + }, { + CustomMessage("the dollar of defeat", /*german*/"der Rubin der Niederlage", /*french*/"le rubis de la défaite")}); + // /*spanish*/el peso de la derrota + + hintTextTable[RHT_TRIFORCE_PIECE] = HintText(CustomMessage("a Piece of the Triforce", /*german*/"ein Triforce-Fragment", /*french*/"un fragment de la Triforce"), + // /*spanish*/un fragmento de la Trifuerza + {}, { + CustomMessage("a triumph fork", /*german*/"ein Dreieck des Triumphs", /*french*/"la Tribosse"), + // /*spanish*/un trígono del triunfo + CustomMessage("cheese", /*german*/"Käse", /*french*/"du fromage"), + // /*spanish*/un porción de queso + CustomMessage("a gold fragment", /*german*/"ein goldenes Fragment", /*french*/"un fragment d'or")}); + // /*spanish*/un fragmento dorado + + hintTextTable[RHT_GOHMA_SOUL] = HintText(CustomMessage("the soul of Gohma", /*german*/"die Seele Gohmas", /*french*/""), + { + CustomMessage("something webbed", /*german*/"etwas Verwobenes", /*french*/"") + }, { + CustomMessage("an invasive soul", /*german*/"eine invasive Seele", /*french*/""), + CustomMessage("some spider essence", /*german*/"etwas spinnenartige Essenz", /*french*/"")}); + + hintTextTable[RHT_KING_DODONGO_SOUL] = HintText(CustomMessage("the soul of King Dodongo", /*german*/"die Seele König Dodongos", /*french*/""), + { + CustomMessage("something explosive", /*german*/"etwas Explosives", /*french*/"") + }, { + CustomMessage("a royal soul", /*german*/"eine royale Seele", /*french*/""), + CustomMessage("some reptile essence", /*german*/"etwas reptilienartige Essenz", /*french*/"")}); + + hintTextTable[RHT_BARINADE_SOUL] = HintText(CustomMessage("the soul of Barinade", /*german*/"die Seele Barinades", /*french*/""), + { + CustomMessage("something fishy", /*german*/"etwas Fischiges", /*french*/"") + }, { + CustomMessage("an infectuous soul", /*german*/"eine infektiöse Seele", /*french*/""), + CustomMessage("some parasitic essence", /*german*/"etwas parasitäre Essenz", /*french*/"")}); + + hintTextTable[RHT_PHANTOM_GANON_SOUL] = HintText(CustomMessage("the soul of Phantom Ganon", /*german*/"die Seele Phantom-Ganons", /*french*/""), + { + CustomMessage("something spectral", /*german*/"etwas Spektrales", /*french*/"") + }, { + CustomMessage("a duplicate soul", /*german*/"eine duplizierte Seele", /*french*/""), + + CustomMessage("some illusionary essence", /*german*/"etwas illusionäre Essenz", /*french*/"")}); + + hintTextTable[RHT_VOLVAGIA_SOUL] = HintText(CustomMessage("the soul of Volvagia", /*german*/"die Seele Volvagias", /*french*/""), + { + CustomMessage("something hot", /*german*/"etwas Heißes", /*french*/"") + }, { + CustomMessage("a draconic soul", /*german*/"eine drakonische Seele", /*french*/""), + CustomMessage("some magmatic essence", /*german*/"etwas magmatische Essenz", /*french*/"")}); + + hintTextTable[RHT_MORPHA_SOUL] = HintText(CustomMessage("the soul of Morpha", /*german*/"die Seele Morphas", /*french*/""), + { + CustomMessage("something wet", /*german*/"etwas Nasses", /*french*/"") + }, { + CustomMessage("an aquatic soul", /*german*/"eine aquatische Seele", /*french*/""), + CustomMessage("some liquid essence", /*german*/"etwas flüssige Essenz", /*french*/"")}); + + hintTextTable[RHT_BONGO_BONGO_SOUL] = HintText(CustomMessage("the soul of Bongo Bongo", /*german*/"die Seele Bongo Bongos", /*french*/""), + { + CustomMessage("something dark", /*german*/"etwas Dunkles", /*french*/"") + }, { + CustomMessage("a shadowy soul", /*german*/"eine schattige Seele", /*french*/""), + CustomMessage("some handy essence", /*german*/"etwas praktische Essenz", /*french*/"")}); + + hintTextTable[RHT_TWINROVA_SOUL] = HintText(CustomMessage("the soul of Twinrova", /*german*/"die Seele Twinrovas", /*french*/""), + { + CustomMessage("something spiritual", /*german*/"etwas Spirituelles", /*french*/"") + }, { + CustomMessage("old souls", /*german*/"alte Seelen", /*french*/""), + CustomMessage("twin essences", /*german*/"Zwillingsessenzen", /*french*/"")}); + + hintTextTable[RHT_GANON_SOUL] = HintText(CustomMessage("the soul of Ganon", /*german*/"die Seele Ganons", /*french*/""), + { + CustomMessage("something strong", /*german*/"etwas Starkes", /*french*/"") + }, { + CustomMessage("an evil soul", /*german*/"eine böse Seele", /*french*/""), + CustomMessage("some powerful essence", /*german*/"etwas mächtige Essenz", /*french*/"")}); + + hintTextTable[RHT_OCARINA_A_BUTTON] = HintText(CustomMessage("an Ocarina A Button", /*german*/"eine Okarina A Taste", /*french*/"la Touche A de l'Ocarina"), + // /*spanish*/un botón A de Ocarina + { + CustomMessage("something melodic", /*german*/"etwas Melodisches", /*french*/"quelque chose de mélodieux") + // /*spanish*/algo melódico + }, { + CustomMessage("a musical letter", /*german*/"ein musikalischer Brief", /*french*/"une lettre musicale")}); + // /*spanish*/una letra musical + + hintTextTable[RHT_OCARINA_C_UP_BUTTON] = HintText(CustomMessage("an Ocarina C Up Button", /*german*/"eine Okarina C-Oben Taste", /*french*/"la Touche C-Haut de l'Ocarina"), + // /*spanish*/un botón C superior de Ocarina + { + CustomMessage("something melodic", /*german*/"etwas Melodisches", /*french*/"quelque chose de mélodieux") + // /*spanish*/algo melódico + }, { + CustomMessage("a high tone", /*german*/"ein hoher Ton", /*french*/"une tonalité élevée")}); + // /*spanish*/un tono alto + + hintTextTable[RHT_OCARINA_C_DOWN_BUTTON] = HintText(CustomMessage("an Ocarina C Down Button", /*german*/"eine Okarina C-Unten Taste", /*french*/"la Touche C-Bas de l'Ocarina"), + // /*spanish*/un botón C inferior de Ocarina + { + CustomMessage("something melodic", /*german*/"etwas Melodisches", /*french*/"quelque chose de mélodieux") + // /*spanish*/algo melódico + }, { + CustomMessage("a low tone", /*german*/"ein tiefer Ton", /*french*/"une tonalité basse")}); + // /*spanish*/un tono bajo + + hintTextTable[RHT_OCARINA_C_LEFT_BUTTON] = HintText(CustomMessage("an Ocarina C Left Button", /*german*/"eine Okarina C-Links Taste", /*french*/"la Touche C-Gauche de l'Ocarina"), + // /*spanish*/un botón C izquierdo de Ocarina + { + CustomMessage("something melodic", /*german*/"etwas Melodisches", /*french*/"quelque chose de mélodieux") + // /*spanish*/algo melódico + }, { + CustomMessage("a leftward tone", /*german*/"ein linksseitiger Ton", /*french*/"une tonalité vers la gauche")}); + // /*spanish*/un tono hacia la izquierda + + hintTextTable[RHT_OCARINA_C_RIGHT_BUTTON] = HintText(CustomMessage("an Ocarina C Right Button", /*german*/"eine Okarina C-Rechts Taste", /*french*/"la Touche C-Droit de l'Ocarina"), + // /*spanish*/un botón C derecho de Ocarina + { + CustomMessage("something melodic", /*german*/"etwas Melodisches", /*french*/"quelque chose de mélodieux") + // /*spanish*/algo melódico + }, { + CustomMessage("a rightward tone", /*german*/"ein rechtsseitiger Ton", /*french*/"une tonalité vers la droite")}); + // /*spanish*/un tono hacia la derecha + + hintTextTable[RHT_FISHING_POLE] = HintText(CustomMessage("a fishing pole", /*german*/"eine Angelrute", /*french*/"canne à pêche"), + // /*spanish*/caña de pescar + { + CustomMessage("the pond owner's property", /*german*/"der Besitz des Teicheigners", /*french*/"(canne à pêche)") + // /*spanish*/(caña de pescar) + }, { + CustomMessage("a fish-puller", /*german*/"ein Fischzieher", /*french*/"(canne à pêche)")}); + // /*spanish*/(caña de pescar) + + hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + { + CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + }, { + CustomMessage("", /*german*/"!!!", /*french*/"!!!")}); + + hintTextTable[RHT_BOMB_BAG_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + { + CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + }, { + CustomMessage("", /*german*/"!!!", /*french*/"!!!")}); + + hintTextTable[RHT_BULLET_BAG_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + { + CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + }, { + CustomMessage("", /*german*/"!!!", /*french*/"!!!")}); + + hintTextTable[RHT_STICK_UPGRADE_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + { + CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + }, { + CustomMessage("", /*german*/"!!!", /*french*/"!!!")}); + + hintTextTable[RHT_NUT_UPGRADE_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + { + CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + }, { + CustomMessage("", /*german*/"!!!", /*french*/"!!!")}); + + hintTextTable[RHT_MAGIC_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + { + CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + }, { + CustomMessage("", /*german*/"!!!", /*french*/"!!!")}); + + hintTextTable[RHT_BOMBCHU_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + { + CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + }, { + CustomMessage("", /*german*/"!!!", /*french*/"!!!")}); + + hintTextTable[RHT_WALLET_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + { + CustomMessage("", /*german*/"!!!", /*french*/"!!!"), + }, { + CustomMessage("", /*german*/"!!!", /*french*/"!!!")}); + + hintTextTable[RHT_EPONA] = HintText(CustomMessage("Epona", /*german*/"Epona", /*french*/"Epona"), + // /*spanish*/a Epona + { + CustomMessage("something from Malon", /*german*/"ein Geschenk von Malon", /*french*/"un cadeau de Malon"), + // /*spanish*/un obsequio de Malon + CustomMessage("a song sung by frogs", /*german*/"ein von Fröschen gesungenes Lied", /*french*/"une chanson aimée des grenouilles"), + // /*spanish*/una melodía de ranas + CustomMessage("something to cross a broken bridge", /*german*/"etwas, um eine kaputte Brücke zu überqueren", /*french*/"une chose pour traverser un pont brisé") + // /*spanish*/algo para cruzar un puente roto + }, { + CustomMessage("a horse", /*german*/"ein Pferd", /*french*/"un fidèle destrier"), + // /*spanish*/una yegua + CustomMessage("a four legged friend", /*german*/"ein vierbeiniger Freund", /*french*/"un puissant animal")}); + // /*spanish*/una amiga cuadrúpeda + + //What is this used for? + hintTextTable[RHT_HINT_MYSTERIOUS] = HintText(CustomMessage("something mysterious", /*german*/"etwas Mysteriöses", /*french*/"un sacré mystère")); + // /*spanish*/algo misterioso + + hintTextTable[RHT_MYSTERIOUS_ITEM] = HintText(CustomMessage("mysterious item", /*german*/"mysteriöser Gegenstand", /*french*/"objet mystérieux")); + // /*spanish*/algo misterioso + + hintTextTable[RHT_MYSTERIOUS_ITEM_CAPITAL] = HintText(CustomMessage("Mysterious Item", /*german*/"Mysteriöser Gegenstand", /*french*/"Objet Mystérieux")); + // /*spanish*/Algo Misterioso + +} } diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index 19fdadc7eeb..124720871f8 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -1,1124 +1,813 @@ #include "hints.hpp" -#include "custom_messages.hpp" -#include "dungeon.hpp" -#include "item_location.hpp" #include "item_pool.hpp" -#include "logic.hpp" #include "random.hpp" -#include "settings.hpp" #include "spoiler_log.hpp" #include "fill.hpp" -#include "hint_list.hpp" -#include "trial.hpp" -#include "entrance.hpp" +#include "../trial.h" +#include "../entrance.h" #include "z64item.h" #include #include "../randomizerTypes.h" +#include "pool_functions.hpp" +#include "../hint.h" +#include "../static_data.h" -using namespace CustomMessages; -using namespace Logic; -using namespace Settings; -using namespace Trial; - -std::unordered_map hintTypeNames = { - { HINT_TYPE_TRIAL, "Trial" }, - { HINT_TYPE_ALWAYS, "Always" }, - { HINT_TYPE_WOTH, "WotH" }, - { HINT_TYPE_BARREN, "Barren" }, - { HINT_TYPE_ENTRANCE, "Entrance" }, - { HINT_TYPE_SOMETIMES, "Sometimes" }, - { HINT_TYPE_RANDOM, "Random"}, - { HINT_TYPE_ITEM, "Item" }, - { HINT_TYPE_SONG, "Song" }, - { HINT_TYPE_OVERWORLD, "Overworld" }, - { HINT_TYPE_DUNGEON, "Dungeon" }, - { HINT_TYPE_JUNK, "Junk" }, - { HINT_TYPE_NAMED_ITEM, "NamedItem" }, -}; -constexpr std::array hintSettingTable{{ - // Useless hints - { - .dungeonsWothLimit = 2, - .dungeonsBarrenLimit = 1, - .namedItemsRequired = false, - .distTable = {{ - {.type = HINT_TYPE_TRIAL, .order = 1, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_ALWAYS, .order = 2, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_WOTH, .order = 3, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_BARREN, .order = 4, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_ENTRANCE, .order = 5, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_SOMETIMES, .order = 6, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_RANDOM, .order = 7, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_ITEM, .order = 8, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_SONG, .order = 9, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_OVERWORLD, .order = 10, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_DUNGEON, .order = 11, .weight = 0, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_JUNK, .order = 12, .weight = 99, .fixed = 0, .copies = 0}, - {.type = HINT_TYPE_NAMED_ITEM, .order = 13, .weight = 0, .fixed = 0, .copies = 0}, - }}, - }, +using namespace Rando; - // Balanced hints - { - .dungeonsWothLimit = 2, - .dungeonsBarrenLimit = 1, - .namedItemsRequired = true, - .distTable = {{ - {.type = HINT_TYPE_TRIAL, .order = 1, .weight = 0, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_ALWAYS, .order = 2, .weight = 0, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_WOTH, .order = 3, .weight = 7, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_BARREN, .order = 4, .weight = 4, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_ENTRANCE, .order = 5, .weight = 6, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_SOMETIMES, .order = 6, .weight = 0, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_RANDOM, .order = 7, .weight = 12, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_ITEM, .order = 8, .weight = 10, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_SONG, .order = 9, .weight = 2, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_OVERWORLD, .order = 10, .weight = 4, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_DUNGEON, .order = 11, .weight = 3, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_JUNK, .order = 12, .weight = 6, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_NAMED_ITEM, .order = 13, .weight = 0, .fixed = 0, .copies = 1}, - }}, - }, - - // Strong hints - { - .dungeonsWothLimit = 2, - .dungeonsBarrenLimit = 1, - .namedItemsRequired = true, - .distTable = {{ - {.type = HINT_TYPE_TRIAL, .order = 1, .weight = 0, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_ALWAYS, .order = 2, .weight = 0, .fixed = 0, .copies = 2}, - {.type = HINT_TYPE_WOTH, .order = 3, .weight = 12, .fixed = 0, .copies = 2}, - {.type = HINT_TYPE_BARREN, .order = 4, .weight = 12, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_ENTRANCE, .order = 5, .weight = 4, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_SOMETIMES, .order = 6, .weight = 0, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_RANDOM, .order = 7, .weight = 8, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_ITEM, .order = 8, .weight = 8, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_SONG, .order = 9, .weight = 4, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_OVERWORLD, .order = 10, .weight = 6, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_DUNGEON, .order = 11, .weight = 6, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_JUNK, .order = 12, .weight = 0, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_NAMED_ITEM, .order = 13, .weight = 0, .fixed = 0, .copies = 1}, - }}, - }, +HintDistributionSetting::HintDistributionSetting(std::string _name, + HintType _type, + uint32_t _weight, + uint8_t _fixed, + uint8_t _copies, + std::function _filter, + uint8_t _dungeonLimit){ + name = _name; + type = _type; + weight = _weight; + fixed = _fixed; + copies = _copies; + filter = _filter; + dungeonLimit = _dungeonLimit; + } - // Very strong hints - { - .dungeonsWothLimit = 40, - .dungeonsBarrenLimit = 40, - .namedItemsRequired = true, - .distTable = {{ - {.type = HINT_TYPE_TRIAL, .order = 1, .weight = 0, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_ALWAYS, .order = 2, .weight = 0, .fixed = 0, .copies = 2}, - {.type = HINT_TYPE_WOTH, .order = 3, .weight = 15, .fixed = 0, .copies = 2}, - {.type = HINT_TYPE_BARREN, .order = 4, .weight = 15, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_ENTRANCE, .order = 5, .weight = 10, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_SOMETIMES, .order = 6, .weight = 0, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_RANDOM, .order = 7, .weight = 0, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_ITEM, .order = 8, .weight = 5, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_SONG, .order = 9, .weight = 2, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_OVERWORLD, .order = 10, .weight = 7, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_DUNGEON, .order = 11, .weight = 7, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_JUNK, .order = 12, .weight = 0, .fixed = 0, .copies = 1}, - {.type = HINT_TYPE_NAMED_ITEM, .order = 13, .weight = 0, .fixed = 0, .copies = 1}, - }}, - }, -}}; +HintText::HintText(CustomMessage clearText_, std::vector ambiguousText_, std::vector obscureText_) +: clearText(std::move(clearText_)), ambiguousText(std::move(ambiguousText_)), obscureText(std::move(obscureText_)){} -std::array dungeonInfoData; - -Text childAltarText; -Text adultAltarText; -Text ganonText; -Text ganonHintText; -Text sheikText; -Text sariaText; -Text dampesText; -Text gregText; -Text warpMinuetText; -Text warpBoleroText; -Text warpSerenadeText; -Text warpRequiemText; -Text warpNocturneText; -Text warpPreludeText; - - -std::string lightArrowHintLoc; -std::string masterSwordHintLoc; -std::string sariaHintLoc; -std::string dampeHintLoc; - -Text& GetChildAltarText() { - return childAltarText; +const CustomMessage& HintText::GetClear() const { + return clearText; } -Text& GetAdultAltarText() { - return adultAltarText; +const CustomMessage& HintText::GetObscure() const { + return obscureText.size() > 0 ? RandomElement(obscureText) : clearText; } -Text& GetGanonText() { - return ganonText; +const CustomMessage& HintText::GetObscure(uint8_t selection) const { + if (obscureText.size() > selection){ + return obscureText[selection]; + } else if (obscureText.size() > 0) { + return obscureText[0]; + } + return clearText; } -Text& GetGanonHintText() { - return ganonHintText; +const CustomMessage& HintText::GetAmbiguous() const { + return ambiguousText.size() > 0 ? RandomElement(ambiguousText) : clearText; } -Text& GetDampeHintText() { - return dampesText; +const CustomMessage& HintText::GetAmbiguous(uint8_t selection) const { + if (ambiguousText.size() > selection){ + return ambiguousText[selection]; + } else if (ambiguousText.size() > 0) { + return ambiguousText[0]; + } + return clearText; } -Text& GetGregHintText() { - return gregText; +uint8_t HintText::GetAmbiguousSize() const{ + return ambiguousText.size(); } -Text& GetSheikHintText() { - return sheikText; +uint8_t HintText::GetObscureSize() const{ + return obscureText.size(); } -Text& GetSariaHintText() { - return sariaText; +const CustomMessage& HintText::GetHintMessage(uint8_t selection) const { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_OBSCURE)) { + return GetObscure(selection); + } else if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_AMBIGUOUS)) { + return GetAmbiguous(selection); + } else { + return GetClear(); + } } -Text& GetWarpMinuetText() { - return warpMinuetText; +const CustomMessage HintText::GetMessageCopy() const { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_OBSCURE)) { + return GetObscure(); + } else if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_AMBIGUOUS)) { + return GetAmbiguous(); + } else { + return GetClear(); + } } -Text& GetWarpBoleroText() { - return warpBoleroText; +bool HintText::operator==(const HintText& right) const { + return obscureText == right.obscureText && + ambiguousText == right.ambiguousText && + clearText == right.clearText; } -Text& GetWarpSerenadeText() { - return warpSerenadeText; +bool HintText::operator!=(const HintText& right) const { + return !operator==(right); } -Text& GetWarpRequiemText() { - return warpRequiemText; -} +StaticHintInfo::StaticHintInfo(HintType _type, std::vector _hintKeys, RandomizerSettingKey _setting, + std::variant _condition, std::vector _targetChecks, + std::vector _targetItems, std::vector _hintChecks, bool _yourPocket, int _num): + type(_type), hintKeys(_hintKeys), setting(_setting), condition(_condition), targetChecks(_targetChecks), + targetItems(_targetItems), hintChecks(_hintChecks), yourPocket(_yourPocket), num(_num){} -Text& GetWarpNocturneText() { - return warpNocturneText; +RandomizerHintTextKey GetRandomJunkHint(){ + //temp code to handle random junk hints now I work in keys instead of a vector of HintText + // Will be replaced with a better system once more customisable hint pools are added + uint32_t range = RHT_JUNK_SG_8 - RHT_JUNK02; + return (RandomizerHintTextKey)(Random(0, range) + RHT_JUNK02); } -Text& GetWarpPreludeText() { - return warpPreludeText; +RandomizerHintTextKey GetRandomGanonJoke(){ + uint32_t range = RHT_GANON_JOKE11 - RHT_GANON_JOKE01; + return (RandomizerHintTextKey)(Random(0, range) + RHT_GANON_JOKE01); } -std::string GetMasterSwordHintLoc() { - return masterSwordHintLoc; + +bool FilterWotHLocations(RandomizerCheck loc){ + auto ctx = Rando::Context::GetInstance(); + return ctx->GetItemLocation(loc)->IsWothCandidate(); } - -std::string GetLightArrowHintLoc() { - return lightArrowHintLoc; + +bool FilterFoolishLocations(RandomizerCheck loc){ + auto ctx = Rando::Context::GetInstance(); + return ctx->GetItemLocation(loc)->IsFoolishCandidate(); } -std::string GetDampeHintLoc() { - return dampeHintLoc; +bool FilterSongLocations(RandomizerCheck loc){ + auto ctx = Rando::Context::GetInstance(); + return Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION; } -std::string GetSariaHintLoc() { - return sariaHintLoc; +bool FilterOverworldLocations(RandomizerCheck loc){ + auto ctx = Rando::Context::GetInstance(); + return Rando::StaticData::GetLocation(loc)->IsOverworld(); } -Area* GetHintRegion(const uint32_t area) { +bool FilterDungeonLocations(RandomizerCheck loc){ + auto ctx = Rando::Context::GetInstance(); + return Rando::StaticData::GetLocation(loc)->IsDungeon(); +} - std::vector alreadyChecked = {}; - std::vector spotQueue = {area}; +bool FilterGoodItems(RandomizerCheck loc){ + auto ctx = Rando::Context::GetInstance(); + return ctx->GetItemLocation(loc)->GetPlacedItem().IsMajorItem(); +} - while (!spotQueue.empty()) { - uint32_t region = spotQueue.back(); - alreadyChecked.push_back(region); - spotQueue.pop_back(); +bool NoFilter(RandomizerCheck loc){ + return true; +} - if (AreaTable(region)->hintKey != NONE) { - return AreaTable(region); +const std::array hintSettingTable{{ + // Useless hints + { + .alwaysCopies = 0, + .trialCopies = 0, + .junkWeight = 1, //RANDOTODO when the hint pool is not implicitly an itemLocations, handle junk like other hint types + .distTable = {} /*RANDOTODO Instead of loading a function into this, + apply this filter on all possible hintables in advance and then filter by what is acually in the seed at the start of generation. + This allows the distTable to hold the current status in hint generation (reducing potential doubled work) and + will make handling custom hint pools easier later*/ + }, + // Balanced hints + { + .alwaysCopies = 1, + .trialCopies = 1, + .junkWeight = 6, + .distTable = { + {"WotH", HINT_TYPE_WOTH, 7, 0, 1, FilterWotHLocations, 2}, + {"Foolish", HINT_TYPE_FOOLISH, 4, 0, 1, FilterFoolishLocations, 1}, + //("Entrance", HINT_TYPE_ENTRANCE, 6, 0, 1), //not yet implemented + {"Song", HINT_TYPE_ITEM, 2, 0, 1, FilterSongLocations}, + {"Overworld", HINT_TYPE_ITEM, 4, 0, 1, FilterOverworldLocations}, + {"Dungeon", HINT_TYPE_ITEM, 3, 0, 1, FilterDungeonLocations}, + {"Named Item", HINT_TYPE_ITEM_AREA, 10, 0, 1, FilterGoodItems}, + {"Random" , HINT_TYPE_ITEM_AREA, 12, 0, 1, NoFilter} } + }, + // Strong hints + { + .alwaysCopies = 2, + .trialCopies = 1, + .junkWeight = 0, + .distTable = { + {"WotH", HINT_TYPE_WOTH, 12, 0, 2, FilterWotHLocations, 2}, + {"Foolish", HINT_TYPE_FOOLISH, 12, 0, 1, FilterFoolishLocations, 1}, + //{"Entrance", HINT_TYPE_ENTRANCE, 4, 0, 1}, //not yet implemented + {"Song", HINT_TYPE_ITEM, 4, 0, 1, FilterSongLocations}, + {"Overworld", HINT_TYPE_ITEM, 6, 0, 1, FilterOverworldLocations}, + {"Dungeon", HINT_TYPE_ITEM, 6, 0, 1, FilterDungeonLocations}, + {"Named Item", HINT_TYPE_ITEM_AREA, 8, 0, 1, FilterGoodItems}, + {"Random" , HINT_TYPE_ITEM_AREA, 8, 0, 1, NoFilter}, + }, + }, + // Very strong hints + { + .alwaysCopies = 2, + .trialCopies = 1, + .junkWeight = 0, + .distTable = { + {"WotH", HINT_TYPE_WOTH, 15, 0, 2, FilterWotHLocations}, + {"Foolish", HINT_TYPE_FOOLISH, 15, 0, 1, FilterFoolishLocations}, + //{"Entrance", HINT_TYPE_ENTRANCE, 10, 0, 1}, //not yet implemented + {"Song", HINT_TYPE_ITEM, 2, 0, 1, FilterSongLocations}, + {"Overworld", HINT_TYPE_ITEM, 7, 0, 1, FilterOverworldLocations}, + {"Dungeon", HINT_TYPE_ITEM, 7, 0, 1, FilterDungeonLocations}, + {"Named Item", HINT_TYPE_ITEM_AREA, 5, 0, 1, FilterGoodItems}, + }, + }, +}}; - //add unchecked entrances to spot queue - bool checked = false; - for (auto& entrance : AreaTable(region)->entrances) { - for (uint32_t checkedEntrance : alreadyChecked) { - if (entrance->GetParentRegionKey() == checkedEntrance) { - checked = true; - break; - } - } - - if (!checked) { - spotQueue.insert(spotQueue.begin(), entrance->GetParentRegionKey()); - } +uint8_t StonesRequiredBySettings() { + auto ctx = Rando::Context::GetInstance(); + uint8_t stones = 0; + if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES)) { + stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Value(); + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { + stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Value() - 6; + } else if ((ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS)) && (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON))) { + stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Value() - 6; } - } - - return AreaTable(NONE); -} - -uint32_t GetHintRegionHintKey(const uint32_t area) { - return GetHintRegion(area)->hintKey; + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) { + stones = std::max({ stones, ctx->GetOption(RSK_LACS_STONE_COUNT).Value() }); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) { + stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Value() - 6 )}); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) { + stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Value() - 6 )}); + } + return stones; +} + +uint8_t MedallionsRequiredBySettings() { + auto ctx = Rando::Context::GetInstance(); + uint8_t medallions = 0; + if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS)) { + medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Value(); + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { + medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Value() - 3; + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { + medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Value() - 3; + } + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) { + medallions = std::max({ medallions, ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Value() }); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) { + medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Value() - 3 )}); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { + medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Value() - 3 )}); + } + return medallions; } -uint32_t GetHintRegionuint32_t(const uint32_t area) { - return GetHintRegion(area)->hintKey; -} +uint8_t TokensRequiredBySettings() { + auto ctx = Rando::Context::GetInstance(); + uint8_t tokens = 0; + if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) { + tokens = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Value(); + } + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) { + tokens = std::max({ tokens, ctx->GetOption(RSK_LACS_TOKEN_COUNT).Value() }); + } + return tokens; +} + +std::vector>> conditionalAlwaysHints = { + std::make_pair(RC_MARKET_10_BIG_POES, []() { + auto ctx = Rando::Context::GetInstance(); + return ctx->GetOption(RSK_BIG_POE_COUNT).Value() >= 3 && !ctx->GetOption(RSK_BIG_POES_HINT); + }), // Remember, the option's value being 3 means 4 are required + std::make_pair(RC_DEKU_THEATER_MASK_OF_TRUTH, []() { + auto ctx = Rando::Context::GetInstance(); + return !ctx->GetOption(RSK_MASK_SHOP_HINT) && !ctx->GetOption(RSK_COMPLETE_MASK_QUEST); + }), + std::make_pair(RC_SONG_FROM_OCARINA_OF_TIME, []() { + auto ctx = Rando::Context::GetInstance(); + return StonesRequiredBySettings() < 2 && !ctx->GetOption(RSK_OOT_HINT); + }), + std::make_pair(RC_HF_OCARINA_OF_TIME_ITEM, []() { return StonesRequiredBySettings() < 2; }), + std::make_pair(RC_SHEIK_IN_KAKARIKO, []() { return MedallionsRequiredBySettings() < 5; }), + std::make_pair(RC_DMT_TRADE_CLAIM_CHECK, []() { + auto ctx = Rando::Context::GetInstance(); + return !ctx->GetOption(RSK_BIGGORON_HINT); + }), + std::make_pair(RC_KAK_30_GOLD_SKULLTULA_REWARD, []() { + auto ctx = Rando::Context::GetInstance(); + return !ctx->GetOption(RSK_KAK_30_SKULLS_HINT) && TokensRequiredBySettings() < 30; + }), + std::make_pair(RC_KAK_40_GOLD_SKULLTULA_REWARD, []() { + auto ctx = Rando::Context::GetInstance(); + return !ctx->GetOption(RSK_KAK_40_SKULLS_HINT) && TokensRequiredBySettings() < 40; + }), + std::make_pair(RC_KAK_50_GOLD_SKULLTULA_REWARD, []() { + auto ctx = Rando::Context::GetInstance(); + return !ctx->GetOption(RSK_KAK_50_SKULLS_HINT) && TokensRequiredBySettings() < 50; + }), + std::make_pair(RC_ZR_FROGS_OCARINA_GAME, []() { + auto ctx = Rando::Context::GetInstance(); + return !ctx->GetOption(RSK_FROGS_HINT); + }), + std::make_pair(RC_KF_LINKS_HOUSE_COW, []() { + auto ctx = Rando::Context::GetInstance(); + return !ctx->GetOption(RSK_MALON_HINT); + }), + std::make_pair(RC_KAK_100_GOLD_SKULLTULA_REWARD, []() { + auto ctx = Rando::Context::GetInstance(); + return !ctx->GetOption(RSK_KAK_100_SKULLS_HINT) && TokensRequiredBySettings() < 100; + }), +}; -uint32_t GetLocationRegionuint32_t(const uint32_t location) { - return GetHintRegion(Location(location)->GetParentRegionKey())->hintKey; +static std::vector GetEmptyGossipStones() { + auto emptyGossipStones = GetEmptyLocations(Rando::StaticData::GetGossipStoneLocations()); + return emptyGossipStones; } -static std::vector GetAccessibleGossipStones(const uint32_t hintedLocation = GANON) { +static std::vector GetAccessibleGossipStones(const RandomizerCheck hintedLocation = RC_GANON) { + auto ctx = Rando::Context::GetInstance(); //temporarily remove the hinted location's item, and then perform a //reachability search for gossip stone locations. - uint32_t originalItem = Location(hintedLocation)->GetPlaceduint32_t(); - Location(hintedLocation)->SetPlacedItem(NONE); + RandomizerGet originalItem = ctx->GetItemLocation(hintedLocation)->GetPlacedRandomizerGet(); + ctx->GetItemLocation(hintedLocation)->SetPlacedItem(RG_NONE); - LogicReset(); - auto accessibleGossipStones = GetAccessibleLocations(gossipStoneLocations); + ctx->GetLogic()->Reset(); + auto accessibleGossipStones = ReachabilitySearch(Rando::StaticData::GetGossipStoneLocations()); //Give the item back to the location - Location(hintedLocation)->SetPlacedItem(originalItem); + ctx->GetItemLocation(hintedLocation)->SetPlacedItem(originalItem); return accessibleGossipStones; } -static void AddHint(Text hint, const uint32_t gossipStone, const std::vector& colors = {}, HintType hintType = HINT_TYPE_ITEM, const uint32_t hintedLocation = NONE) { - //save hints as dummy items for writing to the spoiler log - NewItem(gossipStone, Item{RG_HINT, hint, ITEMTYPE_EVENT, GI_RUPEE_BLUE_LOSE, false, &noVariable, NONE}); - Location(gossipStone)->SetPlacedItem(gossipStone); - Location(gossipStone)->SetHintedLocation(hintedLocation); - Location(gossipStone)->SetHintType(hintType); - Location(gossipStone)->SetHintedRegion(GetHintRegion(Location(hintedLocation)->GetParentRegionKey())->GetHint().GetText().GetEnglish()); -} - -static void CreateLocationHint(const std::vector& possibleHintLocations) { - //return if there aren't any hintable locations or gossip stones available - if (possibleHintLocations.empty()) { - SPDLOG_DEBUG("\tNO LOCATIONS TO HINT\n\n"); - return; - } - - uint32_t hintedLocation = RandomElement(possibleHintLocations); - const std::vector accessibleGossipStones = GetAccessibleGossipStones(hintedLocation); - - SPDLOG_DEBUG("\tLocation: "); - SPDLOG_DEBUG(Location(hintedLocation)->GetName()); - SPDLOG_DEBUG("\n"); - - SPDLOG_DEBUG("\tItem: "); - SPDLOG_DEBUG(Location(hintedLocation)->GetPlacedItemName().GetEnglish()); - SPDLOG_DEBUG("\n"); - - if (accessibleGossipStones.empty()) { +bool IsReachableWithout(std::vector locsToCheck, RandomizerCheck excludedCheck, bool resetAfter = true){ + //temporarily remove the hinted location's item, and then perform a + //reachability search for this check RANDOTODO convert excludedCheck to an ItemLocation + auto ctx = Rando::Context::GetInstance(); + RandomizerGet originalItem = ctx->GetItemLocation(excludedCheck)->GetPlacedRandomizerGet(); + ctx->GetItemLocation(excludedCheck)->SetPlacedItem(RG_NONE); + ctx->GetLogic()->Reset(); + const auto rechableWithout = ReachabilitySearch(locsToCheck); + ctx->GetItemLocation(excludedCheck)->SetPlacedItem(originalItem); + if (resetAfter){ + //if resetAfter is on, reset logic we are done + ctx->GetLogic()->Reset(); + } + if (rechableWithout.empty()) { + return false; + } + return true; +} + +static void SetAllInAreaAsHintAccesible(RandomizerArea area, std::vector locations){ + auto ctx = Rando::Context::GetInstance(); + std::vector locsInArea = FilterFromPool(locations, [area, ctx](const RandomizerCheck loc){ + return ctx->GetItemLocation(loc)->GetAreas().contains(area); + }); + for(RandomizerCheck loc: locsInArea){ + ctx->GetItemLocation(loc)->SetHintAccesible(); + } +} + +static void AddGossipStoneHint( const RandomizerCheck gossipStone, + const HintType hintType, + const std::string distributionName, + const std::vector hintKeys, + const std::vector locations, + const std::vector areas, + const std::vector trials) { + auto ctx = Rando::Context::GetInstance(); + ctx->AddHint(StaticData::gossipStoneCheckToHint[gossipStone], Hint(StaticData::gossipStoneCheckToHint[gossipStone], hintType, distributionName, hintKeys, locations, areas, trials)); + ctx->GetItemLocation(gossipStone)->SetPlacedItem(RG_HINT); //RANDOTODO, better gossip stone to location to hint key system +} + +static void AddGossipStoneHintCopies(uint8_t copies, + const HintType hintType, + const std::string distributionName, + const std::vector hintKeys = {}, + const std::vector locations = {}, + const std::vector areas = {}, + const std::vector trials = {}, + RandomizerCheck firstStone = RC_UNKNOWN_CHECK){ + + if (firstStone != RC_UNKNOWN_CHECK && copies > 0){ + AddGossipStoneHint(firstStone, hintType, distributionName, hintKeys, locations, areas, trials); + copies -= 1; + } + for(int c=0; cSetAsHinted(); - - //make hint text - Text locationHintText = Location(hintedLocation)->GetHint().GetText(); - Text itemHintText = Location(hintedLocation)->GetPlacedItem().GetHint().GetText(); - Text prefix = Hint(PREFIX).GetText(); - - Text finalHint = prefix + "%r" + locationHintText + " #%g" + itemHintText + "#%w."; - SPDLOG_DEBUG("\tMessage: "); - SPDLOG_DEBUG(finalHint.english); - SPDLOG_DEBUG("\n\n"); - - AddHint(finalHint, gossipStone, {QM_GREEN, QM_RED}, HINT_TYPE_ITEM, hintedLocation); } -static void CreateWothHint(uint8_t* remainingDungeonWothHints) { - // get locations that are in the current playthrough - std::vector possibleHintLocations = {}; - // iterate through playthrough locations by sphere - std::vector wothHintLocations = - FilterFromPool(wothLocations, [remainingDungeonWothHints](uint32_t loc) { - return Location(loc)->IsHintable() && // only filter hintable locations - !(Location(loc)->IsHintedAt()) && // only filter locations that haven't been hinted at - (Location(loc)->IsOverworld() || - (Location(loc)->IsDungeon() && - (*remainingDungeonWothHints) > 0)); // make sure we haven't surpassed the woth dungeon limit - }); - AddElementsToPool(possibleHintLocations, wothHintLocations); - - // If no more locations can be hinted at for woth, then just try to get another hint - if (possibleHintLocations.empty()) { - SPDLOG_DEBUG("\tNO LOCATIONS TO HINT\n\n"); - return; - } - uint32_t hintedLocation = RandomElement(possibleHintLocations); - - SPDLOG_DEBUG("\tLocation: "); - SPDLOG_DEBUG(Location(hintedLocation)->GetName()); - SPDLOG_DEBUG("\n"); - - SPDLOG_DEBUG("\tItem: "); - SPDLOG_DEBUG(Location(hintedLocation)->GetPlacedItemName().GetEnglish()); - SPDLOG_DEBUG("\n"); +static bool CreateHint(RandomizerCheck location, uint8_t copies, HintType type, std::string distribution){ + auto ctx = Rando::Context::GetInstance(); - // get an accessible gossip stone - const std::vector gossipStoneLocations = GetAccessibleGossipStones(hintedLocation); - - if (gossipStoneLocations.empty()) { - SPDLOG_DEBUG("\tNO GOSSIP STONES TO PLACE HINT\n\n"); - return; - } - Location(hintedLocation)->SetAsHinted(); - uint32_t gossipStone = RandomElement(gossipStoneLocations); + //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"); + return false; + } + RandomizerCheck gossipStone = RandomElement(gossipStoneLocations); + RandomizerArea area = RandomElementFromSet(ctx->GetItemLocation(location)->GetAreas()); - if (Location(hintedLocation)->IsDungeon()) { - *remainingDungeonWothHints -= 1; - } + //Set that hints are accesible + ctx->GetItemLocation(location)->SetHintAccesible(); + if (type == HINT_TYPE_FOOLISH){ + SetAllInAreaAsHintAccesible(area, ctx->allLocations); + } - // form hint text - Text locationText = GetHintRegion(Location(hintedLocation)->GetParentRegionKey())->GetHint().GetText(); - Text finalWothHint = Hint(PREFIX).GetText() + "%r#" + locationText + "#%w" + Hint(WAY_OF_THE_HERO).GetText(); - SPDLOG_DEBUG("\tMessage: "); - SPDLOG_DEBUG(finalWothHint.english); - SPDLOG_DEBUG("\n\n"); - AddHint(finalWothHint, gossipStone, { QM_LBLUE }, HINT_TYPE_WOTH, hintedLocation); + AddGossipStoneHintCopies(copies, type, distribution, {}, {location}, {area}, {}, gossipStone); + return true; } -static void CreateBarrenHint(uint8_t* remainingDungeonBarrenHints, std::vector& barrenLocations) { - // remove dungeon locations if necessary - if (*remainingDungeonBarrenHints < 1) { - barrenLocations = - FilterFromPool(barrenLocations, [](const uint32_t loc) { return !(Location(loc)->IsDungeon()); }); - } - if (barrenLocations.empty()) { - return; - } +static RandomizerCheck CreateRandomHint(std::vector& possibleHintLocations, + uint8_t copies, + HintType type, + std::string distributionName) { + auto ctx = Rando::Context::GetInstance(); - uint32_t hintedLocation = RandomElement(barrenLocations, true); + //return if there aren't any hintable locations or gossip stones available + if (GetEmptyGossipStones().size() < copies) { + SPDLOG_DEBUG("\tNOT ENOUGH GOSSIP STONES TO PLACE HINTS\n\n"); + return RC_UNKNOWN_CHECK; + } + RandomizerCheck hintedLocation; + bool placed = false; + while (!placed){ + if (possibleHintLocations.empty()) { + SPDLOG_DEBUG("\tNO LOCATIONS TO HINT\n\n"); + return RC_UNKNOWN_CHECK; + } + hintedLocation = RandomElement(possibleHintLocations, true); //removing the location to avoid it being hinted again on fail + SPDLOG_DEBUG("\tLocation: "); - SPDLOG_DEBUG(Location(hintedLocation)->GetName()); + SPDLOG_DEBUG(Rando::StaticData::GetLocation(hintedLocation)->GetName()); SPDLOG_DEBUG("\n"); SPDLOG_DEBUG("\tItem: "); - SPDLOG_DEBUG(Location(hintedLocation)->GetPlacedItemName().GetEnglish()); + SPDLOG_DEBUG(ctx->GetItemLocation(hintedLocation)->GetPlacedItemName().GetEnglish()); SPDLOG_DEBUG("\n"); - // get an accessible gossip stone - const std::vector gossipStoneLocations = GetAccessibleGossipStones(hintedLocation); - if (gossipStoneLocations.empty()) { - SPDLOG_DEBUG("\tNO GOSSIP STONES TO PLACE HINT\n\n"); - return; - } - Location(hintedLocation)->SetAsHinted(); - uint32_t gossipStone = RandomElement(gossipStoneLocations); - - if (Location(hintedLocation)->IsDungeon()) { - *remainingDungeonBarrenHints -= 1; - } - - // form hint text - Text locationText = GetHintRegion(Location(hintedLocation)->GetParentRegionKey())->GetHint().GetText(); - Text finalBarrenHint = - Hint(PREFIX).GetText() + Hint(PLUNDERING).GetText() + "%r#" + locationText + "#%w" + Hint(FOOLISH).GetText(); - SPDLOG_DEBUG("\tMessage: "); - SPDLOG_DEBUG(finalBarrenHint.english); - SPDLOG_DEBUG("\n\n"); - AddHint(finalBarrenHint, gossipStone, { QM_PINK }, HINT_TYPE_BARREN, hintedLocation); - - // get rid of all other locations in this same barren region - barrenLocations = FilterFromPool(barrenLocations, [hintedLocation](uint32_t loc) { - return GetHintRegion(Location(loc)->GetParentRegionKey())->hintKey != - GetHintRegion(Location(hintedLocation)->GetParentRegionKey())->hintKey; - }); -} - -static void CreateRandomLocationHint(const bool goodItem = false) { - const std::vector possibleHintLocations = FilterFromPool(allLocations, [goodItem](const uint32_t loc) { - return Location(loc)->IsHintable() && !(Location(loc)->IsHintedAt()) && (!goodItem || Location(loc)->GetPlacedItem().IsMajorItem()); - }); - //If no more locations can be hinted at, then just try to get another hint - if (possibleHintLocations.empty()) { - SPDLOG_DEBUG("\tNO LOCATIONS TO HINT\n\n"); - return; - } - uint32_t hintedLocation = RandomElement(possibleHintLocations); - - SPDLOG_DEBUG("\tLocation: "); - SPDLOG_DEBUG(Location(hintedLocation)->GetName()); - SPDLOG_DEBUG("\n"); - - SPDLOG_DEBUG("\tItem: "); - SPDLOG_DEBUG(Location(hintedLocation)->GetPlacedItemName().GetEnglish()); - SPDLOG_DEBUG("\n"); - - //get an acessible gossip stone - const std::vector gossipStoneLocations = GetAccessibleGossipStones(hintedLocation); - if (gossipStoneLocations.empty()) { - SPDLOG_DEBUG("\tNO GOSSIP STONES TO PLACE HINT\n\n"); - return; - } - Location(hintedLocation)->SetAsHinted(); - uint32_t gossipStone = RandomElement(gossipStoneLocations); - - //form hint text - Text itemText = Location(hintedLocation)->GetPlacedItem().GetHint().GetText(); - Text locationText = GetHintRegion(Location(hintedLocation)->GetParentRegionKey())->GetHint().GetText(); - // RANDOTODO: reconsider dungeon vs non-dungeon item location hints when boss shuffle mixed pools happens - if (Location(hintedLocation)->IsDungeon()) { - Text finalHint = Hint(PREFIX).GetText()+"%r#"+locationText+"#%w "+Hint(HOARDS).GetText()+" %g#"+itemText+"#%w."; - SPDLOG_DEBUG("\tMessage: "); - SPDLOG_DEBUG(finalHint.english); - SPDLOG_DEBUG("\n\n"); - AddHint(finalHint, gossipStone, {QM_GREEN, QM_RED}, HINT_TYPE_NAMED_ITEM, hintedLocation); - } else { - Text finalHint = Hint(PREFIX).GetText()+"%r#"+itemText+"#%w "+Hint(CAN_BE_FOUND_AT).GetText()+" %g#"+locationText+"#%w."; - SPDLOG_DEBUG("\tMessage: "); - SPDLOG_DEBUG(finalHint.english); - SPDLOG_DEBUG("\n\n"); - AddHint(finalHint, gossipStone, { QM_RED, QM_GREEN }, HINT_TYPE_NAMED_ITEM, hintedLocation); + placed = CreateHint(hintedLocation, copies, type, distributionName); } + return hintedLocation; } -static void CreateGoodItemHint() { - CreateRandomLocationHint(true); +static std::vector FilterHintability(std::vector& locations, + std::function extraFilter = NoFilter){ + auto ctx = Rando::Context::GetInstance(); + return FilterFromPool(locations, [extraFilter, ctx](const RandomizerCheck loc) { + return ctx->GetItemLocation(loc)->IsHintable() && !(ctx->GetItemLocation(loc)->IsAHintAccessible()) + && extraFilter(loc); + }); } -static void CreateJunkHint() { - //duplicate junk hints are possible for now - const HintText junkHint = RandomElement(GetHintCategory(HintCategory::Junk)); - LogicReset(); - const std::vector gossipStones = GetAccessibleLocations(gossipStoneLocations); - if (gossipStones.empty()) { - SPDLOG_DEBUG("\tNO GOSSIP STONES TO PLACE HINT\n\n"); - return; +static void CreateJunkHints(uint8_t numHints) { + for(uint8_t c = 0; c < numHints; c++){ + //duplicate junk hints are possible for now + AddGossipStoneHintCopies(1, HINT_TYPE_HINT_KEY, "Junk", {GetRandomJunkHint()}); } - uint32_t gossipStone = RandomElement(gossipStones); - Text hint = junkHint.GetText(); - - SPDLOG_DEBUG("\tMessage: "); - SPDLOG_DEBUG(hint.english); - SPDLOG_DEBUG("\n\n"); - - AddHint(hint, gossipStone, { QM_PINK }, HINT_TYPE_JUNK); } -static std::vector CalculateBarrenRegions() { - std::vector barrenLocations = {}; - std::vector potentiallyUsefulLocations = {}; - - for (uint32_t loc : allLocations) { - // If a location has a major item or is a way of the hero location, it is not barren - if (Location(loc)->GetPlacedItem().IsMajorItem() || ElementInContainer(loc, wothLocations)) { - AddElementsToPool(potentiallyUsefulLocations, std::vector{loc}); +static void CreateTrialHints(uint8_t copies) { + if (copies > 0) { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_TRIAL_COUNT).Is(6)) {//six trials + AddGossipStoneHintCopies(copies, HINT_TYPE_HINT_KEY, "Trial", {RHT_SIX_TRIALS}); + } else if (ctx->GetOption(RSK_TRIAL_COUNT).Is(0)) {//zero trials + AddGossipStoneHintCopies(copies, HINT_TYPE_HINT_KEY, "Trial", {RHT_ZERO_TRIALS}); } else { - // Link's Pocket & Triforce Hunt "reward" shouldn't be considered for barren areas because it's clear what - // they have to a player. - if (loc != LINKS_POCKET && loc != TRIFORCE_COMPLETED) { - AddElementsToPool(barrenLocations, std::vector{loc}); + std::vector trials = ctx->GetTrials()->GetTrialList(); //there's probably a way to remove this assignment + if (ctx->GetOption(RSK_TRIAL_COUNT).Value() >= 4) {//4 or 5 required trials, get skipped trials + trials = FilterFromPool(trials, [](TrialInfo* trial){return trial->IsSkipped();}); + } else {//1 to 3 trials, get requried trials + auto requiredTrials = FilterFromPool(trials, [](TrialInfo* trial){return trial->IsRequired();}); } - } - } - - // Leave only locations at barren regions in the list - auto finalBarrenLocations = FilterFromPool(barrenLocations, [&potentiallyUsefulLocations](uint32_t loc){ - for (uint32_t usefulLoc : potentiallyUsefulLocations) { - uint32_t barrenKey = GetLocationRegionuint32_t(loc); - uint32_t usefulKey = GetLocationRegionuint32_t(usefulLoc); - if (barrenKey == usefulKey) { - return false; + for (auto& trial : trials) {//create a hint for each hinted trial + AddGossipStoneHintCopies(copies, HINT_TYPE_TRIAL, "Trial", {}, {}, {}, {trial->GetTrialKey()}); } } - return true; - }); - - return finalBarrenLocations; -} - -static void CreateTrialHints() { - //six trials - if (RandomGanonsTrials && GanonsTrialsCount.Is(6)) { - - //get a random gossip stone - auto gossipStones = GetAccessibleGossipStones(); - auto gossipStone = RandomElement(gossipStones, false); - - //make hint - auto hint = Hint(PREFIX).GetText() + Hint(SIX_TRIALS).GetText(); - AddHint(hint, gossipStone, { QM_PINK }, HINT_TYPE_TRIAL); - - //zero trials - } else if (RandomGanonsTrials && GanonsTrialsCount.Is(0)) { - - //get a random gossip stone - auto gossipStones = GetAccessibleGossipStones(); - auto gossipStone = RandomElement(gossipStones, false); - - //make hint - auto hint = Hint(PREFIX).GetText() + Hint(ZERO_TRIALS).GetText(); - AddHint(hint, gossipStone, { QM_YELLOW }, HINT_TYPE_TRIAL); - - //4 or 5 required trials - } else if (GanonsTrialsCount.Is(5) || GanonsTrialsCount.Is(4)) { - - //get skipped trials - std::vector trials = {}; - trials.assign(trialList.begin(), trialList.end()); - auto skippedTrials = FilterFromPool(trials, [](TrialInfo* trial){return trial->IsSkipped();}); - - //create a hint for each skipped trial - for (auto& trial : skippedTrials) { - //get a random gossip stone - auto gossipStones = GetAccessibleGossipStones(); - auto gossipStone = RandomElement(gossipStones, false); - - //make hint - auto hint = Hint(PREFIX).GetText()+"#"+trial->GetName()+"#"+Hint(FOUR_TO_FIVE_TRIALS).GetText(); - AddHint(hint, gossipStone, { QM_YELLOW }, HINT_TYPE_TRIAL); - } - //1 to 3 trials - } else if (GanonsTrialsCount.Value() >= 1 && GanonsTrialsCount.Value() <= 3) { - //get requried trials - std::vector trials = {}; - trials.assign(trialList.begin(), trialList.end()); - auto requiredTrials = FilterFromPool(trials, [](TrialInfo* trial){return trial->IsRequired();}); - - //create a hint for each required trial - for (auto& trial : requiredTrials) { - //get a random gossip stone - auto gossipStones = GetAccessibleGossipStones(); - auto gossipStone = RandomElement(gossipStones, false); - - //make hint - auto hint = Hint(PREFIX).GetText()+"#"+trial->GetName()+"#"+Hint(ONE_TO_THREE_TRIALS).GetText(); - AddHint(hint, gossipStone, { QM_PINK }, HINT_TYPE_TRIAL); - } } } -void CreateGanonText() { - - //funny ganon line - ganonText = RandomElement(GetHintCategory(HintCategory::GanonLine)).GetText(); - CreateMessageFromTextObject(0x70CB, 0, 2, 3, AddColorsAndFormat(ganonText)); - - //Get the location of the light arrows - auto lightArrowLocation = FilterFromPool(allLocations, [](const uint32_t loc){return Location(loc)->GetPlaceduint32_t() == LIGHT_ARROWS;}); - - //If there is no light arrow location, it was in the player's inventory at the start - auto hint = Hint(LIGHT_ARROW_LOCATION_HINT); - if (lightArrowLocation.empty()) { - ganonHintText = hint.GetText()+Hint(YOUR_POCKET).GetText(); - lightArrowHintLoc = "Link's Pocket"; - } else { - ganonHintText = hint.GetText() + "%r" + GetHintRegion(Location(lightArrowLocation[0])->GetParentRegionKey())->GetHint().GetText(); - lightArrowHintLoc = Location(lightArrowLocation[0])->GetName(); - } - ganonHintText = ganonHintText + "!"; - - if (ShuffleMasterSword) { - //Get the location of the master sword - auto masterSwordLocation = FilterFromPool(allLocations, [](const LocationKey loc){return Location(loc)->GetPlacedItemKey() == MASTER_SWORD;}); - - // Add second text box - ganonHintText = ganonHintText + "^"; - if (masterSwordLocation.empty()) { - ganonHintText = ganonHintText+Hint(MASTER_SWORD_LOCATION_HINT).GetText()+Hint(YOUR_POCKET).GetText(); - masterSwordHintLoc = "Link's Pocket"; - } else { - ganonHintText = ganonHintText+Hint(MASTER_SWORD_LOCATION_HINT).GetText()+GetHintRegion(Location(masterSwordLocation[0])->GetParentRegionKey())->GetHint().GetText(); - masterSwordHintLoc = Location(masterSwordLocation[0])->GetName(); +void CreateWarpSongTexts() { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_WARP_SONG_HINTS)){ + auto warpSongEntrances = GetShuffleableEntrances(EntranceType::WarpSong, false); + for (auto entrance : warpSongEntrances) { + //RANDOTODO make random + const auto destination = entrance->GetConnectedRegion()->GetAllAreas().begin(); + switch (entrance->GetIndex()) { + case 0x0600: // minuet RANDOTODO make into entrance hints when they are added + ctx->AddHint(RH_MINUET_WARP_LOC, Hint(RH_MINUET_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {*destination})); + break; + case 0x04F6: // bolero + ctx->AddHint(RH_BOLERO_WARP_LOC, Hint(RH_BOLERO_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {*destination})); + break; + case 0x0604: // serenade + ctx->AddHint(RH_SERENADE_WARP_LOC, Hint(RH_SERENADE_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {*destination})); + break; + case 0x01F1: // requiem + ctx->AddHint(RH_REQUIEM_WARP_LOC, Hint(RH_REQUIEM_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {*destination})); + break; + case 0x0568: // nocturne + ctx->AddHint(RH_NOCTURNE_WARP_LOC, Hint(RH_NOCTURNE_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {*destination})); + break; + case 0x05F4: // prelude + ctx->AddHint(RH_PRELUDE_WARP_LOC, Hint(RH_PRELUDE_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {*destination})); + break; + default: + break; + } } - ganonHintText = ganonHintText + "!"; - } - - CreateMessageFromTextObject(0x70CC, 0, 2, 3, AddColorsAndFormat(ganonHintText)); -} - -//Find the location which has the given itemKey and create the generic altar text for the reward -static Text BuildDungeonRewardText(const uint32_t itemKey) { - uint32_t location = FilterFromPool(allLocations, [itemKey](const uint32_t loc){return Location(loc)->GetPlaceduint32_t() == itemKey;})[0]; - Location(location)->SetAsHinted(); - - std::string rewardString = "$" + std::to_string(itemKey - KOKIRI_EMERALD); - - // RANDOTODO implement colors for locations - return Text()+rewardString+GetHintRegion(Location(location)->GetParentRegionKey())->GetHint().GetText().Capitalize()+"...^"; -} - -static Text BuildDoorOfTimeText() { - std::string itemObtained; - Text doorOfTimeText; - - if (OpenDoorOfTime.Is(OPENDOOROFTIME_OPEN)) { - itemObtained = "$o"; - doorOfTimeText = Hint(CHILD_ALTAR_TEXT_END_DOTOPEN).GetText(); - - } else if (OpenDoorOfTime.Is(OPENDOOROFTIME_SONGONLY)) { - itemObtained = "$c"; - doorOfTimeText = Hint(CHILD_ALTAR_TEXT_END_DOTSONGONLY).GetText(); - - } else if (OpenDoorOfTime.Is(OPENDOOROFTIME_CLOSED)) { - itemObtained = "$i"; - doorOfTimeText = Hint(CHILD_ALTAR_TEXT_END_DOTCLOSED).GetText(); - } - - return Text()+itemObtained+doorOfTimeText; -} - -//insert the required number into the hint and set the singular/plural form -static Text BuildCountReq(const uint32_t req, const Option& count) { - Text requirement = Hint(req).GetTextCopy(); - if (count.Value() == 1) { - requirement.SetForm(SINGULAR); - } else { - requirement.SetForm(PLURAL); - } - requirement.Replace("%d", std::to_string(count.Value())); - return requirement; -} - -static Text BuildBridgeReqsText() { - Text bridgeText; - - if (Bridge.Is(RAINBOWBRIDGE_OPEN)) { - bridgeText = Hint(BRIDGE_OPEN_HINT).GetText(); - - } else if (Bridge.Is(RAINBOWBRIDGE_VANILLA)) { - bridgeText = Hint(BRIDGE_VANILLA_HINT).GetText(); - - } else if (Bridge.Is(RAINBOWBRIDGE_STONES)) { - bridgeText = BuildCountReq(BRIDGE_STONES_HINT, BridgeStoneCount); - - } else if (Bridge.Is(RAINBOWBRIDGE_MEDALLIONS)) { - bridgeText = BuildCountReq(BRIDGE_MEDALLIONS_HINT, BridgeMedallionCount); - - } else if (Bridge.Is(RAINBOWBRIDGE_REWARDS)) { - bridgeText = BuildCountReq(BRIDGE_REWARDS_HINT, BridgeRewardCount); - - } else if (Bridge.Is(RAINBOWBRIDGE_DUNGEONS)) { - bridgeText = BuildCountReq(BRIDGE_DUNGEONS_HINT, BridgeDungeonCount); - - } else if (Bridge.Is(RAINBOWBRIDGE_TOKENS)) { - bridgeText = BuildCountReq(BRIDGE_TOKENS_HINT, BridgeTokenCount); - - } else if (Bridge.Is(RAINBOWBRIDGE_GREG)) { - bridgeText = Hint(BRIDGE_GREG_HINT).GetText(); } - - return Text()+"$l"+bridgeText+"^"; } -static Text BuildGanonBossKeyText() { - Text ganonBossKeyText; - - if (GanonsBossKey.Is(GANONSBOSSKEY_START_WITH)) { - ganonBossKeyText = Hint(GANON_BK_START_WITH_HINT).GetText(); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA)) { - ganonBossKeyText = Hint(GANON_BK_VANILLA_HINT).GetText(); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_OWN_DUNGEON)) { - ganonBossKeyText = Hint(GANON_BK_OWN_DUNGEON_HINT).GetText(); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_ANY_DUNGEON)) { - ganonBossKeyText = Hint(GANON_BK_ANY_DUNGEON_HINT).GetText(); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_OVERWORLD)) { - ganonBossKeyText = Hint(GANON_BK_OVERWORLD_HINT).GetText(); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_ANYWHERE)) { - ganonBossKeyText = Hint(GANON_BK_ANYWHERE_HINT).GetText(); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_FINAL_GS_REWARD)) { - ganonBossKeyText = Hint(GANON_BK_SKULLTULA_HINT).GetText(); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_VANILLA)) { - ganonBossKeyText = Hint(LACS_VANILLA_HINT).GetText(); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_STONES)) { - ganonBossKeyText = BuildCountReq(LACS_STONES_HINT, LACSStoneCount); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_MEDALLIONS)) { - ganonBossKeyText = BuildCountReq(LACS_MEDALLIONS_HINT, LACSMedallionCount); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_REWARDS)) { - ganonBossKeyText = BuildCountReq(LACS_REWARDS_HINT, LACSRewardCount); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_DUNGEONS)) { - ganonBossKeyText = BuildCountReq(LACS_DUNGEONS_HINT, LACSDungeonCount); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_TOKENS)) { - ganonBossKeyText = BuildCountReq(LACS_TOKENS_HINT, LACSTokenCount); - - } else if (GanonsBossKey.Is(GANONSBOSSKEY_TRIFORCE_HUNT)) { - ganonBossKeyText = Hint(GANON_BK_TRIFORCE_HINT).GetText(); +int32_t getRandomWeight(int32_t totalWeight){ + if (totalWeight <= 1){ + return 1; } - - return Text()+"$b"+ganonBossKeyText+"^"; + return Random(1,totalWeight); } -void CreateAltarText() { - - //Child Altar Text - if (AltarHintText) { - childAltarText = Hint(SPIRITUAL_STONE_TEXT_START).GetText()+"^"+ - //Spiritual Stones - (StartingKokiriEmerald.Value() ? Text{ "##", "##", "##" } - : BuildDungeonRewardText(KOKIRI_EMERALD)) + - (StartingGoronRuby.Value() ? Text{ "##", "##", "##" } - : BuildDungeonRewardText(GORON_RUBY)) + - (StartingZoraSapphire.Value() ? Text{ "##", "##", "##" } - : BuildDungeonRewardText(ZORA_SAPPHIRE)) + - //How to open Door of Time, the event trigger is necessary to read the altar multiple times - BuildDoorOfTimeText(); - } else { - childAltarText = BuildDoorOfTimeText(); - } - - CreateMessageFromTextObject(0x7040, 0, 2, 3, AddColorsAndFormat(childAltarText, {QM_GREEN, QM_RED, QM_BLUE})); - - //Adult Altar Text - adultAltarText = Hint(ADULT_ALTAR_TEXT_START).GetText() + "^"; - if (AltarHintText) { - adultAltarText = adultAltarText + - //Medallion Areas - (StartingLightMedallion.Value() ? Text{ "##", "##", "##" } - : BuildDungeonRewardText(LIGHT_MEDALLION)) + - (StartingForestMedallion.Value() ? Text{ "##", "##", "##" } - : BuildDungeonRewardText(FOREST_MEDALLION)) + - (StartingFireMedallion.Value() ? Text{ "##", "##", "##" } - : BuildDungeonRewardText(FIRE_MEDALLION)) + - (StartingWaterMedallion.Value() ? Text{ "##", "##", "##" } - : BuildDungeonRewardText(WATER_MEDALLION)) + - (StartingSpiritMedallion.Value() ? Text{ "##", "##", "##" } - : BuildDungeonRewardText(SPIRIT_MEDALLION)) + - (StartingShadowMedallion.Value() ? Text{ "##", "##", "##" } - : BuildDungeonRewardText(SHADOW_MEDALLION)); - } - adultAltarText = adultAltarText + - //Bridge requirement - BuildBridgeReqsText()+ - - //Ganons Boss Key requirement - BuildGanonBossKeyText()+ - - //End - Hint(ADULT_ALTAR_TEXT_END).GetText(); - CreateMessageFromTextObject(0x7088, 0, 2, 3, AddColorsAndFormat(adultAltarText, {QM_RED, QM_YELLOW, QM_GREEN, QM_RED, QM_BLUE, QM_YELLOW, QM_PINK, QM_RED, QM_RED, QM_RED, QM_RED})); -} - -void CreateMerchantsHints() { - - Text medigoronItemText = Location(GC_MEDIGORON)->GetPlacedItem().GetHint().GetText(); - Text grannyItemText = Location(KAK_GRANNYS_SHOP)->GetPlacedItem().GetHint().GetText(); - Text carpetSalesmanItemText = Location(WASTELAND_BOMBCHU_SALESMAN)->GetPlacedItem().GetHint().GetText(); - Text carpetSalesmanItemClearText = Location(WASTELAND_BOMBCHU_SALESMAN)->GetPlacedItem().GetHint().GetClear(); +static void DistributeHints(std::vector& selected, size_t stoneCount, std::vector distTable, uint8_t junkWieght, bool addFixed = true){ + int32_t totalWeight = junkWieght; //Start with our Junk Weight, the natural chance of a junk hint - Text grannyCapitalItemText = grannyItemText.Capitalize(); - - Text medigoronText = Hint(MEDIGORON_DIALOG_FIRST).GetText()+medigoronItemText+Hint(MEDIGORON_DIALOG_SECOND).GetText(); - Text grannyText = grannyCapitalItemText+Hint(GRANNY_DIALOG).GetText(); - Text carpetSalesmanTextOne = Hint(CARPET_SALESMAN_DIALOG_FIRST).GetText()+carpetSalesmanItemText+Hint(CARPET_SALESMAN_DIALOG_SECOND).GetText(); - Text carpetSalesmanTextTwo = Hint(CARPET_SALESMAN_DIALOG_THIRD).GetText()+carpetSalesmanItemClearText+Hint(CARPET_SALESMAN_DIALOG_FOURTH).GetText(); - - CreateMessageFromTextObject(0x9120, 0, 2, 3, AddColorsAndFormat(medigoronText, {QM_RED, QM_GREEN})); - CreateMessageFromTextObject(0x9121, 0, 2, 3, AddColorsAndFormat(grannyText, {QM_RED, QM_GREEN})); - CreateMessageFromTextObject(0x6077, 0, 2, 3, AddColorsAndFormat(carpetSalesmanTextOne, {QM_RED, QM_GREEN})); - CreateMessageFromTextObject(0x6078, 0, 2, 3, AddColorsAndFormat(carpetSalesmanTextTwo, {QM_RED, QM_YELLOW, QM_RED})); -} - -void CreateDampesDiaryText() { - if (!DampeHintText) { - dampesText = Text(); - dampeHintLoc = ""; - return; + for (size_t c=0; c < distTable.size(); c++){ //Gather the weights of each distribution and, if it's the first pass, apply fixed hints + totalWeight += distTable[c].weight; //Note that PlaceHints will set weights of distributions to zero if it can't place anything from them + if (addFixed){ + selected[c] += distTable[c].fixed; + stoneCount -= distTable[c].fixed * distTable[c].copies; + } } - - uint32_t item = PROGRESSIVE_HOOKSHOT; - uint32_t location = FilterFromPool(allLocations, [item](const uint32_t loc){return Location(loc)->GetPlaceduint32_t() == item;})[0]; - Text area = GetHintRegion(Location(location)->GetParentRegionKey())->GetHint().GetText(); - Text temp1 = Text{ - "Whoever reads this, please enter %r", - "Toi qui lit ce journal, rends-toi dans %r", - "Wer immer dies liest, der möge folgenden Ort aufsuchen: %r" - }; - - Text temp2 = { - "%w. I will let you have my stretching, shrinking keepsake.^I'm waiting for you.&--Dampé", - "%w. Et peut-être auras-tu droit à mon précieux %rtrésor%w.^Je t'attends...&--Igor", - "%w. Ihm gebe ich meinen langen, kurzen Schatz.^Ich warte!&Boris" - }; - - dampesText = temp1 + area + temp2; - dampeHintLoc = Location(location)->GetName(); -} - -void CreateGregRupeeHint() { - if (!GregHintText) { - gregText = Text(); - return; + int32_t currentWeight = getRandomWeight(totalWeight); //Initialise with the first random weight from 1 to the total. + while(stoneCount > 0 && totalWeight > 0){//Loop until we run out of stones or have no TotalWeight. 0 totalWeight means junkWeight is 0 + //and that all weights have been 0'd out for another reason, and skips to placing all junk hints + for (size_t distribution = 0; distribution < distTable.size(); distribution++){ + currentWeight -= distTable[distribution].weight; //go over each distribution, subtracting the weight each time. Once we reach zero or less, + if (currentWeight <= 0){ //tell the system to make 1 of that hint, unless not enough stones remain + if (stoneCount >= distTable[distribution].copies && distTable[distribution].copies > 0){ + selected[distribution] += 1; //if we have enough stones, and copies are not zero, assign 1 to this hint type, remove the stones, and break + stoneCount -= distTable[distribution].copies; + break; //This leaves the whole for loop + } else { //If we don't have the stones, or copies is 0 despite there being the wieght to trigger a hit, temporerally set wieght to zero + totalWeight -= distTable[distribution].weight; //Unlike PlaceHint, distTable is passed by value here, making this temporary + distTable[distribution].weight = 0; //this is so we can still roll this hint type if more stones free up later + break; + } + } + } + //if there's still weight then it's junk, as the leftover weight is junkWeight + if (currentWeight > 0){ //zero TotalWeight breaks the while loop and hits the fallback, so skipping this is fine in that case + selected[selected.size()-1] += 1; + stoneCount -= 1; + } + currentWeight = getRandomWeight(totalWeight); } - - uint32_t location = FilterFromPool(allLocations, [](const uint32_t loc){return Location(loc)->GetPlacedItemKey() == GREG_RUPEE;})[0]; - Text area = GetHintRegion(Location(location)->GetParentRegionKey())->GetHint().GetText(); - - Text temp1 = Text{ - "By the way, if you're interested, I saw the shiniest %gGreen Rupee%w somewhere in%r ", - "Au fait, si ça t'intéresse, j'ai aperçu le plus éclatant des %gRubis Verts%w quelque part à %r", - "" - }; - - Text temp2 = { - "%w.^It's said to have %cmysterious powers%w...^But then, it could just be another regular rupee.&Oh well.", - "%w. On dit qu'il possède des pouvoirs mystérieux... Mais bon, ça pourrait juste être un autre rubis ordinaire.", - "" - }; - - gregText = temp1 + area + temp2; -} - -void CreateSheikText() { - //Get the location of the light arrows - auto lightArrowLocation = FilterFromPool(allLocations, [](const uint32_t loc){return Location(loc)->GetPlaceduint32_t() == LIGHT_ARROWS;}); - lightArrowHintLoc = Location(lightArrowLocation[0])->GetName(); - Text area = GetHintRegion(Location(lightArrowLocation[0])->GetParentRegionKey())->GetHint().GetText(); - Text temp1 = Text{ - "I overheard Ganondorf say that he misplaced the %yLight Arrows%w in %r", - "J'ai entendu dire que Ganondorf aurait caché les %yFlèches de Lumière%w dans %r", - "" - }; - Text temp2 = Text{"%w.", "%w.", "%w."}; - sheikText = temp1 + area + temp2; - if (ShuffleMasterSword) { - sheikText = sheikText + "^"; - auto masterSwordLocation = FilterFromPool(allLocations, [](const uint32_t loc){return Location(loc)->GetPlaceduint32_t() == MASTER_SWORD;}); - masterSwordHintLoc = Location(masterSwordLocation[0])->GetName(); - area = GetHintRegion(Location(masterSwordLocation[0])->GetParentRegionKey())->GetHint().GetText(); - Text temp3 = Text{ - "I also heard that he stole %rthe Master Sword%w and hid it somewhere within %g", - "Test", - "Test" - }; - sheikText = sheikText + temp3 + area + temp2; + //if stones are left, assign junk to every remaining stone as a fallback. + if (stoneCount > 0){ + selected[selected.size()-1] += stoneCount; } } -void CreateSariaText() { - //Get the location of the light arrows - auto magicLocation = FilterFromPool(allLocations, [](const uint32_t loc){return Location(loc)->GetPlaceduint32_t() == PROGRESSIVE_MAGIC_METER;}); - sariaHintLoc = Location(magicLocation[0])->GetName(); - Text area = GetHintRegion(Location(magicLocation[0])->GetParentRegionKey())->GetHint().GetText(); - Text temp1 = Text{ - "Did you feel the %gsurge of magic%w recently? A mysterious bird told me it came from %r", - "As-tu récemment ressenti une vague de %gpuissance magique%w? Un mystérieux hibou m'a dit qu'elle provenait du %r", - "" - }; - Text temp2 = Text{ - "%w.^You should check that place out, @!$C", - "%w. Tu devrais aller y jeter un coup d'oeil, @!$C", - "%w.$C" - }; - sariaText = temp1 + area + temp2; -} - - -void CreateWarpSongTexts() { - if (!ShuffleWarpSongs) { - warpMinuetText = Text(); - warpBoleroText = Text(); - warpSerenadeText = Text(); - warpRequiemText = Text(); - warpNocturneText = Text(); - warpPreludeText = Text(); - return; - } - - auto warpSongEntrances = GetShuffleableEntrances(EntranceType::WarpSong, false); +uint8_t PlaceHints(std::vector& selectedHints, std::vector& distTable){ + auto ctx = Rando::Context::GetInstance(); + uint8_t curSlot = 0; + for (HintDistributionSetting distribution : distTable){ + std::vector hintTypePool = FilterHintability(ctx->allLocations, distribution.filter); + for (uint8_t numHint = 0; numHint < selectedHints[curSlot]; numHint++){ + hintTypePool = FilterHintability(hintTypePool); + SPDLOG_DEBUG("Attempting to make hint of type: " + StaticData::hintTypeNames[distribution.type].GetEnglish(MF_CLEAN) + "\n"); + RandomizerCheck hintedLocation = RC_UNKNOWN_CHECK; - for (auto entrance : warpSongEntrances) { - Text resolvedHint; - // Start with entrance location text - auto region = entrance->GetConnectedRegion()->regionName; - resolvedHint = Text{"","",""} + region; + hintedLocation = CreateRandomHint(hintTypePool, distribution.copies, distribution.type, distribution.name); - auto destination = entrance->GetConnectedRegion()->GetHint().GetText(); - // Prefer hint location when available - if (destination.GetEnglish() != "No Hint") { - resolvedHint = destination; - } - - switch (entrance->GetIndex()) { - case 0x0600: // minuet - warpMinuetText = resolvedHint; - break; - case 0x04F6: // bolero - warpBoleroText = resolvedHint; - break; - case 0x0604: // serenade - warpSerenadeText = resolvedHint; - break; - case 0x01F1: // requiem - warpRequiemText = resolvedHint; - break; - case 0x0568: // nocturne - warpNocturneText = resolvedHint; - break; - case 0x05F4: // prelude - warpPreludeText = resolvedHint; - break; + if (hintedLocation == RC_UNKNOWN_CHECK){ //if hint failed to place, remove all wieght and copies then return the number of stones to redistribute + uint8_t hintsToRemove = (selectedHints[curSlot] - numHint) * distribution.copies; + selectedHints[curSlot] = 0; //as distTable is passed by refernce here, these changes stick for the rest of this seed generation + distTable[curSlot].copies = 0;//and prevent future distribution from choosing this slot + distTable[curSlot].weight = 0; + return hintsToRemove; + } + if(Rando::StaticData::GetLocation(hintedLocation)->IsDungeon()){ + distribution.dungeonLimit -= 1; + if (distribution.dungeonLimit == 0){ + FilterFromPool(hintTypePool, FilterOverworldLocations); + } + } } + selectedHints[curSlot] = 0; + curSlot += 1; } + CreateJunkHints(selectedHints[selectedHints.size() - 1]); + return 0; } -void CreateAllHints() { - +void CreateStoneHints() { + auto ctx = Rando::Context::GetInstance(); SPDLOG_DEBUG("\nNOW CREATING HINTS\n"); - const HintSetting& hintSetting = hintSettingTable[Settings::HintDistribution.Value()]; + const HintSetting& hintSetting = hintSettingTable[ctx->GetOption(RSK_HINT_DISTRIBUTION).Value()]; + std::vector distTable = hintSetting.distTable; - uint8_t remainingDungeonWothHints = hintSetting.dungeonsWothLimit; - uint8_t remainingDungeonBarrenHints = hintSetting.dungeonsBarrenLimit; + // Apply impa's song exclusions when zelda is skipped + if(ctx->GetOption(RSK_SKIP_CHILD_ZELDA)){ + ctx->GetItemLocation(RC_SONG_FROM_IMPA)->SetHintAccesible(); + } // Add 'always' location hints - if (hintSetting.distTable[static_cast(HINT_TYPE_ALWAYS)].copies > 0) { - // Only filter locations that had a random item placed at them (e.g. don't get cow locations if shuffle cows is off) - auto alwaysHintLocations = FilterFromPool(allLocations, [](const uint32_t loc){ - return ((Location(loc)->GetHint().GetType() == HintCategory::Always) || - // If we have Rainbow Bridge set to Greg, add a hint for where Greg is - (Bridge.Is(RAINBOWBRIDGE_GREG) && !GregHintText && Location(loc)->GetPlacedItemKey() == GREG_RUPEE)) && - Location(loc)->IsHintable() && !(Location(loc)->IsHintedAt()); - }); + std::vector alwaysHintLocations = {}; + if (hintSetting.alwaysCopies > 0) { + if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG)){ + // If we have Rainbow Bridge set to Greg and the greg hint isn't useful, add a hint for where Greg is + // Do we really need this with the greg hint? + auto gregLocations = FilterFromPool(ctx->allLocations, [ctx](const RandomizerCheck loc) { + return ( + (ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == RG_GREG_RUPEE)) && + ctx->GetItemLocation(loc)->IsHintable() && + !(ctx->GetOption(RSK_GREG_HINT) && (IsReachableWithout({RC_GREG_HINT}, loc, true))); + }); + if (gregLocations.size() > 0){ + alwaysHintLocations.push_back(gregLocations[0]); + } + } for (auto& hint : conditionalAlwaysHints) { - uint32_t loc = hint.first; - if (hint.second() && Location(loc)->IsHintable() && !Location(loc)->IsHintedAt()) { + RandomizerCheck loc = hint.first; + if (hint.second() && ctx->GetItemLocation(loc)->IsHintable()) { alwaysHintLocations.push_back(loc); } } - for (uint32_t location : alwaysHintLocations) { - CreateLocationHint({location}); + for (RandomizerCheck location : alwaysHintLocations) { + CreateHint(location, hintSetting.alwaysCopies, HINT_TYPE_ITEM, "Always"); } } //Add 'trial' location hints - if (hintSetting.distTable[static_cast(HINT_TYPE_TRIAL)].copies > 0) { - CreateTrialHints(); + if (ctx->GetOption(RSK_GANONS_TRIALS).IsNot(RO_GANONS_TRIALS_SKIP)) { + CreateTrialHints(hintSetting.trialCopies); } - //create a vector with each hint type proportional to it's weight in the distribution setting. - //ootr uses a weighted probability function to decide hint types, but selecting randomly from - //this vector will do for now - std::vector remainingHintTypes = {}; - for (HintDistributionSetting hds : hintSetting.distTable) { - remainingHintTypes.insert(remainingHintTypes.end(), hds.weight, hds.type); + size_t totalStones = GetEmptyGossipStones().size(); + std::vector selectedHints = {}; + for (size_t c=0; c < distTable.size(); c++){ + selectedHints.push_back(0); } - Shuffle(remainingHintTypes); - - //get barren regions - auto barrenLocations = CalculateBarrenRegions(); - - //Calculate dungeon woth/barren info - - std::vector dungeonNames = {"Deku Tree", "Dodongos Cavern", "Jabu Jabus Belly", "Forest Temple", "Fire Temple", - "Water Temple", "Spirit Temple", "Shadow Temple", "Bottom of the Well", "Ice Cavern"}; - //Get list of all barren dungeons - std::vector barrenDungeons; - for (uint32_t barrenLocation : barrenLocations) { - std::string barrenRegion = GetHintRegion(Location(barrenLocation)->GetParentRegionKey())->scene; - bool isDungeon = std::find(dungeonNames.begin(), dungeonNames.end(), barrenRegion) != dungeonNames.end(); - //If it hasn't already been added to the list and is a dungeon, add to list - if (isDungeon && std::find(barrenDungeons.begin(), barrenDungeons.end(), barrenRegion) == barrenDungeons.end()) { - barrenDungeons.push_back(barrenRegion); + selectedHints.push_back(0); + DistributeHints(selectedHints, totalStones, distTable, hintSetting.junkWeight); + + while(totalStones != 0){ + totalStones = PlaceHints(selectedHints, distTable); + if (totalStones != 0){ + DistributeHints(selectedHints, totalStones, distTable, hintSetting.junkWeight, false); } } - SPDLOG_DEBUG("\nBarren Dungeons:\n"); - for (std::string barrenDungeon : barrenDungeons) { - SPDLOG_DEBUG(barrenDungeon + "\n"); - } - //Get list of all woth dungeons - std::vector wothDungeons; - for (uint32_t wothLocation : wothLocations) { - std::string wothRegion = GetHintRegion(Location(wothLocation)->GetParentRegionKey())->scene; - bool isDungeon = std::find(dungeonNames.begin(), dungeonNames.end(), wothRegion) != dungeonNames.end(); - //If it hasn't already been added to the list and is a dungeon, add to list - if (isDungeon && std::find(wothDungeons.begin(), wothDungeons.end(), wothRegion) == wothDungeons.end()) { - wothDungeons.push_back(wothRegion); + //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. + ReachabilitySearch({}); +} + +std::vector FindItemsAndMarkHinted(std::vector items, std::vector hintChecks){ + std::vector locations = {}; + auto ctx = Rando::Context::GetInstance(); + for (size_t c = 0; c < items.size(); c++){ + std::vector found = FilterFromPool(ctx->allLocations, [items, ctx, c](const RandomizerCheck loc) { + 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 (!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); } } - SPDLOG_DEBUG("\nWoth Dungeons:\n"); - for (std::string wothDungeon : wothDungeons) { - SPDLOG_DEBUG(wothDungeon + "\n"); - } + return locations; +} - //Set DungeonInfo array for each dungeon - for (uint32_t i = 0; i < dungeonInfoData.size(); i++) { - std::string dungeonName = dungeonNames[i]; - if (std::find(barrenDungeons.begin(), barrenDungeons.end(), dungeonName) != barrenDungeons.end()) { - dungeonInfoData[i] = DungeonInfo::DUNGEON_BARREN; - } else if (std::find(wothDungeons.begin(), wothDungeons.end(), dungeonName) != wothDungeons.end()) { - dungeonInfoData[i] = DungeonInfo::DUNGEON_WOTH; - } else { - dungeonInfoData[i] = DungeonInfo::DUNGEON_NEITHER; +void CreateChildAltarHint() { + auto ctx = Rando::Context::GetInstance(); + if (!ctx->GetHint(RH_ALTAR_CHILD)->IsEnabled()){ + std::vector stoneLocs = {}; + if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) { + //force marking the rewards as hinted if they are at the end of dungeons as they can be inffered + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)){ + stoneLocs = FindItemsAndMarkHinted({RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE}, {}); + } else { + stoneLocs = FindItemsAndMarkHinted({RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE}, {RC_ALTAR_HINT_CHILD}); + } } + std::vector stoneAreas = {}; + for (auto loc : stoneLocs){ + stoneAreas.push_back(RandomElementFromSet(ctx->GetItemLocation(loc)->GetAreas())); + } + ctx->AddHint(RH_ALTAR_CHILD, Hint(RH_ALTAR_CHILD, HINT_TYPE_ALTAR_CHILD, {}, stoneLocs, stoneAreas)); + } +} + +void CreateAdultAltarHint() { + auto ctx = Rando::Context::GetInstance(); + if (!ctx->GetHint(RH_ALTAR_ADULT)->IsEnabled()){ + std::vector medallionLocs = {}; + if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) { + //force marking the rewards as hinted if they are at the end of dungeons as they can be inffered + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)){ + medallionLocs = FindItemsAndMarkHinted({RG_LIGHT_MEDALLION, RG_FOREST_MEDALLION, RG_FIRE_MEDALLION, RG_WATER_MEDALLION, RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION}, + {}); + } else { + medallionLocs = FindItemsAndMarkHinted({RG_LIGHT_MEDALLION, RG_FOREST_MEDALLION, RG_FIRE_MEDALLION, RG_WATER_MEDALLION, RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION}, + {RC_ALTAR_HINT_ADULT}); + } + } + std::vector medallionAreas = {}; + for (auto loc : medallionLocs){ + medallionAreas.push_back(RandomElementFromSet(ctx->GetItemLocation(loc)->GetAreas())); + } + ctx->AddHint(RH_ALTAR_ADULT, Hint(RH_ALTAR_ADULT, HINT_TYPE_ALTAR_ADULT, {}, medallionLocs, medallionAreas)); } +} - //while there are still gossip stones remaining - while (FilterFromPool(gossipStoneLocations, [](const uint32_t loc){return Location(loc)->GetPlaceduint32_t() == NONE;}).size() != 0) { - //TODO: fixed hint types +void CreateStaticHintFromData(RandomizerHint hint, StaticHintInfo staticData){ + auto ctx = Rando::Context::GetInstance(); + if (!ctx->GetHint(hint)->IsEnabled()){ + 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)))){ - if (remainingHintTypes.empty()) { - break; + std::vector locations = {}; + if (staticData.targetItems.size() > 0){ + locations = FindItemsAndMarkHinted(staticData.targetItems, staticData.hintChecks); + } + for(auto check: staticData.targetChecks){ + ctx->GetItemLocation(check)->SetHintAccesible(); + } + std::vector areas = {}; + for (auto loc : locations){ + areas.push_back(RandomElementFromSet(ctx->GetItemLocation(loc)->GetAreas())); + } + //hintKeys are defaulted to in the hint object and do not need to be specified + ctx->AddHint(hint, Hint(hint, staticData.type, {}, locations, areas, {}, staticData.yourPocket, staticData.num)); } + } +} - //get a random hint type from the remaining hints - HintType type = RandomElement(remainingHintTypes, true); - - SPDLOG_DEBUG("Attempting to make hint of type: "); - SPDLOG_DEBUG(hintTypeNames.find(type)->second); - SPDLOG_DEBUG("\n"); - - //create the appropriate hint for the type - if (type == HINT_TYPE_WOTH) { - CreateWothHint(&remainingDungeonWothHints); - - } else if (type == HINT_TYPE_BARREN) { - CreateBarrenHint(&remainingDungeonBarrenHints, barrenLocations); - - } else if (type == HINT_TYPE_SOMETIMES){ - std::vector sometimesHintLocations = FilterFromPool(allLocations, [](const uint32_t loc){return Location(loc)->GetHint().GetType() == HintCategory::Sometimes && Location(loc)->IsHintable() && !(Location(loc)->IsHintedAt());}); - CreateLocationHint(sometimesHintLocations); - - } else if (type == HINT_TYPE_RANDOM) { - CreateRandomLocationHint(); - - } else if (type == HINT_TYPE_ITEM) { - CreateGoodItemHint(); - - } else if (type == HINT_TYPE_SONG){ - std::vector songHintLocations = FilterFromPool(allLocations, [](const uint32_t loc){return Location(loc)->IsCategory(Category::cSong) && Location(loc)->IsHintable() && !(Location(loc)->IsHintedAt());}); - CreateLocationHint(songHintLocations); - - } else if (type == HINT_TYPE_OVERWORLD){ - std::vector overworldHintLocations = FilterFromPool(allLocations, [](const uint32_t loc){return Location(loc)->IsOverworld() && Location(loc)->IsHintable() && !(Location(loc)->IsHintedAt());}); - CreateLocationHint(overworldHintLocations); +void CreateStaticItemHint(RandomizerHint hintKey, std::vector hintTextKeys, + std::vector items, std::vector hintChecks, bool yourPocket = false) { + //RANDOTODO choose area in case there are multiple + auto ctx = Rando::Context::GetInstance(); + std::vector locations = FindItemsAndMarkHinted(items, hintChecks); + std::vector areas = {}; + for (auto loc : locations){ + areas.push_back(RandomElementFromSet(ctx->GetItemLocation(loc)->GetAreas())); + } + ctx->AddHint(hintKey, Hint(hintKey, HINT_TYPE_AREA, hintTextKeys, locations, areas, {}, yourPocket)); +} - } else if (type == HINT_TYPE_DUNGEON){ - std::vector dungeonHintLocations = FilterFromPool(allLocations, [](const uint32_t loc){return Location(loc)->IsDungeon() && Location(loc)->IsHintable() && !(Location(loc)->IsHintedAt());}); - CreateLocationHint(dungeonHintLocations); +void CreateGanondorfJoke(){ + auto ctx = Rando::Context::GetInstance(); + if (!ctx->GetHint(RH_GANONDORF_JOKE)->IsEnabled()){ + ctx->AddHint(RH_GANONDORF_JOKE, Hint(RH_GANONDORF_JOKE, HINT_TYPE_HINT_KEY, {GetRandomGanonJoke()})); + } +} - } else if (type == HINT_TYPE_JUNK) { - CreateJunkHint(); +void CreateGanondorfHint(){ + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_GANONDORF_HINT) && !ctx->GetHint(RH_GANONDORF_HINT)->IsEnabled()){ + if (ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { + CreateStaticItemHint(RH_GANONDORF_HINT, {RHT_GANONDORF_HINT_LA_ONLY, RHT_GANONDORF_HINT_MS_ONLY, RHT_GANONDORF_HINT_LA_AND_MS}, + {RG_LIGHT_ARROWS, RG_MASTER_SWORD}, {RC_GANONDORF_HINT}, true); + } else { + CreateStaticItemHint(RH_GANONDORF_HINT, {RHT_GANONDORF_HINT_LA_ONLY}, {RG_LIGHT_ARROWS}, {RC_GANONDORF_HINT}, true); } } +} - //If any gossip stones failed to have a hint placed on them for some reason, place a junk hint as a failsafe. - for (uint32_t gossipStone : FilterFromPool(gossipStoneLocations, [](const uint32_t loc){return Location(loc)->GetPlaceduint32_t() == NONE;})) { - const HintText junkHint = RandomElement(GetHintCategory(HintCategory::Junk)); - AddHint(junkHint.GetText(), gossipStone, {QM_PINK}); +void CreateStaticHints(){ + CreateChildAltarHint(); + CreateAdultAltarHint(); + CreateGanondorfJoke(); + CreateGanondorfHint(); + for (auto[hint, staticData] : StaticData::staticHintInfoMap){ + CreateStaticHintFromData(hint, staticData); } +} - //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({}); +void CreateAllHints(){ + auto ctx = Rando::Context::GetInstance(); + + CreateStaticHints(); + + if (ctx->GetOption(RSK_GOSSIP_STONE_HINTS).IsNot(RO_GOSSIP_STONES_NONE)) { + SPDLOG_INFO("Creating Hints..."); + CreateStoneHints(); + SPDLOG_INFO("Creating Hints Done"); + } } diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.hpp b/soh/soh/Enhancements/randomizer/3drando/hints.hpp index 9bc6d61db44..d111c78ca97 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.hpp @@ -1,238 +1,74 @@ #pragma once -#include #include #include +#include -#include "keys.hpp" #include "text.hpp" #include "random.hpp" -#include "settings.hpp" #include +#include "../randomizerTypes.h" +#include "../../custom-message/CustomMessageManager.h" struct HintDistributionSetting { + std::string name; HintType type; - uint8_t order; - size_t weight; + uint32_t weight; uint8_t fixed; uint8_t copies; -}; - -struct HintSetting { - using DistributionTable = std::array(HINT_TYPE_MAX)>; + std::function filter; + uint8_t dungeonLimit; - uint8_t dungeonsWothLimit; - uint8_t dungeonsBarrenLimit; - bool namedItemsRequired; - DistributionTable distTable; + HintDistributionSetting(std::string _name, HintType _type, uint32_t _weight, uint8_t _fixed, uint8_t _copies, + std::function _filter, uint8_t _dungeonLimit = 40); }; -enum class HintCategory { - Item, - Always, - Sometimes, - Exclude, - Entrance, - Region, - Junk, - DungeonName, - Boss, - Bridge, - GanonsBossKey, - LACS, - Altar, - Validation, - LightArrow, - MasterSword, - GanonLine, - MerchantsDialogs, +struct HintSetting { + uint8_t alwaysCopies; + uint8_t trialCopies; + uint8_t junkWeight; + std::vector distTable; }; class HintText { public: HintText() = default; - HintText(std::vector obscureText_, std::vector ambiguousText_, Text clearText_, HintCategory type_) - : obscureText(std::move(obscureText_)), - ambiguousText(std::move(ambiguousText_)), - clearText(std::move(clearText_)), - type(type_) {} - - static auto Item(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Item}; - } - - static auto Always(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Always}; - } - - static auto Sometimes(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Sometimes}; - } - - static auto Exclude(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Exclude}; - } - - static auto Entrance(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Entrance}; - } - - static auto Region(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Region}; - } - - static auto Junk(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Junk}; - } - - static auto DungeonName(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::DungeonName}; - } - - static auto Boss(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Boss}; - } - - static auto Bridge(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Bridge}; - } - - static auto GanonsBossKey(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonsBossKey}; - } - - static auto LACS(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::LACS}; - } - - static auto Altar(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Altar}; - } - - static auto Validation(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Validation}; - } - - static auto LightArrow(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::LightArrow}; - } - - static auto MasterSword(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::MasterSword}; - } - - static auto GanonLine(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonLine}; - } - - static auto MerchantsDialogs(std::vector&& obscureText, std::vector&& ambiguousText = {}, Text&& clearText = {}) { - return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::MerchantsDialogs}; - } - - Text& GetObscure() { - return RandomElement(obscureText); - } - - const Text& GetObscure() const { - return RandomElement(obscureText); - } - - Text& GetAmbiguous() { - if (ambiguousText.size() > 0) { - return RandomElement(ambiguousText); - } - return RandomElement(obscureText); - } - - const Text& GetAmbiguous() const { - if (ambiguousText.size() > 0) { - return RandomElement(ambiguousText); - } - return RandomElement(obscureText); - } - - const Text& GetClear() const { - if (clearText.GetEnglish().empty()) { - return GetObscure(); - } - return clearText; - } - - const Text& GetText() const { - if (Settings::ClearerHints.Is(HINTMODE_OBSCURE)) { - return GetObscure(); - } else if (Settings::ClearerHints.Is(HINTMODE_AMBIGUOUS)){ - return GetAmbiguous(); - } else { - return GetClear(); - } - } - - const Text GetTextCopy() const { - if (Settings::ClearerHints.Is(HINTMODE_OBSCURE)) { - return GetObscure(); - } else if (Settings::ClearerHints.Is(HINTMODE_AMBIGUOUS)){ - return GetAmbiguous(); - } else { - return GetClear(); - } - } - - HintCategory GetType() const { - return type; - } - - bool operator==(const HintText& right) const { - return obscureText == right.obscureText && - ambiguousText == right.ambiguousText && - clearText == right.clearText; - } - bool operator!=(const HintText& right) const { - return !operator==(right); - } + HintText(CustomMessage clearText_, std::vector ambiguousText_ = {}, std::vector obscureText_ = {}); + const CustomMessage& GetClear() const; + const CustomMessage& GetObscure() const; + const CustomMessage& GetObscure(uint8_t selection) const; + const CustomMessage& GetAmbiguous() const; + const CustomMessage& GetAmbiguous(uint8_t selection) const; + uint8_t GetAmbiguousSize() const; + uint8_t GetObscureSize() const; + const CustomMessage& GetHintMessage(uint8_t selection = 0) const; + const CustomMessage GetMessageCopy() const; + bool operator==(const HintText& right) const; + bool operator!=(const HintText& right) const; private: - std::vector obscureText = {}; - std::vector ambiguousText = {}; - Text clearText; - HintCategory type; + CustomMessage clearText; + std::vector ambiguousText = {}; + std::vector obscureText = {}; }; -using ConditionalAlwaysHint = std::pair>; - -//10 dungeons as GTG and GC are excluded -extern std::array dungeonInfoData; - -extern std::array conditionalAlwaysHints; +struct StaticHintInfo{ + HintType type; + std::vector hintKeys; + RandomizerSettingKey setting; + std::variant condition; + std::vector targetChecks; + std::vector targetItems; + std::vector hintChecks; + bool yourPocket; + int num; + + StaticHintInfo() = default; + StaticHintInfo(HintType _type, std::vector _hintKeys, RandomizerSettingKey _setting, std::variant _condition, + std::vector _targetChecks, std::vector _targetItems = {}, + std::vector _hintChecks = {}, bool _yourPocket = false, int _num = 0); +}; -extern uint32_t GetHintRegionHintKey(const uint32_t area); extern void CreateAllHints(); -extern void CreateMerchantsHints(); extern void CreateWarpSongTexts(); -extern void CreateDampesDiaryText(); -extern void CreateGregRupeeHint(); -extern void CreateSheikText(); -extern void CreateSariaText(); -extern void CreateGanonText(); -extern void CreateAltarText(); - -Text& GetChildAltarText(); -Text& GetAdultAltarText(); -Text& GetGanonText(); -Text& GetGanonHintText(); -Text& GetDampeHintText(); -Text& GetGregHintText(); -Text& GetSheikHintText(); -Text& GetSariaHintText(); - -Text& GetWarpMinuetText(); -Text& GetWarpBoleroText(); -Text& GetWarpSerenadeText(); -Text& GetWarpRequiemText(); -Text& GetWarpNocturneText(); -Text& GetWarpPreludeText(); - -std::string GetDampeHintLoc(); -std::string GetMasterSwordHintLoc(); -std::string GetLightArrowHintLoc(); -std::string GetSariaHintLoc(); +void CreateStaticHints(); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/item.cpp b/soh/soh/Enhancements/randomizer/3drando/item.cpp deleted file mode 100644 index 3e10a165c9b..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/item.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "item.hpp" - -#include - -#include "item_location.hpp" -#include "logic.hpp" -#include "random.hpp" -#include "item_pool.hpp" -#include "settings.hpp" -#include "z64item.h" - -Item::Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int getItemId_, bool advancement_, bool* logicVar_, uint32_t hintKey_, - uint16_t price_) - : randomizerGet(randomizerGet_), - name(std::move(name_)), - type(type_), - getItemId(getItemId_), - advancement(advancement_), - logicVar(logicVar_), - hintKey(hintKey_), - price(price_) {} - -Item::Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int getItemId_, bool advancement_, uint8_t* logicVar_, uint32_t hintKey_, - uint16_t price_) - : randomizerGet(randomizerGet_), - name(std::move(name_)), - type(type_), - getItemId(getItemId_), - advancement(advancement_), - logicVar(logicVar_), - hintKey(hintKey_), - price(price_) {} - -Item::~Item() = default; - -void Item::ApplyEffect() { - //If this is a key ring, logically add as many keys as we could need - if (FOREST_TEMPLE_KEY_RING <= hintKey && hintKey <= GANONS_CASTLE_KEY_RING) { - *std::get(logicVar) += 10; - } - else { - if (std::holds_alternative(logicVar)) { - *std::get(logicVar) = true; - } else { - *std::get(logicVar) += 1; - } - } - Logic::UpdateHelpers(); -} - -void Item::UndoEffect() { - if (FOREST_TEMPLE_KEY_RING <= hintKey && hintKey <= GANONS_CASTLE_KEY_RING) { - *std::get(logicVar) -= 10; - } - else { - if (std::holds_alternative(logicVar)) { - *std::get(logicVar) = false; - } else { - *std::get(logicVar) -= 1; - } - } - Logic::UpdateHelpers(); -} - -ItemOverride_Value Item::Value() const { - ItemOverride_Value val; - - val.all = 0; - val.itemId = getItemId; - if (getItemId == GI_ICE_TRAP) { - val.looksLikeItemId = RandomElement(IceTrapModels); - } - if (getItemId >= 0x95 && getItemId <= 0x9A) { //Boss keys - val.looksLikeItemId = GI_KEY_BOSS; - } - if (getItemId >= 0xAF && getItemId <= 0xB7) { //Small keys - val.looksLikeItemId = GI_KEY_SMALL; - } - if (type == ITEMTYPE_SHOP) { - // With the current shopsanity implementation, we need a way to detect - // regular shop items. This method should have no unintended side effects - // unless there was a multiworld with 256 players... so, it should be fine. - val.player = 0xFF; - } - return val; -} diff --git a/soh/soh/Enhancements/randomizer/3drando/item.hpp b/soh/soh/Enhancements/randomizer/3drando/item.hpp deleted file mode 100644 index ee7bfc78387..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/item.hpp +++ /dev/null @@ -1,156 +0,0 @@ -#pragma once - -#include -#include - -#include "keys.hpp" -#include "hint_list.hpp" -#include "settings.hpp" -#include "../randomizerTypes.h" - -union ItemOverride_Value; - -enum ItemType { - ITEMTYPE_ITEM, - ITEMTYPE_MAP, - ITEMTYPE_COMPASS, - ITEMTYPE_BOSSKEY, - ITEMTYPE_SMALLKEY, - ITEMTYPE_TOKEN, - ITEMTYPE_FORTRESS_SMALLKEY, - ITEMTYPE_EVENT, - ITEMTYPE_DROP, - ITEMTYPE_REFILL, - ITEMTYPE_SONG, - ITEMTYPE_SHOP, - ITEMTYPE_DUNGEONREWARD -}; - -class Item { -public: - Item() = default; - Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int getItemId_, bool advancement_, bool* logicVar_, uint32_t hintKey_, - uint16_t price_ = 0); - Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int getItemId_, bool advancement_, uint8_t* logicVar_, uint32_t hintKey_, - uint16_t price_ = 0); - ~Item(); - - void ApplyEffect(); - void UndoEffect(); - - ItemOverride_Value Value() const; - - const Text& GetName() const { - return name; - } - - bool IsAdvancement() const { - return advancement; - } - - int GetItemID() const { - return getItemId; - } - - ItemType GetItemType() const { - return type; - } - - RandomizerGet GetRandomizerGet() { - return randomizerGet; - } - - uint16_t GetPrice() const { - return price; - } - - void SetPrice(uint16_t price_) { - price = price_; - } - - void SetAsPlaythrough() { - playthrough = true; - } - - bool IsPlaythrough() const { - return playthrough; - } - - bool IsBottleItem() const { - return getItemId == 0x0F || //Empty Bottle - getItemId == 0X14 || //Bottle with Milk - (getItemId >= 0x8C && getItemId <= 0x94); //Rest of bottled contents - } - - bool IsMajorItem() const { - using namespace Settings; - if (type == ITEMTYPE_TOKEN) { - return Bridge.Is(RAINBOWBRIDGE_TOKENS) || LACSCondition == LACSCONDITION_TOKENS; - } - - if (type == ITEMTYPE_DROP || type == ITEMTYPE_EVENT || type == ITEMTYPE_SHOP || type == ITEMTYPE_MAP || type == ITEMTYPE_COMPASS) { - return false; - } - - if (type == ITEMTYPE_DUNGEONREWARD && (ShuffleRewards.Is(REWARDSHUFFLE_END_OF_DUNGEON))) { - return false; - } - - if ((randomizerGet == RG_BOMBCHU_5 || randomizerGet == RG_BOMBCHU_10 || randomizerGet == RG_BOMBCHU_20) && !BombchusInLogic) { - return false; - } - - if (hintKey == HEART_CONTAINER || hintKey == PIECE_OF_HEART || hintKey == TREASURE_GAME_HEART) { - return false; - } - - if (type == ITEMTYPE_SMALLKEY && (Keysanity.Is(KEYSANITY_VANILLA) || Keysanity.Is(KEYSANITY_OWN_DUNGEON))) { - return false; - } - - if (type == ITEMTYPE_FORTRESS_SMALLKEY && GerudoKeys.Is(GERUDOKEYS_VANILLA)) { - return false; - } - - if ((type == ITEMTYPE_BOSSKEY && getItemId != 0xAD) && (BossKeysanity.Is(BOSSKEYSANITY_VANILLA) || BossKeysanity.Is(BOSSKEYSANITY_OWN_DUNGEON))) { - return false; - } - //Ganons Castle Boss Key - if (getItemId == 0xAD && (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA) || GanonsBossKey.Is(GANONSBOSSKEY_OWN_DUNGEON))) { - return false; - } - - if (randomizerGet == RG_GREG_RUPEE) { - return Bridge.Is(RAINBOWBRIDGE_GREG); - } - - return IsAdvancement(); - } - - uint32_t GetHintKey() const { - return hintKey; - } - - const HintText& GetHint() const { - return Hint(hintKey); - } - - bool operator== (const Item& right) const { - return type == right.GetItemType() && getItemId == right.GetItemID(); - } - - bool operator!= (const Item& right) const { - return !operator==(right); - } - -private: - RandomizerGet randomizerGet; - Text name; - ItemType type; - int getItemId; - bool advancement; - std::variant logicVar; - uint32_t hintKey; - uint16_t price; - bool playthrough = false; -}; diff --git a/soh/soh/Enhancements/randomizer/3drando/item_list.cpp b/soh/soh/Enhancements/randomizer/3drando/item_list.cpp deleted file mode 100644 index 34e9c779f7b..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/item_list.cpp +++ /dev/null @@ -1,311 +0,0 @@ -#include "item_list.hpp" - -#include "logic.hpp" -#include -#include "z64item.h" -#include "../randomizerTypes.h" - -using namespace Logic; - -static std::array itemTable; - -void ItemTable_Init() { // RandomizerGet English name French Spanish Item Type getItemID advancement logic hint key - itemTable[NONE] = Item(RG_NONE, Text{"No Item", "Rien", "Sin Objeto"}, ITEMTYPE_EVENT, GI_RUPEE_GREEN, false, &noVariable, NONE); - itemTable[KOKIRI_SWORD] = Item(RG_KOKIRI_SWORD, Text{"Kokiri Sword", "Épée Kokiri", "Espada Kokiri"}, ITEMTYPE_ITEM, GI_SWORD_KOKIRI, true, &KokiriSword, KOKIRI_SWORD); - itemTable[MASTER_SWORD] = Item(RG_MASTER_SWORD, Text{"Master Sword", "Épée de Legende", "Espada Master"}, ITEMTYPE_ITEM, 0xE0, true, &MasterSword, MASTER_SWORD); - itemTable[GIANTS_KNIFE] = Item(RG_GIANTS_KNIFE, Text{"Giant's Knife", "Lame des Géants", "Espada de Biggoron"}, ITEMTYPE_ITEM, GI_SWORD_KNIFE, false, &noVariable, GIANTS_KNIFE); - itemTable[BIGGORON_SWORD] = Item(RG_BIGGORON_SWORD, Text{"Biggoron's Sword", "Épée de Biggoron", "Espada de Biggoron"}, ITEMTYPE_ITEM, GI_SWORD_BGS, true, &BiggoronSword, BIGGORON_SWORD); - itemTable[DEKU_SHIELD] = Item(RG_DEKU_SHIELD, Text{"Deku Shield", "Bouclier Mojo", "Escudo deku"}, ITEMTYPE_ITEM, GI_SHIELD_DEKU, false, &noVariable, DEKU_SHIELD); - itemTable[HYLIAN_SHIELD] = Item(RG_HYLIAN_SHIELD, Text{"Hylian Shield", "Bouclier Hylien", "Escudo hyliano"}, ITEMTYPE_ITEM, GI_SHIELD_HYLIAN, false, &noVariable, HYLIAN_SHIELD); - itemTable[MIRROR_SHIELD] = Item(RG_MIRROR_SHIELD, Text{"Mirror Shield", "Bouclier Miroir", "Escudo espejo"}, ITEMTYPE_ITEM, GI_SHIELD_MIRROR, true, &MirrorShield, MIRROR_SHIELD); - itemTable[GORON_TUNIC] = Item(RG_GORON_TUNIC, Text{"Goron Tunic", "Tunique Goron", "Sayo goron"}, ITEMTYPE_ITEM, GI_TUNIC_GORON, true, &GoronTunic, GORON_TUNIC); - itemTable[ZORA_TUNIC] = Item(RG_ZORA_TUNIC, Text{"Zora Tunic", "Tunique Zora", "Sayo zora"}, ITEMTYPE_ITEM, GI_TUNIC_ZORA, true, &ZoraTunic, ZORA_TUNIC); - itemTable[IRON_BOOTS] = Item(RG_IRON_BOOTS, Text{"Iron Boots", "Bottes de plomb", "Botas de hierro"}, ITEMTYPE_ITEM, GI_BOOTS_IRON, true, &IronBoots, IRON_BOOTS); - itemTable[HOVER_BOOTS] = Item(RG_HOVER_BOOTS, Text{"Hover Boots", "Bottes des airs", "Botas voladoras"}, ITEMTYPE_ITEM, GI_BOOTS_HOVER, true, &HoverBoots, HOVER_BOOTS); - - - itemTable[BOOMERANG] = Item(RG_BOOMERANG, Text{"Boomerang", "Boomerang", "Búmeran"}, ITEMTYPE_ITEM, GI_BOOMERANG, true, &Boomerang, BOOMERANG); - itemTable[LENS_OF_TRUTH] = Item(RG_LENS_OF_TRUTH, Text{"Lens of Truth", "Monocle de Vérité", "Lupa de la Verdad"}, ITEMTYPE_ITEM, GI_LENS, true, &LensOfTruth, LENS_OF_TRUTH); - itemTable[MEGATON_HAMMER] = Item(RG_MEGATON_HAMMER, Text{"Megaton Hammer", "Masse des Titans", "Martillo Megatón"}, ITEMTYPE_ITEM, GI_HAMMER, true, &Hammer, MEGATON_HAMMER); - itemTable[STONE_OF_AGONY] = Item(RG_STONE_OF_AGONY, Text{"Stone of Agony", "Pierre de Souffrance", "Piedra de la Agonía"}, ITEMTYPE_ITEM, GI_STONE_OF_AGONY, true, &ShardOfAgony, STONE_OF_AGONY); - itemTable[DINS_FIRE] = Item(RG_DINS_FIRE, Text{"Din's Fire", "Feu de Din", "Fuego de Din"}, ITEMTYPE_ITEM, GI_DINS_FIRE, true, &DinsFire, DINS_FIRE); - itemTable[FARORES_WIND] = Item(RG_FARORES_WIND, Text{"Farore's Wind", "Vent de Farore", "Viento de Farore"}, ITEMTYPE_ITEM, GI_FARORES_WIND, true, &FaroresWind, FARORES_WIND); - itemTable[NAYRUS_LOVE] = Item(RG_NAYRUS_LOVE, Text{"Nayru's Love", "Amour de Nayru", "Amor de Nayru"}, ITEMTYPE_ITEM, GI_NAYRUS_LOVE, true, &NayrusLove, NAYRUS_LOVE); - itemTable[FIRE_ARROWS] = Item(RG_FIRE_ARROWS, Text{"Fire Arrow", "Flèche de Feu", "Flecha de fuego"}, ITEMTYPE_ITEM, GI_ARROW_FIRE, true, &FireArrows, FIRE_ARROWS); - itemTable[ICE_ARROWS] = Item(RG_ICE_ARROWS, Text{"Ice Arrow", "Flèche de Glace", "Flecha de hielo"}, ITEMTYPE_ITEM, GI_ARROW_ICE, true, &IceArrows, ICE_ARROWS); - itemTable[LIGHT_ARROWS] = Item(RG_LIGHT_ARROWS, Text{"Light Arrow", "Flèche de Lumière", "Flecha de luz"}, ITEMTYPE_ITEM, GI_ARROW_LIGHT, true, &LightArrows, LIGHT_ARROWS); - itemTable[GERUDO_MEMBERSHIP_CARD] = Item(RG_GERUDO_MEMBERSHIP_CARD, Text{"Gerudo Membership Card", "Carte Gerudo", "Pase de socio gerudo"}, ITEMTYPE_ITEM, GI_GERUDO_CARD, true, &GerudoToken, GERUDO_MEMBERSHIP_CARD); - itemTable[MAGIC_BEAN] = Item(RG_MAGIC_BEAN, Text{"Magic Bean", "Haricots Magiques", "Habichuelas mágicas"}, ITEMTYPE_ITEM, GI_BEAN, true, &MagicBean, MAGIC_BEAN); - itemTable[MAGIC_BEAN_PACK] = Item(RG_MAGIC_BEAN_PACK, Text{"Magic Bean Pack", "Paquet de Haricots Magiques", "Lote de habichuelas mágicas"}, ITEMTYPE_ITEM, 0xC9, true, &MagicBeanPack, MAGIC_BEAN_PACK); - itemTable[DOUBLE_DEFENSE] = Item(RG_DOUBLE_DEFENSE, Text{"Double Defense", "Double Défence", "Doble poder defensivo"}, ITEMTYPE_ITEM, 0xB8, true, &DoubleDefense, DOUBLE_DEFENSE); - - itemTable[WEIRD_EGG] = Item(RG_WEIRD_EGG, Text{"Weird Egg", "Oeuf Curieux", "Huevo extraño"}, ITEMTYPE_ITEM, GI_WEIRD_EGG, true, &WeirdEgg, WEIRD_EGG); -// itemTable[CUCCO] = Item(RG_CUCCO, Text{"Cucco", "Cocotte", "Cuco"}, ITEMTYPE_ITEM, GI_CUCCO, true, &Cucco, CUCCO); - itemTable[ZELDAS_LETTER] = Item(RG_ZELDAS_LETTER, Text{"Zelda's Letter", "Lettre de Zelda", "Carta de Zelda"}, ITEMTYPE_ITEM, GI_LETTER_ZELDA, true, &ZeldasLetter, ZELDAS_LETTER); -// itemTable[KEATON_MASK] = Item(RG_KEATON_MASK, Text{"Keaton Mask", "Masque du Renard", "Careta de Keaton"}, ITEMTYPE_ITEM, GI_MASK_KEATON, true, &KeatonMask, KEATON_MASK); -// itemTable[SKULL_MASK] = Item(RG_SKULL_MASK, Text{"Skull Mask", "Masque de Mort", "Máscara de calavera"}, ITEMTYPE_ITEM, GI_MASK_SKULL, true, &SkullMask, SKULL_MASK); -// itemTable[SPOOKY_MASK] = Item(RG_SPOOKY_MASK, Text{"Spooky Mask", "Masque d'Effroi", "Máscara tenebrosa"}, ITEMTYPE_ITEM, GI_MASK_SPOOKY, true, &SpookyMask, SPOOKY_MASK); -// itemTable[BUNNY_HOOD] = Item(RG_BUNNY_HOOD, Text{"Bunny Hood", "Masque du Lapin", "Capucha de conejo"}, ITEMTYPE_ITEM, GI_MASK_BUNNY, true, &BunnyHood, BUNNY_HOOD); -// itemTable[GORON_MASK] = Item(RG_GORON_MASK, Text{"Goron Mask", "Masque de Goron", "Máscara Goron"}, ITEMTYPE_ITEM, GI_MASK_GORON, true, &GoronMask, GORON_MASK); -// itemTable[ZORA_MASK] = Item(RG_ZORA_MASK, Text{"Zora Mask", "Masque de Zora", "Máscara Zora"}, ITEMTYPE_ITEM, GI_MASK_ZORA, true, &ZoraMask, ZORA_MASK); -// itemTable[GERUDO_MASK] = Item(RG_GERUDO_MASK, Text{"Gerudo Mask", "Masque de Gerudo", "Máscara Gerudo"}, ITEMTYPE_ITEM, GI_MASK_GERUDO, true, &GerudoMask, GERUDO_MASK); -// itemTable[MASK_OF_TRUTH] = Item(RG_MASK_OF_TRUTH, Text{"Mask of Truth", "Masque de Vérité", "Máscara de la Verdad"}, ITEMTYPE_ITEM, GI_MASK_MASK, true, &MaskofTruth, MASK_OF_TRUTH); - itemTable[POCKET_EGG] = Item(RG_POCKET_EGG, Text{"Pocket Egg", "Oeuf de poche", "Huevo de bolsillo"}, ITEMTYPE_ITEM, GI_POCKET_EGG, true, &PocketEgg, POCKET_EGG); -// itemTable[POCKET_CUCCO] = Item(RG_POCKET_CUCCO, Text{"Pocket Cucco", "Cocotte de poche", "Cuco de bolsillo"}, ITEMTYPE_ITEM, GI_POCKET_CUCCO, true, &PocketCucco, POCKET_CUCCO); - itemTable[COJIRO] = Item(RG_COJIRO, Text{"Cojiro", "P'tit Poulet", "Cojiro"}, ITEMTYPE_ITEM, GI_COJIRO, true, &Cojiro, COJIRO); - itemTable[ODD_MUSHROOM] = Item(RG_ODD_MUSHROOM, Text{"Odd Mushroom", "Champignon Suspect", "Champiñón extraño"}, ITEMTYPE_ITEM, GI_ODD_MUSHROOM, true, &OddMushroom, ODD_MUSHROOM); - itemTable[ODD_POTION] = Item(RG_ODD_POTION, Text{"Odd Potion", "Mixture Suspecte", "Medicina rara"}, ITEMTYPE_ITEM, GI_ODD_POTION, true, &OddPoultice, ODD_POTION); - itemTable[POACHERS_SAW] = Item(RG_POACHERS_SAW, Text{"Poacher's Saw", "Scie du Chasseur", "Sierra del furtivo"}, ITEMTYPE_ITEM, GI_SAW, true, &PoachersSaw, POACHERS_SAW); - itemTable[BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{"Broken Goron's Sword", "Épée Brisée de Goron", "Espada goron rota"}, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, &BrokenSword, BROKEN_SWORD); - itemTable[PRESCRIPTION] = Item(RG_PRESCRIPTION, Text{"Prescription", "Ordonnance", "Receta"}, ITEMTYPE_ITEM, GI_PRESCRIPTION, true, &Prescription, PRESCRIPTION); - itemTable[EYEBALL_FROG] = Item(RG_EYEBALL_FROG, Text{"Eyeball Frog", "Crapaud-qui-louche", "Rana de ojos saltones"}, ITEMTYPE_ITEM, GI_FROG, true, &EyeballFrog, EYEBALL_FROG); - itemTable[EYEDROPS] = Item(RG_EYEDROPS, Text{"World's Finest Eyedrops", "Super Gouttes", "Supergotas oculares"}, ITEMTYPE_ITEM, GI_EYEDROPS, true, &Eyedrops, EYEDROPS); - itemTable[CLAIM_CHECK] = Item(RG_CLAIM_CHECK, Text{"Claim Check", "Certificat", "Recibo"}, ITEMTYPE_ITEM, GI_CLAIM_CHECK, true, &ClaimCheck, CLAIM_CHECK); - - itemTable[GOLD_SKULLTULA_TOKEN] = Item(RG_GOLD_SKULLTULA_TOKEN, Text{"Gold Skulltula Token", "Symbole de Skulltula d'Or", "Símbolo de skulltula dorada"}, ITEMTYPE_TOKEN, GI_SKULL_TOKEN, true, &GoldSkulltulaTokens, GOLD_SKULLTULA_TOKEN); - - //Progression Items - itemTable[PROGRESSIVE_HOOKSHOT] = Item(RG_PROGRESSIVE_HOOKSHOT, Text{"Progressive Hookshot", "Grappin (prog.)", "Gancho progresivo"}, ITEMTYPE_ITEM, 0x80, true, &ProgressiveHookshot, PROGRESSIVE_HOOKSHOT); - itemTable[PROGRESSIVE_STRENGTH] = Item(RG_PROGRESSIVE_STRENGTH, Text{"Strength Upgrade", "Amélioration de Force (prog.)", "Fuerza progresiva"}, ITEMTYPE_ITEM, 0x81, true, &ProgressiveStrength, PROGRESSIVE_STRENGTH); - itemTable[PROGRESSIVE_BOMB_BAG] = Item(RG_PROGRESSIVE_BOMB_BAG, Text{"Progressive Bomb Bag", "Sac de Bombes (prog.)", "Saco de bombas progresivo"}, ITEMTYPE_ITEM, 0x82, true, &ProgressiveBombBag, PROGRESSIVE_BOMB_BAG); - itemTable[PROGRESSIVE_BOW] = Item(RG_PROGRESSIVE_BOW, Text{"Progressive Bow", "Arc (prog.)", "Arco progresivo"}, ITEMTYPE_ITEM, 0x83, true, &ProgressiveBow, PROGRESSIVE_BOW); - itemTable[PROGRESSIVE_SLINGSHOT] = Item(RG_PROGRESSIVE_SLINGSHOT, Text{"Progressive Slingshot", "Lance-Pierre (prog.)", "Resortera progresiva"}, ITEMTYPE_ITEM, 0x84, true, &ProgressiveBulletBag, PROGRESSIVE_SLINGSHOT); - itemTable[PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{"Progressive Wallet", "Bourse (prog.)", "Bolsa de rupias progresiva"}, ITEMTYPE_ITEM, 0x85, true, &ProgressiveWallet, PROGRESSIVE_WALLET); - itemTable[PROGRESSIVE_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{"Progressive Scale", "Écaille (prog.)", "Escama progresiva"}, ITEMTYPE_ITEM, 0x86, true, &ProgressiveScale, PROGRESSIVE_SCALE); - itemTable[PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{"Progressive Nut Capacity", "Capacité de Noix (prog.)", "Capacidad de nueces deku progresiva"}, ITEMTYPE_ITEM, 0x87, false, &noVariable, PROGRESSIVE_NUT_UPGRADE); - itemTable[PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{"Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Capacidad de palos deku progresiva"}, ITEMTYPE_ITEM, 0x88, false, &noVariable, PROGRESSIVE_STICK_UPGRADE); - itemTable[PROGRESSIVE_BOMBCHUS] = Item(RG_PROGRESSIVE_BOMBCHUS, Text{"Progressive Bombchu", "Missiles (prog.)", "Bombchus progresivos"}, ITEMTYPE_ITEM, 0x89, true, &Bombchus, PROGRESSIVE_BOMBCHUS); - itemTable[PROGRESSIVE_MAGIC_METER] = Item(RG_PROGRESSIVE_MAGIC_METER, Text{"Progressive Magic Meter", "Jauge de Magie (prog.)", "Poder mágico progresivo"}, ITEMTYPE_ITEM, 0x8A, true, &ProgressiveMagic, PROGRESSIVE_MAGIC_METER); - itemTable[PROGRESSIVE_OCARINA] = Item(RG_PROGRESSIVE_OCARINA, Text{"Progressive Ocarina", "Ocarina (prog.)", "Ocarina progresiva"}, ITEMTYPE_ITEM, 0x8B, true, &ProgressiveOcarina, PROGRESSIVE_OCARINA); - itemTable[PROGRESSIVE_GORONSWORD] = Item(RG_PROGRESSIVE_GORONSWORD, Text{"Progressive Goron Sword", "Épée Goron (prog.)", "Espada Goron progresiva"}, ITEMTYPE_ITEM, 0xD4, true, &ProgressiveGiantKnife, PROGRESSIVE_GORONSWORD); - - //Bottles - itemTable[EMPTY_BOTTLE] = Item(RG_EMPTY_BOTTLE, Text{"Empty Bottle", "Bouteille Vide", "Botella vacía"}, ITEMTYPE_ITEM, 0x0F, true, &Bottles, EMPTY_BOTTLE); - itemTable[BOTTLE_WITH_MILK] = Item(RG_BOTTLE_WITH_MILK, Text{"Bottle with Milk", "Bouteille avec du Lait", "Botella de leche Lon Lon"}, ITEMTYPE_ITEM, 0x14, true, &Bottles, BOTTLE_WITH_MILK); - itemTable[BOTTLE_WITH_RED_POTION] = Item(RG_BOTTLE_WITH_RED_POTION, Text{"Bottle with Red Potion", "Bouteille avec une Potion Rouge", "Botella de poción roja"}, ITEMTYPE_ITEM, 0x8C, true, &Bottles, BOTTLE_WITH_RED_POTION); - itemTable[BOTTLE_WITH_GREEN_POTION] = Item(RG_BOTTLE_WITH_GREEN_POTION, Text{"Bottle with Green Potion", "Bouteille avec une Potion Verte", "Botella de poción verde"}, ITEMTYPE_ITEM, 0x8D, true, &Bottles, BOTTLE_WITH_GREEN_POTION); - itemTable[BOTTLE_WITH_BLUE_POTION] = Item(RG_BOTTLE_WITH_BLUE_POTION, Text{"Bottle with Blue Potion", "Bouteille avec une Potion Bleue", "Botella de poción azul"}, ITEMTYPE_ITEM, 0x8E, true, &Bottles, BOTTLE_WITH_BLUE_POTION); - itemTable[BOTTLE_WITH_FAIRY] = Item(RG_BOTTLE_WITH_FAIRY, Text{"Bottle with Fairy", "Bouteille avec une Fée", "Hada en una botella"}, ITEMTYPE_ITEM, 0x8F, true, &Bottles, BOTTLE_WITH_FAIRY); - itemTable[BOTTLE_WITH_FISH] = Item(RG_BOTTLE_WITH_FISH, Text{"Bottle with Fish", "Bouteille avec un Poisson", "Pez en una botella"}, ITEMTYPE_ITEM, 0x90, true, &Bottles, BOTTLE_WITH_FISH); - itemTable[BOTTLE_WITH_BLUE_FIRE] = Item(RG_BOTTLE_WITH_BLUE_FIRE, Text{"Bottle with Blue Fire", "Bouteille avec une Flamme Bleue", "Botella de fuego azul"}, ITEMTYPE_ITEM, 0x91, true, &Bottles, BOTTLE_WITH_BLUE_FIRE); - itemTable[BOTTLE_WITH_BUGS] = Item(RG_BOTTLE_WITH_BUGS, Text{"Bottle with Bugs", "Bouteille avec des Insectes", "Insecto en una botella"}, ITEMTYPE_ITEM, 0x92, true, &Bottles, BOTTLE_WITH_BUGS); - itemTable[BOTTLE_WITH_POE] = Item(RG_BOTTLE_WITH_POE, Text{"Bottle with Poe", "Bouteille avec un Esprit", "Poe en una botella"}, ITEMTYPE_ITEM, 0x94, true, &Bottles, BOTTLE_WITH_POE); - - //Special bottles that can't immediately dump contents - itemTable[RUTOS_LETTER] = Item(RG_RUTOS_LETTER, Text{"Bottle with Ruto's Letter", "Bouteille avec la Lettre de Ruto", "Carta de Ruto"}, ITEMTYPE_ITEM, 0x15, true, &RutosLetter, RUTOS_LETTER); - itemTable[BOTTLE_WITH_BIG_POE] = Item(RG_BOTTLE_WITH_BIG_POE, Text{"Bottle with Big Poe", "Bouteille avec une Âme", "Gran Poe en una botella"}, ITEMTYPE_ITEM, 0x93, true, &BottleWithBigPoe, BOTTLE_WITH_BIG_POE); - - //Songs - itemTable[ZELDAS_LULLABY] = Item(RG_ZELDAS_LULLABY, Text{"Zelda's Lullaby", "Berceuse de Zelda", "Nana de Zelda"}, ITEMTYPE_SONG, 0xC1, true, &ZeldasLullaby, ZELDAS_LULLABY); - itemTable[EPONAS_SONG] = Item(RG_EPONAS_SONG, Text{"Epona's Song", "Chant d'Épona", "Canción de Epona"}, ITEMTYPE_SONG, 0xC2, true, &EponasSong, EPONAS_SONG); - itemTable[SARIAS_SONG] = Item(RG_SARIAS_SONG, Text{"Saria's Song", "Chant de Saria", "Canción de Saria"}, ITEMTYPE_SONG, 0xC3, true, &SariasSong, SARIAS_SONG); - itemTable[SUNS_SONG] = Item(RG_SUNS_SONG, Text{"Sun's Song", "Chant du Soleil", "Canción del Sol"}, ITEMTYPE_SONG, 0xC4, true, &SunsSong, SUNS_SONG); - itemTable[SONG_OF_TIME] = Item(RG_SONG_OF_TIME, Text{"Song of Time", "Chant du Temps", "Canción del tiempo"}, ITEMTYPE_SONG, 0xC5, true, &SongOfTime, SONG_OF_TIME); - itemTable[SONG_OF_STORMS] = Item(RG_SONG_OF_STORMS, Text{"Song of Storms", "Chant des Tempêtes", "Canción de la tormenta"}, ITEMTYPE_SONG, 0xC6, true, &SongOfStorms, SONG_OF_STORMS); - itemTable[MINUET_OF_FOREST] = Item(RG_MINUET_OF_FOREST, Text{"Minuet of Forest", "Menuet des Bois", "Minueto del bosque"}, ITEMTYPE_SONG, 0xBB, true, &MinuetOfForest, MINUET_OF_FOREST); - itemTable[BOLERO_OF_FIRE] = Item(RG_BOLERO_OF_FIRE, Text{"Bolero of Fire", "Boléro du Feu", "Bolero del fuego"}, ITEMTYPE_SONG, 0xBC, true, &BoleroOfFire, BOLERO_OF_FIRE); - itemTable[SERENADE_OF_WATER] = Item(RG_SERENADE_OF_WATER, Text{"Serenade of Water", "Sérénade de l'Eau", "Serenata del agua"}, ITEMTYPE_SONG, 0xBD, true, &SerenadeOfWater, SERENADE_OF_WATER); - itemTable[REQUIEM_OF_SPIRIT] = Item(RG_REQUIEM_OF_SPIRIT, Text{"Requiem of Spirit", "Requiem des Esprits", "Réquiem del espíritu"}, ITEMTYPE_SONG, 0xBE, true, &RequiemOfSpirit, REQUIEM_OF_SPIRIT); - itemTable[NOCTURNE_OF_SHADOW] = Item(RG_NOCTURNE_OF_SHADOW, Text{"Nocturne of Shadow", "Nocturne de l'Ombre", "Nocturno de la sombra"}, ITEMTYPE_SONG, 0xBF, true, &NocturneOfShadow, NOCTURNE_OF_SHADOW); - itemTable[PRELUDE_OF_LIGHT] = Item(RG_PRELUDE_OF_LIGHT, Text{"Prelude of Light", "Prélude de la Lumière", "Preludio de la luz"}, ITEMTYPE_SONG, 0xC0, true, &PreludeOfLight, PRELUDE_OF_LIGHT); - - //Maps and Compasses - itemTable[DEKU_TREE_MAP] = Item(RG_DEKU_TREE_MAP, Text{"Great Deku Tree Map", "Carte de l'Arbre Mojo", "Mapa del Gran Árbol Deku"}, ITEMTYPE_MAP, 0xA5, false, &noVariable, DEKU_TREE_MAP); - itemTable[DODONGOS_CAVERN_MAP] = Item(RG_DODONGOS_CAVERN_MAP, Text{"Dodongo's Cavern Map", "Carte de la Caverne Dodongo", "Mapa de la Cueva de los Dodongos"}, ITEMTYPE_MAP, 0xA6, false, &noVariable, DODONGOS_CAVERN_MAP); - itemTable[JABU_JABUS_BELLY_MAP] = Item(RG_JABU_JABUS_BELLY_MAP, Text{"Jabu-Jabu's Belly Map", "Carte du Ventre de Jabu-Jabu", "Mapa de la tripa de Jabu-Jabu"}, ITEMTYPE_MAP, 0xA7, false, &noVariable, JABU_JABUS_BELLY_MAP); - itemTable[FOREST_TEMPLE_MAP] = Item(RG_FOREST_TEMPLE_MAP, Text{"Forest Temple Map", "Carte du Temple de la Forêt", "Mapa del Templo del Bosque"}, ITEMTYPE_MAP, 0xA8, false, &noVariable, FOREST_TEMPLE_MAP); - itemTable[FIRE_TEMPLE_MAP] = Item(RG_FIRE_TEMPLE_MAP, Text{"Fire Temple Map", "Carte du Temple du Feu", "Mapa del Templo del Fuego"}, ITEMTYPE_MAP, 0xA9, false, &noVariable, FIRE_TEMPLE_MAP); - itemTable[WATER_TEMPLE_MAP] = Item(RG_WATER_TEMPLE_MAP, Text{"Water Temple Map", "Carte du Temple de l'Eau", "Mapa del Templo del Agua"}, ITEMTYPE_MAP, 0xAA, false, &noVariable, WATER_TEMPLE_MAP); - itemTable[SPIRIT_TEMPLE_MAP] = Item(RG_SPIRIT_TEMPLE_MAP, Text{"Spirit Temple Map", "Carte du Temple de l'Esprit", "Mapa del Templo del Espíritu"}, ITEMTYPE_MAP, 0xAB, false, &noVariable, SPIRIT_TEMPLE_MAP); - itemTable[SHADOW_TEMPLE_MAP] = Item(RG_SHADOW_TEMPLE_MAP, Text{"Shadow Temple Map", "Carte du Temple de l'Ombre", "Mapa del Templo de la Sombra"}, ITEMTYPE_MAP, 0xAC, false, &noVariable, SHADOW_TEMPLE_MAP); - itemTable[BOTTOM_OF_THE_WELL_MAP] = Item(RG_BOTTOM_OF_THE_WELL_MAP, Text{"Bottom of the Well Map", "Carte du Puits", "Mapa del fondo del pozo"}, ITEMTYPE_MAP, 0xAD, false, &noVariable, BOTTOM_OF_THE_WELL_MAP); - itemTable[ICE_CAVERN_MAP] = Item(RG_ICE_CAVERN_MAP, Text{"Ice Cavern Map", "Carte de la Caverne Polaire", "Mapa de la caverna de hielo"}, ITEMTYPE_MAP, 0xAE, false, &noVariable, ICE_CAVERN_MAP); - - itemTable[DEKU_TREE_COMPASS] = Item(RG_DEKU_TREE_COMPASS, Text{"Great Deku Tree Compass", "Boussole de l'Arbre Mojo", "Brújula del Gran Árbol Deku"}, ITEMTYPE_COMPASS, 0x9B, false, &noVariable, DEKU_TREE_COMPASS); - itemTable[DODONGOS_CAVERN_COMPASS] = Item(RG_DODONGOS_CAVERN_COMPASS, Text{"Dodongo's Cavern Compass", "Boussole de la Caverne Dodongo", "Brújula de la Cueva de los Dodongos"}, ITEMTYPE_COMPASS, 0x9C, false, &noVariable, DODONGOS_CAVERN_COMPASS); - itemTable[JABU_JABUS_BELLY_COMPASS] = Item(RG_JABU_JABUS_BELLY_COMPASS, Text{"Jabu-Jabu's Belly Compass", "Boussole du Ventre de Jabu-Jabu", "Brújula de la tripa de Jabu-Jabu"}, ITEMTYPE_COMPASS, 0x9D, false, &noVariable, JABU_JABUS_BELLY_COMPASS); - itemTable[FOREST_TEMPLE_COMPASS] = Item(RG_FOREST_TEMPLE_COMPASS, Text{"Forest Temple Compass", "Boussole du Temple de la Forêt", "Brújula del Templo del Bosque"}, ITEMTYPE_COMPASS, 0x9E, false, &noVariable, FOREST_TEMPLE_COMPASS); - itemTable[FIRE_TEMPLE_COMPASS] = Item(RG_FIRE_TEMPLE_COMPASS, Text{"Fire Temple Compass", "Boussole du Temple du Feu", "Brújula del Templo del Fuego"}, ITEMTYPE_COMPASS, 0x9F, false, &noVariable, FIRE_TEMPLE_COMPASS); - itemTable[WATER_TEMPLE_COMPASS] = Item(RG_WATER_TEMPLE_COMPASS, Text{"Water Temple Compass", "Boussole du Temple de l'Eau", "Brújula del Templo del Agua"}, ITEMTYPE_COMPASS, 0xA0, false, &noVariable, WATER_TEMPLE_COMPASS); - itemTable[SPIRIT_TEMPLE_COMPASS] = Item(RG_SPIRIT_TEMPLE_COMPASS, Text{"Spirit Temple Compass", "Boussole du Temple de l'Esprit", "Brújula del Templo del Espíritu"}, ITEMTYPE_COMPASS, 0xA1, false, &noVariable, SPIRIT_TEMPLE_COMPASS); - itemTable[SHADOW_TEMPLE_COMPASS] = Item(RG_SHADOW_TEMPLE_COMPASS, Text{"Shadow Temple Compass", "Boussole du Temple de l'Ombre", "Brújula del Templo de las Sombras"}, ITEMTYPE_COMPASS, 0xA2, false, &noVariable, SHADOW_TEMPLE_COMPASS); - itemTable[BOTTOM_OF_THE_WELL_COMPASS] = Item(RG_BOTTOM_OF_THE_WELL_COMPASS, Text{"Bottom of the Well Compass", "Boussole du Puits", "Brújula del fondo del pozo"}, ITEMTYPE_COMPASS, 0xA3, false, &noVariable, BOTTOM_OF_THE_WELL_COMPASS); - itemTable[ICE_CAVERN_COMPASS] = Item(RG_ICE_CAVERN_COMPASS, Text{"Ice Cavern Compass", "Boussole de la Caverne Polaire", "Brújula de la caverna de hielo"}, ITEMTYPE_COMPASS, 0xA4, false, &noVariable, ICE_CAVERN_COMPASS); - - //Boss Keys - itemTable[FOREST_TEMPLE_BOSS_KEY] = Item(RG_FOREST_TEMPLE_BOSS_KEY, Text{"Forest Temple Boss Key", "Clé d'Or du Temple de la Forêt", "Gran llave del Templo del Bosque"}, ITEMTYPE_BOSSKEY, 0x95, true, &BossKeyForestTemple, FOREST_TEMPLE_BOSS_KEY); - itemTable[FIRE_TEMPLE_BOSS_KEY] = Item(RG_FIRE_TEMPLE_BOSS_KEY, Text{"Fire Temple Boss Key", "Clé d'Or du Temple du Feu", "Gran llave del Templo del Fuego"}, ITEMTYPE_BOSSKEY, 0x96, true, &BossKeyFireTemple, FIRE_TEMPLE_BOSS_KEY); - itemTable[WATER_TEMPLE_BOSS_KEY] = Item(RG_WATER_TEMPLE_BOSS_KEY, Text{"Water Temple Boss Key", "Clé d'Or du Temple de l'Eau", "Gran llave del Templo del Agua"}, ITEMTYPE_BOSSKEY, 0x97, true, &BossKeyWaterTemple, WATER_TEMPLE_BOSS_KEY); - itemTable[SPIRIT_TEMPLE_BOSS_KEY] = Item(RG_SPIRIT_TEMPLE_BOSS_KEY, Text{"Spirit Temple Boss Key", "Clé d'Or du Temple de l'Esprit", "Gran llave del Templo del Espíritu"}, ITEMTYPE_BOSSKEY, 0x98, true, &BossKeySpiritTemple, SPIRIT_TEMPLE_BOSS_KEY); - itemTable[SHADOW_TEMPLE_BOSS_KEY] = Item(RG_SHADOW_TEMPLE_BOSS_KEY, Text{"Shadow Temple Boss Key", "Clé d'Or du Temple de l'Ombre", "Gran llave del Templo de las Sombras"}, ITEMTYPE_BOSSKEY, 0x99, true, &BossKeyShadowTemple, SHADOW_TEMPLE_BOSS_KEY); - itemTable[GANONS_CASTLE_BOSS_KEY] = Item(RG_GANONS_CASTLE_BOSS_KEY, Text{"Ganon's Castle Boss Key", "Clé d'Or du Château de Ganon", "Gran llave del Castillo de Ganon"}, ITEMTYPE_BOSSKEY, 0x9A, true, &BossKeyGanonsCastle, GANONS_CASTLE_BOSS_KEY); - - //Small Keys - itemTable[FOREST_TEMPLE_SMALL_KEY] = Item(RG_FOREST_TEMPLE_SMALL_KEY, Text{"Forest Temple Small Key", "Petite Clé du Temple de la Forêt", "Llave del Templo del Bosque"}, ITEMTYPE_SMALLKEY, 0xAF, true, &ForestTempleKeys, FOREST_TEMPLE_SMALL_KEY); - itemTable[FIRE_TEMPLE_SMALL_KEY] = Item(RG_FIRE_TEMPLE_SMALL_KEY, Text{"Fire Temple Small Key", "Petite Clé du Temple du Feu", "Llave del Templo del Fuego"}, ITEMTYPE_SMALLKEY, 0xB0, true, &FireTempleKeys, FIRE_TEMPLE_SMALL_KEY); - itemTable[WATER_TEMPLE_SMALL_KEY] = Item(RG_WATER_TEMPLE_SMALL_KEY, Text{"Water Temple Small Key", "Petite Clé du Temple de l'Eau", "Llave del Templo del Agua"}, ITEMTYPE_SMALLKEY, 0xB1, true, &WaterTempleKeys, WATER_TEMPLE_SMALL_KEY); - itemTable[SPIRIT_TEMPLE_SMALL_KEY] = Item(RG_SPIRIT_TEMPLE_SMALL_KEY, Text{"Spirit Temple Small Key", "Petite Clé du Temple de l'Esprit", "Llave del Templo del Espíritu"}, ITEMTYPE_SMALLKEY, 0xB2, true, &SpiritTempleKeys, SPIRIT_TEMPLE_SMALL_KEY); - itemTable[SHADOW_TEMPLE_SMALL_KEY] = Item(RG_SHADOW_TEMPLE_SMALL_KEY, Text{"Shadow Temple Small Key", "Petite Clé du Temple de l'Ombre", "Llave del Templo de las Sombras"}, ITEMTYPE_SMALLKEY, 0xB3, true, &ShadowTempleKeys, SHADOW_TEMPLE_SMALL_KEY); - itemTable[BOTTOM_OF_THE_WELL_SMALL_KEY] = Item(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, Text{"Bottom of the Well Small Key", "Petite Clé du Puits", "Llave del fondo del pozo"}, ITEMTYPE_SMALLKEY, 0xB4, true, &BottomOfTheWellKeys, BOTTOM_OF_THE_WELL_SMALL_KEY); - itemTable[GERUDO_TRAINING_GROUNDS_SMALL_KEY] = Item(RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, Text{"Training Grounds Small Key", "Petite Clé du Gymnase Gerudo", "Llave del Centro de Instrucción"}, ITEMTYPE_SMALLKEY, 0xB5, true, &GerudoTrainingGroundsKeys, GERUDO_TRAINING_GROUNDS_SMALL_KEY); - itemTable[GERUDO_FORTRESS_SMALL_KEY] = Item(RG_GERUDO_FORTRESS_SMALL_KEY, Text{"Gerudo Fortress Small Key", "Petite Clé du Repaire des Voleurs","Llave de la Fortaleza Gerudo"}, ITEMTYPE_FORTRESS_SMALLKEY, 0xB6, true, &GerudoFortressKeys, GERUDO_FORTRESS_SMALL_KEY); - itemTable[GANONS_CASTLE_SMALL_KEY] = Item(RG_GANONS_CASTLE_SMALL_KEY, Text{"Ganon's Castle Small Key", "Petite Clé du Château de Ganon", "Llave del Castillo de Ganon"}, ITEMTYPE_SMALLKEY, 0xB7, true, &GanonsCastleKeys, GANONS_CASTLE_SMALL_KEY); - itemTable[TREASURE_GAME_SMALL_KEY] = Item(RG_TREASURE_GAME_SMALL_KEY, Text{"Chest Game Small Key", "Petite Clé du jeu la Chasse-aux-Trésors","Llave del Cofre del Tesoro"}, ITEMTYPE_ITEM, 0xDE, true, &TreasureGameKeys, TREASURE_GAME_SMALL_KEY); - - // Key Rings - itemTable[FOREST_TEMPLE_KEY_RING] = Item(RG_FOREST_TEMPLE_KEY_RING, Text{"Forest Temple Key Ring", "Trousseau du Temple de la Forêt", "Llavero del Templo del Bosque"}, ITEMTYPE_SMALLKEY, 0xD5, true, &ForestTempleKeys, FOREST_TEMPLE_KEY_RING); - itemTable[FIRE_TEMPLE_KEY_RING] = Item(RG_FIRE_TEMPLE_KEY_RING, Text{"Fire Temple Key Ring", "Trousseau du Temple du Feu", "Llavero del Templo del Fuego"}, ITEMTYPE_SMALLKEY, 0xD6, true, &FireTempleKeys, FIRE_TEMPLE_KEY_RING); - itemTable[WATER_TEMPLE_KEY_RING] = Item(RG_WATER_TEMPLE_KEY_RING, Text{"Water Temple Key Ring", "Trousseau du Temple de l'Eau", "Llavero del Templo del Agua"}, ITEMTYPE_SMALLKEY, 0xD7, true, &WaterTempleKeys, WATER_TEMPLE_KEY_RING); - itemTable[SPIRIT_TEMPLE_KEY_RING] = Item(RG_SPIRIT_TEMPLE_KEY_RING, Text{"Spirit Temple Key Ring", "Trousseau du Temple de l'Esprit", "Llavero del Templo del Espíritu"}, ITEMTYPE_SMALLKEY, 0xD8, true, &SpiritTempleKeys, SPIRIT_TEMPLE_KEY_RING); - itemTable[SHADOW_TEMPLE_KEY_RING] = Item(RG_SHADOW_TEMPLE_KEY_RING, Text{"Shadow Temple Key Ring", "Trousseau du Temple de l'Ombre", "Llavero del Templo de las Sombras"}, ITEMTYPE_SMALLKEY, 0xD9, true, &ShadowTempleKeys, SHADOW_TEMPLE_KEY_RING); - itemTable[BOTTOM_OF_THE_WELL_KEY_RING] = Item(RG_BOTTOM_OF_THE_WELL_KEY_RING, Text{"Bottom of the Well Key Ring", "Trousseau du Puits", "Llavero del fondo del pozo"}, ITEMTYPE_SMALLKEY, 0xDA, true, &BottomOfTheWellKeys, BOTTOM_OF_THE_WELL_KEY_RING); - itemTable[GERUDO_TRAINING_GROUNDS_KEY_RING] = Item(RG_GERUDO_TRAINING_GROUNDS_KEY_RING, Text{"Training Grounds Key Ring", "Trousseau du Gymnase Gerudo", "Llavero del Centro de Instrucción"}, ITEMTYPE_SMALLKEY, 0xDB, true, &GerudoTrainingGroundsKeys, GERUDO_TRAINING_GROUNDS_KEY_RING); - itemTable[GERUDO_FORTRESS_KEY_RING] = Item(RG_GERUDO_FORTRESS_KEY_RING, Text{"Gerudo Fortress Key Ring", "Trousseau du Repaire des Voleurs", "Llavero de la Fortaleza Gerudo"}, ITEMTYPE_FORTRESS_SMALLKEY, 0xDC, true, &GerudoFortressKeys, GERUDO_FORTRESS_KEY_RING); - itemTable[GANONS_CASTLE_KEY_RING] = Item(RG_GANONS_CASTLE_KEY_RING, Text{"Ganon's Castle Key Ring", "Trousseau du Château de Ganon", "Llavero del Castillo de Ganon"}, ITEMTYPE_SMALLKEY, 0xDD, true, &GanonsCastleKeys, GANONS_CASTLE_KEY_RING); - - //Stones and Medallions - itemTable[KOKIRI_EMERALD] = Item(RG_KOKIRI_EMERALD, Text{"Kokiri's Emerald", "Émeraude Kokiri", "Esmeralda de los Kokiri"}, ITEMTYPE_DUNGEONREWARD, 0xCB, true, &KokiriEmerald, KOKIRI_EMERALD); - itemTable[GORON_RUBY] = Item(RG_GORON_RUBY, Text{"Goron's Ruby", "Rubis Goron", "Rubí de los Goron"}, ITEMTYPE_DUNGEONREWARD, 0xCC, true, &GoronRuby, GORON_RUBY); - itemTable[ZORA_SAPPHIRE] = Item(RG_ZORA_SAPPHIRE, Text{"Zora's Sapphire", "Saphir Zora", "Zafiro de los Zora"}, ITEMTYPE_DUNGEONREWARD, 0xCD, true, &ZoraSapphire, ZORA_SAPPHIRE); - itemTable[FOREST_MEDALLION] = Item(RG_FOREST_MEDALLION, Text{"Forest Medallion", "Médaillon de la Forêt", "Medallón del Bosque"}, ITEMTYPE_DUNGEONREWARD, 0xCE, true, &ForestMedallion, FOREST_MEDALLION); - itemTable[FIRE_MEDALLION] = Item(RG_FIRE_MEDALLION, Text{"Fire Medallion", "Médaillon du Feu", "Medallón del Fuego"}, ITEMTYPE_DUNGEONREWARD, 0xCF, true, &FireMedallion, FIRE_MEDALLION); - itemTable[WATER_MEDALLION] = Item(RG_WATER_MEDALLION, Text{"Water Medallion", "Médaillon de l'Eau", "Medallón del Agua"}, ITEMTYPE_DUNGEONREWARD, 0xD0, true, &WaterMedallion, WATER_MEDALLION); - itemTable[SPIRIT_MEDALLION] = Item(RG_SPIRIT_MEDALLION, Text{"Spirit Medallion", "Médaillon de l'Esprit", "Medallón del Espíritu"}, ITEMTYPE_DUNGEONREWARD, 0xD1, true, &SpiritMedallion, SPIRIT_MEDALLION); - itemTable[SHADOW_MEDALLION] = Item(RG_SHADOW_MEDALLION, Text{"Shadow Medallion", "Médaillon de l'Ombre", "Medallón de la Sombra"}, ITEMTYPE_DUNGEONREWARD, 0xD2, true, &ShadowMedallion, SHADOW_MEDALLION); - itemTable[LIGHT_MEDALLION] = Item(RG_LIGHT_MEDALLION, Text{"Light Medallion", "Médaillon de la Lumière", "Medallón de la Luz"}, ITEMTYPE_DUNGEONREWARD, 0xD3, true, &LightMedallion, LIGHT_MEDALLION); - - //Generic Items - itemTable[RECOVERY_HEART] = Item(RG_RECOVERY_HEART, Text{"Recovery Heart", "Coeur de Vie", "Corazón"}, ITEMTYPE_ITEM, GI_HEART, false, &noVariable, RECOVERY_HEART); - itemTable[GREEN_RUPEE] = Item(RG_GREEN_RUPEE, Text{"Green Rupee", "Rubis Vert", "Rupia verde"}, ITEMTYPE_ITEM, GI_RUPEE_GREEN, false, &noVariable, GREEN_RUPEE); - itemTable[GREG_RUPEE] = Item(RG_GREG_RUPEE, Text{"Greg the Green Rupee", "Rubis Greg", "Rupia Greg"}, ITEMTYPE_ITEM, GI_RUPEE_GREEN, true, &Greg, GREG_RUPEE); - itemTable[BLUE_RUPEE] = Item(RG_BLUE_RUPEE, Text{"Blue Rupee", "Rubis Bleu", "Rupia azul"}, ITEMTYPE_ITEM, GI_RUPEE_BLUE, false, &noVariable, BLUE_RUPEE); - itemTable[RED_RUPEE] = Item(RG_RED_RUPEE, Text{"Red Rupee", "Rubis Rouge", "Rupia roja"}, ITEMTYPE_ITEM, GI_RUPEE_RED, false, &noVariable, RED_RUPEE); - itemTable[PURPLE_RUPEE] = Item(RG_PURPLE_RUPEE, Text{"Purple Rupee", "Rubis Pourpre", "Rupia morada"}, ITEMTYPE_ITEM, GI_RUPEE_PURPLE, false, &noVariable, PURPLE_RUPEE); - itemTable[HUGE_RUPEE] = Item(RG_HUGE_RUPEE, Text{"Huge Rupee", "Énorme Rubis", "Rupia gigante"}, ITEMTYPE_ITEM, GI_RUPEE_GOLD, false, &noVariable, HUGE_RUPEE); - itemTable[PIECE_OF_HEART] = Item(RG_PIECE_OF_HEART, Text{"Piece of Heart", "Quart de Coeur", "Pieza de corazón"}, ITEMTYPE_ITEM, GI_HEART_PIECE, true, &PieceOfHeart, PIECE_OF_HEART); - itemTable[HEART_CONTAINER] = Item(RG_HEART_CONTAINER, Text{"Heart Container", "Réceptacle de Coeur", "Contenedor de corazón"}, ITEMTYPE_ITEM, GI_HEART_CONTAINER_2, true, &HeartContainer, HEART_CONTAINER); - itemTable[ICE_TRAP] = Item(RG_ICE_TRAP, Text{"Ice Trap", "Piège de Glace", "Trampa de hielo"}, ITEMTYPE_ITEM, GI_ICE_TRAP, false, &noVariable, ICE_TRAP); - itemTable[MILK] = Item(RG_MILK, Text{"Milk", "Lait", "Leche Lon Lon"}, ITEMTYPE_ITEM, GI_MILK, false, &noVariable, NONE); - - //Refills - itemTable[BOMBS_5] = Item(RG_BOMBS_5, Text{"Bombs (5)", "Bombes (5)", "Bombas (5)"}, ITEMTYPE_REFILL, GI_BOMBS_5, false, &noVariable, BOMBS_5); - itemTable[BOMBS_10] = Item(RG_BOMBS_10, Text{"Bombs (10)", "Bombes (10)", "Bombas (10)"}, ITEMTYPE_REFILL, GI_BOMBS_10, false, &noVariable, BOMBS_10); - itemTable[BOMBS_20] = Item(RG_BOMBS_20, Text{"Bombs (20)", "Bombes (20)", "Bombas (20)"}, ITEMTYPE_REFILL, GI_BOMBS_20, false, &noVariable, BOMBS_20); - itemTable[BOMBCHU_5] = Item(RG_BOMBCHU_5, Text{"Bombchus (5)", "Missiles (5)", "Bombchus (5)"}, ITEMTYPE_REFILL, GI_BOMBCHUS_5, true, &Bombchus5, BOMBCHU_5); - itemTable[BOMBCHU_10] = Item(RG_BOMBCHU_10, Text{"Bombchus (10)", "Missiles (10)", "Bombchus (10)"}, ITEMTYPE_REFILL, GI_BOMBCHUS_10, true, &Bombchus10, BOMBCHU_10); - itemTable[BOMBCHU_20] = Item(RG_BOMBCHU_20, Text{"Bombchus (20)", "Missiles (20)", "Bombchus (20)"}, ITEMTYPE_REFILL, GI_BOMBCHUS_20, true, &Bombchus20, BOMBCHU_20); - itemTable[BOMBCHU_DROP] = Item(RG_BOMBCHU_DROP, Text{"Bombchu Drop", "Drop Missiles", "Bombchus"}, ITEMTYPE_DROP, GI_BOMBCHUS_10, true, &BombchuDrop, NONE); - itemTable[ARROWS_5] = Item(RG_ARROWS_5, Text{"Arrows (5)", "Flèches (5)", "Flechas (5)"}, ITEMTYPE_REFILL, GI_ARROWS_SMALL, false, &noVariable, ARROWS_5); - itemTable[ARROWS_10] = Item(RG_ARROWS_10, Text{"Arrows (10)", "Flèches (10)", "Flechas (10)"}, ITEMTYPE_REFILL, GI_ARROWS_MEDIUM, false, &noVariable, ARROWS_10); - itemTable[ARROWS_30] = Item(RG_ARROWS_30, Text{"Arrows (30)", "Flèches (30)", "Flechas (30)"}, ITEMTYPE_REFILL, GI_ARROWS_LARGE, false, &noVariable, ARROWS_30); - itemTable[DEKU_NUTS_5] = Item(RG_DEKU_NUTS_5, Text{"Deku Nuts (5)", "Noix Mojo (5)", "Nueces deku (5)"}, ITEMTYPE_REFILL, GI_NUTS_5, false, &noVariable, DEKU_NUTS_5); - itemTable[DEKU_NUTS_10] = Item(RG_DEKU_NUTS_10, Text{"Deku Nuts (10)", "Noix Mojo (10)", "Nueces deku (10)"}, ITEMTYPE_REFILL, GI_NUTS_10, false, &noVariable, DEKU_NUTS_10); - itemTable[DEKU_SEEDS_30] = Item(RG_DEKU_SEEDS_30, Text{"Deku Seeds (30)", "Graines Mojo (30)", "Semillas deku (30)"}, ITEMTYPE_REFILL, GI_SEEDS_30, false, &noVariable, DEKU_SEEDS_30); - itemTable[DEKU_STICK_1] = Item(RG_DEKU_STICK_1, Text{"Deku Stick (1)", "Bâton Mojo (1)", "Palo deku (1)"}, ITEMTYPE_REFILL, GI_STICKS_1, false, &noVariable, DEKU_STICK_1); - itemTable[RED_POTION_REFILL] = Item(RG_RED_POTION_REFILL, Text{"Red Potion Refill", "Recharge de Potion Rouge", "Recarga de poción roja"}, ITEMTYPE_REFILL, GI_POTION_RED, false, &noVariable, NONE); - itemTable[GREEN_POTION_REFILL] = Item(RG_GREEN_POTION_REFILL, Text{"Green Potion Refill", "Recharge de Potion Verte", "Recarga de poción verde"}, ITEMTYPE_REFILL, GI_POTION_GREEN, false, &noVariable, NONE); - itemTable[BLUE_POTION_REFILL] = Item(RG_BLUE_POTION_REFILL, Text{"Blue Potion Refill", "Recharge de Potion Bleue", "Recarga de poción azul"}, ITEMTYPE_REFILL, GI_POTION_BLUE, false, &noVariable, NONE); - - //Treasure Game - itemTable[TREASURE_GAME_HEART] = Item(RG_TREASURE_GAME_HEART, Text{"Piece of Heart (WINNER)", "Quart de Coeur (Chasse-aux-Trésors)", "Pieza de corazón (Cofre del Tesoro)"}, ITEMTYPE_ITEM, GI_HEART_PIECE_WIN, true, &PieceOfHeart, TREASURE_GAME_HEART); - itemTable[TREASURE_GAME_GREEN_RUPEE] = Item(RG_TREASURE_GAME_GREEN_RUPEE, Text{"Green Rupee (LOSER)", "Rubis Vert (Chasse-aux-Trésors)", "Rupia Verde (Cofre del Tesoro)"}, ITEMTYPE_ITEM, GI_RUPEE_GREEN_LOSE, false, &noVariable, TREASURE_GAME_GREEN_RUPEE); - - //Shop Items price - itemTable[BUY_DEKU_NUT_5] = Item(RG_BUY_DEKU_NUT_5, Text{"Buy Deku Nut (5)", "Acheter: Noix Mojo (5)", "Comprar nueces deku (5)"}, ITEMTYPE_SHOP, 0x00, true, &Nuts, DEKU_NUTS_5, 15); - itemTable[BUY_ARROWS_30] = Item(RG_BUY_ARROWS_30, Text{"Buy Arrows (30)", "Acheter: Flèches (30)", "Comprar flechas (30)"}, ITEMTYPE_SHOP, 0x01, true, &BuyArrow, ARROWS_30, 60); - itemTable[BUY_ARROWS_50] = Item(RG_BUY_ARROWS_50, Text{"Buy Arrows (50)", "Acheter: Flèches (50)", "Comprar flechas (50)"}, ITEMTYPE_SHOP, 0x02, true, &BuyArrow, ARROWS_30, 90); - itemTable[BUY_BOMBS_525] = Item(RG_BUY_BOMBS_525, Text{"Buy Bombs (5) [25]", "Acheter: Bombes (5) [25]", "Comprar bombas (5) [25]"}, ITEMTYPE_SHOP, 0x03, true, &BuyBomb, BOMBS_5, 25); - itemTable[BUY_DEKU_NUT_10] = Item(RG_BUY_DEKU_NUT_10, Text{"Buy Deku Nut (10)", "Acheter: Noix Mojo (10)", "Comprar Nueces deku (10)"}, ITEMTYPE_SHOP, 0x04, true, &Nuts, DEKU_NUTS_10, 30); - itemTable[BUY_DEKU_STICK_1] = Item(RG_BUY_DEKU_STICK_1, Text{"Buy Deku Stick (1)", "Acheter: Bâton Mojo (1)", "Comprar palos deku (1)"}, ITEMTYPE_SHOP, 0x05, true, &Sticks, DEKU_STICK_1, 10); - itemTable[BUY_BOMBS_10] = Item(RG_BUY_BOMBS_10, Text{"Buy Bombs (10)", "Acheter: Bombes (10)", "Comprar Bombas (10)"}, ITEMTYPE_SHOP, 0x06, true, &BuyBomb, BOMBS_10, 50); - itemTable[BUY_FISH] = Item(RG_BUY_FISH, Text{"Buy Fish", "Acheter: Poisson", "Comprar pez"}, ITEMTYPE_SHOP, 0x07, true, &FishAccess, BOTTLE_WITH_FISH, 200); - itemTable[BUY_RED_POTION_30] = Item(RG_BUY_RED_POTION_30, Text{"Buy Red Potion [30]", "Acheter: Potion Rouge [30]", "Comprar poción roja [30]"}, ITEMTYPE_SHOP, 0x08, false, &noVariable, BOTTLE_WITH_RED_POTION, 30); - itemTable[BUY_GREEN_POTION] = Item(RG_BUY_GREEN_POTION, Text{"Buy Green Potion", "Acheter: Potion Verte", "Comprar poción verde"}, ITEMTYPE_SHOP, 0x09, true, &BuyGPotion, BOTTLE_WITH_GREEN_POTION, 30); - itemTable[BUY_BLUE_POTION] = Item(RG_BUY_BLUE_POTION, Text{"Buy Blue Potion", "Acheter: Potion Bleue", "Comprar poción azul"}, ITEMTYPE_SHOP, 0x0A, true, &BuyBPotion, BOTTLE_WITH_BLUE_POTION, 100); - itemTable[BUY_HYLIAN_SHIELD] = Item(RG_BUY_HYLIAN_SHIELD, Text{"Buy Hylian Shield", "Acheter: Bouclier Hylien", "Comprar escudo hyliano"}, ITEMTYPE_SHOP, 0x0C, true, &HylianShield, HYLIAN_SHIELD, 80); - itemTable[BUY_DEKU_SHIELD] = Item(RG_BUY_DEKU_SHIELD, Text{"Buy Deku Shield", "Acheter: Bouclier Mojo", "Comprar escudo deku"}, ITEMTYPE_SHOP, 0x0D, true, &DekuShield, DEKU_SHIELD, 40); - itemTable[BUY_GORON_TUNIC] = Item(RG_BUY_GORON_TUNIC, Text{"Buy Goron Tunic", "Acheter: Tunique Goron", "Comprar sayo goron"}, ITEMTYPE_SHOP, 0x0E, true, &GoronTunic, GORON_TUNIC, 200); - itemTable[BUY_ZORA_TUNIC] = Item(RG_BUY_ZORA_TUNIC, Text{"Buy Zora Tunic", "Acheter: Tunique Zora", "Comprar sayo zora"}, ITEMTYPE_SHOP, 0x0F, true, &ZoraTunic, ZORA_TUNIC, 300); - itemTable[BUY_HEART] = Item(RG_BUY_HEART, Text{"Buy Heart", "Acheter: Coeur de Vie", "Comprar corazón"}, ITEMTYPE_SHOP, 0x10, false, &noVariable, RECOVERY_HEART, 10); - itemTable[BUY_BOMBCHU_10] = Item(RG_BUY_BOMBCHU_10, Text{"Buy Bombchu (10)", "Acheter: Missiles (10)", "Comprar bombchus (10)"}, ITEMTYPE_SHOP, 0x15, true, &BuyBombchus10, BOMBCHU_10, 99); - itemTable[BUY_BOMBCHU_20] = Item(RG_BUY_BOMBCHU_20, Text{"Buy Bombchu (20)", "Acheter: Missiles (20)", "Comprar bombchus (20)"}, ITEMTYPE_SHOP, 0x16, true, &BuyBombchus20, BOMBCHU_20, 180); - itemTable[BUY_DEKU_SEEDS_30] = Item(RG_BUY_DEKU_SEEDS_30, Text{"Buy Deku Seeds (30)", "Acheter: Graines Mojo (30)", "Comprar semillas deku (30)"}, ITEMTYPE_SHOP, 0x1D, true, &BuySeed, DEKU_SEEDS_30, 30); - itemTable[SOLD_OUT] = Item(RG_SOLD_OUT, Text{"Sold Out", "Rupture de stock", "Vendido"}, ITEMTYPE_SHOP, 0x26, false, &noVariable, NONE, 0); - itemTable[BUY_BLUE_FIRE] = Item(RG_BUY_BLUE_FIRE, Text{"Buy Blue Fire", "Acheter: Flamme Bleue", "Comprar fuego azul"}, ITEMTYPE_SHOP, 0x27, true, &BlueFireAccess, BOTTLE_WITH_BLUE_FIRE, 300); - itemTable[BUY_BOTTLE_BUG] = Item(RG_BUY_BOTTLE_BUG, Text{"Buy Bottle Bug", "Acheter: Insecte en bouteille", "Comprar bichos"}, ITEMTYPE_SHOP, 0x28, true, &BugsAccess, BOTTLE_WITH_BUGS, 50); - itemTable[BUY_POE] = Item(RG_BUY_POE, Text{"Buy Poe", "Acheter: Esprit", "Comprar Poe"}, ITEMTYPE_SHOP, 0x2A, false, &noVariable, BOTTLE_WITH_BIG_POE, 30); - itemTable[BUY_FAIRYS_SPIRIT] = Item(RG_BUY_FAIRYS_SPIRIT, Text{"Buy Fairy's Spirit", "Acheter: Esprit de Fée", "Comprar hada"}, ITEMTYPE_SHOP, 0x2B, true, &FairyAccess, BOTTLE_WITH_FAIRY, 50); - itemTable[BUY_ARROWS_10] = Item(RG_BUY_ARROWS_10, Text{"Buy Arrows (10)", "Acheter: Flèches (10)", "Comprar flechas (10)"}, ITEMTYPE_SHOP, 0x2C, true, &BuyArrow, ARROWS_10, 20); - itemTable[BUY_BOMBS_20] = Item(RG_BUY_BOMBS_20, Text{"Buy Bombs (20)", "Acheter: Bombes (20)", "Comprar bombas (20)"}, ITEMTYPE_SHOP, 0x2D, true, &BuyBomb, BOMBS_20, 80); - itemTable[BUY_BOMBS_30] = Item(RG_BUY_BOMBS_30, Text{"Buy Bombs (30)", "Acheter: Bombes (30)", "Comprar bombas (30)"}, ITEMTYPE_SHOP, 0x2E, true, &BuyBomb, BOMBS_20, 120); - itemTable[BUY_BOMBS_535] = Item(RG_BUY_BOMBS_535, Text{"Buy Bombs (5) [35]", "Acheter: Bombes (5) [35]", "Comprar bombas (5) [35]"}, ITEMTYPE_SHOP, 0x2F, true, &BuyBomb, BOMBS_5, 35); - itemTable[BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{"Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Comprar poción roja [40]"}, ITEMTYPE_SHOP, 0x30, false, &noVariable, BOTTLE_WITH_RED_POTION, 40); - itemTable[BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{"Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Comprar poción roja [50]"}, ITEMTYPE_SHOP, 0x31, false, &noVariable, BOTTLE_WITH_RED_POTION, 50); - - itemTable[TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{"Triforce Piece", "Triforce Piece", "Triforce Piece"}, ITEMTYPE_ITEM, 0xDF, true, &TriforcePieces, TRIFORCE_PIECE); - itemTable[TRIFORCE] = Item(RG_TRIFORCE, Text{"Triforce", "Triforce", "Trifuerza"}, ITEMTYPE_EVENT, GI_RUPEE_RED_LOSE, false, &noVariable, NONE); - itemTable[HINT] = Item(RG_HINT, Text{"Hint", "Indice", "Pista"}, ITEMTYPE_EVENT, GI_RUPEE_BLUE_LOSE, false, &noVariable, NONE); - -// itemTable[HOOKSHOT] = Item(RG_HOOKSHOT, Text{"Hookshot", "Grappin", "Gancho"}, ITEMTYPE_ITEM, 0x80, true, &ProgressiveHookshot, HOOKSHOT); -// itemTable[LONGSHOT] = Item(RG_LONGSHOT, Text{"Longshot", "Super-Grappin", "Supergancho"}, ITEMTYPE_ITEM, 0x80, true, &ProgressiveHookshot, LONGSHOT); -// itemTable[FAIRY_OCARINA] = Item(RG_FAIRY_OCARINA, Text{"Fairy Ocarina", "Ocarina des fées", "Ocarina de las Hadas"}, ITEMTYPE_ITEM, 0x8B, true, &ProgressiveOcarina, FAIRY_OCARINA); -// itemTable[OCARINA_OF_TIME] = Item(RG_OCARINA_OF_TIME, Text{"Ocarina of Time", "Ocarina du Temps", "Ocarina del Tiempo"}, ITEMTYPE_ITEM, 0x8B, true, &ProgressiveOcarina, OCARINA_OF_TIME); -// itemTable[BOMB_BAG] = Item(RG_BOMB_BAG, Text{"Bomb Bag", "Sac de Bombes", "Saco de bombas"}, ITEMTYPE_ITEM, 0x82, true, &ProgressiveBombBag, BOMB_BAG); -// itemTable[BIG_BOMB_BAG] = Item(RG_BIG_BOMB_BAG, Text{"Big Bomb Bag", "Grand Sac de Bombes", "Saco de bombas grande"}, ITEMTYPE_ITEM, 0x82, true, &ProgressiveBombBag, BIG_BOMB_BAG); -// itemTable[BIGGEST_BOMB_BAG] = Item(RG_BIGGEST_BOMB_BAG, Text{"Biggest Bomb Bag", "Énorme Sac de Bombes", "Saco de bombas gigante"}, ITEMTYPE_ITEM, 0x82, true, &ProgressiveBombBag, BIGGEST_BOMB_BAG); -// itemTable[FAIRY_BOW] = Item(RG_FAIRY_BOW, Text{"Fairy Bow", "Arc des Fées", "Arco de las Hadas"}, ITEMTYPE_ITEM, 0x83, true, &ProgressiveBow, FAIRY_BOW); -// itemTable[BIG_QUIVER] = Item(RG_BIG_QUIVER, Text{"Big Quiver", "Grand carquois", "Carcaj grande"}, ITEMTYPE_ITEM, 0x83, true, &ProgressiveBow, BIG_QUIVER); -// itemTable[BIGGEST_QUIVER] = Item(RG_BIGGEST_QUIVER, Text{"Biggest Quiver", "Énorme carquois", "Carcaj gigante"}, ITEMTYPE_ITEM, 0x83, true, &ProgressiveBow, BIGGEST_QUIVER); -// itemTable[FAIRY_SLINGSHOT] = Item(RG_FAIRY_SLINGSHOT, Text{"Fairy Slingshot", "Lance-Pierre des Fées", "Resortera de las hadas"}, ITEMTYPE_ITEM, 0x84, true, &ProgressiveBulletBag, FAIRY_SLINGSHOT); -// itemTable[BIG_BULLET_BAG] = Item(RG_BIG_BULLET_BAG, Text{"Big Deku Seed Bullet Bag", "Grand sac de graines mojo", "Bolsa de semillas deku grande"}, ITEMTYPE_ITEM, 0x84, true, &ProgressiveBulletBag, BIG_BULLET_BAG); -// itemTable[BIGGEST_BULLET_BAD] = Item(RG_BIGGEST_BULLET_BAD, Text{"Biggest Deku Seed Bullet Bag", "Énorme sac de graines mojo", "Bolsa de semillas deku gigante"}, ITEMTYPE_ITEM, 0x84, true, &ProgressiveBulletBag, BIGGEST_BULLET_BAD); -// itemTable[GORONS_BRACELET] = Item(RG_GORONS_BRACELET, Text{"Goron's Bracelet", "Bracelet Goron", "Brazalete de los Goron"}, ITEMTYPE_ITEM, 0x81, true, &ProgressiveStrength, GORONS_BRACELET); -// itemTable[SILVER_GAUNTLETS] = Item(RG_SILVER_GAUNTLETS, Text{"Silver Gauntlets", "Gantelets d'argent", "Guantes de plata"}, ITEMTYPE_ITEM, 0x81, true, &ProgressiveStrength, SILVER_GAUNTLETS); -// itemTable[GOLDEN_GAUNTLETS] = Item(RG_GOLDEN_GAUNTLETS, Text{"Golden Gauntlets", "Gantelets d'or", "Guantes de oro"}, ITEMTYPE_ITEM, 0x81, true, &ProgressiveStrength, GOLDEN_GAUNTLETS); -// itemTable[SILVER_SCALE] = Item(RG_SILVER_SCALE, Text{"Silver Scale", "Écaille d'argent", "Escama de Plata"}, ITEMTYPE_ITEM, 0x86, true, &ProgressiveScale, SILVER_SCALE); -// itemTable[GOLDEN_SCALE] = Item(RG_GOLDEN_SCALE, Text{"Golden Scale", "Écaille d'or", "Escama de Oro"}, ITEMTYPE_ITEM, 0x86, true, &ProgressiveScale, GOLDEN_SCALE); -// itemTable[ADULT_WALLET] = Item(RG_ADULT_WALLET, Text{"Adult Wallet", "Grande Bourse", "Bolsa de adulto"}, ITEMTYPE_ITEM, 0x85, true, &ProgressiveWallet, ADULT_WALLET); -// itemTable[GIANT_WALLET] = Item(RG_GIANT_WALLET, Text{"Giant Wallet", "Bourse de Géant", "Bolsa gigante"}, ITEMTYPE_ITEM, 0x85, true, &ProgressiveWallet, GIANT_WALLET); -// itemTable[TYCOON_WALLET] = Item(RG_TYCOON_WALLET, Text{"Tycoon Wallet", "Bourse de Magnat", "Bolsa de ricachón"}, ITEMTYPE_ITEM, 0x85, true, &ProgressiveWallet, TYCOON_WALLET); -// itemTable[DEKU_NUT_CAPACITY_30] = Item(RG_DEKU_NUT_CAPACITY_30, Text{"Deku Nut Capacity (30)", "Capacité de noix Mojo (20)", "Capacidad de nueces deku (40)"}, ITEMTYPE_ITEM, 0x87, false, &noVariable, DEKU_NUT_CAPACITY_30); -// itemTable[DEKU_NUT_CAPACITY_40] = Item(RG_DEKU_NUT_CAPACITY_40, Text{"Deku Nut Capacity (40)", "Capacité de noix Mojo (30)", "Capacidad de nueces deku (50)"}, ITEMTYPE_ITEM, 0x87, false, &noVariable, DEKU_NUT_CAPACITY_40); -// itemTable[DEKU_NUT_CAPACITY_20] = Item(RG_DEKU_NUT_CAPACITY_20, Text{"Deku Stick Capacity (20)", "Capacité de Bâtons Mojo (20)", "Capacidad de palos deku (20)"}, ITEMTYPE_ITEM, 0x88, false, &noVariable, DEKU_NUT_CAPACITY_20); -// itemTable[DEKU_NUT_CAPACITY_30] = Item(RG_DEKU_NUT_CAPACITY_30, Text{"Deku Nut Capacity (30)", "Capacité de noix Mojo (20)", "Capacidad de nueces deku (40)"}, ITEMTYPE_ITEM, 0x88, false, &noVariable, DEKU_NUT_CAPACITY_30); -// itemTable[MAGIC_METER] = Item(RG_MAGIC_METER, Text{"Magic Meter", "Jauge de Magie", "Poder mágico"}, ITEMTYPE_ITEM, 0x8A, true, &ProgressiveMagic, MAGIC_METER); -// itemTable[ENHANCED_MAGIC_METER] = Item(RG_ENHANCED_MAGIC_METER, Text{"Enhanced Magic Meter", "Jauge de Magie améliorée", "Poder mágico mejorado"}, ITEMTYPE_ITEM, 0x8A, true, &ProgressiveMagic, ENHANCED_MAGIC_METER); - -} - -Item& ItemTable(const uint32_t itemKey) { - return itemTable[itemKey]; -} - -Item& ItemFromGIID(const int giid) { - uint32_t index = 0; - while (index < KEY_ENUM_MAX) { - if (itemTable[index].GetItemID() == giid) { - return itemTable[index]; - } - index++; - } - - // there are vanilla items that don't exist in the item table we're reading from here - // if we made it this far, it means we didn't find an item in the table - // if we don't return anything, the game will crash, so, as a workaround, return greg - return itemTable[GREEN_RUPEE]; -} - -//This function should only be used to place items containing hint text -//at gossip stone locations. -void NewItem(const uint32_t itemKey, const Item item) { - if (itemKey <= BUY_RED_POTION_50) { - printf("\x1b[25;0HWARNING: ATTEMPTED TO OVERWRITE ITEM %lu\n", itemKey); - return; - } - - itemTable[itemKey] = item; -} - -std::array* GetFullItemTable_() { - return &itemTable; -} diff --git a/soh/soh/Enhancements/randomizer/3drando/item_list.hpp b/soh/soh/Enhancements/randomizer/3drando/item_list.hpp deleted file mode 100644 index 2bcea700ade..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/item_list.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "item.hpp" -#include "keys.hpp" - -void ItemTable_Init(); -Item& ItemTable(uint32_t itemKey); -Item& ItemFromGIID(int giid); -void NewItem(uint32_t itemKey, Item item); -std::array* GetFullItemTable_(); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp index 850157ad86f..e69de29bb2d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp @@ -1,1659 +0,0 @@ -#include "item_location.hpp" - -#include "dungeon.hpp" -#include "settings.hpp" -#include "spoiler_log.hpp" -#include "shops.hpp" -#include "keys.hpp" -#include -#include "../randomizerTypes.h" - -//Location definitions -static std::array locationTable; -static std::unordered_map locationLookupTable; - -void LocationTable_Init() { - locationTable[NONE] = ItemLocation::Base (RC_UNKNOWN_CHECK, 0xFF, "Invalid Location", NONE, NONE, {}, SpoilerCollectionCheck::None()); - //Kokiri Forest scene flag name hint key (hint_list.cpp) vanilla item categories collection check (if needed) collection check group - locationTable[KF_KOKIRI_SWORD_CHEST] = ItemLocation::Chest (RC_KF_KOKIRI_SWORD_CHEST, 0x55, 0x00, "KF Kokiri Sword Chest", KF_KOKIRI_SWORD_CHEST, KOKIRI_SWORD, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_MIDOS_TOP_LEFT_CHEST] = ItemLocation::Chest (RC_KF_MIDOS_TOP_LEFT_CHEST, 0x28, 0x00, "KF Mido Top Left Chest", KF_MIDOS_TOP_LEFT_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_MIDOS_TOP_RIGHT_CHEST] = ItemLocation::Chest (RC_KF_MIDOS_TOP_RIGHT_CHEST, 0x28, 0x01, "KF Mido Top Right Chest", KF_MIDOS_TOP_RIGHT_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_MIDOS_BOTTOM_LEFT_CHEST] = ItemLocation::Chest (RC_KF_MIDOS_BOTTOM_LEFT_CHEST, 0x28, 0x02, "KF Mido Bottom Left Chest", KF_MIDOS_BOTTOM_LEFT_CHEST, GREG_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_MIDOS_BOTTOM_RIGHT_CHEST] = ItemLocation::Chest (RC_KF_MIDOS_BOTTOM_RIGHT_CHEST, 0x28, 0x03, "KF Mido Bottom Right Chest", KF_MIDOS_BOTTOM_RIGHT_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_STORMS_GROTTO_CHEST] = ItemLocation::Chest (RC_KF_STORMS_GROTTO_CHEST, 0x3E, 0x0C, "KF Storms Grotto Chest", KF_STORMS_GROTTO_CHEST, RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - - //Lost Woods - locationTable[LW_NEAR_SHORTCUTS_GROTTO_CHEST] = ItemLocation::Chest (RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, 0x3E, 0x14, "LW Near Shortcuts Grotto Chest", LW_NEAR_SHORTCUTS_GROTTO_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_SKULL_KID] = ItemLocation::Base (RC_LW_SKULL_KID, 0x5B, "LW Skull Kid", LW_SKULL_KID, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(22), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_TRADE_COJIRO] = ItemLocation::Base (RC_LW_TRADE_COJIRO, 0x5B, "LW Trade Cojiro", LW_TRADE_COJIRO, ODD_MUSHROOM, {Category::cAdultTrade}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_TRADE_ODD_POTION] = ItemLocation::Base (RC_LW_TRADE_ODD_POTION, 0x5B, "LW Trade Odd Potion", LW_TRADE_ODD_POTION, POACHERS_SAW, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(49), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_OCARINA_MEMORY_GAME] = ItemLocation::Base (RC_LW_OCARINA_MEMORY_GAME, 0x5B, "LW Ocarina Memory Game", LW_OCARINA_MEMORY_GAME, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(23), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_TARGET_IN_WOODS] = ItemLocation::Base (RC_LW_TARGET_IN_WOODS, 0x5B, "LW Target in Woods", LW_TARGET_IN_WOODS, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = ItemLocation::Base (RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, 0x5B, "LW Deku Scrub Near Deku Theater Right",LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = ItemLocation::Base (RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, 0x5B, "LW Deku Scrub Near Deku Theater Left", LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, BUY_DEKU_STICK_1, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_DEKU_SCRUB_NEAR_BRIDGE] = ItemLocation::Base (RC_LW_DEKU_SCRUB_NEAR_BRIDGE, 0x5B, "LW Deku Scrub Near Bridge", LW_DEKU_SCRUB_NEAR_BRIDGE, PROGRESSIVE_STICK_UPGRADE, {Category::cDekuScrub, Category::cDekuScrubUpgrades}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_DEKU_SCRUB_GROTTO_REAR] = ItemLocation::GrottoScrub(RC_LW_DEKU_SCRUB_GROTTO_REAR, 0xF5, "LW Deku Scrub Grotto Rear", LW_DEKU_SCRUB_GROTTO_REAR, BUY_DEKU_SEEDS_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_DEKU_SCRUB_GROTTO_FRONT] = ItemLocation::GrottoScrub(RC_LW_DEKU_SCRUB_GROTTO_FRONT, 0xF5, "LW Deku Scrub Grotto Front", LW_DEKU_SCRUB_GROTTO_FRONT, PROGRESSIVE_NUT_UPGRADE, {Category::cDekuScrub, Category::cDekuScrubUpgrades}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[DEKU_THEATER_SKULL_MASK] = ItemLocation::Base (RC_DEKU_THEATER_SKULL_MASK, 0x3E, "Deku Theater Skull Mask", DEKU_THEATER_SKULL_MASK, PROGRESSIVE_STICK_UPGRADE, {}, SpoilerCollectionCheck::Chest(0x3E, 0x1F), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[DEKU_THEATER_MASK_OF_TRUTH] = ItemLocation::Base (RC_DEKU_THEATER_MASK_OF_TRUTH, 0x3E, "Deku Theater Mask of Truth", DEKU_THEATER_MASK_OF_TRUTH, PROGRESSIVE_NUT_UPGRADE, {}, SpoilerCollectionCheck::Chest(0x3E, 0x1E), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - - //Sacred Forest Meadow - locationTable[SFM_WOLFOS_GROTTO_CHEST] = ItemLocation::Chest (RC_SFM_WOLFOS_GROTTO_CHEST, 0x3E, 0x11, "SFM Wolfos Grotto Chest", SFM_WOLFOS_GROTTO_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[SFM_DEKU_SCRUB_GROTTO_REAR] = ItemLocation::GrottoScrub(RC_SFM_DEKU_SCRUB_GROTTO_REAR, 0xEE, "SFM Deku Scrub Grotto Rear", SFM_DEKU_SCRUB_GROTTO_REAR, BUY_RED_POTION_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[SFM_DEKU_SCRUB_GROTTO_FRONT] = ItemLocation::GrottoScrub(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, 0xEE, "SFM Deku Scrub Grotto Front", SFM_DEKU_SCRUB_GROTTO_FRONT, BUY_GREEN_POTION, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - - //Hyrule Field - locationTable[HF_SOUTHEAST_GROTTO_CHEST] = ItemLocation::Chest (RC_HF_SOUTHEAST_GROTTO_CHEST, 0x3E, 0x02, "HF Southeast Grotto Chest", HF_SOUTHEAST_GROTTO_CHEST, RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[HF_OPEN_GROTTO_CHEST] = ItemLocation::Chest (RC_HF_OPEN_GROTTO_CHEST, 0x3E, 0x03, "HF Open Grotto Chest", HF_OPEN_GROTTO_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[HF_NEAR_MARKET_GROTTO_CHEST] = ItemLocation::Chest (RC_HF_NEAR_MARKET_GROTTO_CHEST, 0x3E, 0x00, "HF Near Market Grotto Chest", HF_NEAR_MARKET_GROTTO_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[HF_OCARINA_OF_TIME_ITEM] = ItemLocation::Base (RC_HF_OCARINA_OF_TIME_ITEM, 0x51, "HF Ocarina of Time Item", HF_OCARINA_OF_TIME_ITEM, PROGRESSIVE_OCARINA, {}, SpoilerCollectionCheck::EventChkInf(0x43), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[HF_TEKTITE_GROTTO_FREESTANDING_POH] = ItemLocation::Collectable(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, 0x3E, 0x01, "HF Tektite Grotto Freestanding PoH", HF_TEKTITE_GROTTO_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[HF_DEKU_SCRUB_GROTTO] = ItemLocation::GrottoScrub(RC_HF_DEKU_SCRUB_GROTTO, 0xE6, "HF Deku Scrub Grotto", HF_DEKU_SCRUB_GROTTO, PIECE_OF_HEART, {Category::cDekuScrub, Category::cDekuScrubUpgrades}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - - //Lake Hylia - locationTable[LH_CHILD_FISHING] = ItemLocation::Base (RC_LH_CHILD_FISHING, 0x49, "LH Child Fishing", LH_CHILD_FISHING, PIECE_OF_HEART, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_ADULT_FISHING] = ItemLocation::Base (RC_LH_ADULT_FISHING, 0x49, "LH Adult Fishing", LH_ADULT_FISHING, PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_LAB_DIVE] = ItemLocation::Base (RC_LH_LAB_DIVE, 0x38, "LH Lab Dive", LH_LAB_DIVE, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(16), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_TRADE_FROG] = ItemLocation::Base (RC_LH_TRADE_FROG, 0x38, "LH Lab Trade Eyeball Frog", LH_TRADE_FROG, EYEDROPS, {Category::cAdultTrade}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_UNDERWATER_ITEM] = ItemLocation::Base (RC_LH_UNDERWATER_ITEM, 0x57, "LH Underwater Item", LH_UNDERWATER_ITEM, RUTOS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x31), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_SUN] = ItemLocation::Base (RC_LH_SUN, 0x57, "LH Sun", LH_SUN, FIRE_ARROWS, {}, SpoilerCollectionCheck::Chest(0x57, 0x1F), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_FREESTANDING_POH] = ItemLocation::Collectable(RC_LH_FREESTANDING_POH, 0x57, 0x1E, "LH Freestanding PoH", LH_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_DEKU_SCRUB_GROTTO_LEFT] = ItemLocation::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_LEFT, 0xEF, "LH Deku Scrub Grotto Left", LH_DEKU_SCRUB_GROTTO_LEFT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_DEKU_SCRUB_GROTTO_RIGHT] = ItemLocation::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, 0xEF, "LH Deku Scrub Grotto Right", LH_DEKU_SCRUB_GROTTO_RIGHT, BUY_BOMBS_535, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_DEKU_SCRUB_GROTTO_CENTER] = ItemLocation::GrottoScrub(RC_LH_DEKU_SCRUB_GROTTO_CENTER, 0xEF, "LH Deku Scrub Grotto Center", LH_DEKU_SCRUB_GROTTO_CENTER, BUY_DEKU_SEEDS_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - - //Gerudo Valley - locationTable[GV_CHEST] = ItemLocation::Chest (RC_GV_CHEST, 0x5A, 0x00, "GV Chest", GV_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GV_TRADE_SAW] = ItemLocation::Base (RC_GV_TRADE_SAW, 0x5A, "GV Trade Saw", GV_TRADE_SAW, BROKEN_SWORD, {Category::cAdultTrade}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GV_WATERFALL_FREESTANDING_POH] = ItemLocation::Collectable(RC_GV_WATERFALL_FREESTANDING_POH, 0x5A, 0x01, "GV Waterfall Freestanding PoH", GV_WATERFALL_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GV_CRATE_FREESTANDING_POH] = ItemLocation::Collectable(RC_GV_CRATE_FREESTANDING_POH, 0x5A, 0x02, "GV Crate Freestanding PoH", GV_CRATE_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GV_DEKU_SCRUB_GROTTO_REAR] = ItemLocation::GrottoScrub(RC_GV_DEKU_SCRUB_GROTTO_REAR, 0xF0, "GV Deku Scrub Grotto Rear", GV_DEKU_SCRUB_GROTTO_REAR, BUY_RED_POTION_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GV_DEKU_SCRUB_GROTTO_FRONT] = ItemLocation::GrottoScrub(RC_GV_DEKU_SCRUB_GROTTO_FRONT, 0xF0, "GV Deku Scrub Grotto Front", GV_DEKU_SCRUB_GROTTO_FRONT, BUY_GREEN_POTION, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - - //Gerudo Fortress - locationTable[GF_CHEST] = ItemLocation::Chest (RC_GF_CHEST, 0x5D, 0x00, "GF Chest", GF_CHEST, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GF_HBA_1000_POINTS] = ItemLocation::Base (RC_GF_HBA_1000_POINTS, 0x5D, "GF HBA 1000 Points", GF_HBA_1000_POINTS, PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x08), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GF_HBA_1500_POINTS] = ItemLocation::Base (RC_GF_HBA_1500_POINTS, 0x5D, "GF HBA 1500 Points", GF_HBA_1500_POINTS, PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(15), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GF_GERUDO_MEMBERSHIP_CARD] = ItemLocation::Base (RC_GF_GERUDO_MEMBERSHIP_CARD, 0x0C, "GF Gerudo Membership Card", GF_GERUDO_MEMBERSHIP_CARD, GERUDO_MEMBERSHIP_CARD, {}, SpoilerCollectionCheck::GerudoToken(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GF_NORTH_F1_CARPENTER] = ItemLocation::Collectable(RC_GF_NORTH_F1_CARPENTER, 0x0C, 0x0C, "GF North F1 Carpenter", GF_NORTH_F1_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, {Category::cVanillaGFSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GF_NORTH_F2_CARPENTER] = ItemLocation::Collectable(RC_GF_NORTH_F2_CARPENTER, 0x0C, 0x0A, "GF North F2 Carpenter", GF_NORTH_F2_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, {Category::cVanillaGFSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GF_SOUTH_F1_CARPENTER] = ItemLocation::Collectable(RC_GF_SOUTH_F1_CARPENTER, 0x0C, 0x0E, "GF South F1 Carpenter", GF_SOUTH_F1_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, {Category::cVanillaGFSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GF_SOUTH_F2_CARPENTER] = ItemLocation::Collectable(RC_GF_SOUTH_F2_CARPENTER, 0x0C, 0x0F, "GF South F2 Carpenter", GF_SOUTH_F2_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, {Category::cVanillaGFSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - - //Haunted Wasteland - locationTable[WASTELAND_CHEST] = ItemLocation::Chest (RC_WASTELAND_CHEST, 0x5E, 0x00, "Wasteland Chest", WASTELAND_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[WASTELAND_BOMBCHU_SALESMAN] = ItemLocation::Base (RC_WASTELAND_BOMBCHU_SALESMAN, 0x5E, "Wasteland Carpet Salesman", WASTELAND_BOMBCHU_SALESMAN, BOMBCHU_10, {Category::cMerchant}, SpoilerCollectionCheck::Merchant(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - - //Desert Colossus - locationTable[COLOSSUS_FREESTANDING_POH] = ItemLocation::Collectable(RC_COLOSSUS_FREESTANDING_POH, 0x5C, 0x0D, "Colossus Freestanding PoH", COLOSSUS_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = ItemLocation::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, 0xFD, "Colossus Deku Scrub Grotto Rear", COLOSSUS_DEKU_SCRUB_GROTTO_REAR, BUY_RED_POTION_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = ItemLocation::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, 0xFD, "Colossus Deku Scrub Grotto Front", COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, BUY_GREEN_POTION, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - - //Market - locationTable[MARKET_TREASURE_CHEST_GAME_REWARD] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_REWARD, 0x10, "MK Treasure Chest Game Reward", MARKET_TREASURE_CHEST_GAME_REWARD, TREASURE_GAME_HEART, {}, SpoilerCollectionCheck::ItemGetInf(27), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, 0x4B, "MK Bombchu Bowling First Prize", MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(17), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, 0x4B, "MK Bombchu Bowling Second Prize", MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(18), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_BOWLING_BOMBCHUS] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, 0x4B, "MK Bombchu Bowling Bombchus", NONE, BOMBCHU_DROP, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_LOST_DOG] = ItemLocation::Base (RC_MARKET_LOST_DOG, 0x35, "MK Lost Dog", MARKET_LOST_DOG, PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x09), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_MARKET_SHOOTING_GALLERY_REWARD, 0x42, "MK Shooting Gallery", MARKET_SHOOTING_GALLERY_REWARD, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(13), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_10_BIG_POES] = ItemLocation::Base (RC_MARKET_10_BIG_POES, 0x4D, "MK 10 Big Poes", MARKET_10_BIG_POES, EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_TREASURE_CHEST_GAME_ITEM_1] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, 0x10, 0x01, "MK Chest Game First Room Chest", MARKET_TREASURE_CHEST_GAME_ITEM_1, TREASURE_GAME_SMALL_KEY, {Category::cChestMinigame}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_TREASURE_CHEST_GAME_ITEM_2] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, 0x10, 0x03, "MK Chest Game Second Room Chest", MARKET_TREASURE_CHEST_GAME_ITEM_2, TREASURE_GAME_SMALL_KEY, {Category::cChestMinigame}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_TREASURE_CHEST_GAME_ITEM_3] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, 0x10, 0x05, "MK Chest Game Third Room Chest", MARKET_TREASURE_CHEST_GAME_ITEM_3, TREASURE_GAME_SMALL_KEY, {Category::cChestMinigame}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_TREASURE_CHEST_GAME_ITEM_4] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, 0x10, 0x07, "MK Chest Game Fourth Room Chest", MARKET_TREASURE_CHEST_GAME_ITEM_4, TREASURE_GAME_SMALL_KEY, {Category::cChestMinigame}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_TREASURE_CHEST_GAME_ITEM_5] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, 0x10, 0x09, "MK Chest Game Fifth Room Chest", MARKET_TREASURE_CHEST_GAME_ITEM_5, TREASURE_GAME_SMALL_KEY, {Category::cChestMinigame}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - - //Hyrule Castle - locationTable[HC_MALON_EGG] = ItemLocation::Base (RC_HC_MALON_EGG, 0x5F, "HC Malon Egg", HC_MALON_EGG, WEIRD_EGG, {}, SpoilerCollectionCheck::EventChkInf(0x12), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[HC_ZELDAS_LETTER] = ItemLocation::Base (RC_HC_ZELDAS_LETTER, 0x4A, "HC Zeldas Letter", HC_ZELDAS_LETTER, ZELDAS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x40), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - - //Kakariko - locationTable[KAK_REDEAD_GROTTO_CHEST] = ItemLocation::Chest (RC_KAK_REDEAD_GROTTO_CHEST, 0x3E, 0x0A, "Kak Redead Grotto Chest", KAK_REDEAD_GROTTO_CHEST, HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_OPEN_GROTTO_CHEST] = ItemLocation::Chest (RC_KAK_OPEN_GROTTO_CHEST, 0x3E, 0x08, "Kak Open Grotto Chest", KAK_OPEN_GROTTO_CHEST, RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_10_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_10_GOLD_SKULLTULA_REWARD, 0x50, "Kak 10 Gold Skulltula Reward", KAK_10_GOLD_SKULLTULA_REWARD, PROGRESSIVE_WALLET, {}, SpoilerCollectionCheck::EventChkInf(0xDA), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_20_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_20_GOLD_SKULLTULA_REWARD, 0x50, "Kak 20 Gold Skulltula Reward", KAK_20_GOLD_SKULLTULA_REWARD, STONE_OF_AGONY, {}, SpoilerCollectionCheck::EventChkInf(0xDB), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_30_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_30_GOLD_SKULLTULA_REWARD, 0x50, "Kak 30 Gold Skulltula Reward", KAK_30_GOLD_SKULLTULA_REWARD, PROGRESSIVE_WALLET, {}, SpoilerCollectionCheck::EventChkInf(0xDC), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_40_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_40_GOLD_SKULLTULA_REWARD, 0x50, "Kak 40 Gold Skulltula Reward", KAK_40_GOLD_SKULLTULA_REWARD, BOMBCHU_10, {}, SpoilerCollectionCheck::EventChkInf(0xDD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_50_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_50_GOLD_SKULLTULA_REWARD, 0x50, "Kak 50 Gold Skulltula Reward", KAK_50_GOLD_SKULLTULA_REWARD, PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xDE), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_100_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_100_GOLD_SKULLTULA_REWARD, 0x50, "Kak 100 Gold Skulltula Reward", KAK_100_GOLD_SKULLTULA_REWARD, HUGE_RUPEE, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_MAN_ON_ROOF] = ItemLocation::Base (RC_KAK_MAN_ON_ROOF, 0x52, "Kak Man on Roof", KAK_MAN_ON_ROOF, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(21), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_KAK_SHOOTING_GALLERY_REWARD, 0x42, "Kak Shooting Gallery Reward", KAK_SHOOTING_GALLERY_REWARD, PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::Chest(0x42, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_TRADE_ODD_MUSHROOM] = ItemLocation::Base (RC_KAK_TRADE_ODD_MUSHROOM, 0x4E, "Kak Trade Odd Mushroom", KAK_TRADE_ODD_MUSHROOM, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(48), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_GRANNYS_SHOP] = ItemLocation::Base (RC_KAK_GRANNYS_SHOP, 0x4E, "Kak Granny's Shop", KAK_GRANNYS_SHOP, BLUE_POTION_REFILL, {Category::cMerchant}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_ANJU_AS_ADULT] = ItemLocation::Base (RC_KAK_ANJU_AS_ADULT, 0x52, "Kak Anju as Adult", KAK_ANJU_AS_ADULT, POCKET_EGG, {}, SpoilerCollectionCheck::ItemGetInf(44), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_ANJU_AS_CHILD] = ItemLocation::Base (RC_KAK_ANJU_AS_CHILD, 0x52, "Kak Anju as Child", KAK_ANJU_AS_CHILD, EMPTY_BOTTLE, {}, SpoilerCollectionCheck::ItemGetInf(12), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_TRADE_POCKET_CUCCO] = ItemLocation::Base (RC_KAK_TRADE_POCKET_CUCCO, 0x52, "Kak Trade Pocket Cucco", KAK_TRADE_POCKET_CUCCO, COJIRO, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(46), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_IMPAS_HOUSE_FREESTANDING_POH] = ItemLocation::Collectable(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, 0x37, 0x01, "Kak Impas House Freestanding PoH", KAK_IMPAS_HOUSE_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_WINDMILL_FREESTANDING_POH] = ItemLocation::Collectable(RC_KAK_WINDMILL_FREESTANDING_POH, 0x48, 0x01, "Kak Windmill Freestanding PoH", KAK_WINDMILL_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - - //Graveyard - locationTable[GRAVEYARD_SHIELD_GRAVE_CHEST] = ItemLocation::Chest (RC_GRAVEYARD_SHIELD_GRAVE_CHEST, 0x40, 0x00, "GY Shield Grave Chest", GRAVEYARD_SHIELD_GRAVE_CHEST, HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[GRAVEYARD_HEART_PIECE_GRAVE_CHEST] = ItemLocation::Chest (RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, 0x3F, 0x00, "GY Heart Piece Grave Chest", GRAVEYARD_HEART_PIECE_GRAVE_CHEST, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[GRAVEYARD_COMPOSERS_GRAVE_CHEST] = ItemLocation::Chest (RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, 0x41, 0x00, "GY Composers Grave Chest", GRAVEYARD_COMPOSERS_GRAVE_CHEST, BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[GRAVEYARD_HOOKSHOT_CHEST] = ItemLocation::Chest (RC_GRAVEYARD_HOOKSHOT_CHEST, 0x48, 0x00, "GY Hookshot Chest", GRAVEYARD_HOOKSHOT_CHEST, PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[GRAVEYARD_DAMPE_RACE_FREESTANDING_POH] = ItemLocation::Collectable(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, 0x48, 0x07, "GY Dampe Race Freestanding PoH", GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[GRAVEYARD_FREESTANDING_POH] = ItemLocation::Collectable(RC_GRAVEYARD_FREESTANDING_POH, 0x53, 0x04, "GY Freestanding PoH", GRAVEYARD_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = ItemLocation::Collectable(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, 0x53, "GY Dampe Gravedigging Tour", GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, PIECE_OF_HEART, {}, SpoilerCollectionCheck::Gravedigger(0x53, 0x19), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - - //Death Mountain - locationTable[DMT_CHEST] = ItemLocation::Chest (RC_DMT_CHEST, 0x60, 0x01, "DMT Chest", DMT_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMT_STORMS_GROTTO_CHEST] = ItemLocation::Chest (RC_DMT_STORMS_GROTTO_CHEST, 0x3E, 0x17, "DMT Storms Grotto Chest", DMT_STORMS_GROTTO_CHEST, HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMT_TRADE_BROKEN_SWORD] = ItemLocation::Base (RC_DMT_TRADE_BROKEN_SWORD, 0x60, "DMT Trade Broken Sword", DMT_TRADE_BROKEN_SWORD, PRESCRIPTION, {Category::cAdultTrade}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMT_TRADE_EYEDROPS] = ItemLocation::Base (RC_DMT_TRADE_EYEDROPS, 0x60, "DMT Trade Eyedrops", DMT_TRADE_EYEDROPS, CLAIM_CHECK, {Category::cAdultTrade}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMT_TRADE_CLAIM_CHECK] = ItemLocation::Base (RC_DMT_TRADE_CLAIM_CHECK, 0x60, "DMT Trade Claim Check", DMT_TRADE_CLAIM_CHECK, BIGGORON_SWORD, {}, SpoilerCollectionCheck::Chest(0x60, 0x1F), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMT_FREESTANDING_POH] = ItemLocation::Collectable(RC_DMT_FREESTANDING_POH, 0x60, 0x1E, "DMT Freestanding PoH", DMT_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - - //Goron City - locationTable[GC_MAZE_LEFT_CHEST] = ItemLocation::Chest (RC_GC_MAZE_LEFT_CHEST, 0x62, 0x00, "GC Maze Left Chest", GC_MAZE_LEFT_CHEST, HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_MAZE_RIGHT_CHEST] = ItemLocation::Chest (RC_GC_MAZE_RIGHT_CHEST, 0x62, 0x01, "GC Maze Right Chest", GC_MAZE_RIGHT_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_MAZE_CENTER_CHEST] = ItemLocation::Chest (RC_GC_MAZE_CENTER_CHEST, 0x62, 0x02, "GC Maze Center Chest", GC_MAZE_CENTER_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_ROLLING_GORON_AS_CHILD] = ItemLocation::Base (RC_GC_ROLLING_GORON_AS_CHILD, 0x62, "GC Rolling Goron as Child", GC_ROLLING_GORON_AS_CHILD, PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::InfTable(0x11, 0x06), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_ROLLING_GORON_AS_ADULT] = ItemLocation::Base (RC_GC_ROLLING_GORON_AS_ADULT, 0x62, "GC Rolling Goron as Adult", GC_ROLLING_GORON_AS_ADULT, GORON_TUNIC, {}, SpoilerCollectionCheck::InfTable(0x10, 0x01), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_DARUNIAS_JOY] = ItemLocation::Base (RC_GC_DARUNIAS_JOY, 0x62, "GC Darunias Joy", GC_DARUNIAS_JOY, PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheck::Chest(0x62, 0x1E), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_POT_FREESTANDING_POH] = ItemLocation::Collectable(RC_GC_POT_FREESTANDING_POH, 0x62, 0x1F, "GC Pot Freestanding PoH", GC_POT_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_DEKU_SCRUB_GROTTO_LEFT] = ItemLocation::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_LEFT, 0xFB, "GC Deku Scrub Grotto Left", GC_DEKU_SCRUB_GROTTO_LEFT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_DEKU_SCRUB_GROTTO_RIGHT] = ItemLocation::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, 0xFB, "GC Deku Scrub Grotto Right", GC_DEKU_SCRUB_GROTTO_RIGHT, BUY_BOMBS_535, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_DEKU_SCRUB_GROTTO_CENTER] = ItemLocation::GrottoScrub(RC_GC_DEKU_SCRUB_GROTTO_CENTER, 0xFB, "GC Deku Scrub Grotto Center", GC_DEKU_SCRUB_GROTTO_CENTER, BUY_ARROWS_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_MEDIGORON] = ItemLocation::Base (RC_GC_MEDIGORON, 0x62, "GC Medigoron", GC_MEDIGORON, GIANTS_KNIFE, {Category::cMerchant}, SpoilerCollectionCheck::Merchant(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - - //Death Mountain Crater - locationTable[DMC_UPPER_GROTTO_CHEST] = ItemLocation::Chest (RC_DMC_UPPER_GROTTO_CHEST, 0x3E, 0x1A, "DMC Upper Grotto Chest", DMC_UPPER_GROTTO_CHEST, BOMBS_20, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMC_WALL_FREESTANDING_POH] = ItemLocation::Collectable(RC_DMC_WALL_FREESTANDING_POH, 0x61, 0x02, "DMC Wall Freestanding PoH", DMC_WALL_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMC_VOLCANO_FREESTANDING_POH] = ItemLocation::Collectable(RC_DMC_VOLCANO_FREESTANDING_POH, 0x61, 0x08, "DMC Volcano Freestanding PoH", DMC_VOLCANO_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMC_DEKU_SCRUB] = ItemLocation::Base (RC_DMC_DEKU_SCRUB, 0x61, "DMC Deku Scrub", DMC_DEKU_SCRUB, BUY_BOMBS_535, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMC_DEKU_SCRUB_GROTTO_LEFT] = ItemLocation::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, 0xF9, "DMC Deku Scrub Grotto Left", DMC_DEKU_SCRUB_GROTTO_LEFT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMC_DEKU_SCRUB_GROTTO_RIGHT] = ItemLocation::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, 0xF9, "DMC Deku Scrub Grotto Right", DMC_DEKU_SCRUB_GROTTO_RIGHT, BUY_BOMBS_535, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMC_DEKU_SCRUB_GROTTO_CENTER] = ItemLocation::GrottoScrub(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, 0xF9, "DMC Deku Scrub Grotto Center", DMC_DEKU_SCRUB_GROTTO_CENTER, BUY_ARROWS_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - - //Zoras River - locationTable[ZR_OPEN_GROTTO_CHEST] = ItemLocation::Chest (RC_ZR_OPEN_GROTTO_CHEST, 0x3E, 0x09, "ZR Open Grotto Chest", ZR_OPEN_GROTTO_CHEST, RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_MAGIC_BEAN_SALESMAN] = ItemLocation::Base (RC_ZR_MAGIC_BEAN_SALESMAN, 0x54, "ZR Magic Bean Salesman", ZR_MAGIC_BEAN_SALESMAN, MAGIC_BEAN, {}, SpoilerCollectionCheck::MagicBeans(), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_FROGS_ZELDAS_LULLABY] = ItemLocation::Base (RC_ZR_FROGS_ZELDAS_LULLABY, 0x54, "ZR Frogs Zelda's Lullaby", ZR_FROGS_ZELDAS_LULLABY, PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD1), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_FROGS_EPONAS_SONG] = ItemLocation::Base (RC_ZR_FROGS_EPONAS_SONG, 0x54, "ZR Frogs Epona's Song", ZR_FROGS_EPONAS_SONG, PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD2), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_FROGS_SARIAS_SONG] = ItemLocation::Base (RC_ZR_FROGS_SARIAS_SONG, 0x54, "ZR Frogs Saria's Song", ZR_FROGS_SARIAS_SONG, PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD4), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_FROGS_SUNS_SONG] = ItemLocation::Base (RC_ZR_FROGS_SUNS_SONG, 0x54, "ZR Frogs Sun's Song", ZR_FROGS_SUNS_SONG, PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD3), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_FROGS_SONG_OF_TIME] = ItemLocation::Base (RC_ZR_FROGS_SONG_OF_TIME, 0x54, "ZR Frogs Song of Time", ZR_FROGS_SONG_OF_TIME, PURPLE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xD5), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_FROGS_IN_THE_RAIN] = ItemLocation::Base (RC_ZR_FROGS_IN_THE_RAIN, 0x54, "ZR Frogs in the Rain", ZR_FROGS_IN_THE_RAIN, PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xD6), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_FROGS_OCARINA_GAME] = ItemLocation::Base (RC_ZR_FROGS_OCARINA_GAME, 0x54, "ZR Frogs Ocarina Game", ZR_FROGS_OCARINA_GAME, PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xD0), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = ItemLocation::Collectable(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, 0x54, 0x04, "ZR Near Open Grotto Freestanding PoH", ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_NEAR_DOMAIN_FREESTANDING_POH] = ItemLocation::Collectable(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, 0x54, 0x0B, "ZR Near Domain Freestanding PoH", ZR_NEAR_DOMAIN_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_DEKU_SCRUB_GROTTO_REAR] = ItemLocation::GrottoScrub(RC_ZR_DEKU_SCRUB_GROTTO_REAR, 0xEB, "ZR Deku Scrub Grotto Rear", ZR_DEKU_SCRUB_GROTTO_REAR, BUY_RED_POTION_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_DEKU_SCRUB_GROTTO_FRONT] = ItemLocation::GrottoScrub(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, 0xEB, "ZR Deku Scrub Grotto Front", ZR_DEKU_SCRUB_GROTTO_FRONT, BUY_GREEN_POTION, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - - //Zoras Domain - locationTable[ZD_CHEST] = ItemLocation::Chest (RC_ZD_CHEST, 0x58, 0x00, "ZD Chest", ZD_CHEST, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZD_DIVING_MINIGAME] = ItemLocation::Base (RC_ZD_DIVING_MINIGAME, 0x58, "ZD Diving Minigame", ZD_DIVING_MINIGAME, PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::EventChkInf(0x38), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZD_KING_ZORA_THAWED] = ItemLocation::Base (RC_ZD_KING_ZORA_THAWED, 0x58, "ZD King Zora Thawed", ZD_KING_ZORA_THAWED, ZORA_TUNIC, {}, SpoilerCollectionCheck::InfTable(0x13, 0x01), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZD_TRADE_PRESCRIPTION] = ItemLocation::Base (RC_ZD_TRADE_PRESCRIPTION, 0x58, "ZD Trade Prescription", ZD_TRADE_PRESCRIPTION, EYEBALL_FROG, {Category::cAdultTrade}, SpoilerCollectionCheck::Chest(0x58, 0x1F), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - - //Zoras Fountain - locationTable[ZF_ICEBERG_FREESTANDING_POH] = ItemLocation::Collectable(RC_ZF_ICEBERC_FREESTANDING_POH, 0x59, 0x01, "ZF Iceberg Freestanding PoH", ZF_ICEBERG_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZF_BOTTOM_FREESTANDING_POH] = ItemLocation::Collectable(RC_ZF_BOTTOM_FREESTANDING_POH, 0x59, 0x14, "ZF Bottom Freestanding PoH", ZF_BOTTOM_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - - //Lon Lon Ranch - locationTable[LLR_TALONS_CHICKENS] = ItemLocation::Base (RC_LLR_TALONS_CHICKENS, 0x4C, "LLR Talons Chickens", LLR_TALONS_CHICKENS, BOTTLE_WITH_MILK, {}, SpoilerCollectionCheck::ItemGetInf(2), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[LLR_FREESTANDING_POH] = ItemLocation::Collectable(RC_LLR_FREESTANDING_POH, 0x4C, 0x01, "LLR Freestanding PoH", LLR_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[LLR_DEKU_SCRUB_GROTTO_LEFT] = ItemLocation::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, 0xFC, "LLR Deku Scrub Grotto Left", LLR_DEKU_SCRUB_GROTTO_LEFT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[LLR_DEKU_SCRUB_GROTTO_RIGHT] = ItemLocation::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, 0xFC, "LLR Deku Scrub Grotto Right", LLR_DEKU_SCRUB_GROTTO_RIGHT, BUY_BOMBS_535, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[LLR_DEKU_SCRUB_GROTTO_CENTER] = ItemLocation::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, 0xFC, "LLR Deku Scrub Grotto Center", LLR_DEKU_SCRUB_GROTTO_CENTER, BUY_DEKU_SEEDS_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - - /*------------------- - --- DUNGEONS --- - -------------------*/ - - //Deku Tree Vanilla - locationTable[DEKU_TREE_MAP_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_MAP_CHEST, 0x00, 0x03, "Deku Tree Map Chest", DEKU_TREE_MAP_CHEST, DEKU_TREE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_COMPASS_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_COMPASS_CHEST, 0x00, 0x02, "Deku Tree Compass Chest", DEKU_TREE_COMPASS_CHEST, DEKU_TREE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_COMPASS_ROOM_SIDE_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, 0x00, 0x06, "Deku Tree Compass Room Side Chest", DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_BASEMENT_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_BASEMENT_CHEST, 0x00, 0x04, "Deku Tree Basement Chest", DEKU_TREE_BASEMENT_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_SLINGSHOT_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_SLINGSHOT_CHEST, 0x00, 0x01, "Deku Tree Slingshot Chest", DEKU_TREE_SLINGSHOT_CHEST, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, 0x00, 0x05, "Deku Tree Slingshot Room Side Chest", DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - //Deku Tree MQ - locationTable[DEKU_TREE_MQ_MAP_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_MQ_MAP_CHEST, 0x00, 0x03, "Deku Tree MQ Map Chest", DEKU_TREE_MQ_MAP_CHEST, DEKU_TREE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_MQ_COMPASS_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_MQ_COMPASS_CHEST, 0x00, 0x01, "Deku Tree MQ Compass Chest", DEKU_TREE_MQ_COMPASS_CHEST, DEKU_TREE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_MQ_SLINGSHOT_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, 0x00, 0x06, "Deku Tree MQ Slingshot Chest", DEKU_TREE_MQ_SLINGSHOT_CHEST, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, 0x00, 0x02, "Deku Tree MQ Slingshot Room Back Chest", DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_MQ_BASEMENT_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_MQ_BASEMENT_CHEST, 0x00, 0x04, "Deku Tree MQ Basement Chest", DEKU_TREE_MQ_BASEMENT_CHEST, DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, 0x00, 0x05, "Deku Tree MQ Before Spinning Log Chest", DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST] = ItemLocation::Chest (RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, 0x00, 0x00, "Deku Tree MQ After Spinning Log Chest", DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_MQ_DEKU_SCRUB] = ItemLocation::Base (RC_DEKU_TREE_MQ_DEKU_SCRUB, 0x00, "Deku Tree MQ Deku Scrub", DEKU_TREE_MQ_DEKU_SCRUB, BUY_DEKU_SHIELD, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - - //Dodongos Cavern Shared - locationTable[DODONGOS_CAVERN_BOSS_ROOM_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, 0x12, 0x00, "Dodongos Cavern Boss Room Chest", DODONGOS_CAVERN_BOSS_ROOM_CHEST, BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - //Dodongos Cavern Vanilla - locationTable[DODONGOS_CAVERN_MAP_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_MAP_CHEST, 0x01, 0x08, "Dodongos Cavern Map Chest", DODONGOS_CAVERN_MAP_CHEST, DODONGOS_CAVERN_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_COMPASS_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_COMPASS_CHEST, 0x01, 0x05, "Dodongos Cavern Compass Chest", DODONGOS_CAVERN_COMPASS_CHEST, DODONGOS_CAVERN_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, 0x01, 0x06, "Dodongos Cavern Bomb Flower Platform Chest", DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_BOMB_BAG_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, 0x01, 0x04, "Dodongos Cavern Bomb Bag Chest", DODONGOS_CAVERN_BOMB_BAG_CHEST, PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_END_OF_BRIDGE_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, 0x01, 0x0A, "Dodongos Cavern End Of Bridge Chest", DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = ItemLocation::Base (RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, 0x01, "Dodongos Cavern Deku Scrub Near Bomb Bag Left", DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = ItemLocation::Base (RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, 0x01, "Dodongos Cavern Deku Scrub Side Room Near Dodongos", DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, BUY_DEKU_STICK_1, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = ItemLocation::Base (RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, 0x01, "Dodongos Cavern Deku Scrub Near Bomb Bag Right", DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, BUY_DEKU_SEEDS_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = ItemLocation::Base (RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, 0x01, "Dodongos Cavern Deku Scrub Lobby", DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, BUY_DEKU_SHIELD, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - //Dodongos Cavern MQ - locationTable[DODONGOS_CAVERN_MQ_MAP_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_MQ_MAP_CHEST, 0x01, 0x00, "Dodongos Cavern MQ Map Chest", DODONGOS_CAVERN_MQ_MAP_CHEST, DODONGOS_CAVERN_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, 0x01, 0x04, "Dodongos Cavern MQ Bomb Bag Chest", DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_COMPASS_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, 0x01, 0x05, "Dodongos Cavern MQ Compass Chest", DODONGOS_CAVERN_MQ_COMPASS_CHEST, DODONGOS_CAVERN_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, 0x01, 0x02, "Dodongos Cavern MQ Larvae Room Chest", DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, 0x01, 0x03, "Dodongos Cavern MQ Torch Puzzle Room Chest", DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST] = ItemLocation::Chest (RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, 0x01, 0x01, "Dodongos Cavern MQ Under Grave Chest", DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = ItemLocation::Base (RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, 0x01, "Dodongos Cavern Deku Scrub Lobby Rear", DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, BUY_DEKU_STICK_1, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = ItemLocation::Base (RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, 0x01, "Dodongos Cavern Deku Scrub Lobby Front", DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, BUY_DEKU_SEEDS_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = ItemLocation::Base (RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, 0x01, "Dodongos Cavern Deku Scrub Staircase", DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, BUY_DEKU_SHIELD, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = ItemLocation::Base (RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, 0x01, "Dodongos Cavern Deku Scrub Side Room Near Lower Lizalfos",DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, BUY_RED_POTION_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - - //Jabu Jabus Belly Vanilla - locationTable[JABU_JABUS_BELLY_MAP_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MAP_CHEST, 0x02, 0x02, "Jabu Jabus Belly Map Chest", JABU_JABUS_BELLY_MAP_CHEST, JABU_JABUS_BELLY_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_COMPASS_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_COMPASS_CHEST, 0x02, 0x04, "Jabu Jabus Belly Compass Chest", JABU_JABUS_BELLY_COMPASS_CHEST, JABU_JABUS_BELLY_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_BOOMERANG_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, 0x02, 0x01, "Jabu Jabus Belly Boomerang Chest", JABU_JABUS_BELLY_BOOMERANG_CHEST, BOOMERANG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_DEKU_SCRUB] = ItemLocation::Base (RC_JABU_JABUS_BELLY_DEKU_SCRUB, 0x02, "Jabu Jabus Belly Deku Scrub", JABU_JABUS_BELLY_DEKU_SCRUB, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - //Jabu Jabus Belly MQ - locationTable[JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, 0x02, 0x05, "Jabu Jabus Belly MQ First Room Side Chest", JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_MAP_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, 0x02, 0x03, "Jabu Jabus Belly MQ Map Chest", JABU_JABUS_BELLY_MQ_MAP_CHEST, JABU_JABUS_BELLY_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, 0x02, 0x02, "Jabu Jabus Belly MQ Second Room Lower Chest", JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_COMPASS_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, 0x02, 0x00, "Jabu Jabus Belly MQ Compass Chest", JABU_JABUS_BELLY_MQ_COMPASS_CHEST, JABU_JABUS_BELLY_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, 0x02, 0x07, "Jabu Jabus Belly MQ Second Room Upper Chest", JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, 0x02, 0x08, "Jabu Jabus Belly MQ Basement Near Switches Chest", JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, 0x02, 0x04, "Jabu Jabus Belly MQ Basement Near Vines Chest", JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, 0x02, 0x0A, "Jabu Jabus Belly MQ Near Boss Chest", JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, 0x02, 0x09, "Jabu Jabus Belly MQ Falling Like Like Room Chest", JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, DEKU_STICK_1, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, 0x02, 0x01, "Jabu Jabus Belly MQ Boomerang Room Small Chest", JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST] = ItemLocation::Chest (RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, 0x02, 0x06, "Jabu Jabus Belly MQ Boomerang Chest", JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, BOOMERANG, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - //COW - - //Forest Temple Vanilla - locationTable[FOREST_TEMPLE_FIRST_ROOM_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, 0x03, 0x03, "Forest Temple First Room Chest", FOREST_TEMPLE_FIRST_ROOM_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_FIRST_STALFOS_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, 0x03, 0x00, "Forest Temple First Stalfos Chest", FOREST_TEMPLE_FIRST_STALFOS_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, 0x03, 0x05, "Forest Temple Raised Island Courtyard Chest", FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MAP_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MAP_CHEST, 0x03, 0x01, "Forest Temple Map Chest", FOREST_TEMPLE_MAP_CHEST, FOREST_TEMPLE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_WELL_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_WELL_CHEST, 0x03, 0x09, "Forest Temple Well Chest", FOREST_TEMPLE_WELL_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, 0x03, 0x07, "Forest Temple Falling Ceiling Room Chest", FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_EYE_SWITCH_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, 0x03, 0x04, "Forest Temple Eye Switch Chest", FOREST_TEMPLE_EYE_SWITCH_CHEST, ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_BOSS_KEY_CHEST, 0x03, 0x0E, "Forest Temple Boss Key Chest", FOREST_TEMPLE_BOSS_KEY_CHEST, FOREST_TEMPLE_BOSS_KEY, {Category::cVanillaBossKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_FLOORMASTER_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_FLOORMASTER_CHEST, 0x03, 0x02, "Forest Temple Floormaster Chest", FOREST_TEMPLE_FLOORMASTER_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_BOW_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_BOW_CHEST, 0x03, 0x0C, "Forest Temple Bow Chest", FOREST_TEMPLE_BOW_CHEST, PROGRESSIVE_BOW, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_RED_POE_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_RED_POE_CHEST, 0x03, 0x0D, "Forest Temple Red Poe Chest", FOREST_TEMPLE_RED_POE_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_BLUE_POE_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_BLUE_POE_CHEST, 0x03, 0x0F, "Forest Temple Blue Poe Chest", FOREST_TEMPLE_BLUE_POE_CHEST, FOREST_TEMPLE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_BASEMENT_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_BASEMENT_CHEST, 0x03, 0x0B, "Forest Temple Basement Chest", FOREST_TEMPLE_BASEMENT_CHEST, ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - //Forest Temple MQ - locationTable[FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, 0x03, 0x03, "Forest Temple MQ First Room Chest", FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_WOLFOS_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, 0x03, 0x00, "Forest Temple MQ Wolfos Chest", FOREST_TEMPLE_MQ_WOLFOS_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_BOW_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_BOW_CHEST, 0x03, 0x0C, "Forest Temple MQ Bow Chest", FOREST_TEMPLE_MQ_BOW_CHEST, PROGRESSIVE_BOW, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, 0x03, 0x01, "Forest Temple MQ Raised Island Courtyard Lower Chest", FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, 0x03, 0x05, "Forest Temple MQ Raised Island Courtyard Upper Chest", FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_WELL_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_WELL_CHEST, 0x03, 0x09, "Forest Temple MQ Well Chest", FOREST_TEMPLE_MQ_WELL_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_MAP_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_MAP_CHEST, 0x03, 0x0D, "Forest Temple MQ Map Chest", FOREST_TEMPLE_MQ_MAP_CHEST, FOREST_TEMPLE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_COMPASS_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, 0x03, 0x0F, "Forest Temple MQ Compass Chest", FOREST_TEMPLE_MQ_COMPASS_CHEST, FOREST_TEMPLE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, 0x03, 0x06, "Forest Temple MQ Falling Ceiling Room Chest", FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_BASEMENT_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, 0x03, 0x0B, "Forest Temple MQ Basement Chest", FOREST_TEMPLE_MQ_BASEMENT_CHEST, ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_REDEAD_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, 0x03, 0x02, "Forest Temple MQ Redead Chest", FOREST_TEMPLE_MQ_REDEAD_CHEST, FOREST_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, 0x03, 0x0E, "Forest Temple MQ Boss Key Chest", FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, FOREST_TEMPLE_BOSS_KEY, {Category::cVanillaBossKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - - //Fire Temple Vanilla - locationTable[FIRE_TEMPLE_NEAR_BOSS_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, 0x04, 0x01, "Fire Temple Near Boss Chest", FIRE_TEMPLE_NEAR_BOSS_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_FLARE_DANCER_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, 0x04, 0x00, "Fire Temple Flare Dancer Chest", FIRE_TEMPLE_FLARE_DANCER_CHEST, BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_BOSS_KEY_CHEST, 0x04, 0x0C, "Fire Temple Boss Key Chest", FIRE_TEMPLE_BOSS_KEY_CHEST, FIRE_TEMPLE_BOSS_KEY, {Category::cVanillaBossKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, 0x04, 0x02, "Fire Temple Big Lava Room Blocked Door Chest", FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, 0x04, 0x04, "Fire Temple Big Lava Room Lower Open Door Chest", FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, 0x04, 0x03, "Fire Temple Boulder Maze Lower Chest", FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, 0x04, 0x06, "Fire Temple Boulder Maze Upper Chest", FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, 0x04, 0x08, "Fire Temple Boulder Maze Side Room Chest", FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, 0x04, 0x0B, "Fire Temple Boulder Maze Shortcut Chest", FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_SCARECROW_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_SCARECROW_CHEST, 0x04, 0x0D, "Fire Temple Scarecrow Chest", FIRE_TEMPLE_SCARECROW_CHEST, HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MAP_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MAP_CHEST, 0x04, 0x0A, "Fire Temple Map Chest", FIRE_TEMPLE_MAP_CHEST, FIRE_TEMPLE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_COMPASS_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_COMPASS_CHEST, 0x04, 0x07, "Fire Temple Compass Chest", FIRE_TEMPLE_COMPASS_CHEST, FIRE_TEMPLE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_HIGHEST_GORON_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, 0x04, 0x09, "Fire Temple Highest Goron Chest", FIRE_TEMPLE_HIGHEST_GORON_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MEGATON_HAMMER_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, 0x04, 0x05, "Fire Temple Megaton Hammer Chest", FIRE_TEMPLE_MEGATON_HAMMER_CHEST, MEGATON_HAMMER, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - //Fire Temple MQ - locationTable[FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, 0x04, 0x07, "Fire Temple MQ Near Boss Chest", FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, 0x04, 0x00, "Fire Temple MQ Megaton Hammer Chest", FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, MEGATON_HAMMER, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_COMPASS_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, 0x04, 0x0B, "Fire Temple MQ Compass Chest", FIRE_TEMPLE_MQ_COMPASS_CHEST, FIRE_TEMPLE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, 0x04, 0x03, "Fire Temple MQ Lizalfos Maze Lower Chest", FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, 0x04, 0x06, "Fire Temple MQ Lizalfos Maze Upper Chest", FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_CHEST_ON_FIRE] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, 0x04, 0x05, "Fire Temple MQ Chest on Fire", FIRE_TEMPLE_MQ_CHEST_ON_FIRE, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, 0x04, 0x02, "Fire Temple MQ Map Room Side Chest", FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_MAP_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_MAP_CHEST, 0x04, 0x0C, "Fire Temple MQ Map Chest", FIRE_TEMPLE_MQ_MAP_CHEST, FIRE_TEMPLE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, 0x04, 0x04, "Fire Temple MQ Boss Key Chest", FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, FIRE_TEMPLE_BOSS_KEY, {Category::cVanillaBossKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, 0x04, 0x01, "Fire Temple MQ Big Lava Room Blocked Door Chest", FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST] = ItemLocation::Chest (RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, 0x04, 0x08, "Fire Temple MQ Lizalfos Maze Side Room Chest", FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_FREESTANDING_KEY] = ItemLocation::Collectable(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, 0x04, 0x1C, "Fire Temple MQ Freestanding Key", FIRE_TEMPLE_MQ_FREESTANDING_KEY, FIRE_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - - //Water Temple Vanilla - locationTable[WATER_TEMPLE_MAP_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_MAP_CHEST, 0x05, 0x02, "Water Temple Map Chest", WATER_TEMPLE_MAP_CHEST, WATER_TEMPLE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_COMPASS_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_COMPASS_CHEST, 0x05, 0x09, "Water Temple Compass Chest", WATER_TEMPLE_COMPASS_CHEST, WATER_TEMPLE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_TORCHES_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_TORCHES_CHEST, 0x05, 0x01, "Water Temple Torches Chest", WATER_TEMPLE_TORCHES_CHEST, WATER_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_DRAGON_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_DRAGON_CHEST, 0x05, 0x0A, "Water Temple Dragon Chest", WATER_TEMPLE_DRAGON_CHEST, WATER_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, 0x05, 0x08, "Water Temple Central Bow Target Chest", WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, WATER_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_CENTRAL_PILLAR_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, 0x05, 0x06, "Water Temple Central Pillar Chest", WATER_TEMPLE_CENTRAL_PILLAR_CHEST, WATER_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_CRACKED_WALL_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_CRACKED_WALL_CHEST, 0x05, 0x00, "Water Temple Cracked Wall Chest", WATER_TEMPLE_CRACKED_WALL_CHEST, WATER_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_BOSS_KEY_CHEST, 0x05, 0x05, "Water Temple Boss Key Chest", WATER_TEMPLE_BOSS_KEY_CHEST, WATER_TEMPLE_BOSS_KEY, {Category::cVanillaBossKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_LONGSHOT_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_LONGSHOT_CHEST, 0x05, 0x07, "Water Temple Longshot Chest", WATER_TEMPLE_LONGSHOT_CHEST, PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_RIVER_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_RIVER_CHEST, 0x05, 0x03, "Water Temple River Chest", WATER_TEMPLE_RIVER_CHEST, WATER_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - //Water Temple MQ - locationTable[WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, 0x05, 0x06, "Water Temple MQ Central Pillar Chest", WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, WATER_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_MQ_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, 0x05, 0x05, "Water Temple MQ Boss Key Chest", WATER_TEMPLE_MQ_BOSS_KEY_CHEST, WATER_TEMPLE_BOSS_KEY, {Category::cVanillaBossKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_MQ_LONGSHOT_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, 0x05, 0x00, "Water Temple MQ Longshot Chest", WATER_TEMPLE_MQ_LONGSHOT_CHEST, PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_MQ_COMPASS_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_MQ_COMPASS_CHEST, 0x05, 0x01, "Water Temple MQ Compass Chest", WATER_TEMPLE_MQ_COMPASS_CHEST, WATER_TEMPLE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_MQ_MAP_CHEST] = ItemLocation::Chest (RC_WATER_TEMPLE_MQ_MAP_CHEST, 0x05, 0x02, "Water Temple MQ Map Chest", WATER_TEMPLE_MQ_MAP_CHEST, WATER_TEMPLE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_MQ_FREESTANDING_KEY] = ItemLocation::Collectable(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, 0x05, 0x01, "Water Temple MQ Freestanding Key", WATER_TEMPLE_MQ_FREESTANDING_KEY, WATER_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - - //Spirit Temple Shared - locationTable[SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, 0x5C, 0x0B, "Spirit Temple Silver Gauntlets Chest", SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, 0x5C, 0x09, "Spirit Temple Mirror Shield Chest", SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, MIRROR_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - //Spirit Temple Vanilla - locationTable[SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, 0x06, 0x08, "Spirit Temple Child Bridge Chest", SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, 0x06, 0x00, "Spirit Temple Child Early Torches Chest", SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_COMPASS_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_COMPASS_CHEST, 0x06, 0x04, "Spirit Temple Compass Chest", SPIRIT_TEMPLE_COMPASS_CHEST, SPIRIT_TEMPLE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, 0x06, 0x07, "Spirit Temple Early Adult Right Chest", SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, 0x06, 0x0D, "Spirit Temple First Mirror Left Chest", SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, 0x06, 0x0E, "Spirit Temple First Mirror Right Chest", SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MAP_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MAP_CHEST, 0x06, 0x03, "Spirit Temple Map Chest", SPIRIT_TEMPLE_MAP_CHEST, SPIRIT_TEMPLE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, 0x06, 0x06, "Spirit Temple Child Climb North Chest", SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, 0x06, 0x0C, "Spirit Temple Child Climb East Chest", SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, 0x06, 0x01, "Spirit Temple Sun Block Room Chest", SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, 0x06, 0x02, "Spirit Temple Statue Room Hand Chest", SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, 0x06, 0x0F, "Spirit Temple Statue Room Northeast Chest", SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, 0x06, 0x05, "Spirit Temple Near Four Armos Chest", SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, 0x06, 0x14, "Spirit Temple Hallway Right Invisible Chest", SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, 0x06, 0x15, "Spirit Temple Hallway Left Invisible Chest", SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, 0x06, 0x0A, "Spirit Temple Boss Key Chest", SPIRIT_TEMPLE_BOSS_KEY_CHEST, SPIRIT_TEMPLE_BOSS_KEY, {Category::cVanillaBossKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_TOPMOST_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_TOPMOST_CHEST, 0x06, 0x12, "Spirit Temple Topmost Chest", SPIRIT_TEMPLE_TOPMOST_CHEST, BOMBS_20, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - //Spirit Temple MQ - locationTable[SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, 0x06, 0x1A, "Spirit Temple MQ Entrance Front Left Chest", SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, 0x06, 0x1F, "Spirit Temple MQ Entrance Back Right Chest", SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, 0x06, 0x1B, "Spirit Temple MQ Entrance Front Right Chest", SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, 0x06, 0x1E, "Spirit Temple MQ Entrance Back Left Chest", SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, 0x06, 0x1D, "Spirit Temple MQ Child Hammer Switch Chest", SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_MAP_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, 0x06, 0x00, "Spirit Temple MQ Map Chest", SPIRIT_TEMPLE_MQ_MAP_CHEST, SPIRIT_TEMPLE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, 0x06, 0x08, "Spirit Temple MQ Map Room Enemy Chest", SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, 0x06, 0x06, "Spirit Temple MQ Child Climb North Chest", SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, 0x06, 0x0C, "Spirit Temple MQ Child Climb South Chest", SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_COMPASS_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, 0x06, 0x03, "Spirit Temple MQ Compass Chest", SPIRIT_TEMPLE_MQ_COMPASS_CHEST, SPIRIT_TEMPLE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, 0x06, 0x0F, "Spirit Temple MQ Statue Room Lullaby Chest", SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, 0x06, 0x02, "Spirit Temple MQ Statue Room Invisible Chest", SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, 0x06, 0x1C, "Spirit Temple MQ Silver Block Hallway Chest", SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, 0x06, 0x01, "Spirit Temple MQ Sun Block Room Chest", SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, 0x06, 0x07, "Spirit Temple MQ Symphony Room Chest", SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, 0x06, 0x04, "Spirit Temple MQ Leever Room Chest", SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, 0x06, 0x19, "Spirit Temple MQ Beamos Room Chest", SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, 0x06, 0x18, "Spirit Temple MQ Chest Switch Chest", SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, 0x06, 0x05, "Spirit Temple MQ Boss Key Chest", SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, SPIRIT_TEMPLE_BOSS_KEY, {Category::cVanillaBossKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST] = ItemLocation::Chest (RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, 0x06, 0x12, "Spirit Temple MQ Mirror Puzzle Invisible Chest", SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, SPIRIT_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - - //Shadow Temple Vanilla - locationTable[SHADOW_TEMPLE_MAP_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MAP_CHEST, 0x07, 0x01, "Shadow Temple Map Chest", SHADOW_TEMPLE_MAP_CHEST, SHADOW_TEMPLE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_HOVER_BOOTS_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, 0x07, 0x07, "Shadow Temple Hover Boots Chest", SHADOW_TEMPLE_HOVER_BOOTS_CHEST, HOVER_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_COMPASS_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_COMPASS_CHEST, 0x07, 0x03, "Shadow Temple Compass Chest", SHADOW_TEMPLE_COMPASS_CHEST, SHADOW_TEMPLE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, 0x07, 0x02, "Shadow Temple Early Silver Rupee Chest", SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, 0x07, 0x0C, "Shadow Temple Invisible Blades Visible Chest", SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, 0x07, 0x16, "Shadow Temple Invisible Blades Invisible Chest", SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, 0x07, 0x05, "Shadow Temple Falling Spikes Lower Chest", SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, 0x07, 0x06, "Shadow Temple Falling Spikes Upper Chest", SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, 0x07, 0x04, "Shadow Temple Falling Spikes Switch Chest", SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, 0x07, 0x09, "Shadow Temple Invisible Spikes Chest", SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_WIND_HINT_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_WIND_HINT_CHEST, 0x07, 0x15, "Shadow Temple Wind Hint Chest", SHADOW_TEMPLE_WIND_HINT_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, 0x07, 0x08, "Shadow Temple After Wind Enemy Chest", SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, 0x07, 0x14, "Shadow Temple After Wind Hidden Chest", SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, 0x07, 0x0A, "Shadow Temple Spike Walls Left Chest", SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, 0x07, 0x0B, "Shadow Temple Boss Key Chest", SHADOW_TEMPLE_BOSS_KEY_CHEST, SHADOW_TEMPLE_BOSS_KEY, {Category::cVanillaBossKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, 0x07, 0x0D, "Shadow Temple Invisible Floormaster Chest", SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_FREESTANDING_KEY] = ItemLocation::Collectable(RC_SHADOW_TEMPLE_FREESTANDING_KEY, 0x07, 0x01, "Shadow Temple Freestanding Key", SHADOW_TEMPLE_FREESTANDING_KEY, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - //Shadow Temple MQ - locationTable[SHADOW_TEMPLE_MQ_COMPASS_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, 0x07, 0x01, "Shadow Temple MQ Compass Chest", SHADOW_TEMPLE_MQ_COMPASS_CHEST, SHADOW_TEMPLE_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, 0x07, 0x07, "Shadow Temple MQ Hover Boots Chest", SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, HOVER_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, 0x07, 0x03, "Shadow Temple MQ Early Gibdos Chest", SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_MAP_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_MAP_CHEST, 0x07, 0x02, "Shadow Temple MQ Map Chest", SHADOW_TEMPLE_MQ_MAP_CHEST, SHADOW_TEMPLE_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, 0x07, 0x0F, "Shadow Temple MQ Beamos Silver Rupees Chest", SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, 0x07, 0x04, "Shadow Temple MQ Falling Spikes Switch Chest", SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, 0x07, 0x05, "Shadow Temple MQ Falling Spikes Lower Chest", SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, 0x07, 0x06, "Shadow Temple MQ Falling Spikes Upper Chest", SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, 0x07, 0x09, "Shadow Temple MQ Invisible Spikes Chest", SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, 0x07, 0x0B, "Shadow Temple MQ Boss Key Chest", SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, SHADOW_TEMPLE_BOSS_KEY, {Category::cVanillaBossKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, 0x07, 0x0A, "Shadow Temple MQ Spike Walls Left Chest", SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, 0x07, 0x10, "Shadow Temple MQ Stalfos Room Chest", SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, 0x07, 0x16, "Shadow Temple MQ Invisible Blades Invisible Chest", SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, 0x07, 0x0C, "Shadow Temple MQ Invisible Blades Visible Chest", SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, 0x07, 0x0D, "Shadow Temple MQ Bomb Flower Chest", SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_WIND_HINT_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, 0x07, 0x15, "Shadow Temple MQ Wind Hint Chest", SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, 0x07, 0x14, "Shadow Temple MQ After Wind Hidden Chest", SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, ARROWS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, 0x07, 0x08, "Shadow Temple MQ After Wind Enemy Chest", SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST] = ItemLocation::Chest (RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, 0x07, 0x0E, "Shadow Temple MQ Near Ship Invisible Chest", SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_FREESTANDING_KEY] = ItemLocation::Collectable(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, 0x07, 0x06, "Shadow Temple MQ Freestanding Key", SHADOW_TEMPLE_MQ_FREESTANDING_KEY, SHADOW_TEMPLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - - //Bottom of the Well Vanilla - locationTable[BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, 0x08, 0x08, "Bottom of the Well Front Left Fake Wall Chest", BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, BOTTOM_OF_THE_WELL_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, 0x08, 0x02, "Bottom of the Well Front Center Bombable Chest", BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, 0x08, 0x05, "Bottom of the Well Right Bottom Fake Wall Chest", BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, BOTTOM_OF_THE_WELL_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_COMPASS_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, 0x08, 0x01, "Bottom of the Well Compass Chest", BOTTOM_OF_THE_WELL_COMPASS_CHEST, BOTTOM_OF_THE_WELL_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, 0x08, 0x0E, "Bottom of the Well Center Skulltula Chest", BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, DEKU_NUTS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, 0x08, 0x04, "Bottom of the Well Back Left Bombable Chest", BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, DEKU_NUTS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, 0x08, 0x03, "Bottom of the Well Lens of Truth Chest", BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, LENS_OF_TRUTH, {Category::cSongDungeonReward}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_INVISIBLE_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, 0x08, 0x14, "Bottom of the Well Invisible Chest", BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, 0x08, 0x10, "Bottom of the Well Underwater Front Chest", BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, BOMBS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, 0x08, 0x09, "Bottom of the Well Underwater Left Chest", BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_MAP_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_MAP_CHEST, 0x08, 0x07, "Bottom of the Well Map Chest", BOTTOM_OF_THE_WELL_MAP_CHEST, BOTTOM_OF_THE_WELL_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, 0x08, 0x0A, "Bottom of the Well Fire Keese Chest", BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, DEKU_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, 0x08, 0x0C, "Bottom of the Well Like Like Chest", BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, HYLIAN_SHIELD, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_FREESTANDING_KEY] = ItemLocation::Collectable(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, 0x08, 0x01, "Bottom of the Well Freestanding Key", BOTTOM_OF_THE_WELL_FREESTANDING_KEY, BOTTOM_OF_THE_WELL_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - //Bottom of the Well MQBottomOfTheWell] - locationTable[BOTTOM_OF_THE_WELL_MQ_MAP_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, 0x08, 0x03, "Bottom of the Well MQ Map Chest", BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, BOTTOM_OF_THE_WELL_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, 0x08, 0x01, "Bottom of the Well MQ Lens of Truth Chest", BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, LENS_OF_TRUTH, {Category::cSongDungeonReward}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST] = ItemLocation::Chest (RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, 0x08, 0x02, "Bottom of the Well MQ Compass Chest", BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, BOTTOM_OF_THE_WELL_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY] = ItemLocation::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, 0x08, 0x02, "Bottom of the Well MQ Dead Hand Freestanding Key", BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, BOTTOM_OF_THE_WELL_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY] = ItemLocation::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, 0x08, 0x01, "Bottom of the Well MQ East Inner Room Freestanding Key",BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, BOTTOM_OF_THE_WELL_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - - //Ice Cavern Vanilla - locationTable[ICE_CAVERN_MAP_CHEST] = ItemLocation::Chest (RC_ICE_CAVERN_MAP_CHEST, 0x09, 0x00, "Ice Cavern Map Chest", ICE_CAVERN_MAP_CHEST, ICE_CAVERN_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[ICE_CAVERN_COMPASS_CHEST] = ItemLocation::Chest (RC_ICE_CAVERN_COMPASS_CHEST, 0x09, 0x01, "Ice Cavern Compass Chest", ICE_CAVERN_COMPASS_CHEST, ICE_CAVERN_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[ICE_CAVERN_IRON_BOOTS_CHEST] = ItemLocation::Chest (RC_ICE_CAVERN_IRON_BOOTS_CHEST, 0x09, 0x02, "Ice Cavern Iron Boots Chest", ICE_CAVERN_IRON_BOOTS_CHEST, IRON_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[ICE_CAVERN_FREESTANDING_POH] = ItemLocation::Collectable(RC_ICE_CAVERN_FREESTANDING_POH, 0x09, 0x01, "Ice Cavern Freestanding PoH", ICE_CAVERN_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - //Ice Cavern MQIceCavern] - locationTable[ICE_CAVERN_MQ_IRON_BOOTS_CHEST] = ItemLocation::Chest (RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, 0x09, 0x02, "Ice Cavern MQ Iron Boots Chest", ICE_CAVERN_MQ_IRON_BOOTS_CHEST, IRON_BOOTS, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[ICE_CAVERN_MQ_COMPASS_CHEST] = ItemLocation::Chest (RC_ICE_CAVERN_MQ_COMPASS_CHEST, 0x09, 0x00, "Ice Cavern MQ Compass Chest", ICE_CAVERN_MQ_COMPASS_CHEST, ICE_CAVERN_COMPASS, {Category::cVanillaCompass}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[ICE_CAVERN_MQ_MAP_CHEST] = ItemLocation::Chest (RC_ICE_CAVERN_MQ_MAP_CHEST, 0x09, 0x01, "Ice Cavern MQ Map Chest", ICE_CAVERN_MQ_MAP_CHEST, ICE_CAVERN_MAP, {Category::cVanillaMap}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[ICE_CAVERN_MQ_FREESTANDING_POH] = ItemLocation::Collectable(RC_ICE_CAVERN_MQ_FREESTANDING_POH, 0x09, 0x01, "Ice Cavern MQ Freestanding PoH", ICE_CAVERN_MQ_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - - //Gerudo Training Ground Vanilla - locationTable[GERUDO_TRAINING_GROUNDS_LOBBY_LEFT_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, 0x0B, 0x13, "Gerudo Training Grounds Lobby Left Chest", GERUDO_TRAINING_GROUNDS_LOBBY_LEFT_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_LOBBY_RIGHT_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, 0x0B, 0x07, "Gerudo Training Grounds Lobby Right Chest", GERUDO_TRAINING_GROUNDS_LOBBY_RIGHT_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_STALFOS_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, 0x0B, 0x00, "Gerudo Training Grounds Stalfos Chest", GERUDO_TRAINING_GROUNDS_STALFOS_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_BEAMOS_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, 0x0B, 0x01, "Gerudo Training Grounds Beamos Chest", GERUDO_TRAINING_GROUNDS_BEAMOS_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_HIDDEN_CEILING_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, 0x0B, 0x0B, "Gerudo Training Grounds Hidden Ceiling Chest", GERUDO_TRAINING_GROUNDS_HIDDEN_CEILING_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MAZE_PATH_FIRST_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, 0x0B, 0x06, "Gerudo Training Grounds Maze Path First Chest", GERUDO_TRAINING_GROUNDS_MAZE_PATH_FIRST_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MAZE_PATH_SECOND_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, 0x0B, 0x0A, "Gerudo Training Grounds Maze Path Second Chest", GERUDO_TRAINING_GROUNDS_MAZE_PATH_SECOND_CHEST, RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MAZE_PATH_THIRD_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, 0x0B, 0x09, "Gerudo Training Grounds Maze Path Third Chest", GERUDO_TRAINING_GROUNDS_MAZE_PATH_THIRD_CHEST, ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MAZE_PATH_FINAL_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, 0x0B, 0x0C, "Gerudo Training Grounds Maze Path Final Chest", GERUDO_TRAINING_GROUNDS_MAZE_PATH_FINAL_CHEST, ICE_ARROWS, {Category::cSongDungeonReward}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_CENTRAL_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, 0x0B, 0x05, "Gerudo Training Grounds Maze Right Central Chest", GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_CENTRAL_CHEST, BOMBCHU_5, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_SIDE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, 0x0B, 0x08, "Gerudo Training Grounds Maze Right Side Chest", GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_SIDE_CHEST, ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_UNDERWATER_SILVER_RUPEE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, 0x0B, 0x0D, "Gerudo Training Grounds Underwater Silver Rupee Chest", GERUDO_TRAINING_GROUNDS_UNDERWATER_SILVER_RUPEE_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_CLEAR_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, 0x0B, 0x12, "Gerudo Training Grounds Hammer Room Clear Chest", GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_CLEAR_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_SWITCH_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, 0x0B, 0x10, "Gerudo Training Grounds Hammer Room Switch Chest", GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_SWITCH_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_EYE_STATUE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, 0x0B, 0x03, "Gerudo Training Grounds Eye Statue Chest", GERUDO_TRAINING_GROUNDS_EYE_STATUE_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_NEAR_SCARECROW_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, 0x0B, 0x04, "Gerudo Training Grounds Near Scarecrow Chest", GERUDO_TRAINING_GROUNDS_NEAR_SCARECROW_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_BEFORE_HEAVY_BLOCK_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, 0x0B, 0x11, "Gerudo Training Grounds Before Heavy Block Chest", GERUDO_TRAINING_GROUNDS_BEFORE_HEAVY_BLOCK_CHEST, ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FIRST_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, 0x0B, 0x0F, "Gerudo Training Grounds Heavy Block First Chest", GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FIRST_CHEST, HUGE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_SECOND_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, 0x0B, 0x0E, "Gerudo Training Grounds Heavy Block Second Chest", GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_SECOND_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_THIRD_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, 0x0B, 0x14, "Gerudo Training Grounds Heavy Block Third Chest", GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_THIRD_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FOURTH_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, 0x0B, 0x02, "Gerudo Training Grounds Heavy Block Fourth Chest", GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FOURTH_CHEST, ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_FREESTANDING_KEY] = ItemLocation::Collectable(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, 0x0B, 0x01, "Gerudo Training Grounds Freestanding Key", GERUDO_TRAINING_GROUNDS_FREESTANDING_KEY, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - //Gerudo Training Grounds MQ - locationTable[GERUDO_TRAINING_GROUNDS_MQ_LOBBY_RIGHT_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, 0x0B, 0x07, "Gerudo Training Grounds MQ Lobby Right Chest", GERUDO_TRAINING_GROUNDS_MQ_LOBBY_RIGHT_CHEST, BOMBCHU_5, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_LOBBY_LEFT_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, 0x0B, 0x13, "Gerudo Training Grounds MQ Lobby Left Chest", GERUDO_TRAINING_GROUNDS_MQ_LOBBY_LEFT_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_FIRST_IRON_KNUCKLE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, 0x0B, 0x00, "Gerudo Training Grounds MQ First Iron Knuckle Chest", GERUDO_TRAINING_GROUNDS_MQ_FIRST_IRON_KNUCKLE_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_BEFORE_HEAVY_BLOCK_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, 0x0B, 0x11, "Gerudo Training Grounds MQ Before Heavy Block Chest", GERUDO_TRAINING_GROUNDS_MQ_BEFORE_HEAVY_BLOCK_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_EYE_STATUE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, 0x0B, 0x03, "Gerudo Training Grounds MQ Eye Statue Chest", GERUDO_TRAINING_GROUNDS_MQ_EYE_STATUE_CHEST, BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_FLAME_CIRCLE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, 0x0B, 0x0E, "Gerudo Training Grounds MQ Flame Circle Chest", GERUDO_TRAINING_GROUNDS_MQ_FLAME_CIRCLE_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_SECOND_IRON_KNUCKLE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, 0x0B, 0x12, "Gerudo Training Grounds MQ Second Iron Knuckle Chest", GERUDO_TRAINING_GROUNDS_MQ_SECOND_IRON_KNUCKLE_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_DINOLFOS_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, 0x0B, 0x01, "Gerudo Training Grounds MQ Dinolfos Chest", GERUDO_TRAINING_GROUNDS_MQ_DINOLFOS_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_ICE_ARROWS_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, 0x0B, 0x04, "Gerudo Training Grounds MQ Ice Arrows Chest", GERUDO_TRAINING_GROUNDS_MQ_ICE_ARROWS_CHEST, ICE_ARROWS, {Category::cSongDungeonReward}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_CENTRAL_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, 0x0B, 0x05, "Gerudo Training Grounds MQ Maze Right Central Chest", GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_CENTRAL_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_FIRST_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, 0x0B, 0x06, "Gerudo Training Grounds MQ Maze Path First Chest", GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_FIRST_CHEST, GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_SIDE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, 0x0B, 0x08, "Gerudo Training Grounds MQ Maze Right Side Chest", GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_SIDE_CHEST, TREASURE_GAME_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_THIRD_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, 0x0B, 0x09, "Gerudo Training Grounds MQ Maze Path Third Chest", GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_THIRD_CHEST, TREASURE_GAME_GREEN_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_SECOND_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, 0x0B, 0x0A, "Gerudo Training Grounds MQ Maze Path Second Chest", GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_SECOND_CHEST, RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_HIDDEN_CEILING_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, 0x0B, 0x0B, "Gerudo Training Grounds MQ Hidden Ceiling Chest", GERUDO_TRAINING_GROUNDS_MQ_HIDDEN_CEILING_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER_SILVER_RUPEE_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, 0x0B, 0x0D, "Gerudo Training Grounds MQ Underwater Silver Rupee Chest",GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER_SILVER_RUPEE_CHEST, GERUDO_TRAINING_GROUNDS_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - locationTable[GERUDO_TRAINING_GROUNDS_MQ_HEAVY_BLOCK_CHEST] = ItemLocation::Chest (RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, 0x0B, 0x02, "Gerudo Training Grounds MQ Heavy Block Chest", GERUDO_TRAINING_GROUNDS_MQ_HEAVY_BLOCK_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_TRAINING_GROUND); - - //Ganons Castle Shared - locationTable[GANONS_TOWER_BOSS_KEY_CHEST] = ItemLocation::Chest (RC_GANONS_TOWER_BOSS_KEY_CHEST, 0x0A, 0x0B, "Ganon's Tower Boss Key Chest", GANONS_TOWER_BOSS_KEY_CHEST, GANONS_CASTLE_BOSS_KEY, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - //Ganons Castle Vanilla - locationTable[GANONS_CASTLE_FOREST_TRIAL_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, 0x0D, 0x09, "Ganon's Castle Forest Trial Chest", GANONS_CASTLE_FOREST_TRIAL_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, 0x0D, 0x07, "Ganon's Castle Water Trial Left Chest", GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, 0x0D, 0x06, "Ganon's Castle Water Trial Right Chest", GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, 0x0D, 0x08, "Ganon's Castle Shadow Trial Front Chest", GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, 0x0D, 0x05, "Ganon's Castle Shadow Trial Golden Gauntlets Chest", GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, 0x0D, 0x12, "Ganon's Castle Spirit Trial Crystal Switch Chest", GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, BOMBCHU_20, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, 0x0D, 0x14, "Ganon's Castle Spirit Trial Invisible Chest", GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, 0x0D, 0x0C, "Ganon's Castle Light Trial First Left Chest", GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, 0x0D, 0x0B, "Ganon's Castle Light Trial Second Left Chest", GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, 0x0D, 0x0D, "Ganon's Castle Light Trial Third Left Chest", GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, 0x0D, 0x0E, "Ganon's Castle Light Trial First Right Chest", GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, 0x0D, 0x0A, "Ganon's Castle Light Trial Second Right Chest", GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, ARROWS_30, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, 0x0D, 0x0F, "Ganon's Castle Light Trial Third Right Chest", GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, ICE_TRAP, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, 0x0D, 0x10, "Ganon's Castle Light Trial Invisible Enemies Chest", GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, GANONS_CASTLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, 0x0D, 0x11, "Ganon's Castle Light Trial Lullaby Chest", GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, GANONS_CASTLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = ItemLocation::Base (RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, 0x0D, "Ganon's Castle Deku Scrub Center-Left", GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, BUY_BOMBS_535, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = ItemLocation::Base (RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, 0x0D, "Ganon's Castle Deku Scrub Center-Right", GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, BUY_ARROWS_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_DEKU_SCRUB_RIGHT] = ItemLocation::Base (RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, 0x0D, "Ganon's Castle Deku Scrub Right", GANONS_CASTLE_DEKU_SCRUB_RIGHT, BUY_RED_POTION_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_DEKU_SCRUB_LEFT] = ItemLocation::Base (RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, 0x0D, "Ganon's Castle Deku Scrub Left", GANONS_CASTLE_DEKU_SCRUB_LEFT, BUY_GREEN_POTION, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - //Ganons Castle MQ - locationTable[GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, 0x0D, 0x01, "Ganon's Castle MQ Water Trial Chest", GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RED_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, 0x0D, 0x02, "Ganon's Castle MQ Forest Trial Eye Switch Chest", GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, 0x0D, 0x03, "Ganon's Castle MQ Forest Trial Frozen Eye Switch Chest",GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, BOMBS_5, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, 0x0D, 0x04, "Ganon's Castle MQ Light Trial Lullaby Chest", GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, 0x0D, 0x00, "Ganon's Castle MQ Shadow Trial Bomb Flower Chest", GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, 0x0D, 0x05, "Ganon's Castle MQ Shadow Trial Eye Switch Chest", GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, GANONS_CASTLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, 0x0D, 0x06, "Ganon's Castle MQ Spirit Trial Golden Gauntlets Chest", GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, PROGRESSIVE_STRENGTH, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, 0x0D, 0x07, "Ganon's Castle MQ Spirit Trial Sun Back Right Chest", GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, 0x0D, 0x08, "Ganon's Castle MQ Spirit Trial Sun Back Left Chest", GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, GANONS_CASTLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, 0x0D, 0x09, "Ganon's Castle MQ Spirit Trial Sun Front Left Chest", GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, RECOVERY_HEART, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, 0x0D, 0x0A, "Ganon's Castle MQ Spirit Trial First Chest", GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, BOMBCHU_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST] = ItemLocation::Chest (RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, 0x0D, 0x14, "Ganon's Castle MQ Spirit Trial Invisible Chest", GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, ARROWS_10, {}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY] = ItemLocation::Collectable(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, 0x0D, 0x01, "Ganon's Castle MQ Forest Trial Freestanding Key", GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, GANONS_CASTLE_SMALL_KEY, {Category::cVanillaSmallKey}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = ItemLocation::Base (RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, 0x0D, "Ganon's Castle MQ Deku Scrub Right", GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = ItemLocation::Base (RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, 0x0D, "Ganon's Castle MQ Deku Scrub Center-Left", GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, BUY_BOMBS_535, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = ItemLocation::Base (RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, 0x0D, "Ganon's Castle MQ Deku Scrub Center", GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, BUY_ARROWS_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = ItemLocation::Base (RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, 0x0D, "Ganon's Castle MQ Deku Scrub Center-Right", GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, BUY_RED_POTION_30, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = ItemLocation::Base (RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, 0x0D, "Ganon's Castle MQ Deku Scrub Left", GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, BUY_GREEN_POTION, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - - /*------------------------------- - --- GOLD SKULLTULA TOKENS --- - -------------------------------*/ - - //Dungeons - locationTable[DEKU_TREE_GS_BASEMENT_BACK_ROOM] = ItemLocation::GSToken(RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM, 0x00, 0x01, "Deku Tree GS Basement Back Room", DEKU_TREE_GS_BASEMENT_BACK_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_GS_BASEMENT_GATE] = ItemLocation::GSToken(RC_DEKU_TREE_GS_BASEMENT_GATE, 0x00, 0x02, "Deku Tree GS Basement Gate", DEKU_TREE_GS_BASEMENT_GATE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_GS_BASEMENT_VINES] = ItemLocation::GSToken(RC_DEKU_TREE_GS_BASEMENT_VINES, 0x00, 0x04, "Deku Tree GS Basement Vines", DEKU_TREE_GS_BASEMENT_VINES, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_GS_COMPASS_ROOM] = ItemLocation::GSToken(RC_DEKU_TREE_GS_COMPASS_ROOM, 0x00, 0x08, "Deku Tree GS Compass Room", DEKU_TREE_GS_COMPASS_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - - locationTable[DEKU_TREE_MQ_GS_LOBBY] = ItemLocation::GSToken(RC_DEKU_TREE_MQ_GS_LOBBY, 0x00, 0x02, "Deku Tree MQ GS Lobby", DEKU_TREE_MQ_GS_LOBBY, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_MQ_GS_COMPASS_ROOM] = ItemLocation::GSToken(RC_DEKU_TREE_MQ_GS_COMPASS_ROOM, 0x00, 0x08, "Deku Tree MQ GS Compass Room", DEKU_TREE_MQ_GS_COMPASS_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM] = ItemLocation::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, 0x00, 0x04, "Deku Tree MQ GS Basement Graves Room", DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM] = ItemLocation::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, 0x00, 0x01, "Deku Tree MQ GS Basement Back Room", DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - - locationTable[DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS] = ItemLocation::GSToken(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, 0x01, 0x01, "Dodongos Cavern GS Vines Above Stairs", DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_GS_SCARECROW] = ItemLocation::GSToken(RC_DODONGOS_CAVERN_GS_SCARECROW, 0x01, 0x02, "Dodongos Cavern GS Scarecrow", DODONGOS_CAVERN_GS_SCARECROW, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS] = ItemLocation::GSToken(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, 0x01, 0x04, "Dodongos Cavern GS Alcove Above Stairs", DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_GS_BACK_ROOM] = ItemLocation::GSToken(RC_DODONGOS_CAVERN_GS_BACK_ROOM, 0x01, 0x08, "Dodongos Cavern GS Back Room", DODONGOS_CAVERN_GS_BACK_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = ItemLocation::GSToken(RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, 0x01, 0x10, "Dodongos Cavern GS Side Room Near Lower Lizalfos", DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - - locationTable[DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM] = ItemLocation::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, 0x01, 0x02, "Dodongos Cavern MQ GS Scrub Room", DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM] = ItemLocation::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, 0x01, 0x08, "Dodongos Cavern MQ GS Song of Time Block Room", DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM] = ItemLocation::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, 0x01, 0x04, "Dodongos Cavern MQ GS Lizalfos Room", DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM] = ItemLocation::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, 0x01, 0x10, "Dodongos Cavern MQ GS Larvae Room", DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[DODONGOS_CAVERN_MQ_GS_BACK_AREA] = ItemLocation::GSToken(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, 0x01, 0x01, "Dodongos Cavern MQ GS Back Room", DODONGOS_CAVERN_MQ_GS_BACK_AREA, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - - locationTable[JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER] = ItemLocation::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, 0x02, 0x01, "Jabu Jabus Belly GS Lobby Basement Lower", JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER] = ItemLocation::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, 0x02, 0x02, "Jabu Jabus Belly GS Lobby Basement Upper", JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_GS_NEAR_BOSS] = ItemLocation::GSToken(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, 0x02, 0x04, "Jabu Jabus Belly GS Near Boss", JABU_JABUS_BELLY_GS_NEAR_BOSS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM] = ItemLocation::GSToken(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, 0x02, 0x08, "Jabu Jabus Belly GS Water Switch Room", JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - - locationTable[JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM] = ItemLocation::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, 0x02, 0x04, "Jabu Jabus Belly MQ GS Tail Parasan Room", JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM] = ItemLocation::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, 0x02, 0x08, "Jabu Jabus Belly MQ GS Invisible Enemies Room", JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM] = ItemLocation::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, 0x02, 0x01, "Jabu Jabus Belly MQ GS Boomerang Chest Room", JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS] = ItemLocation::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, 0x02, 0x02, "Jabu Jabus Belly MQ GS Near Boss", JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - - locationTable[FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD] = ItemLocation::GSToken(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, 0x03, 0x01, "Forest Temple GS Raised Island Courtyard", FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_GS_FIRST_ROOM] = ItemLocation::GSToken(RC_FOREST_TEMPLE_GS_FIRST_ROOM, 0x03, 0x02, "Forest Temple GS First Room", FOREST_TEMPLE_GS_FIRST_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD] = ItemLocation::GSToken(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, 0x03, 0x04, "Forest Temple GS Level Island Courtyard", FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_GS_LOBBY] = ItemLocation::GSToken(RC_FOREST_TEMPLE_GS_LOBBY, 0x03, 0x08, "Forest Temple GS Lobby", FOREST_TEMPLE_GS_LOBBY, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_GS_BASEMENT] = ItemLocation::GSToken(RC_FOREST_TEMPLE_GS_BASEMENT, 0x03, 0x10, "Forest Temple GS Basement", FOREST_TEMPLE_GS_BASEMENT, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - - locationTable[FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY] = ItemLocation::GSToken(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, 0x03, 0x02, "Forest Temple MQ GS First Hallway", FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM] = ItemLocation::GSToken(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, 0x03, 0x10, "Forest Temple MQ GS Block Push Room", FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD] = ItemLocation::GSToken(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, 0x03, 0x01, "Forest Temple MQ GS Raised Island Courtyard", FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD] = ItemLocation::GSToken(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, 0x03, 0x04, "Forest Temple MQ GS Level Island Courtyard", FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FOREST_TEMPLE_MQ_GS_WELL] = ItemLocation::GSToken(RC_FOREST_TEMPLE_MQ_GS_WELL, 0x03, 0x08, "Forest Temple MQ GS Well", FOREST_TEMPLE_MQ_GS_WELL, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - - locationTable[FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM] = ItemLocation::GSToken(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, 0x04, 0x01, "Fire Temple GS Song of Time Room", FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_GS_BOSS_KEY_LOOP] = ItemLocation::GSToken(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, 0x04, 0x02, "Fire Temple GS Boss Key Loop", FIRE_TEMPLE_GS_BOSS_KEY_LOOP, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_GS_BOULDER_MAZE] = ItemLocation::GSToken(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, 0x04, 0x04, "Fire Temple GS Boulder Maze", FIRE_TEMPLE_GS_BOULDER_MAZE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_GS_SCARECROW_TOP] = ItemLocation::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, 0x04, 0x08, "Fire Temple GS Scarecrow Top", FIRE_TEMPLE_GS_SCARECROW_TOP, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_GS_SCARECROW_CLIMB] = ItemLocation::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, 0x04, 0x10, "Fire Temple GS Scarecrow Climb", FIRE_TEMPLE_GS_SCARECROW_CLIMB, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - - locationTable[FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE] = ItemLocation::GSToken(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, 0x04, 0x02, "Fire Temple MQ GS Above Fire Wall Maze", FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = ItemLocation::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, 0x04, 0x08, "Fire Temple MQ GS Fire Wall Maze Center", FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = ItemLocation::GSToken(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, 0x04, 0x01, "Fire Temple MQ GS Big Lava Room Open Door", FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = ItemLocation::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, 0x04, 0x10, "Fire Temple MQ GS Fire Wall Maze Side Room", FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE] = ItemLocation::GSToken(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, 0x04, 0x04, "Fire Temple MQ GS Skull on Fire", FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - - locationTable[WATER_TEMPLE_GS_BEHIND_GATE] = ItemLocation::GSToken(RC_WATER_TEMPLE_GS_BEHIND_GATE, 0x05, 0x01, "Water Temple GS Behind Gate", WATER_TEMPLE_GS_BEHIND_GATE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM] = ItemLocation::GSToken(RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, 0x05, 0x02, "Water Temple GS Falling Platform Room", WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_GS_CENTRAL_PILLAR] = ItemLocation::GSToken(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, 0x05, 0x04, "Water Temple GS Central Pillar", WATER_TEMPLE_GS_CENTRAL_PILLAR, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST] = ItemLocation::GSToken(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, 0x05, 0x08, "Water Temple GS Near Boss Key Chest", WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_GS_RIVER] = ItemLocation::GSToken(RC_WATER_TEMPLE_GS_RIVER, 0x05, 0x10, "Water Temple GS River", WATER_TEMPLE_GS_RIVER, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - - locationTable[WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH] = ItemLocation::GSToken(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, 0x05, 0x04, "Water Temple MQ GS Before Upper Water Switch", WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA] = ItemLocation::GSToken(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, 0x05, 0x08, "Water Temple MQ GS Freestanding Key Area", WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY] = ItemLocation::GSToken(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, 0x05, 0x01, "Water Temple MQ GS Lizalfos Hallway", WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_MQ_GS_RIVER] = ItemLocation::GSToken(RC_WATER_TEMPLE_MQ_GS_RIVER, 0x05, 0x02, "Water Temple MQ GS River", WATER_TEMPLE_MQ_GS_RIVER, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH] = ItemLocation::GSToken(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, 0x05, 0x10, "Water Temple MQ GS Triple Wall Torch", WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - - locationTable[SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM] = ItemLocation::GSToken(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, 0x06, 0x01, "Spirit Temple GS Hall After Sun Block Room", SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_GS_BOULDER_ROOM] = ItemLocation::GSToken(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, 0x06, 0x02, "Spirit Temple GS Boulder Room", SPIRIT_TEMPLE_GS_BOULDER_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_GS_LOBBY] = ItemLocation::GSToken(RC_SPIRIT_TEMPLE_GS_LOBBY, 0x06, 0x04, "Spirit Temple GS Lobby", SPIRIT_TEMPLE_GS_LOBBY, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM] = ItemLocation::GSToken(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, 0x06, 0x08, "Spirit Temple GS Sun on Floor Room", SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_GS_METAL_FENCE] = ItemLocation::GSToken(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, 0x06, 0x10, "Spirit Temple GS Metal Fence", SPIRIT_TEMPLE_GS_METAL_FENCE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - - locationTable[SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM] = ItemLocation::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, 0x06, 0x08, "Spirit Temple MQ GS Symphony Room", SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM] = ItemLocation::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, 0x06, 0x02, "Spirit Temple MQ GS Leever Room", SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST] = ItemLocation::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, 0x06, 0x04, "Spirit Temple MQ GS Nine Thrones Room West", SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH] = ItemLocation::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, 0x06, 0x10, "Spirit Temple MQ GS Nine Thrones Room North", SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM] = ItemLocation::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, 0x06, 0x01, "Spirit Temple MQ GS Sun Block Room", SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - - locationTable[SHADOW_TEMPLE_GS_SINGLE_GIANT_POT] = ItemLocation::GSToken(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, 0x07, 0x01, "Shadow Temple GS Single Giant Pot", SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM] = ItemLocation::GSToken(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, 0x07, 0x02, "Shadow Temple GS Falling Spikes Room", SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT] = ItemLocation::GSToken(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, 0x07, 0x04, "Shadow Temple GS Triple Giant Pot", SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM] = ItemLocation::GSToken(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, 0x07, 0x08, "Shadow Temple GS Like Like Room", SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_GS_NEAR_SHIP] = ItemLocation::GSToken(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, 0x07, 0x10, "Shadow Temple GS Near Ship", SHADOW_TEMPLE_GS_NEAR_SHIP, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - - locationTable[SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM] = ItemLocation::GSToken(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, 0x07, 0x02, "Shadow Temple MQ GS Falling Spikes Room", SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM] = ItemLocation::GSToken(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, 0x07, 0x01, "Shadow Temple MQ GS Wind Hint Room", SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_GS_AFTER_WIND] = ItemLocation::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, 0x07, 0x08, "Shadow Temple MQ GS After Wind", SHADOW_TEMPLE_MQ_GS_AFTER_WIND, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_GS_AFTER_SHIP] = ItemLocation::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, 0x07, 0x10, "Shadow Temple MQ GS After Ship", SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[SHADOW_TEMPLE_MQ_GS_NEAR_BOSS] = ItemLocation::GSToken(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, 0x07, 0x04, "Shadow Temple MQ GS Near Boss", SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - - locationTable[BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE] = ItemLocation::GSToken(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, 0x08, 0x01, "Bottom of the Well GS Like Like Cage", BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM] = ItemLocation::GSToken(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, 0x08, 0x02, "Bottom of the Well GS East Inner Room", BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM] = ItemLocation::GSToken(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, 0x08, 0x04, "Bottom of the Well GS West Inner Room", BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - - locationTable[BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT] = ItemLocation::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, 0x08, 0x01, "Bottom of the Well MQ GS Basement", BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM] = ItemLocation::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, 0x08, 0x04, "Bottom of the Well MQ GS Coffin Room", BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - locationTable[BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM] = ItemLocation::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, 0x08, 0x02, "Bottom of the Well MQ GS West Inner Room", BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_BOTTOM_OF_THE_WELL); - - locationTable[ICE_CAVERN_GS_PUSH_BLOCK_ROOM] = ItemLocation::GSToken(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, 0x09, 0x01, "Ice Cavern GS Push Block Room", ICE_CAVERN_GS_PUSH_BLOCK_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM] = ItemLocation::GSToken(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, 0x09, 0x02, "Ice Cavern GS Spinning Scythe Room", ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[ICE_CAVERN_GS_HEART_PIECE_ROOM] = ItemLocation::GSToken(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, 0x09, 0x04, "Ice Cavern GS Heart Piece Room", ICE_CAVERN_GS_HEART_PIECE_ROOM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - - locationTable[ICE_CAVERN_MQ_GS_SCARECROW] = ItemLocation::GSToken(RC_ICE_CAVERN_MQ_GS_SCARECROW, 0x09, 0x01, "Ice Cavern MQ GS Scarecrow", ICE_CAVERN_MQ_GS_SCARECROW, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[ICE_CAVERN_MQ_GS_ICE_BLOCK] = ItemLocation::GSToken(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, 0x09, 0x04, "Ice Cavern MQ GS Ice Block", ICE_CAVERN_MQ_GS_ICE_BLOCK, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[ICE_CAVERN_MQ_GS_RED_ICE] = ItemLocation::GSToken(RC_ICE_CAVERN_MQ_GS_RED_ICE, 0x09, 0x02, "Ice Cavern MQ GS Red Ice", ICE_CAVERN_MQ_GS_RED_ICE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - - //Overworld - locationTable[KF_GS_BEAN_PATCH] = ItemLocation::GSToken(RC_KF_GS_BEAN_PATCH, 0x0C, 0x01, "KF GS Bean Patch", KF_GS_BEAN_PATCH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_GS_KNOW_IT_ALL_HOUSE] = ItemLocation::GSToken(RC_KF_GS_KNOW_IT_ALL_HOUSE, 0x0C, 0x02, "KF GS Know It All House", KF_GS_KNOW_IT_ALL_HOUSE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_GS_HOUSE_OF_TWINS] = ItemLocation::GSToken(RC_KF_GS_HOUSE_OF_TWINS, 0x0C, 0x04, "KF GS House of Twins", KF_GS_HOUSE_OF_TWINS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - - locationTable[LW_GS_BEAN_PATCH_NEAR_BRIDGE] = ItemLocation::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, 0x0D, 0x01, "LW GS Bean Patch Near Bridge", LW_GS_BEAN_PATCH_NEAR_BRIDGE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_GS_BEAN_PATCH_NEAR_THEATER] = ItemLocation::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, 0x0D, 0x02, "LW GS Bean Patch Near Theater", LW_GS_BEAN_PATCH_NEAR_THEATER, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[LW_GS_ABOVE_THEATER] = ItemLocation::GSToken(RC_LW_GS_ABOVE_THEATER, 0x0D, 0x04, "LW GS Above Theater", LW_GS_ABOVE_THEATER, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[SFM_GS] = ItemLocation::GSToken(RC_SFM_GS, 0x0D, 0x08, "SFM GS", SFM_GS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - - locationTable[HF_GS_COW_GROTTO] = ItemLocation::GSToken(RC_HF_GS_COW_GROTTO, 0x0A, 0x01, "HF GS Cow Grotto", HF_GS_COW_GROTTO, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[HF_GS_NEAR_KAK_GROTTO] = ItemLocation::GSToken(RC_HF_GS_NEAR_KAK_GROTTO, 0x0A, 0x02, "HF GS Near Kak Grotto", HF_GS_NEAR_KAK_GROTTO, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - - locationTable[LH_GS_BEAN_PATCH] = ItemLocation::GSToken(RC_LH_GS_BEAN_PATCH, 0x12, 0x01, "LH GS Bean Patch", LH_GS_BEAN_PATCH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_GS_SMALL_ISLAND] = ItemLocation::GSToken(RC_LH_GS_SMALL_ISLAND, 0x12, 0x02, "LH GS Small Island", LH_GS_SMALL_ISLAND, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_GS_LAB_WALL] = ItemLocation::GSToken(RC_LH_GS_LAB_WALL, 0x12, 0x04, "LH GS Lab Wall", LH_GS_LAB_WALL, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_GS_LAB_CRATE] = ItemLocation::GSToken(RC_LH_GS_LAB_CRATE, 0x12, 0x08, "LH GS Lab Crate", LH_GS_LAB_CRATE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - locationTable[LH_GS_TREE] = ItemLocation::GSToken(RC_LH_GS_TREE, 0x12, 0x10, "LH GS Tree", LH_GS_TREE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA); - - locationTable[GV_GS_BEAN_PATCH] = ItemLocation::GSToken(RC_GV_GS_BEAN_PATCH, 0x13, 0x01, "GV GS Bean Patch", GV_GS_BEAN_PATCH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GV_GS_SMALL_BRIDGE] = ItemLocation::GSToken(RC_GV_GS_SMALL_BRIDGE, 0x13, 0x02, "GV GS Small Bridge", GV_GS_SMALL_BRIDGE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GV_GS_PILLAR] = ItemLocation::GSToken(RC_GV_GS_PILLAR, 0x13, 0x04, "GV GS Pillar", GV_GS_PILLAR, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GV_GS_BEHIND_TENT] = ItemLocation::GSToken(RC_GV_GS_BEHIND_TENT, 0x13, 0x08, "GV GS Behind Tent", GV_GS_BEHIND_TENT, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - - locationTable[GF_GS_ARCHERY_RANGE] = ItemLocation::GSToken(RC_GF_GS_ARCHERY_RANGE, 0x14, 0x01, "GF GS Archery Range", GF_GS_ARCHERY_RANGE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[GF_GS_TOP_FLOOR] = ItemLocation::GSToken(RC_GF_GS_TOP_FLOOR, 0x14, 0x02, "GF GS Top Floor", GF_GS_TOP_FLOOR, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - - locationTable[WASTELAND_GS] = ItemLocation::GSToken(RC_WASTELAND_GS, 0x15, 0x02, "Wasteland GS", WASTELAND_GS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[COLOSSUS_GS_BEAN_PATCH] = ItemLocation::GSToken(RC_COLOSSUS_GS_BEAN_PATCH, 0x15, 0x01, "Colossus GS Bean Patch", COLOSSUS_GS_BEAN_PATCH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[COLOSSUS_GS_HILL] = ItemLocation::GSToken(RC_COLOSSUS_GS_HILL, 0x15, 0x04, "Colossus GS Hill", COLOSSUS_GS_HILL, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[COLOSSUS_GS_TREE] = ItemLocation::GSToken(RC_COLOSSUS_GS_TREE, 0x15, 0x08, "Colossus GS Tree", COLOSSUS_GS_TREE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - - locationTable[OGC_GS] = ItemLocation::GSToken(RC_OGC_GS, 0x0E, 0x01, "OGC GS", OGC_GS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - locationTable[HC_GS_STORMS_GROTTO] = ItemLocation::GSToken(RC_HC_GS_STORMS_GROTTO, 0x0E, 0x02, "HC GS Storms Grotto", HC_GS_STORMS_GROTTO, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[HC_GS_TREE] = ItemLocation::GSToken(RC_HC_GS_TREE, 0x0E, 0x04, "HC GS Tree", HC_GS_TREE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_GS_GUARD_HOUSE] = ItemLocation::GSToken(RC_MARKET_GS_GUARD_HOUSE, 0x0E, 0x08, "Market GS Guard House", MARKET_GS_GUARD_HOUSE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - - locationTable[KAK_GS_HOUSE_UNDER_CONSTRUCTION] = ItemLocation::GSToken(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, 0x10, 0x08, "Kak GS House Under Construction", KAK_GS_HOUSE_UNDER_CONSTRUCTION, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_GS_SKULLTULA_HOUSE] = ItemLocation::GSToken(RC_KAK_GS_SKULLTULA_HOUSE, 0x10, 0x10, "Kak GS Skulltula House", KAK_GS_SKULLTULA_HOUSE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_GS_GUARDS_HOUSE] = ItemLocation::GSToken(RC_KAK_GS_GUARDS_HOUSE, 0x10, 0x02, "Kak GS Guards House", KAK_GS_GUARDS_HOUSE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_GS_TREE] = ItemLocation::GSToken(RC_KAK_GS_TREE, 0x10, 0x20, "Kak GS Tree", KAK_GS_TREE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_GS_WATCHTOWER] = ItemLocation::GSToken(RC_KAK_GS_WATCHTOWER, 0x10, 0x04, "Kak GS Watchtower", KAK_GS_WATCHTOWER, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_GS_ABOVE_IMPAS_HOUSE] = ItemLocation::GSToken(RC_KAK_GS_ABOVE_IMPAS_HOUSE, 0x10, 0x40, "Kak GS Above Impas House", KAK_GS_ABOVE_IMPAS_HOUSE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - - locationTable[GRAVEYARD_GS_WALL] = ItemLocation::GSToken(RC_GRAVEYARD_GS_WALL, 0x10, 0x80, "Graveyard GS Wall", GRAVEYARD_GS_WALL, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[GRAVEYARD_GS_BEAN_PATCH] = ItemLocation::GSToken(RC_GRAVEYARD_GS_BEAN_PATCH, 0x10, 0x01, "Graveyard GS Bean Patch", GRAVEYARD_GS_BEAN_PATCH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - - locationTable[DMC_GS_BEAN_PATCH] = ItemLocation::GSToken(RC_DMC_GS_BEAN_PATCH, 0x0F, 0x01, "DMC GS Bean Patch", DMC_GS_BEAN_PATCH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMC_GS_CRATE] = ItemLocation::GSToken(RC_DMC_GS_CRATE, 0x0F, 0x80, "DMC GS Crate", DMC_GS_CRATE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - - locationTable[DMT_GS_BEAN_PATCH] = ItemLocation::GSToken(RC_DMT_GS_BEAN_PATCH, 0x0F, 0x02, "DMT GS Bean Patch", DMT_GS_BEAN_PATCH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMT_GS_NEAR_KAK] = ItemLocation::GSToken(RC_DMT_GS_NEAR_KAK, 0x0F, 0x04, "DMT GS Near Kak", DMT_GS_NEAR_KAK, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMT_GS_ABOVE_DODONGOS_CAVERN] = ItemLocation::GSToken(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, 0x0F, 0x08, "DMT GS Above Dodongos Cavern", DMT_GS_ABOVE_DODONGOS_CAVERN, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMT_GS_FALLING_ROCKS_PATH] = ItemLocation::GSToken(RC_DMT_GS_FALLING_ROCKS_PATH, 0x0F, 0x10, "DMT GS Falling Rocks Path", DMT_GS_FALLING_ROCKS_PATH, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - - locationTable[GC_GS_CENTER_PLATFORM] = ItemLocation::GSToken(RC_GC_GS_CENTER_PLATFORM, 0x0F, 0x20, "GC GS Center Platform", GC_GS_CENTER_PLATFORM, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_GS_BOULDER_MAZE] = ItemLocation::GSToken(RC_GC_GS_BOULDER_MAZE, 0x0F, 0x40, "GC GS Boulder Maze", GC_GS_BOULDER_MAZE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - - locationTable[ZR_GS_LADDER] = ItemLocation::GSToken(RC_ZR_GS_LADDER, 0x11, 0x01, "ZR GS Ladder", ZR_GS_LADDER, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_GS_TREE] = ItemLocation::GSToken(RC_ZR_GS_TREE, 0x11, 0x02, "ZR GS Tree", ZR_GS_TREE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_GS_ABOVE_BRIDGE] = ItemLocation::GSToken(RC_ZR_GS_ABOVE_BRIDGE, 0x11, 0x08, "ZR GS Above Bridge", ZR_GS_ABOVE_BRIDGE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - locationTable[ZR_GS_NEAR_RAISED_GROTTOS] = ItemLocation::GSToken(RC_ZR_GS_NEAR_RAISED_GROTTOS, 0x11, 0x10, "ZR GS Near Raised Grottos", ZR_GS_NEAR_RAISED_GROTTOS, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_ZORAS_RIVER); - - locationTable[ZD_GS_FROZEN_WATERFALL] = ItemLocation::GSToken(RC_ZD_GS_FROZEN_WATERFALL, 0x11, 0x40, "ZD GS Frozen Waterfall", ZD_GS_FROZEN_WATERFALL, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZF_GS_ABOVE_THE_LOG] = ItemLocation::GSToken(RC_ZF_GS_ABOVE_THE_LOG, 0x11, 0x04, "ZF GS Above The Log", ZF_GS_ABOVE_THE_LOG, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZF_GS_HIDDEN_CAVE] = ItemLocation::GSToken(RC_ZF_GS_HIDDEN_CAVE, 0x11, 0x20, "ZF GS Hidden Cave", ZF_GS_HIDDEN_CAVE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZF_GS_TREE] = ItemLocation::GSToken(RC_ZF_GS_TREE, 0x11, 0x80, "ZF GS Tree", ZF_GS_TREE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - - locationTable[LLR_GS_BACK_WALL] = ItemLocation::GSToken(RC_LLR_GS_BACK_WALL, 0x0B, 0x01, "LLR GS Back Wall", LLR_GS_BACK_WALL, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[LLR_GS_RAIN_SHED] = ItemLocation::GSToken(RC_LLR_GS_RAIN_SHED, 0x0B, 0x02, "LLR GS Rain Shed", LLR_GS_RAIN_SHED, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[LLR_GS_HOUSE_WINDOW] = ItemLocation::GSToken(RC_LLR_GS_HOUSE_WINDOW, 0x0B, 0x04, "LLR GS House Window", LLR_GS_HOUSE_WINDOW, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[LLR_GS_TREE] = ItemLocation::GSToken(RC_LLR_GS_TREE, 0x0B, 0x08, "LLR GS Tree", LLR_GS_TREE, {Category::cSkulltula}, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - - /*------------------------------- - --- BOSSES --- - -------------------------------*/ - - locationTable[LINKS_POCKET] = ItemLocation::Reward (RC_LINKS_POCKET, 0xFF, "Link's Pocket", LINKS_POCKET, LIGHT_MEDALLION, {}, SpoilerCollectionCheck::AlwaysCollected(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[QUEEN_GOHMA] = ItemLocation::Reward (RC_QUEEN_GOHMA, 0xFF, "Queen Gohma", QUEEN_GOHMA, KOKIRI_EMERALD, {}, SpoilerCollectionCheck::Chest(0x11, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[KING_DODONGO] = ItemLocation::Reward (RC_KING_DODONGO, 0xFF, "King Dodongo", KING_DODONGO, GORON_RUBY, {}, SpoilerCollectionCheck::Chest(0x12, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[BARINADE] = ItemLocation::Reward (RC_BARINADE, 0xFF, "Barinade", BARINADE, ZORA_SAPPHIRE, {}, SpoilerCollectionCheck::Chest(0x13, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[PHANTOM_GANON] = ItemLocation::Reward (RC_PHANTOM_GANON, 0xFF, "Phantom Ganon", PHANTOM_GANON, FOREST_MEDALLION, {}, SpoilerCollectionCheck::Chest(0x14, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[VOLVAGIA] = ItemLocation::Reward (RC_VOLVAGIA, 0xFF, "Volvagia", VOLVAGIA, FIRE_MEDALLION, {}, SpoilerCollectionCheck::Chest(0x15, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[MORPHA] = ItemLocation::Reward (RC_MORPHA, 0xFF, "Morpha", MORPHA, WATER_MEDALLION, {}, SpoilerCollectionCheck::Chest(0x16, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[TWINROVA] = ItemLocation::Reward (RC_TWINROVA, 0xFF, "Twinrova", TWINROVA, SPIRIT_MEDALLION, {}, SpoilerCollectionCheck::Chest(0x17, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[BONGO_BONGO] = ItemLocation::Reward (RC_BONGO_BONGO, 0xFF, "Bongo Bongo", BONGO_BONGO, SHADOW_MEDALLION, {}, SpoilerCollectionCheck::Chest(0x18, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - locationTable[GANON] = ItemLocation::Reward (RC_GANON, 0xFF, "Ganon", NONE, TRIFORCE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - - /*------------------------------- - ---HEART CONTAINERS --- - -------------------------------*/ - - locationTable[DEKU_TREE_QUEEN_GOHMA_HEART] = ItemLocation::Base (RC_DEKU_TREE_QUEEN_GOHMA_HEART, 0x11, "Deku Tree Queen Gohma Heart Container", DEKU_TREE_QUEEN_GOHMA_HEART, HEART_CONTAINER, {Category::cSongDungeonReward}, SpoilerCollectionCheck::Collectable(0x11, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DEKU_TREE); - locationTable[DODONGOS_CAVERN_KING_DODONGO_HEART] = ItemLocation::Base (RC_DODONGOS_CAVERN_KING_DODONGO_HEART, 0x12, "Dodongos Cavern King Dodongo Heart Container", DODONGOS_CAVERN_KING_DODONGO_HEART, HEART_CONTAINER, {Category::cSongDungeonReward}, SpoilerCollectionCheck::Collectable(0x12, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_DODONGOS_CAVERN); - locationTable[JABU_JABUS_BELLY_BARINADE_HEART] = ItemLocation::Base (RC_JABU_JABUS_BELLY_BARINADE_HEART, 0x13, "Jabu Jabus Belly Barinade Heart Container", JABU_JABUS_BELLY_BARINADE_HEART, HEART_CONTAINER, {Category::cSongDungeonReward}, SpoilerCollectionCheck::Collectable(0x13, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - locationTable[FOREST_TEMPLE_PHANTOM_GANON_HEART] = ItemLocation::Base (RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, 0x14, "Forest Temple Phantom Ganon Heart Container", FOREST_TEMPLE_PHANTOM_GANON_HEART, HEART_CONTAINER, {Category::cSongDungeonReward}, SpoilerCollectionCheck::Collectable(0x14, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FOREST_TEMPLE); - locationTable[FIRE_TEMPLE_VOLVAGIA_HEART] = ItemLocation::Base (RC_FIRE_TEMPLE_VOLVAGIA_HEART, 0x15, "Fire Temple Volvagia Heart Container", FIRE_TEMPLE_VOLVAGIA_HEART, HEART_CONTAINER, {Category::cSongDungeonReward}, SpoilerCollectionCheck::Collectable(0x15, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_FIRE_TEMPLE); - locationTable[WATER_TEMPLE_MORPHA_HEART] = ItemLocation::Base (RC_WATER_TEMPLE_MORPHA_HEART, 0x16, "Water Temple Morpha Heart Container", WATER_TEMPLE_MORPHA_HEART, HEART_CONTAINER, {Category::cSongDungeonReward}, SpoilerCollectionCheck::Collectable(0x16, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_WATER_TEMPLE); - locationTable[SPIRIT_TEMPLE_TWINROVA_HEART] = ItemLocation::Base (RC_SPIRIT_TEMPLE_TWINROVA_HEART, 0x17, "Spirit Temple Twinrova Heart Container", SPIRIT_TEMPLE_TWINROVA_HEART, HEART_CONTAINER, {Category::cSongDungeonReward}, SpoilerCollectionCheck::Collectable(0x17, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SPIRIT_TEMPLE); - locationTable[SHADOW_TEMPLE_BONGO_BONGO_HEART] = ItemLocation::Base (RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, 0x18, "Shadow Temple Bongo Bongo Heart Container", SHADOW_TEMPLE_BONGO_BONGO_HEART, HEART_CONTAINER, {Category::cSongDungeonReward}, SpoilerCollectionCheck::Collectable(0x18, 0x1F), SpoilerCollectionCheckGroup::GROUP_DUNGEON_SHADOW_TEMPLE); - - /*------------------------------- - --- CUTSCENES --- - -------------------------------*/ - locationTable[TOT_MASTER_SWORD] = ItemLocation::Delayed(RC_TOT_MASTER_SWORD, 0xFF, "ToT Master Sword", TOT_MASTER_SWORD, MASTER_SWORD, {}, SpoilerCollectionCheck::MasterSword(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[TOT_LIGHT_ARROWS_CUTSCENE] = ItemLocation::Delayed(RC_TOT_LIGHT_ARROWS_CUTSCENE, 0xFF, "ToT Light Arrow Cutscene", TOT_LIGHT_ARROWS_CUTSCENE, LIGHT_ARROWS, {}, SpoilerCollectionCheck::Chest(0x43, 0x1E), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[LW_GIFT_FROM_SARIA] = ItemLocation::Delayed(RC_LW_GIFT_FROM_SARIA, 0xFF, "LW Gift From Saria", LW_GIFT_FROM_SARIA, PROGRESSIVE_OCARINA, {}, SpoilerCollectionCheck::EventChkInf(0xC1), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[ZF_GREAT_FAIRY_REWARD] = ItemLocation::Delayed(RC_ZF_GREAT_FAIRY_REWARD, 0xFF, "ZF Great Fairy Reward", ZF_GREAT_FAIRY_REWARD, FARORES_WIND, {}, SpoilerCollectionCheck::Chest(0x3D, 0x01), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[HC_GREAT_FAIRY_REWARD] = ItemLocation::Delayed(RC_HC_GREAT_FAIRY_REWARD, 0xFF, "HC Great Fairy Reward", HC_GREAT_FAIRY_REWARD, DINS_FIRE, {}, SpoilerCollectionCheck::Chest(0x3D, 0x02), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[COLOSSUS_GREAT_FAIRY_REWARD] = ItemLocation::Delayed(RC_COLOSSUS_GREAT_FAIRY_REWARD, 0xFF, "Colossus Great Fairy Reward", COLOSSUS_GREAT_FAIRY_REWARD, NAYRUS_LOVE, {}, SpoilerCollectionCheck::Chest(0x3D, 0x03), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[DMT_GREAT_FAIRY_REWARD] = ItemLocation::Delayed(RC_DMT_GREAT_FAIRY_REWARD, 0xFF, "DMT Great Fairy Reward", DMT_GREAT_FAIRY_REWARD, PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::Chest(0x3B, 0x01), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[DMC_GREAT_FAIRY_REWARD] = ItemLocation::Delayed(RC_DMC_GREAT_FAIRY_REWARD, 0xFF, "DMC Great Fairy Reward", DMC_GREAT_FAIRY_REWARD, PROGRESSIVE_MAGIC_METER, {}, SpoilerCollectionCheck::Chest(0x3B, 0x02), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[OGC_GREAT_FAIRY_REWARD] = ItemLocation::Delayed(RC_OGC_GREAT_FAIRY_REWARD, 0xFF, "OGC Great Fairy Reward", OGC_GREAT_FAIRY_REWARD, DOUBLE_DEFENSE, {}, SpoilerCollectionCheck::Chest(0x3B, 0x03), SpoilerCollectionCheckGroup::GROUP_DUNGEON_GANONS_CASTLE); - - locationTable[SHEIK_IN_FOREST] = ItemLocation::Delayed(RC_SHEIK_IN_FOREST, 0xFF, "Sheik in Forest", SHEIK_IN_FOREST, MINUET_OF_FOREST, {Category::cSong}, SpoilerCollectionCheck::EventChkInf(0x50), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[SHEIK_IN_CRATER] = ItemLocation::Delayed(RC_SHEIK_IN_CRATER, 0xFF, "Sheik in Crater", SHEIK_IN_CRATER, BOLERO_OF_FIRE, {Category::cSong}, SpoilerCollectionCheck::EventChkInf(0x51), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[SHEIK_IN_ICE_CAVERN] = ItemLocation::Delayed(RC_SHEIK_IN_ICE_CAVERN, 0xFF, "Sheik in Ice Cavern", SHEIK_IN_ICE_CAVERN, SERENADE_OF_WATER, {Category::cSong, Category::cSongDungeonReward}, SpoilerCollectionCheck::EventChkInf(0x52), SpoilerCollectionCheckGroup::GROUP_DUNGEON_ICE_CAVERN); - locationTable[SHEIK_AT_COLOSSUS] = ItemLocation::Delayed(RC_SHEIK_AT_COLOSSUS, 0xFF, "Sheik at Colossus", SHEIK_AT_COLOSSUS, REQUIEM_OF_SPIRIT, {Category::cSong}, SpoilerCollectionCheck::EventChkInf(0xAC), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[SHEIK_IN_KAKARIKO] = ItemLocation::Delayed(RC_SHEIK_IN_KAKARIKO, 0xFF, "Sheik in Kakariko", SHEIK_IN_KAKARIKO, NOCTURNE_OF_SHADOW, {Category::cSong}, SpoilerCollectionCheck::EventChkInf(0xAA), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[SHEIK_AT_TEMPLE] = ItemLocation::Delayed(RC_SHEIK_AT_TEMPLE, 0xFF, "Sheik at Temple", SHEIK_AT_TEMPLE, PRELUDE_OF_LIGHT, {Category::cSong}, SpoilerCollectionCheck::Chest(0x43, 0x1F), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[SONG_FROM_IMPA] = ItemLocation::Delayed(RC_SONG_FROM_IMPA, 0xFF, "Song from Impa", SONG_FROM_IMPA, ZELDAS_LULLABY, {Category::cSong, Category::cSongDungeonReward}, SpoilerCollectionCheck::EventChkInf(0x59), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[SONG_FROM_MALON] = ItemLocation::Delayed(RC_SONG_FROM_MALON, 0xFF, "Song from Malon", SONG_FROM_MALON, EPONAS_SONG, {Category::cSong}, SpoilerCollectionCheck::Chest(0x63, 0x1F), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[SONG_FROM_SARIA] = ItemLocation::Delayed(RC_SONG_FROM_SARIA, 0xFF, "Song from Saria", SONG_FROM_SARIA, SARIAS_SONG, {Category::cSong}, SpoilerCollectionCheck::Chest(0x56, 0x1F), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS); - locationTable[SONG_FROM_COMPOSERS_GRAVE] = ItemLocation::Delayed(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, 0xFF, "Song from Composers Grave", SONG_FROM_COMPOSERS_GRAVE, SUNS_SONG, {Category::cSong}, SpoilerCollectionCheck::Chest(0x41, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[SONG_FROM_OCARINA_OF_TIME] = ItemLocation::Delayed(RC_SONG_FROM_OCARINA_OF_TIME, 0xFF, "Song from Ocarina of Time", SONG_FROM_OCARINA_OF_TIME, SONG_OF_TIME, {Category::cSong}, SpoilerCollectionCheck::Chest(0x51, 0x1F), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[SONG_FROM_WINDMILL] = ItemLocation::Delayed(RC_SONG_FROM_WINDMILL, 0xFF, "Song from Windmill", SONG_FROM_WINDMILL, SONG_OF_STORMS, {Category::cSong}, SpoilerCollectionCheck::EventChkInf(0x5B), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - - /*------------------------------- - --- COWS --- - -------------------------------*/ - - locationTable[KF_LINKS_HOUSE_COW] = ItemLocation::Base (RC_KF_LINKS_HOUSE_COW, 0x34, "KF Links House Cow", KF_LINKS_HOUSE_COW, MILK, {Category::cCow}, SpoilerCollectionCheck::Cow(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[HF_COW_GROTTO_COW] = ItemLocation::Base (RC_HF_COW_GROTTO_COW, 0x3E, "HF Cow Grotto Cow", HF_COW_GROTTO_COW, MILK, {Category::cCow}, SpoilerCollectionCheck::Cow(), SpoilerCollectionCheckGroup::GROUP_HYRULE_FIELD); - locationTable[LLR_STABLES_LEFT_COW] = ItemLocation::Base (RC_LLR_STABLES_LEFT_COW, 0x36, "LLR Stables Left Cow", LLR_STABLES_LEFT_COW, MILK, {Category::cCow}, SpoilerCollectionCheck::Cow(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[LLR_STABLES_RIGHT_COW] = ItemLocation::Base (RC_LLR_STABLES_RIGHT_COW, 0x36, "LLR Stables Right Cow", LLR_STABLES_RIGHT_COW, MILK, {Category::cCow}, SpoilerCollectionCheck::Cow(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[LLR_TOWER_LEFT_COW] = ItemLocation::Base (RC_LLR_TOWER_LEFT_COW, 0x4C, "LLR Tower Left Cow", LLR_TOWER_LEFT_COW, MILK, {Category::cCow}, SpoilerCollectionCheck::Cow(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[LLR_TOWER_RIGHT_COW] = ItemLocation::Base (RC_LLR_TOWER_RIGHT_COW, 0x4C, "LLR Tower Right Cow", LLR_TOWER_RIGHT_COW, MILK, {Category::cCow}, SpoilerCollectionCheck::Cow(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH); - locationTable[KAK_IMPAS_HOUSE_COW] = ItemLocation::Base (RC_KAK_IMPAS_HOUSE_COW, 0x37, "Kak Impas House Cow", KAK_IMPAS_HOUSE_COW, MILK, {Category::cCow}, SpoilerCollectionCheck::Cow(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[DMT_COW_GROTTO_COW] = ItemLocation::Base (RC_DMT_COW_GROTTO_COW, 0x3E, "DMT Cow Grotto Cow", DMT_COW_GROTTO_COW, MILK, {Category::cCow}, SpoilerCollectionCheck::Cow(), SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN); - locationTable[GV_COW] = ItemLocation::Base (RC_GV_COW, 0x5A, "GV Cow", GV_COW, MILK, {Category::cCow}, SpoilerCollectionCheck::Cow(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY); - locationTable[JABU_JABUS_BELLY_MQ_COW] = ItemLocation::Base (RC_JABU_JABUS_BELLY_MQ_COW, 0x02, "Jabu Jabus Belly MQ Cow", JABU_JABUS_BELLY_MQ_COW, MILK, {Category::cCow}, SpoilerCollectionCheck::Cow(), SpoilerCollectionCheckGroup::GROUP_DUNGEON_JABUJABUS_BELLY); - - /*------------------------------- - --- SHOPS --- - 8 6 2 4 - - 7 5 1 3 - -------------------------------*/ - - locationTable[KF_SHOP_ITEM_1] = ItemLocation::Base(RC_KF_SHOP_ITEM_1, 0x2D, "KF Shop Item 1", KF_SHOP_ITEM_1, BUY_DEKU_SHIELD, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_SHOP_ITEM_2] = ItemLocation::Base(RC_KF_SHOP_ITEM_2, 0x2D, "KF Shop Item 2", KF_SHOP_ITEM_2, BUY_DEKU_NUT_5, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_SHOP_ITEM_3] = ItemLocation::Base(RC_KF_SHOP_ITEM_3, 0x2D, "KF Shop Item 3", KF_SHOP_ITEM_3, BUY_DEKU_NUT_10, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_SHOP_ITEM_4] = ItemLocation::Base(RC_KF_SHOP_ITEM_4, 0x2D, "KF Shop Item 4", KF_SHOP_ITEM_4, BUY_DEKU_STICK_1, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_SHOP_ITEM_5] = ItemLocation::Base(RC_KF_SHOP_ITEM_5, 0x2D, "KF Shop Item 5", KF_SHOP_ITEM_5, BUY_DEKU_SEEDS_30, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_SHOP_ITEM_6] = ItemLocation::Base(RC_KF_SHOP_ITEM_6, 0x2D, "KF Shop Item 6", KF_SHOP_ITEM_6, BUY_ARROWS_10, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_SHOP_ITEM_7] = ItemLocation::Base(RC_KF_SHOP_ITEM_7, 0x2D, "KF Shop Item 7", KF_SHOP_ITEM_7, BUY_ARROWS_30, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KF_SHOP_ITEM_8] = ItemLocation::Base(RC_KF_SHOP_ITEM_8, 0x2D, "KF Shop Item 8", KF_SHOP_ITEM_8, BUY_HEART, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - - locationTable[KAK_POTION_SHOP_ITEM_1] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_1, 0x30, "Kak Potion Shop Item 1", KAK_POTION_SHOP_ITEM_1, BUY_GREEN_POTION, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_2] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_2, 0x30, "Kak Potion Shop Item 2", KAK_POTION_SHOP_ITEM_2, BUY_BLUE_FIRE, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_3] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_3, 0x30, "Kak Potion Shop Item 3", KAK_POTION_SHOP_ITEM_3, BUY_RED_POTION_30, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_4] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_4, 0x30, "Kak Potion Shop Item 4", KAK_POTION_SHOP_ITEM_4, BUY_FAIRYS_SPIRIT, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_5] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_5, 0x30, "Kak Potion Shop Item 5", KAK_POTION_SHOP_ITEM_5, BUY_DEKU_NUT_5, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_6] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_6, 0x30, "Kak Potion Shop Item 6", KAK_POTION_SHOP_ITEM_6, BUY_BOTTLE_BUG, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_7] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_7, 0x30, "Kak Potion Shop Item 7", KAK_POTION_SHOP_ITEM_7, BUY_POE, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_8] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_8, 0x30, "Kak Potion Shop Item 8", KAK_POTION_SHOP_ITEM_8, BUY_FISH, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - - locationTable[MARKET_BOMBCHU_SHOP_ITEM_1] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, 0x32, "MK Bombchu Shop Item 1", MARKET_BOMBCHU_SHOP_ITEM_1, BUY_BOMBCHU_10, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_SHOP_ITEM_2] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, 0x32, "MK Bombchu Shop Item 2", MARKET_BOMBCHU_SHOP_ITEM_2, BUY_BOMBCHU_10, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_SHOP_ITEM_3] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_3, 0x32, "MK Bombchu Shop Item 3", MARKET_BOMBCHU_SHOP_ITEM_3, BUY_BOMBCHU_10, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_SHOP_ITEM_4] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_4, 0x32, "MK Bombchu Shop Item 4", MARKET_BOMBCHU_SHOP_ITEM_4, BUY_BOMBCHU_10, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_SHOP_ITEM_5] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_5, 0x32, "MK Bombchu Shop Item 5", MARKET_BOMBCHU_SHOP_ITEM_5, BUY_BOMBCHU_20, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_SHOP_ITEM_6] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_6, 0x32, "MK Bombchu Shop Item 6", MARKET_BOMBCHU_SHOP_ITEM_6, BUY_BOMBCHU_20, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_SHOP_ITEM_7] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_7, 0x32, "MK Bombchu Shop Item 7", MARKET_BOMBCHU_SHOP_ITEM_7, BUY_BOMBCHU_20, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BOMBCHU_SHOP_ITEM_8] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_8, 0x32, "MK Bombchu Shop Item 8", MARKET_BOMBCHU_SHOP_ITEM_8, BUY_BOMBCHU_20, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - - locationTable[MARKET_POTION_SHOP_ITEM_1] = ItemLocation::Base(RC_MARKET_POTION_SHOP_ITEM_1, 0x31, "MK Potion Shop Item 1", MARKET_POTION_SHOP_ITEM_1, BUY_GREEN_POTION, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_POTION_SHOP_ITEM_2] = ItemLocation::Base(RC_MARKET_POTION_SHOP_ITEM_2, 0x31, "MK Potion Shop Item 2", MARKET_POTION_SHOP_ITEM_2, BUY_BLUE_FIRE, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_POTION_SHOP_ITEM_3] = ItemLocation::Base(RC_MARKET_POTION_SHOP_ITEM_3, 0x31, "MK Potion Shop Item 3", MARKET_POTION_SHOP_ITEM_3, BUY_RED_POTION_30, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_POTION_SHOP_ITEM_4] = ItemLocation::Base(RC_MARKET_POTION_SHOP_ITEM_4, 0x31, "MK Potion Shop Item 4", MARKET_POTION_SHOP_ITEM_4, BUY_FAIRYS_SPIRIT, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_POTION_SHOP_ITEM_5] = ItemLocation::Base(RC_MARKET_POTION_SHOP_ITEM_5, 0x31, "MK Potion Shop Item 5", MARKET_POTION_SHOP_ITEM_5, BUY_DEKU_NUT_5, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_POTION_SHOP_ITEM_6] = ItemLocation::Base(RC_MARKET_POTION_SHOP_ITEM_6, 0x31, "MK Potion Shop Item 6", MARKET_POTION_SHOP_ITEM_6, BUY_BOTTLE_BUG, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_POTION_SHOP_ITEM_7] = ItemLocation::Base(RC_MARKET_POTION_SHOP_ITEM_7, 0x31, "MK Potion Shop Item 7", MARKET_POTION_SHOP_ITEM_7, BUY_POE, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_POTION_SHOP_ITEM_8] = ItemLocation::Base(RC_MARKET_POTION_SHOP_ITEM_8, 0x31, "MK Potion Shop Item 8", MARKET_POTION_SHOP_ITEM_8, BUY_FISH, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - - locationTable[MARKET_BAZAAR_ITEM_1] = ItemLocation::Base(RC_MARKET_BAZAAR_ITEM_1, 0x2C, "MK Bazaar Item 1", MARKET_BAZAAR_ITEM_1, BUY_HYLIAN_SHIELD, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BAZAAR_ITEM_2] = ItemLocation::Base(RC_MARKET_BAZAAR_ITEM_2, 0x2C, "MK Bazaar Item 2", MARKET_BAZAAR_ITEM_2, BUY_BOMBS_535, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BAZAAR_ITEM_3] = ItemLocation::Base(RC_MARKET_BAZAAR_ITEM_3, 0x2C, "MK Bazaar Item 3", MARKET_BAZAAR_ITEM_3, BUY_DEKU_NUT_5, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BAZAAR_ITEM_4] = ItemLocation::Base(RC_MARKET_BAZAAR_ITEM_4, 0x2C, "MK Bazaar Item 4", MARKET_BAZAAR_ITEM_4, BUY_HEART, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BAZAAR_ITEM_5] = ItemLocation::Base(RC_MARKET_BAZAAR_ITEM_5, 0x2C, "MK Bazaar Item 5", MARKET_BAZAAR_ITEM_5, BUY_ARROWS_10, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BAZAAR_ITEM_6] = ItemLocation::Base(RC_MARKET_BAZAAR_ITEM_6, 0x2C, "MK Bazaar Item 6", MARKET_BAZAAR_ITEM_6, BUY_ARROWS_50, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BAZAAR_ITEM_7] = ItemLocation::Base(RC_MARKET_BAZAAR_ITEM_7, 0x2C, "MK Bazaar Item 7", MARKET_BAZAAR_ITEM_7, BUY_DEKU_STICK_1, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - locationTable[MARKET_BAZAAR_ITEM_8] = ItemLocation::Base(RC_MARKET_BAZAAR_ITEM_8, 0x2C, "MK Bazaar Item 8", MARKET_BAZAAR_ITEM_8, BUY_ARROWS_30, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); - - locationTable[KAK_BAZAAR_ITEM_1] = ItemLocation::Base(RC_KAK_BAZAAR_ITEM_1, 0x2C, "Kak Bazaar Item 1", KAK_BAZAAR_ITEM_1, BUY_HYLIAN_SHIELD, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_BAZAAR_ITEM_2] = ItemLocation::Base(RC_KAK_BAZAAR_ITEM_2, 0x2C, "Kak Bazaar Item 2", KAK_BAZAAR_ITEM_2, BUY_BOMBS_535, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_BAZAAR_ITEM_3] = ItemLocation::Base(RC_KAK_BAZAAR_ITEM_3, 0x2C, "Kak Bazaar Item 3", KAK_BAZAAR_ITEM_3, BUY_DEKU_NUT_5, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_BAZAAR_ITEM_4] = ItemLocation::Base(RC_KAK_BAZAAR_ITEM_4, 0x2C, "Kak Bazaar Item 4", KAK_BAZAAR_ITEM_4, BUY_HEART, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_BAZAAR_ITEM_5] = ItemLocation::Base(RC_KAK_BAZAAR_ITEM_5, 0x2C, "Kak Bazaar Item 5", KAK_BAZAAR_ITEM_5, BUY_ARROWS_10, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_BAZAAR_ITEM_6] = ItemLocation::Base(RC_KAK_BAZAAR_ITEM_6, 0x2C, "Kak Bazaar Item 6", KAK_BAZAAR_ITEM_6, BUY_ARROWS_50, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_BAZAAR_ITEM_7] = ItemLocation::Base(RC_KAK_BAZAAR_ITEM_7, 0x2C, "Kak Bazaar Item 7", KAK_BAZAAR_ITEM_7, BUY_DEKU_STICK_1, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_BAZAAR_ITEM_8] = ItemLocation::Base(RC_KAK_BAZAAR_ITEM_8, 0x2C, "Kak Bazaar Item 8", KAK_BAZAAR_ITEM_8, BUY_ARROWS_30, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - - locationTable[ZD_SHOP_ITEM_1] = ItemLocation::Base(RC_ZD_SHOP_ITEM_1, 0x2F, "ZD Shop Item 1", ZD_SHOP_ITEM_1, BUY_ZORA_TUNIC, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZD_SHOP_ITEM_2] = ItemLocation::Base(RC_ZD_SHOP_ITEM_2, 0x2F, "ZD Shop Item 2", ZD_SHOP_ITEM_2, BUY_ARROWS_10, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZD_SHOP_ITEM_3] = ItemLocation::Base(RC_ZD_SHOP_ITEM_3, 0x2F, "ZD Shop Item 3", ZD_SHOP_ITEM_3, BUY_HEART, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZD_SHOP_ITEM_4] = ItemLocation::Base(RC_ZD_SHOP_ITEM_4, 0x2F, "ZD Shop Item 4", ZD_SHOP_ITEM_4, BUY_ARROWS_30, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZD_SHOP_ITEM_5] = ItemLocation::Base(RC_ZD_SHOP_ITEM_5, 0x2F, "ZD Shop Item 5", ZD_SHOP_ITEM_5, BUY_DEKU_NUT_5, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZD_SHOP_ITEM_6] = ItemLocation::Base(RC_ZD_SHOP_ITEM_6, 0x2F, "ZD Shop Item 6", ZD_SHOP_ITEM_6, BUY_ARROWS_50, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZD_SHOP_ITEM_7] = ItemLocation::Base(RC_ZD_SHOP_ITEM_7, 0x2F, "ZD Shop Item 7", ZD_SHOP_ITEM_7, BUY_FISH, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - locationTable[ZD_SHOP_ITEM_8] = ItemLocation::Base(RC_ZD_SHOP_ITEM_8, 0x2F, "ZD Shop Item 8", ZD_SHOP_ITEM_8, BUY_RED_POTION_50, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN); - - locationTable[GC_SHOP_ITEM_1] = ItemLocation::Base(RC_GC_SHOP_ITEM_1, 0x2E, "GC Shop Item 1", GC_SHOP_ITEM_1, BUY_BOMBS_525, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_SHOP_ITEM_2] = ItemLocation::Base(RC_GC_SHOP_ITEM_2, 0x2E, "GC Shop Item 2", GC_SHOP_ITEM_2, BUY_BOMBS_10, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_SHOP_ITEM_3] = ItemLocation::Base(RC_GC_SHOP_ITEM_3, 0x2E, "GC Shop Item 3", GC_SHOP_ITEM_3, BUY_BOMBS_20, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_SHOP_ITEM_4] = ItemLocation::Base(RC_GC_SHOP_ITEM_4, 0x2E, "GC Shop Item 4", GC_SHOP_ITEM_4, BUY_BOMBS_30, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_SHOP_ITEM_5] = ItemLocation::Base(RC_GC_SHOP_ITEM_5, 0x2E, "GC Shop Item 5", GC_SHOP_ITEM_5, BUY_GORON_TUNIC, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_SHOP_ITEM_6] = ItemLocation::Base(RC_GC_SHOP_ITEM_6, 0x2E, "GC Shop Item 6", GC_SHOP_ITEM_6, BUY_HEART, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_SHOP_ITEM_7] = ItemLocation::Base(RC_GC_SHOP_ITEM_7, 0x2E, "GC Shop Item 7", GC_SHOP_ITEM_7, BUY_RED_POTION_40, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - locationTable[GC_SHOP_ITEM_8] = ItemLocation::Base(RC_GC_SHOP_ITEM_8, 0x2E, "GC Shop Item 8", GC_SHOP_ITEM_8, BUY_HEART, {Category::cShop}, SpoilerCollectionCheck::ShopItem(), SpoilerCollectionCheckGroup::GROUP_GORON_CITY); - - /*------------------------------- - --- GOSSIP STONES --- - -------------------------------*/ - // These are not actual locations, but are filler spots used for hint reachability. - OoT Randomizer - locationTable[DMC_GOSSIP_STONE] = ItemLocation::HintStone(RC_DMC_GOSSIP_STONE, "DMC Gossip Stone"); - locationTable[DMT_GOSSIP_STONE] = ItemLocation::HintStone(RC_DMT_GOSSIP_STONE, "DMT Gossip Stone"); - locationTable[COLOSSUS_GOSSIP_STONE] = ItemLocation::HintStone(RC_COLOSSUS_GOSSIP_STONE, "Colossus Gossip Stone"); - locationTable[DODONGOS_CAVERN_GOSSIP_STONE] = ItemLocation::HintStone(RC_DODONGOS_CAVERN_GOSSIP_STONE, "Dodongo's Cavern Gossip Stone"); - locationTable[GV_GOSSIP_STONE] = ItemLocation::HintStone(RC_GV_GOSSIP_STONE, "GV Gossip Stone"); - locationTable[GC_MAZE_GOSSIP_STONE] = ItemLocation::HintStone(RC_GC_MAZE_GOSSIP_STONE, "GC Maze Gossip Stone"); - locationTable[GC_MEDIGORON_GOSSIP_STONE] = ItemLocation::HintStone(RC_GC_MEDIGORON_GOSSIP_STONE, "GC Medigoron Gossip Stone"); - locationTable[GRAVEYARD_GOSSIP_STONE] = ItemLocation::HintStone(RC_GY_GOSSIP_STONE, "GY Gossip Stone"); - locationTable[HC_MALON_GOSSIP_STONE] = ItemLocation::HintStone(RC_HC_MALON_GOSSIP_STONE, "HC Malon Gossip Stone"); - locationTable[HC_ROCK_WALL_GOSSIP_STONE] = ItemLocation::HintStone(RC_HC_ROCK_WALL_GOSSIP_STONE, "HC Rock Wall Gossip Stone"); - locationTable[HC_STORMS_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_HC_STORMS_GROTTO_GOSSIP_STONE, "HC Storms Grotto Gossip Stone"); - locationTable[KF_DEKU_TREE_GOSSIP_STONE_LEFT] = ItemLocation::HintStone(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, "KF Deku Tree Left Gossip Stone"); - locationTable[KF_DEKU_TREE_GOSSIP_STONE_RIGHT] = ItemLocation::HintStone(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, "KF Deku Tree Right Gossip Stone"); - locationTable[KF_GOSSIP_STONE] = ItemLocation::HintStone(RC_KF_GOSSIP_STONE, "KF Gossip Stone"); - locationTable[LH_LAB_GOSSIP_STONE] = ItemLocation::HintStone(RC_LH_LAB_GOSSIP_STONE, "LH Lab Gossip Stone"); - locationTable[LH_GOSSIP_STONE_SOUTHEAST] = ItemLocation::HintStone(RC_LH_SOUTHEAST_GOSSIP_STONE, "LH Southeast Gossip Stone"); - locationTable[LH_GOSSIP_STONE_SOUTHWEST] = ItemLocation::HintStone(RC_LH_SOUTHWEST_GOSSIP_STONE, "LH Southwest Gossip Stone"); - locationTable[LW_GOSSIP_STONE] = ItemLocation::HintStone(RC_LW_GOSSIP_STONE, "LW Gossip Stone"); - locationTable[SFM_MAZE_GOSSIP_STONE_LOWER] = ItemLocation::HintStone(RC_SFM_MAZE_LOWER_GOSSIP_STONE, "SFM Maze Lower Gossip Stone"); - locationTable[SFM_MAZE_GOSSIP_STONE_UPPER] = ItemLocation::HintStone(RC_SFM_MAZE_UPPER_GOSSIP_STONE, "SFM Maze Upper Gossip Stone"); - locationTable[SFM_SARIA_GOSSIP_STONE] = ItemLocation::HintStone(RC_SFM_SARIA_GOSSIP_STONE, "SFM Saria Gossip Stone"); - locationTable[TOT_GOSSIP_STONE_LEFT] = ItemLocation::HintStone(RC_TOT_LEFT_GOSSIP_STONE, "ToT Left Gossip Stone"); - locationTable[TOT_GOSSIP_STONE_RIGHT] = ItemLocation::HintStone(RC_TOT_RIGHT_GOSSIP_STONE, "ToT Left Center Gossip Stone"); - locationTable[TOT_GOSSIP_STONE_RIGHT_CENTER] = ItemLocation::HintStone(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, "ToT Right Center Gossip Stone"); - locationTable[TOT_GOSSIP_STONE_LEFT_CENTER] = ItemLocation::HintStone(RC_TOT_LEFT_CENTER_GOSSIP_STONE, "ToT Right Gossip Stone"); - locationTable[ZD_GOSSIP_STONE] = ItemLocation::HintStone(RC_ZD_GOSSIP_STONE, "ZD Gossip Stone"); - locationTable[ZF_FAIRY_GOSSIP_STONE] = ItemLocation::HintStone(RC_FAIRY_GOSSIP_STONE, "Fairy Gossip Stone"); - locationTable[ZF_JABU_GOSSIP_STONE] = ItemLocation::HintStone(RC_JABU_GOSSIP_STONE, "Jabu Gossip Stone"); - locationTable[ZR_NEAR_GROTTOS_GOSSIP_STONE] = ItemLocation::HintStone(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, "ZR Near Grottos Gossip Stone"); - locationTable[ZR_NEAR_DOMAIN_GOSSIP_STONE] = ItemLocation::HintStone(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, "ZR Near Domain Gossip Stone"); - locationTable[HF_COW_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_HF_COW_GROTTO_GOSSIP_STONE, "HF Cow Grotto Gossip Stone"); - - locationTable[HF_NEAR_MARKET_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_HF_NEAR_MARKET_GOSSIP_STONE, "HF Near Market Gossip Stone"); - locationTable[HF_SOUTHEAST_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_HF_SOUTHEAST_GOSSIP_STONE, "HF Southeast Gossip Stone"); - locationTable[HF_OPEN_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_HF_OPEN_GROTTO_GOSSIP_STONE, "HF Open Grotto Gossip Stone"); - locationTable[KAK_OPEN_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, "Kak Open Grotto Gossip Stone"); - locationTable[ZR_OPEN_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, "ZR Open Grotto Gossip Stone"); - locationTable[KF_STORMS_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_KF_STORMS_GOSSIP_STONE, "KF Storms Gossip Stone"); - locationTable[LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE, "LW Near Shortcuts Gossip Stone"); - locationTable[DMT_STORMS_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, "DMT Storms Grotto Gossip Stone"); - locationTable[DMC_UPPER_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, "DMC Upper Grotto Gossip Stone"); - - locationTable[GANONDORF_HINT] = ItemLocation::OtherHint(RC_GANONDORF_HINT, "Ganondorf Hint"); - locationTable[TRIFORCE_COMPLETED] = ItemLocation::Reward (RC_TRIFORCE_COMPLETED, 0xFF, "Completed Triforce", NONE, NONE, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP); - - for (int i = NONE; i != KEY_ENUM_MAX; i++) - locationLookupTable.insert(std::make_pair(locationTable[i].GetRandomizerCheck(), static_cast(i))); -} - -std::vector KF_ShopLocations = { - KF_SHOP_ITEM_1, - KF_SHOP_ITEM_2, - KF_SHOP_ITEM_3, - KF_SHOP_ITEM_4, - KF_SHOP_ITEM_5, - KF_SHOP_ITEM_6, - KF_SHOP_ITEM_7, - KF_SHOP_ITEM_8, -}; -std::vector Kak_PotionShopLocations = { - KAK_POTION_SHOP_ITEM_1, - KAK_POTION_SHOP_ITEM_2, - KAK_POTION_SHOP_ITEM_3, - KAK_POTION_SHOP_ITEM_4, - KAK_POTION_SHOP_ITEM_5, - KAK_POTION_SHOP_ITEM_6, - KAK_POTION_SHOP_ITEM_7, - KAK_POTION_SHOP_ITEM_8, -}; -std::vector MK_BombchuShopLocations = { - MARKET_BOMBCHU_SHOP_ITEM_1, - MARKET_BOMBCHU_SHOP_ITEM_2, - MARKET_BOMBCHU_SHOP_ITEM_3, - MARKET_BOMBCHU_SHOP_ITEM_4, - MARKET_BOMBCHU_SHOP_ITEM_5, - MARKET_BOMBCHU_SHOP_ITEM_6, - MARKET_BOMBCHU_SHOP_ITEM_7, - MARKET_BOMBCHU_SHOP_ITEM_8, -}; -std::vector MK_PotionShopLocations = { - MARKET_POTION_SHOP_ITEM_1, - MARKET_POTION_SHOP_ITEM_2, - MARKET_POTION_SHOP_ITEM_3, - MARKET_POTION_SHOP_ITEM_4, - MARKET_POTION_SHOP_ITEM_5, - MARKET_POTION_SHOP_ITEM_6, - MARKET_POTION_SHOP_ITEM_7, - MARKET_POTION_SHOP_ITEM_8, -}; -std::vector MK_BazaarLocations = { - MARKET_BAZAAR_ITEM_1, - MARKET_BAZAAR_ITEM_2, - MARKET_BAZAAR_ITEM_3, - MARKET_BAZAAR_ITEM_4, - MARKET_BAZAAR_ITEM_5, - MARKET_BAZAAR_ITEM_6, - MARKET_BAZAAR_ITEM_7, - MARKET_BAZAAR_ITEM_8, -}; -std::vector Kak_BazaarLocations = { - KAK_BAZAAR_ITEM_1, - KAK_BAZAAR_ITEM_2, - KAK_BAZAAR_ITEM_3, - KAK_BAZAAR_ITEM_4, - KAK_BAZAAR_ITEM_5, - KAK_BAZAAR_ITEM_6, - KAK_BAZAAR_ITEM_7, - KAK_BAZAAR_ITEM_8, -}; -std::vector ZD_ShopLocations = { - ZD_SHOP_ITEM_1, - ZD_SHOP_ITEM_2, - ZD_SHOP_ITEM_3, - ZD_SHOP_ITEM_4, - ZD_SHOP_ITEM_5, - ZD_SHOP_ITEM_6, - ZD_SHOP_ITEM_7, - ZD_SHOP_ITEM_8, -}; -std::vector GC_ShopLocations = { - GC_SHOP_ITEM_1, - GC_SHOP_ITEM_2, - GC_SHOP_ITEM_3, - GC_SHOP_ITEM_4, - GC_SHOP_ITEM_5, - GC_SHOP_ITEM_6, - GC_SHOP_ITEM_7, - GC_SHOP_ITEM_8, -}; -//List of shop location lists, used for shop shuffle -std::vector> ShopLocationLists = { - KF_ShopLocations, - Kak_PotionShopLocations, - MK_BombchuShopLocations, - MK_PotionShopLocations, - MK_BazaarLocations, - Kak_BazaarLocations, - ZD_ShopLocations, - GC_ShopLocations, -}; - -//List of scrubs, used for pricing the scrubs -std::vector ScrubLocations = { - LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, - LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, - LW_DEKU_SCRUB_NEAR_BRIDGE, - LW_DEKU_SCRUB_GROTTO_REAR, - LW_DEKU_SCRUB_GROTTO_FRONT, - SFM_DEKU_SCRUB_GROTTO_REAR, - SFM_DEKU_SCRUB_GROTTO_FRONT, - HF_DEKU_SCRUB_GROTTO, - LH_DEKU_SCRUB_GROTTO_LEFT, - LH_DEKU_SCRUB_GROTTO_RIGHT, - LH_DEKU_SCRUB_GROTTO_CENTER, - GV_DEKU_SCRUB_GROTTO_REAR, - GV_DEKU_SCRUB_GROTTO_FRONT, - COLOSSUS_DEKU_SCRUB_GROTTO_REAR, - COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, - GC_DEKU_SCRUB_GROTTO_LEFT, - GC_DEKU_SCRUB_GROTTO_RIGHT, - GC_DEKU_SCRUB_GROTTO_CENTER, - DMC_DEKU_SCRUB, - DMC_DEKU_SCRUB_GROTTO_LEFT, - DMC_DEKU_SCRUB_GROTTO_RIGHT, - DMC_DEKU_SCRUB_GROTTO_CENTER, - ZR_DEKU_SCRUB_GROTTO_REAR, - ZR_DEKU_SCRUB_GROTTO_FRONT, - LLR_DEKU_SCRUB_GROTTO_LEFT, - LLR_DEKU_SCRUB_GROTTO_RIGHT, - LLR_DEKU_SCRUB_GROTTO_CENTER, - DEKU_TREE_MQ_DEKU_SCRUB, - DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, - DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, - DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, - DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, - JABU_JABUS_BELLY_DEKU_SCRUB, - GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, - GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, - GANONS_CASTLE_DEKU_SCRUB_RIGHT, - GANONS_CASTLE_DEKU_SCRUB_LEFT, - GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, - GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, - GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, - GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, - GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, -}; - -//List of gossip stone locations for hints -std::vector gossipStoneLocations = { - DMC_GOSSIP_STONE, - DMT_GOSSIP_STONE, - COLOSSUS_GOSSIP_STONE, - DODONGOS_CAVERN_GOSSIP_STONE, - GV_GOSSIP_STONE, - GC_MAZE_GOSSIP_STONE, - GC_MEDIGORON_GOSSIP_STONE, - GRAVEYARD_GOSSIP_STONE, - HC_MALON_GOSSIP_STONE, - HC_ROCK_WALL_GOSSIP_STONE, - HC_STORMS_GROTTO_GOSSIP_STONE, - KF_DEKU_TREE_GOSSIP_STONE_LEFT, - KF_DEKU_TREE_GOSSIP_STONE_RIGHT, - KF_GOSSIP_STONE, - LH_LAB_GOSSIP_STONE, - LH_GOSSIP_STONE_SOUTHEAST, - LH_GOSSIP_STONE_SOUTHWEST, - LW_GOSSIP_STONE, - SFM_MAZE_GOSSIP_STONE_LOWER, - SFM_MAZE_GOSSIP_STONE_UPPER, - SFM_SARIA_GOSSIP_STONE, - TOT_GOSSIP_STONE_LEFT, - TOT_GOSSIP_STONE_RIGHT, - TOT_GOSSIP_STONE_RIGHT_CENTER, - TOT_GOSSIP_STONE_LEFT_CENTER, - ZD_GOSSIP_STONE, - ZF_FAIRY_GOSSIP_STONE, - ZF_JABU_GOSSIP_STONE, - ZR_NEAR_GROTTOS_GOSSIP_STONE, - ZR_NEAR_DOMAIN_GOSSIP_STONE, - HF_COW_GROTTO_GOSSIP_STONE, - HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, - HF_SOUTHEAST_GROTTO_GOSSIP_STONE, - HF_OPEN_GROTTO_GOSSIP_STONE, - KAK_OPEN_GROTTO_GOSSIP_STONE, - ZR_OPEN_GROTTO_GOSSIP_STONE, - KF_STORMS_GROTTO_GOSSIP_STONE, - LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, - DMT_STORMS_GROTTO_GOSSIP_STONE, - DMC_UPPER_GROTTO_GOSSIP_STONE, -}; - -std::vector dungeonRewardLocations = { - //Bosses - QUEEN_GOHMA, - KING_DODONGO, - BARINADE, - PHANTOM_GANON, - VOLVAGIA, - MORPHA, - TWINROVA, - BONGO_BONGO, - LINKS_POCKET, -}; -std::vector overworldLocations = { - //Kokiri Forest - KF_KOKIRI_SWORD_CHEST, - KF_MIDOS_TOP_LEFT_CHEST, - KF_MIDOS_TOP_RIGHT_CHEST, - KF_MIDOS_BOTTOM_LEFT_CHEST, - KF_MIDOS_BOTTOM_RIGHT_CHEST, - KF_STORMS_GROTTO_CHEST, - KF_LINKS_HOUSE_COW, - - //Shop - KF_SHOP_ITEM_1, - KF_SHOP_ITEM_2, - KF_SHOP_ITEM_3, - KF_SHOP_ITEM_4, - KF_SHOP_ITEM_5, - KF_SHOP_ITEM_6, - KF_SHOP_ITEM_7, - KF_SHOP_ITEM_8, - - //Lost Woods - LW_GIFT_FROM_SARIA, - LW_SKULL_KID, - LW_TRADE_COJIRO, - LW_TRADE_ODD_POTION, - LW_OCARINA_MEMORY_GAME, - LW_TARGET_IN_WOODS, - LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, - LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, - LW_DEKU_SCRUB_NEAR_BRIDGE, - LW_NEAR_SHORTCUTS_GROTTO_CHEST, - LW_DEKU_SCRUB_GROTTO_REAR, - LW_DEKU_SCRUB_GROTTO_FRONT, - DEKU_THEATER_SKULL_MASK, - DEKU_THEATER_MASK_OF_TRUTH, - - //Sacred Forest Meadow - SONG_FROM_SARIA, - SHEIK_IN_FOREST, - SFM_WOLFOS_GROTTO_CHEST, - SFM_DEKU_SCRUB_GROTTO_REAR, - SFM_DEKU_SCRUB_GROTTO_FRONT, - - //Hyrule Field - HF_SOUTHEAST_GROTTO_CHEST, - HF_OPEN_GROTTO_CHEST, - HF_NEAR_MARKET_GROTTO_CHEST, - HF_OCARINA_OF_TIME_ITEM, - SONG_FROM_OCARINA_OF_TIME, - HF_TEKTITE_GROTTO_FREESTANDING_POH, - HF_DEKU_SCRUB_GROTTO, - HF_COW_GROTTO_COW, - - //Lake Hylia - LH_CHILD_FISHING, - LH_ADULT_FISHING, - LH_LAB_DIVE, - LH_TRADE_FROG, - LH_UNDERWATER_ITEM, - LH_SUN, - LH_FREESTANDING_POH, - LH_DEKU_SCRUB_GROTTO_LEFT, - LH_DEKU_SCRUB_GROTTO_RIGHT, - LH_DEKU_SCRUB_GROTTO_CENTER, - - //Gerudo Valley - GV_CHEST, - GV_TRADE_SAW, - GV_WATERFALL_FREESTANDING_POH, - GV_CRATE_FREESTANDING_POH, - GV_DEKU_SCRUB_GROTTO_REAR, - GV_DEKU_SCRUB_GROTTO_FRONT, - GV_COW, - - //Gerudo Fortress - GF_CHEST, - GF_HBA_1000_POINTS, - GF_HBA_1500_POINTS, - GF_NORTH_F1_CARPENTER, - GF_NORTH_F2_CARPENTER, - GF_SOUTH_F1_CARPENTER, - GF_SOUTH_F2_CARPENTER, - GF_GERUDO_MEMBERSHIP_CARD, - - //Haunted Wasteland - WASTELAND_CHEST, - WASTELAND_BOMBCHU_SALESMAN, - - //Desert Colossus - SHEIK_AT_COLOSSUS, - COLOSSUS_FREESTANDING_POH, - COLOSSUS_GREAT_FAIRY_REWARD, - COLOSSUS_DEKU_SCRUB_GROTTO_REAR, - COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, - - //Market - MARKET_TREASURE_CHEST_GAME_REWARD, - MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, - MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, - MARKET_BOMBCHU_BOWLING_BOMBCHUS, - MARKET_LOST_DOG, - MARKET_SHOOTING_GALLERY_REWARD, - MARKET_10_BIG_POES, - MARKET_TREASURE_CHEST_GAME_ITEM_1, - MARKET_TREASURE_CHEST_GAME_ITEM_2, - MARKET_TREASURE_CHEST_GAME_ITEM_3, - MARKET_TREASURE_CHEST_GAME_ITEM_4, - MARKET_TREASURE_CHEST_GAME_ITEM_5, - - //Market Shops - MARKET_BOMBCHU_SHOP_ITEM_1, - MARKET_BOMBCHU_SHOP_ITEM_2, - MARKET_BOMBCHU_SHOP_ITEM_3, - MARKET_BOMBCHU_SHOP_ITEM_4, - MARKET_BOMBCHU_SHOP_ITEM_5, - MARKET_BOMBCHU_SHOP_ITEM_6, - MARKET_BOMBCHU_SHOP_ITEM_7, - MARKET_BOMBCHU_SHOP_ITEM_8, - MARKET_POTION_SHOP_ITEM_1, - MARKET_POTION_SHOP_ITEM_2, - MARKET_POTION_SHOP_ITEM_3, - MARKET_POTION_SHOP_ITEM_4, - MARKET_POTION_SHOP_ITEM_5, - MARKET_POTION_SHOP_ITEM_6, - MARKET_POTION_SHOP_ITEM_7, - MARKET_POTION_SHOP_ITEM_8, - MARKET_BAZAAR_ITEM_1, - MARKET_BAZAAR_ITEM_2, - MARKET_BAZAAR_ITEM_3, - MARKET_BAZAAR_ITEM_4, - MARKET_BAZAAR_ITEM_5, - MARKET_BAZAAR_ITEM_6, - MARKET_BAZAAR_ITEM_7, - MARKET_BAZAAR_ITEM_8, - - //Hyrule Castle - HC_MALON_EGG, - HC_ZELDAS_LETTER, - SONG_FROM_IMPA, - HC_GREAT_FAIRY_REWARD, - OGC_GREAT_FAIRY_REWARD, - - //Temple of Time - TOT_MASTER_SWORD, - SHEIK_AT_TEMPLE, - TOT_LIGHT_ARROWS_CUTSCENE, - - //Kakariko - SHEIK_IN_KAKARIKO, - KAK_REDEAD_GROTTO_CHEST, - KAK_OPEN_GROTTO_CHEST, - KAK_10_GOLD_SKULLTULA_REWARD, - KAK_20_GOLD_SKULLTULA_REWARD, - KAK_30_GOLD_SKULLTULA_REWARD, - KAK_40_GOLD_SKULLTULA_REWARD, - KAK_50_GOLD_SKULLTULA_REWARD, - KAK_100_GOLD_SKULLTULA_REWARD, - KAK_MAN_ON_ROOF, - KAK_SHOOTING_GALLERY_REWARD, - KAK_TRADE_ODD_MUSHROOM, - KAK_GRANNYS_SHOP, - KAK_ANJU_AS_CHILD, - KAK_ANJU_AS_ADULT, - KAK_TRADE_POCKET_CUCCO, - KAK_IMPAS_HOUSE_FREESTANDING_POH, - KAK_WINDMILL_FREESTANDING_POH, - SONG_FROM_WINDMILL, - KAK_IMPAS_HOUSE_COW, - - //Kakariko Shops - KAK_POTION_SHOP_ITEM_1, - KAK_POTION_SHOP_ITEM_2, - KAK_POTION_SHOP_ITEM_3, - KAK_POTION_SHOP_ITEM_4, - KAK_POTION_SHOP_ITEM_5, - KAK_POTION_SHOP_ITEM_6, - KAK_POTION_SHOP_ITEM_7, - KAK_POTION_SHOP_ITEM_8, - KAK_BAZAAR_ITEM_1, - KAK_BAZAAR_ITEM_2, - KAK_BAZAAR_ITEM_3, - KAK_BAZAAR_ITEM_4, - KAK_BAZAAR_ITEM_5, - KAK_BAZAAR_ITEM_6, - KAK_BAZAAR_ITEM_7, - KAK_BAZAAR_ITEM_8, - - //Graveyard - GRAVEYARD_HOOKSHOT_CHEST, - GRAVEYARD_SHIELD_GRAVE_CHEST, - GRAVEYARD_HEART_PIECE_GRAVE_CHEST, - GRAVEYARD_COMPOSERS_GRAVE_CHEST, - SONG_FROM_COMPOSERS_GRAVE, - GRAVEYARD_FREESTANDING_POH, - GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, - GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, - - //Death Mountain Trail - DMT_CHEST, - DMT_STORMS_GROTTO_CHEST, - DMT_TRADE_BROKEN_SWORD, - DMT_TRADE_EYEDROPS, - DMT_TRADE_CLAIM_CHECK, - DMT_GREAT_FAIRY_REWARD, - DMT_FREESTANDING_POH, - DMT_COW_GROTTO_COW, - - //Goron City - GC_MAZE_LEFT_CHEST, - GC_MAZE_CENTER_CHEST, - GC_MAZE_RIGHT_CHEST, - GC_ROLLING_GORON_AS_CHILD, - GC_ROLLING_GORON_AS_ADULT, - GC_DARUNIAS_JOY, - GC_POT_FREESTANDING_POH, - GC_DEKU_SCRUB_GROTTO_LEFT, - GC_DEKU_SCRUB_GROTTO_RIGHT, - GC_DEKU_SCRUB_GROTTO_CENTER, - GC_MEDIGORON, - - //Goron City Shop - GC_SHOP_ITEM_1, - GC_SHOP_ITEM_2, - GC_SHOP_ITEM_3, - GC_SHOP_ITEM_4, - GC_SHOP_ITEM_5, - GC_SHOP_ITEM_6, - GC_SHOP_ITEM_7, - GC_SHOP_ITEM_8, - - //Death Mountain - DMC_UPPER_GROTTO_CHEST, - DMC_WALL_FREESTANDING_POH, - DMC_VOLCANO_FREESTANDING_POH, - SHEIK_IN_CRATER, - DMC_DEKU_SCRUB, - DMC_GREAT_FAIRY_REWARD, - DMC_DEKU_SCRUB_GROTTO_LEFT, - DMC_DEKU_SCRUB_GROTTO_RIGHT, - DMC_DEKU_SCRUB_GROTTO_CENTER, - - //Zoras River - ZR_OPEN_GROTTO_CHEST, - ZR_MAGIC_BEAN_SALESMAN, - ZR_FROGS_ZELDAS_LULLABY, - ZR_FROGS_EPONAS_SONG, - ZR_FROGS_SARIAS_SONG, - ZR_FROGS_SUNS_SONG, - ZR_FROGS_SONG_OF_TIME, - ZR_FROGS_IN_THE_RAIN, - ZR_FROGS_OCARINA_GAME, - ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, - ZR_NEAR_DOMAIN_FREESTANDING_POH, - ZR_DEKU_SCRUB_GROTTO_REAR, - ZR_DEKU_SCRUB_GROTTO_FRONT, - - //Zoras Domain - ZD_CHEST, - ZD_DIVING_MINIGAME, - ZD_KING_ZORA_THAWED, - ZD_TRADE_PRESCRIPTION, - - //Zora's Domain Shop - ZD_SHOP_ITEM_1, - ZD_SHOP_ITEM_2, - ZD_SHOP_ITEM_3, - ZD_SHOP_ITEM_4, - ZD_SHOP_ITEM_5, - ZD_SHOP_ITEM_6, - ZD_SHOP_ITEM_7, - ZD_SHOP_ITEM_8, - - //Zoras Fountain - ZF_ICEBERG_FREESTANDING_POH, - ZF_BOTTOM_FREESTANDING_POH, - ZF_GREAT_FAIRY_REWARD, - - //Lon Lon Ranch - SONG_FROM_MALON, - LLR_TALONS_CHICKENS, - LLR_FREESTANDING_POH, - LLR_DEKU_SCRUB_GROTTO_LEFT, - LLR_DEKU_SCRUB_GROTTO_RIGHT, - LLR_DEKU_SCRUB_GROTTO_CENTER, - LLR_STABLES_LEFT_COW, - LLR_STABLES_RIGHT_COW, - LLR_TOWER_LEFT_COW, - LLR_TOWER_RIGHT_COW, - - /*------------------------------- - --- GOLD SKULLTULA TOKENS --- - -------------------------------*/ - - //Overworld - KF_GS_BEAN_PATCH, - KF_GS_KNOW_IT_ALL_HOUSE, - KF_GS_HOUSE_OF_TWINS, - - LW_GS_BEAN_PATCH_NEAR_BRIDGE, - LW_GS_BEAN_PATCH_NEAR_THEATER, - LW_GS_ABOVE_THEATER, - SFM_GS, - - HF_GS_COW_GROTTO, - HF_GS_NEAR_KAK_GROTTO, - - LH_GS_BEAN_PATCH, - LH_GS_SMALL_ISLAND, - LH_GS_LAB_WALL, - LH_GS_LAB_CRATE, - LH_GS_TREE, - - GV_GS_BEAN_PATCH, - GV_GS_SMALL_BRIDGE, - GV_GS_PILLAR, - GV_GS_BEHIND_TENT, - - GF_GS_ARCHERY_RANGE, - GF_GS_TOP_FLOOR, - - WASTELAND_GS, - COLOSSUS_GS_BEAN_PATCH, - COLOSSUS_GS_HILL, - COLOSSUS_GS_TREE, - - OGC_GS, - HC_GS_STORMS_GROTTO, - HC_GS_TREE, - MARKET_GS_GUARD_HOUSE, - - KAK_GS_HOUSE_UNDER_CONSTRUCTION, - KAK_GS_SKULLTULA_HOUSE, - KAK_GS_GUARDS_HOUSE, - KAK_GS_TREE, - KAK_GS_WATCHTOWER, - KAK_GS_ABOVE_IMPAS_HOUSE, - - DMC_GS_BEAN_PATCH, - DMC_GS_CRATE, - - DMT_GS_BEAN_PATCH, - DMT_GS_NEAR_KAK, - DMT_GS_ABOVE_DODONGOS_CAVERN, - DMT_GS_FALLING_ROCKS_PATH, - - GC_GS_CENTER_PLATFORM, - GC_GS_BOULDER_MAZE, - GRAVEYARD_GS_WALL, - GRAVEYARD_GS_BEAN_PATCH, - - ZR_GS_LADDER, - ZR_GS_TREE, - ZR_GS_ABOVE_BRIDGE, - ZR_GS_NEAR_RAISED_GROTTOS, - - ZD_GS_FROZEN_WATERFALL, - ZF_GS_ABOVE_THE_LOG, - ZF_GS_HIDDEN_CAVE, - ZF_GS_TREE, - - LLR_GS_BACK_WALL, - LLR_GS_RAIN_SHED, - LLR_GS_HOUSE_WINDOW, - LLR_GS_TREE, -}; - -ItemLocation* Location(uint32_t locKey) { - return &(locationTable[locKey]); -} - -ItemLocation* Location(RandomizerCheck rc) { - return &(locationTable[locationLookupTable[rc]]); -} - -std::vector allLocations = {}; -std::vector everyPossibleLocation = {}; - -//set of overrides to write to the patch -std::set overrides = {}; -std::unordered_map iceTrapModels = {}; - -std::vector> playthroughLocations; -std::vector wothLocations; -bool playthroughBeatable = false; -bool allLocationsReachable = false; -bool showItemProgress = false; - -uint16_t itemsPlaced = 0; - -void AddLocation(uint32_t loc, std::vector* destination = &allLocations) { - destination->push_back(loc); -} - -template -void AddLocations(const Container& locations, std::vector* destination = &allLocations) { - destination->insert(destination->end(), std::cbegin(locations), std::cend(locations)); -} - -//sort through Vanilla and MQ dungeon locations -void GenerateLocationPool() { - - allLocations.clear(); - AddLocation(LINKS_POCKET); - if (Settings::TriforceHunt.Is(TRIFORCE_HUNT_ON)) { - AddLocation(TRIFORCE_COMPLETED); - } - AddLocations(overworldLocations); - - for (auto dungeon : Dungeon::dungeonList) { - AddLocations(dungeon->GetDungeonLocations()); - } -} - -void PlaceItemInLocation(uint32_t locKey, uint32_t item, bool applyEffectImmediately /*= false*/, bool setHidden /*= false*/) { - auto loc = Location(locKey); - SPDLOG_DEBUG("\n"); - SPDLOG_DEBUG(ItemTable(item).GetName().GetEnglish()); - SPDLOG_DEBUG(" placed at "); - SPDLOG_DEBUG(loc->GetName()); - SPDLOG_DEBUG("\n\n"); - - if (applyEffectImmediately || Settings::Logic.Is(LOGIC_NONE) || Settings::Logic.Is(LOGIC_VANILLA)) { - ItemTable(item).ApplyEffect(); - } - - itemsPlaced++; - if (showItemProgress) { - double completion = (double) itemsPlaced / (double)(allLocations.size() + dungeonRewardLocations.size()); - std::string message = "\x1b[8;10HPlacing Items."; - message += completion > 0.25 ? "." : " "; - message += completion > 0.50 ? "." : " "; - printf("%s", message.c_str()); - } - - //If we're placing a non-shop item in a shop location, we want to record it for custom messages - if (ItemTable(item).GetItemType() != ITEMTYPE_SHOP && loc->IsCategory(Category::cShop)) { - int index = TransformShopIndex(GetShopIndex(locKey)); - NonShopItems[index].Name = ItemTable(item).GetName(); - NonShopItems[index].Repurchaseable = ItemTable(item).GetItemType() == ITEMTYPE_REFILL || ItemTable(item).GetHintKey() == PROGRESSIVE_BOMBCHUS; - } - - loc->SetPlacedItem(item); - if (setHidden) { - loc->SetHidden(true); - } -} - -std::vector GetLocations(const std::vector& locationPool, Category categoryInclude, Category categoryExclude /*= Category::cNull*/) { - std::vector locationsInCategory; - for (uint32_t locKey : locationPool) { - if (Location(locKey)->IsCategory(categoryInclude) && !Location(locKey)->IsCategory(categoryExclude)) { - locationsInCategory.push_back(locKey); - } - } - return locationsInCategory; -} - -void LocationReset() { - for (uint32_t il : allLocations) { - Location(il)->RemoveFromPool(); - } - - for (uint32_t il : dungeonRewardLocations) { - Location(il)->RemoveFromPool(); - } - - for (uint32_t il : gossipStoneLocations) { - Location(il)->RemoveFromPool(); - } - - Location(GANONDORF_HINT)->RemoveFromPool(); -} - -void ItemReset() { - for (uint32_t il : allLocations) { - Location(il)->ResetVariables(); - } - - for (uint32_t il : dungeonRewardLocations) { - Location(il)->ResetVariables(); - } - - itemsPlaced = 0; -} - -void HintReset() { - for (uint32_t il : gossipStoneLocations) { - Location(il)->ResetVariables(); - } -} - -//Fills everyPossibleLocation and creates an exclusion option for each location. -//everyPossibleLocation is used in the menu to lock/hide excluding locations -void AddExcludedOptions() { - AddLocations(overworldLocations, &everyPossibleLocation); - - for (auto dungeon : Dungeon::dungeonList) { - AddLocations(dungeon->GetEveryLocation(), &everyPossibleLocation); - } - - for (uint32_t il: everyPossibleLocation) { - Location(il)->AddExcludeOption(); - } -} - -void CreateItemOverrides() { - SPDLOG_DEBUG("NOW CREATING OVERRIDES\n\n"); - for (uint32_t locKey : allLocations) { - auto loc = Location(locKey); - ItemOverride_Value val = ItemTable(loc->GetPlaceduint32_t()).Value(); - // If this is an ice trap, store the disguise model in iceTrapModels - if (loc->GetPlaceduint32_t() == ICE_TRAP) { - iceTrapModels[loc->GetRandomizerCheck()] = val.looksLikeItemId; - // If this is ice trap is in a shop, change the name based on what the model will look like - if (loc->IsCategory(Category::cShop)) { - NonShopItems[TransformShopIndex(GetShopIndex(locKey))].Name = GetIceTrapName(val.looksLikeItemId); - } - } - overrides.insert({ - .key = loc->Key(), - .value = val, - }); - SPDLOG_DEBUG("\tScene: "); - SPDLOG_DEBUG(std::to_string(loc->Key().scene)); - SPDLOG_DEBUG("\tType: "); - SPDLOG_DEBUG(std::to_string(loc->Key().type)); - SPDLOG_DEBUG("\t"); - SPDLOG_DEBUG(loc->GetName()); - SPDLOG_DEBUG(": "); - SPDLOG_DEBUG(loc->GetPlacedItemName().GetEnglish()); - SPDLOG_DEBUG("\n"); - } - SPDLOG_DEBUG("Overrides Created: "); - SPDLOG_DEBUG(std::to_string(overrides.size())); -} diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.hpp b/soh/soh/Enhancements/randomizer/3drando/item_location.hpp deleted file mode 100644 index 5a61c29860a..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/item_location.hpp +++ /dev/null @@ -1,534 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include "spoiler_log.hpp" -#include "item_list.hpp" -#include "../randomizerTypes.h" - -enum ItemOverride_Type { - OVR_BASE_ITEM = 0, - OVR_CHEST = 1, - OVR_COLLECTABLE = 2, - OVR_SKULL = 3, - OVR_GROTTO_SCRUB = 4, - OVR_DELAYED = 5, - OVR_TEMPLE = 6, -}; - -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; - -typedef union ItemOverride_Key { - uint32_t all; - struct { - char pad_; - uint8_t scene; - uint8_t type; - }; -} ItemOverride_Key; - -typedef union ItemOverride_Value { - uint32_t all; - struct { - uint16_t itemId; - uint8_t player; - uint8_t looksLikeItemId; - }; -} ItemOverride_Value; - -typedef struct ItemOverride { - ItemOverride_Key key; - ItemOverride_Value value; -} ItemOverride; - -class Entrance; - -enum class ItemLocationType { - Base, - Chest, - Collectable, - GSToken, - GrottoScrub, - Delayed, - TempleReward, - HintStone, - OtherHint, -}; - -class SpoilerCollectionCheck { - public: - SpoilerCollectionCheckType type = SpoilerCollectionCheckType::SPOILER_CHK_NONE; - uint8_t scene = 0; - uint8_t flag = 0; - - SpoilerCollectionCheck() {} - SpoilerCollectionCheck(SpoilerCollectionCheckType type_, uint8_t scene_, uint8_t flag_) : type(type_), scene(scene_), flag(flag_) {} - - static auto None() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_NONE, 0x00, 0x00); - } - - static auto AlwaysCollected() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_ALWAYS_COLLECTED, 0x00, 0x00); - } - - static auto ItemGetInf(uint8_t slot) { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_ITEM_GET_INF, 0x00, slot); - } - - static auto EventChkInf(uint8_t flag) { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF, 0xFF, flag); - } - - static auto InfTable(uint8_t offset, uint8_t bit) { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_INF_TABLE, offset, bit); - } - - static auto Collectable(uint8_t scene, uint8_t flag) { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE, scene, flag); - } - - static auto Chest(uint8_t scene, uint8_t flag) { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_CHEST, scene, flag); - } - - static auto Cow() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_COW, 0x00, 0x00); - } - - static auto Fishing() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MINIGAME, 0x00, 0x00); - } - - static auto Scrub() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_SCRUB, 0x00, 0x00); - } - - static auto GerudoToken() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_GERUDO_MEMBERSHIP_CARD, 0x00, 0x00); - } - - static auto BigPoePoints() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_POE_POINTS, 0x00, 0x00); - } - - static auto Gravedigger(uint8_t scene, uint8_t flag) { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_GRAVEDIGGER, scene, flag); - } - - static auto ShopItem() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM, 0x00, 0x00); - } - - static auto MagicBeans() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MAGIC_BEANS, 0x00, 0x00); - } - - static auto MasterSword() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD, 0x00, 0x00); - } - - static auto Merchant() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT, 0x00, 0x00); - - } - - static auto RandomizerInf() { - return SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF, 0x00, 0x00); - } -}; - -class ItemLocation { -public: - ItemLocation() = default; - ItemLocation(RandomizerCheck rc_, uint8_t scene_, ItemLocationType type_, std::string name_, uint32_t hintKey_, uint32_t vanillaItem_, std::vector categories_, uint16_t price_ = 0, SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck(), SpoilerCollectionCheckGroup collectionCheckGroup_ = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) - : rc(rc_), scene(scene_), type(type_), name(std::move(name_)), hintKey(hintKey_), vanillaItem(vanillaItem_), categories(std::move(categories_)), price(price_), collectionCheck(collectionCheck_), collectionCheckGroup(collectionCheckGroup_) {} - - ItemOverride_Key Key() const { - ItemOverride_Key key; - key.all = 0; - - key.scene = scene; - key.type = static_cast(type); //TODO make sure these match up - return key; - } - - RandomizerCheck GetRandomizerCheck() const { - return rc; - } - - SpoilerCollectionCheck GetCollectionCheck() const { - return collectionCheck; - } - - SpoilerCollectionCheckGroup GetCollectionCheckGroup() const { - return collectionCheckGroup; - } - - uint8_t GetScene() const { - return scene; - } - - bool IsAddedToPool() const { - return addedToPool; - } - - void AddToPool() { - addedToPool = true; - } - - uint32_t GetHintKey() const { - return hintKey; - } - - void RemoveFromPool() { - addedToPool = false; - } - - const std::string& GetName() const { - return name; - } - - const Text& GetPlacedItemName() const { - return ItemTable(placedItem).GetName(); - } - - const Item& GetPlacedItem() const { - return ItemTable(placedItem); - } - - uint32_t GetPlacedItemKey() const { - return placedItem; - } - - uint32_t GetPlaceduint32_t() const { - return placedItem; - } - - void SetPlacedItem(const uint32_t item) { - placedItem = item; - SetPrice(ItemTable(placedItem).GetPrice()); - } - - //Saves an item to be set as placedItem later - void SetDelayedItem(const uint32_t item) { - delayedItem = item; - } - - //Place the vanilla item in this location - void PlaceVanillaItem() { - placedItem = vanillaItem; - } - - void ApplyPlacedItemEffect() { - ItemTable(placedItem).ApplyEffect(); - } - - //Set placedItem as item saved in SetDelayedItem - void SaveDelayedItem() { - placedItem = delayedItem; - delayedItem = NONE; - } - - uint16_t GetPrice() const { - if (ItemTable(placedItem).GetItemType() == ITEMTYPE_SHOP) { - return ItemTable(placedItem).GetPrice(); - } - return price; - } - - void SetPrice(uint16_t price_) { - //don't override price if the price was set for shopsanity/scrubsanity - if (hasShopsanityPrice || hasScrubsanityPrice) { - return; - } - price = price_; - } - - void SetShopsanityPrice(uint16_t price_) { - price = price_; - hasShopsanityPrice = true; - } - - void SetScrubsanityPrice(uint16_t price_) { - price = price_; - hasScrubsanityPrice = true; - } - - bool HasShopsanityPrice() const { - return hasShopsanityPrice; - } - - bool HasScrubsanityPrice() const { - return hasScrubsanityPrice; - } - - bool IsExcluded() const { - return excludedOption.Value(); - } - - bool IsCategory(Category category) const { - return std::any_of(categories.begin(), categories.end(), - [category](auto entry) { return entry == category; }); - } - - bool IsDungeon() const { - return (type != ItemLocationType::GSToken && (scene < 0x0E || (scene > 0x10 && scene < 0x1A))) || (type == ItemLocationType::GSToken && scene < 0x0A); - } - - bool IsOverworld() const { - return !IsDungeon(); - } - - bool IsShop() const { - return (scene >= 0x2C && scene <= 0x32); - } - - Option * GetExcludedOption() { - return &excludedOption; - } - - uint32_t Getuint32_t() const { - return hintKey; - } - - const HintText& GetHint() const { - return Hint(hintKey); - } - - bool IsHintedAt() const { - return hintedAt; - } - - void SetAsHinted() { - hintedAt = true; - } - - bool IsHidden() const { - return hidden; - } - - void SetHidden(const bool hidden_) { - hidden = hidden_; - } - - bool IsHintable() const { - return isHintable; - } - - void SetHintedLocation(uint32_t location) { - hintedLocation = location; - } - - uint32_t GetHintedLocation() { - return hintedLocation; - } - - void SetHintType(HintType type) { - hintType = type; - } - - HintType GetHintType() { - return hintType; - } - - void SetHintedRegion (std::string region) { - hintedRegion = region; - } - - std::string GetHintedRegion() { - return hintedRegion; - } - - void SetAsHintable() { - isHintable = true; - } - - void SetParentRegion(uint32_t region) { - parentRegion = region; - } - - uint32_t GetParentRegionKey() const { - return parentRegion; - } - - void AddExcludeOption() { - //add option to forbid any location from progress items - if (name.length() < 23) { - excludedOption = Option::Bool(name, {"Include", "Exclude"}); - } else { - //insert a newline character if the text is too long for one row - size_t lastSpace = name.rfind(' ', 23); - std::string settingText = name; - settingText.replace(lastSpace, 1, "\n "); - - excludedOption = Option::Bool(settingText, {"Include", "Exclude"}); - } - - // RANDOTODO: this without string compares and loops - bool alreadyAdded = false; - for(const Option* location : Settings::excludeLocationsOptionsVector[collectionCheckGroup]) { - if (location->GetName() == excludedOption.GetName()) { - alreadyAdded = true; - } - } - if (!alreadyAdded) { - Settings::excludeLocationsOptionsVector[collectionCheckGroup].push_back(&excludedOption); - } - } - - static auto Base(RandomizerCheck rc, uint8_t scene, std::string&& name, const uint32_t hintKey, const uint32_t vanillaItem, std::vector&& categories, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), SpoilerCollectionCheckGroup collectionCheckGroup = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) { - return ItemLocation{rc, scene, ItemLocationType::Base, std::move(name), hintKey, vanillaItem, std::move(categories), 0, collectionCheck, collectionCheckGroup}; - } - - static auto Chest(RandomizerCheck rc, uint8_t scene, uint8_t flag, std::string&& name, const uint32_t hintKey, const uint32_t vanillaItem, std::vector&& categories, SpoilerCollectionCheckGroup collectionCheckGroup = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) { - return ItemLocation{rc, scene, ItemLocationType::Chest, std::move(name), hintKey, vanillaItem, std::move(categories), 0, SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_CHEST, scene, flag), collectionCheckGroup}; - } - - static auto Chest(RandomizerCheck rc, uint8_t scene, std::string&& name, const uint32_t hintKey, const uint32_t vanillaItem, std::vector&& categories, SpoilerCollectionCheck collectionCheck, SpoilerCollectionCheckGroup collectionCheckGroup = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) { - return ItemLocation{rc, scene, ItemLocationType::Chest, std::move(name), hintKey, vanillaItem, std::move(categories), 0, collectionCheck, collectionCheckGroup}; - } - - static auto Collectable(RandomizerCheck rc, uint8_t scene, uint8_t flag, std::string&& name, const uint32_t hintKey, const uint32_t vanillaItem, std::vector&& categories, SpoilerCollectionCheckGroup collectionCheckGroup = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) { - return ItemLocation{rc, scene, ItemLocationType::Collectable, std::move(name), hintKey, vanillaItem, std::move(categories), 0, SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE, scene, flag), collectionCheckGroup}; - } - - static auto Collectable(RandomizerCheck rc, uint8_t scene, std::string&& name, const uint32_t hintKey, const uint32_t vanillaItem, std::vector&& categories, SpoilerCollectionCheck collectionCheck, SpoilerCollectionCheckGroup collectionCheckGroup = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) { - return ItemLocation{rc, scene, ItemLocationType::Collectable, std::move(name), hintKey, vanillaItem, std::move(categories), 0, collectionCheck, collectionCheckGroup}; - } - - static auto GSToken(RandomizerCheck rc, uint8_t scene, uint8_t flag, std::string&& name, const uint32_t hintKey, std::vector&& categories, SpoilerCollectionCheckGroup collectionCheckGroup = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) { - return ItemLocation{rc, scene, ItemLocationType::GSToken, std::move(name), hintKey, GOLD_SKULLTULA_TOKEN, std::move(categories), 0, SpoilerCollectionCheck(SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA, scene, flag), collectionCheckGroup}; - } - - static auto GrottoScrub(RandomizerCheck rc, uint8_t scene, std::string&& name, const uint32_t hintKey, const uint32_t vanillaItem, std::vector&& categories, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), SpoilerCollectionCheckGroup collectionCheckGroup = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) { - return ItemLocation{rc, scene, ItemLocationType::GrottoScrub, std::move(name), hintKey, vanillaItem, std::move(categories), 0, collectionCheck, collectionCheckGroup}; - } - - static auto Delayed(RandomizerCheck rc, uint8_t scene, std::string&& name, const uint32_t hintKey, const uint32_t vanillaItem, std::vector&& categories, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), SpoilerCollectionCheckGroup collectionCheckGroup = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) { - return ItemLocation{rc, scene, ItemLocationType::Delayed, std::move(name), hintKey, vanillaItem, std::move(categories), 0, collectionCheck, collectionCheckGroup}; - } - - static auto Reward(RandomizerCheck rc, uint8_t scene, std::string&& name, const uint32_t hintKey, const uint32_t vanillaItem, std::vector&& categories, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), SpoilerCollectionCheckGroup collectionCheckGroup = SpoilerCollectionCheckGroup::GROUP_NO_GROUP) { - return ItemLocation{rc, scene, ItemLocationType::TempleReward, std::move(name), hintKey, vanillaItem, std::move(categories), 0, collectionCheck, collectionCheckGroup}; - } - - static auto OtherHint(RandomizerCheck rc, std::string&& name) { - return ItemLocation{rc, 0, ItemLocationType::OtherHint, std::move(name), NONE, NONE, {}}; - } - - static auto HintStone(RandomizerCheck rc, std::string&& name) { - return ItemLocation{rc, 0, ItemLocationType::HintStone, std::move(name), NONE, NONE, {}}; - } - - void ResetVariables() { - checked = false; - addedToPool = false; - placedItem = NONE; - delayedItem = NONE; - hintedAt = false; - isHintable = false; - price = 0; - hasShopsanityPrice = false; - hasScrubsanityPrice = false; - hidden = false; - } - -private: - RandomizerCheck rc; - uint8_t scene; - ItemLocationType type; - bool checked = false; - - std::string name; - uint32_t hintKey = NONE; - uint32_t vanillaItem = NONE; - bool hintedAt = false; - std::vector categories; - bool addedToPool = false; - uint32_t placedItem = NONE; - uint32_t hintedLocation = NONE; - HintType hintType; - std::string hintedRegion; - uint32_t delayedItem = NONE; - Option excludedOption = Option::Bool(name, {"Include", "Exclude"}); - uint16_t price = 0; - SpoilerCollectionCheck collectionCheck; - SpoilerCollectionCheckGroup collectionCheckGroup; - bool isHintable = false; - uint32_t parentRegion = NONE; - bool hasShopsanityPrice = false; - bool hasScrubsanityPrice = false; - bool hidden = false; -}; - -class ItemOverride_Compare { -public: - bool operator()(ItemOverride lhs, ItemOverride rhs) const { - return lhs.key.all < rhs.key.all; - } -}; - -void LocationTable_Init(); - -ItemLocation* Location(uint32_t locKey); -ItemLocation* Location(RandomizerCheck rc); - -extern std::vector> ShopLocationLists; - -extern std::vector ScrubLocations; - -extern std::vector gossipStoneLocations; - -extern std::vector dungeonRewardLocations; -extern std::vector overworldLocations; -extern std::vector allLocations; -extern std::vector everyPossibleLocation; - -//set of overrides to write to the patch -extern std::set overrides; -extern std::unordered_map iceTrapModels; - -extern std::vector> playthroughLocations; -extern std::vector wothLocations; -extern bool playthroughBeatable; -extern bool allLocationsReachable; -extern bool showItemProgress; - -extern uint16_t itemsPlaced; - -void GenerateLocationPool(); -void PlaceItemInLocation(uint32_t loc, uint32_t item, bool applyEffectImmediately = false, bool setHidden = false); -std::vector GetLocations(const std::vector& locationPool, Category categoryInclude, - Category categoryExclude = Category::cNull); -void LocationReset(); -void ItemReset(); -void HintReset(); -void AddExcludedOptions(); -void CreateItemOverrides(); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 1eb496eb298..08a9a5179c7 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -1,440 +1,435 @@ #include "item_pool.hpp" -#include "dungeon.hpp" +#include "../dungeon.h" #include "fill.hpp" -#include "item_list.hpp" -#include "item_location.hpp" +#include "../static_data.h" +#include "../context.h" #include "pool_functions.hpp" #include "random.hpp" -#include "settings.hpp" #include "spoiler_log.hpp" #include "z64item.h" #include - -using namespace Settings; -using namespace Dungeon; - -std::vector ItemPool = {}; -std::vector PendingJunkPool = {}; -std::vector IceTrapModels = {}; -const std::array dungeonRewards = { - KOKIRI_EMERALD, - GORON_RUBY, - ZORA_SAPPHIRE, - FOREST_MEDALLION, - FIRE_MEDALLION, - WATER_MEDALLION, - SPIRIT_MEDALLION, - SHADOW_MEDALLION, - LIGHT_MEDALLION, +std::vector ItemPool = {}; +std::vector PendingJunkPool = {}; +const std::array dungeonRewards = { + RG_KOKIRI_EMERALD, + RG_GORON_RUBY, + RG_ZORA_SAPPHIRE, + RG_FOREST_MEDALLION, + RG_FIRE_MEDALLION, + RG_WATER_MEDALLION, + RG_SPIRIT_MEDALLION, + RG_SHADOW_MEDALLION, + RG_LIGHT_MEDALLION, }; -const std::array JunkPoolItems = { - BOMBS_5, - BOMBS_10, - BOMBS_20, - DEKU_NUTS_5, - DEKU_STICK_1, - DEKU_SEEDS_30, - RECOVERY_HEART, - ARROWS_5, - ARROWS_10, - ARROWS_30, - BLUE_RUPEE, - RED_RUPEE, - PURPLE_RUPEE, - HUGE_RUPEE, - DEKU_NUTS_10, - ICE_TRAP, +const std::array JunkPoolItems = { + RG_BOMBS_5, + RG_BOMBS_10, + RG_BOMBS_20, + RG_DEKU_NUTS_5, + RG_DEKU_STICK_1, + RG_DEKU_SEEDS_30, + RG_RECOVERY_HEART, + RG_ARROWS_5, + RG_ARROWS_10, + RG_ARROWS_30, + RG_BLUE_RUPEE, + RG_RED_RUPEE, + RG_PURPLE_RUPEE, + RG_HUGE_RUPEE, + RG_DEKU_NUTS_10, + RG_ICE_TRAP, }; -const std::array alwaysItems = { - BIGGORON_SWORD, - BOOMERANG, - LENS_OF_TRUTH, - MEGATON_HAMMER, - IRON_BOOTS, - GORON_TUNIC, - ZORA_TUNIC, - HOVER_BOOTS, - MIRROR_SHIELD, - STONE_OF_AGONY, - FIRE_ARROWS, - ICE_ARROWS, - LIGHT_ARROWS, - DINS_FIRE, - FARORES_WIND, - NAYRUS_LOVE, - GREG_RUPEE, - PROGRESSIVE_HOOKSHOT, //2 progressive hookshots - PROGRESSIVE_HOOKSHOT, - DEKU_SHIELD, - HYLIAN_SHIELD, - PROGRESSIVE_STRENGTH, //3 progressive strength upgrades - PROGRESSIVE_STRENGTH, - PROGRESSIVE_STRENGTH, - PROGRESSIVE_SCALE, //2 progressive scales - PROGRESSIVE_SCALE, - PROGRESSIVE_BOW, //3 progressive Bows - PROGRESSIVE_BOW, - PROGRESSIVE_BOW, - PROGRESSIVE_SLINGSHOT, //3 progressive bullet bags - PROGRESSIVE_SLINGSHOT, - PROGRESSIVE_SLINGSHOT, - PROGRESSIVE_BOMB_BAG, //3 progressive bomb bags - PROGRESSIVE_BOMB_BAG, - PROGRESSIVE_BOMB_BAG, - PROGRESSIVE_WALLET, //2 progressive wallets - PROGRESSIVE_WALLET, - PROGRESSIVE_MAGIC_METER, //2 progressive magic meters - PROGRESSIVE_MAGIC_METER, - DOUBLE_DEFENSE, - PROGRESSIVE_STICK_UPGRADE, //2 stick upgrades - PROGRESSIVE_STICK_UPGRADE, - PROGRESSIVE_NUT_UPGRADE, //2 nut upgrades - PROGRESSIVE_NUT_UPGRADE, - RECOVERY_HEART, //6 recovery hearts - RECOVERY_HEART, - RECOVERY_HEART, - RECOVERY_HEART, - RECOVERY_HEART, - RECOVERY_HEART, - BOMBS_5, //2 - BOMBS_5, - BOMBS_10, - BOMBS_20, - ARROWS_5, - ARROWS_10, //5 - ARROWS_10, - ARROWS_10, - TREASURE_GAME_HEART, +const std::array alwaysItems = { + RG_BIGGORON_SWORD, + RG_BOOMERANG, + RG_LENS_OF_TRUTH, + RG_MEGATON_HAMMER, + RG_IRON_BOOTS, + RG_GORON_TUNIC, + RG_ZORA_TUNIC, + RG_HOVER_BOOTS, + RG_MIRROR_SHIELD, + RG_STONE_OF_AGONY, + RG_FIRE_ARROWS, + RG_ICE_ARROWS, + RG_LIGHT_ARROWS, + RG_DINS_FIRE, + RG_FARORES_WIND, + RG_NAYRUS_LOVE, + RG_GREG_RUPEE, + RG_PROGRESSIVE_HOOKSHOT, //2 progressive hookshots + RG_PROGRESSIVE_HOOKSHOT, + RG_DEKU_SHIELD, + RG_HYLIAN_SHIELD, + RG_PROGRESSIVE_STRENGTH, //3 progressive strength upgrades + RG_PROGRESSIVE_STRENGTH, + RG_PROGRESSIVE_STRENGTH, + RG_PROGRESSIVE_SCALE, //2 progressive scales + RG_PROGRESSIVE_SCALE, + RG_PROGRESSIVE_BOW, //3 progressive Bows + RG_PROGRESSIVE_BOW, + RG_PROGRESSIVE_BOW, + RG_PROGRESSIVE_SLINGSHOT, //3 progressive bullet bags + RG_PROGRESSIVE_SLINGSHOT, + RG_PROGRESSIVE_SLINGSHOT, + RG_PROGRESSIVE_BOMB_BAG, //3 progressive bomb bags + RG_PROGRESSIVE_BOMB_BAG, + RG_PROGRESSIVE_BOMB_BAG, + RG_PROGRESSIVE_WALLET, //2 progressive wallets + RG_PROGRESSIVE_WALLET, + RG_PROGRESSIVE_MAGIC_METER, //2 progressive magic meters + RG_PROGRESSIVE_MAGIC_METER, + RG_DOUBLE_DEFENSE, + RG_PROGRESSIVE_STICK_UPGRADE, //2 stick upgrades + RG_PROGRESSIVE_STICK_UPGRADE, + RG_PROGRESSIVE_NUT_UPGRADE, //2 nut upgrades + RG_PROGRESSIVE_NUT_UPGRADE, + RG_RECOVERY_HEART, //6 recovery hearts + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_BOMBS_5, //2 + RG_BOMBS_5, + RG_BOMBS_10, + RG_BOMBS_20, + RG_ARROWS_5, + RG_ARROWS_10, //5 + RG_ARROWS_10, + RG_ARROWS_10, + RG_TREASURE_GAME_HEART, }; -const std::array easyItems = { - BIGGORON_SWORD, - KOKIRI_SWORD, - MASTER_SWORD, - BOOMERANG, - LENS_OF_TRUTH, - MEGATON_HAMMER, - IRON_BOOTS, - GORON_TUNIC, - ZORA_TUNIC, - HOVER_BOOTS, - MIRROR_SHIELD, - FIRE_ARROWS, - LIGHT_ARROWS, - DINS_FIRE, - PROGRESSIVE_HOOKSHOT, - PROGRESSIVE_STRENGTH, - PROGRESSIVE_SCALE, - PROGRESSIVE_WALLET, - PROGRESSIVE_MAGIC_METER, - PROGRESSIVE_STICK_UPGRADE, - PROGRESSIVE_NUT_UPGRADE, - PROGRESSIVE_BOW, - PROGRESSIVE_SLINGSHOT, - PROGRESSIVE_BOMB_BAG, - DOUBLE_DEFENSE, - HEART_CONTAINER, //16 Heart Containers - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - PIECE_OF_HEART, //3 heart pieces - PIECE_OF_HEART, - PIECE_OF_HEART, +const std::array easyItems = { + RG_BIGGORON_SWORD, + RG_KOKIRI_SWORD, + RG_MASTER_SWORD, + RG_BOOMERANG, + RG_LENS_OF_TRUTH, + RG_MEGATON_HAMMER, + RG_IRON_BOOTS, + RG_GORON_TUNIC, + RG_ZORA_TUNIC, + RG_HOVER_BOOTS, + RG_MIRROR_SHIELD, + RG_FIRE_ARROWS, + RG_LIGHT_ARROWS, + RG_DINS_FIRE, + RG_PROGRESSIVE_HOOKSHOT, + RG_PROGRESSIVE_STRENGTH, + RG_PROGRESSIVE_SCALE, + RG_PROGRESSIVE_WALLET, + RG_PROGRESSIVE_MAGIC_METER, + RG_PROGRESSIVE_STICK_UPGRADE, + RG_PROGRESSIVE_NUT_UPGRADE, + RG_PROGRESSIVE_BOW, + RG_PROGRESSIVE_SLINGSHOT, + RG_PROGRESSIVE_BOMB_BAG, + RG_DOUBLE_DEFENSE, + RG_HEART_CONTAINER, //16 Heart Containers + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_PIECE_OF_HEART, //3 heart pieces + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, }; -const std::array normalItems = { - PIECE_OF_HEART, //35 pieces of heart - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - PIECE_OF_HEART, - HEART_CONTAINER, //8 heart containers - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, - HEART_CONTAINER, +const std::array normalItems = { + RG_PIECE_OF_HEART, //35 pieces of heart + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_HEART_CONTAINER, //8 heart containers + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, }; -const std::array DT_Vanilla = { - RECOVERY_HEART, - RECOVERY_HEART, +const std::array DT_Vanilla = { + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, }; -const std::array DT_MQ = { - DEKU_SHIELD, - DEKU_SHIELD, - PURPLE_RUPEE, +const std::array DT_MQ = { + RG_DEKU_SHIELD, + RG_DEKU_SHIELD, + RG_PURPLE_RUPEE, }; -const std::array DC_Vanilla = { - RED_RUPEE, +const std::array DC_Vanilla = { + RG_RED_RUPEE, }; -const std::array DC_MQ = { - HYLIAN_SHIELD, - BLUE_RUPEE, +const std::array DC_MQ = { + RG_HYLIAN_SHIELD, + RG_BLUE_RUPEE, }; -const std::array JB_MQ = { - DEKU_NUTS_5, - DEKU_NUTS_5, - DEKU_NUTS_5, - DEKU_NUTS_5, - RECOVERY_HEART, - DEKU_SHIELD, - DEKU_STICK_1, +const std::array JB_MQ = { + RG_DEKU_NUTS_5, + RG_DEKU_NUTS_5, + RG_DEKU_NUTS_5, + RG_DEKU_NUTS_5, + RG_RECOVERY_HEART, + RG_DEKU_SHIELD, + RG_DEKU_STICK_1, }; -const std::array FoT_Vanilla = { - RECOVERY_HEART, - ARROWS_10, - ARROWS_30, +const std::array FoT_Vanilla = { + RG_RECOVERY_HEART, + RG_ARROWS_10, + RG_ARROWS_30, }; -const std::array FoT_MQ = { - ARROWS_5, +const std::array FoT_MQ = { + RG_ARROWS_5, }; -const std::array FiT_Vanilla = { - HUGE_RUPEE, +const std::array FiT_Vanilla = { + RG_HUGE_RUPEE, }; -const std::array FiT_MQ = { - BOMBS_20, - HYLIAN_SHIELD, +const std::array FiT_MQ = { + RG_BOMBS_20, + RG_HYLIAN_SHIELD, }; -const std::array SpT_Vanilla = { - DEKU_SHIELD, - DEKU_SHIELD, - RECOVERY_HEART, - BOMBS_20, +const std::array SpT_Vanilla = { + RG_DEKU_SHIELD, + RG_DEKU_SHIELD, + RG_RECOVERY_HEART, + RG_BOMBS_20, }; -const std::array SpT_MQ = { - PURPLE_RUPEE, - PURPLE_RUPEE, - ARROWS_30, +const std::array SpT_MQ = { + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_ARROWS_30, }; -const std::array ShT_Vanilla = { - ARROWS_30, +const std::array ShT_Vanilla = { + RG_ARROWS_30, }; -const std::array ShT_MQ = { - ARROWS_5, - ARROWS_5, - RED_RUPEE, +const std::array ShT_MQ = { + RG_ARROWS_5, + RG_ARROWS_5, + RG_RED_RUPEE, }; -const std::array BW_Vanilla = { - RECOVERY_HEART, - BOMBS_10, - HUGE_RUPEE, - DEKU_NUTS_5, - DEKU_NUTS_10, - DEKU_SHIELD, - HYLIAN_SHIELD, +const std::array BW_Vanilla = { + RG_RECOVERY_HEART, + RG_BOMBS_10, + RG_HUGE_RUPEE, + RG_DEKU_NUTS_5, + RG_DEKU_NUTS_10, + RG_DEKU_SHIELD, + RG_HYLIAN_SHIELD, }; -const std::array GTG_Vanilla = { - ARROWS_30, - ARROWS_30, - ARROWS_30, - HUGE_RUPEE, +const std::array GTG_Vanilla = { + RG_ARROWS_30, + RG_ARROWS_30, + RG_ARROWS_30, + RG_HUGE_RUPEE, }; -const std::array GTG_MQ = { - TREASURE_GAME_GREEN_RUPEE, - TREASURE_GAME_GREEN_RUPEE, - ARROWS_10, - GREEN_RUPEE, - PURPLE_RUPEE, +const std::array GTG_MQ = { + RG_TREASURE_GAME_GREEN_RUPEE, + RG_TREASURE_GAME_GREEN_RUPEE, + RG_ARROWS_10, + RG_GREEN_RUPEE, + RG_PURPLE_RUPEE, }; -const std::array GC_Vanilla = { - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - ARROWS_30, +const std::array GC_Vanilla = { + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_ARROWS_30, }; -const std::array GC_MQ = { - ARROWS_10, - ARROWS_10, - BOMBS_5, - RED_RUPEE, - RECOVERY_HEART, +const std::array GC_MQ = { + RG_ARROWS_10, + RG_ARROWS_10, + RG_BOMBS_5, + RG_RED_RUPEE, + RG_RECOVERY_HEART, }; -const std::array normalBottles = { - EMPTY_BOTTLE, - BOTTLE_WITH_MILK, - BOTTLE_WITH_RED_POTION, - BOTTLE_WITH_GREEN_POTION, - BOTTLE_WITH_BLUE_POTION, - BOTTLE_WITH_FAIRY, - BOTTLE_WITH_FISH, - BOTTLE_WITH_BUGS, - BOTTLE_WITH_POE, - BOTTLE_WITH_BIG_POE, - BOTTLE_WITH_BLUE_FIRE, +const std::array normalBottles = { + RG_EMPTY_BOTTLE, + RG_BOTTLE_WITH_MILK, + RG_BOTTLE_WITH_RED_POTION, + RG_BOTTLE_WITH_GREEN_POTION, + RG_BOTTLE_WITH_BLUE_POTION, + RG_BOTTLE_WITH_FAIRY, + RG_BOTTLE_WITH_FISH, + RG_BOTTLE_WITH_BUGS, + RG_BOTTLE_WITH_POE, + RG_BOTTLE_WITH_BIG_POE, + RG_BOTTLE_WITH_BLUE_FIRE, }; -const std::array normalRupees = { - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - HUGE_RUPEE, - HUGE_RUPEE, - HUGE_RUPEE, +const std::array normalRupees = { + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_HUGE_RUPEE, + RG_HUGE_RUPEE, + RG_HUGE_RUPEE, }; -const std::array shopsanityRupees = { - BLUE_RUPEE, - BLUE_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - RED_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - PURPLE_RUPEE, - HUGE_RUPEE, - HUGE_RUPEE, - HUGE_RUPEE, - HUGE_RUPEE, - HUGE_RUPEE, - PROGRESSIVE_WALLET, +const std::array shopsanityRupees = { + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_RED_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_HUGE_RUPEE, + RG_HUGE_RUPEE, + RG_HUGE_RUPEE, + RG_HUGE_RUPEE, + RG_HUGE_RUPEE, + RG_HUGE_RUPEE, }; -const std::array dekuScrubItems = { - DEKU_NUTS_5, - DEKU_NUTS_5, - DEKU_NUTS_5, - DEKU_NUTS_5, - DEKU_NUTS_5, - DEKU_STICK_1, - BOMBS_5, - BOMBS_5, - BOMBS_5, - BOMBS_5, - BOMBS_5, - RECOVERY_HEART, - RECOVERY_HEART, - RECOVERY_HEART, - RECOVERY_HEART, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, - BLUE_RUPEE, +const std::array dekuScrubItems = { + RG_DEKU_NUTS_5, + RG_DEKU_NUTS_5, + RG_DEKU_NUTS_5, + RG_DEKU_NUTS_5, + RG_DEKU_NUTS_5, + RG_DEKU_STICK_1, + RG_BOMBS_5, + RG_BOMBS_5, + RG_BOMBS_5, + RG_BOMBS_5, + RG_BOMBS_5, + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, }; -const std::array songList = { - ZELDAS_LULLABY, - EPONAS_SONG, - SUNS_SONG, - SARIAS_SONG, - SONG_OF_TIME, - SONG_OF_STORMS, - MINUET_OF_FOREST, - PRELUDE_OF_LIGHT, - BOLERO_OF_FIRE, - SERENADE_OF_WATER, - NOCTURNE_OF_SHADOW, - REQUIEM_OF_SPIRIT, +const std::array songList = { + RG_ZELDAS_LULLABY, + RG_EPONAS_SONG, + RG_SUNS_SONG, + RG_SARIAS_SONG, + RG_SONG_OF_TIME, + RG_SONG_OF_STORMS, + RG_MINUET_OF_FOREST, + RG_PRELUDE_OF_LIGHT, + RG_BOLERO_OF_FIRE, + RG_SERENADE_OF_WATER, + RG_NOCTURNE_OF_SHADOW, + RG_REQUIEM_OF_SPIRIT, }; -const std::array tradeItems = { - POCKET_EGG, - //POCKET_CUCCO, - COJIRO, - ODD_MUSHROOM, - POACHERS_SAW, - BROKEN_SWORD, - PRESCRIPTION, - EYEBALL_FROG, - EYEDROPS, - CLAIM_CHECK, +const std::array tradeItems = { + RG_POCKET_EGG, + //RG_POCKET_CUCCO, + RG_COJIRO, + RG_ODD_MUSHROOM, + RG_POACHERS_SAW, + RG_BROKEN_SWORD, + RG_PRESCRIPTION, + RG_EYEBALL_FROG, + RG_EYEDROPS, + RG_CLAIM_CHECK, }; -void AddItemToPool(std::vector& pool, uint32_t item, size_t count /*= 1*/) { +void AddItemToPool(std::vector& pool, RandomizerGet item, size_t count /*= 1*/) { pool.insert(pool.end(), count, item); } template -static void AddItemsToPool(std::vector& toPool, const FromPool& fromPool) { +static void AddItemsToPool(std::vector& toPool, const FromPool& fromPool) { AddElementsToPool(toPool, fromPool); } -static void AddItemToMainPool(const uint32_t item, size_t count = 1) { +static void AddItemToMainPool(const RandomizerGet item, size_t count = 1) { ItemPool.insert(ItemPool.end(), count, item); } -static void AddRandomBottle(std::vector& bottlePool) { +static void AddRandomBottle(std::vector& bottlePool) { AddItemToMainPool(RandomElement(bottlePool, true)); } -uint32_t GetJunkItem() { - if (IceTrapValue.Is(ICETRAPS_MAYHEM) || IceTrapValue.Is(ICETRAPS_ONSLAUGHT)) { - return ICE_TRAP; - } else if (IceTrapValue.Is(ICETRAPS_EXTRA)) { +RandomizerGet GetJunkItem() { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_MAYHEM) || ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_ONSLAUGHT)) { + return RG_ICE_TRAP; + } else if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_EXTRA)) { return RandomElement(JunkPoolItems); } //Ice Trap is the last item in JunkPoolItems, so subtract 1 to never hit that index @@ -442,7 +437,7 @@ uint32_t GetJunkItem() { return JunkPoolItems[idx]; } -static uint32_t GetPendingJunkItem() { +static RandomizerGet GetPendingJunkItem() { if (PendingJunkPool.empty()) { return GetJunkItem(); } @@ -451,7 +446,7 @@ static uint32_t GetPendingJunkItem() { } //Replace junk items in the pool with pending junk -static void ReplaceMaxItem(const uint32_t itemToReplace, int max) { +static void ReplaceMaxItem(const RandomizerGet itemToReplace, int max) { int itemCount = 0; for (size_t i = 0; i < ItemPool.size(); i++) { if (ItemPool[i] == itemToReplace) { @@ -463,446 +458,634 @@ static void ReplaceMaxItem(const uint32_t itemToReplace, int max) { } } -void PlaceJunkInExcludedLocation(const uint32_t il) { +void PlaceJunkInExcludedLocation(const RandomizerCheck il) { //place a non-advancement item in this location + auto ctx = Rando::Context::GetInstance(); for (size_t i = 0; i < ItemPool.size(); i++) { - if (!ItemTable(ItemPool[i]).IsAdvancement()) { - PlaceItemInLocation(il, ItemPool[i]); + if (!Rando::StaticData::RetrieveItem(ItemPool[i]).IsAdvancement()) { + ctx->PlaceItemInLocation(il, ItemPool[i]); ItemPool.erase(ItemPool.begin() + i); return; } } - printf("ERROR: No Junk to Place!!!\n"); + SPDLOG_ERROR("ERROR: No Junk to Place!!!"); } -static void PlaceVanillaDekuScrubItems() { - PlaceItemInLocation(ZR_DEKU_SCRUB_GROTTO_REAR, RED_POTION_REFILL, false, true); - PlaceItemInLocation(ZR_DEKU_SCRUB_GROTTO_FRONT, GREEN_POTION_REFILL, false, true); - PlaceItemInLocation(SFM_DEKU_SCRUB_GROTTO_REAR, RED_POTION_REFILL, false, true); - PlaceItemInLocation(SFM_DEKU_SCRUB_GROTTO_FRONT, GREEN_POTION_REFILL, false, true); - PlaceItemInLocation(LH_DEKU_SCRUB_GROTTO_LEFT, DEKU_NUTS_5, false, true); - PlaceItemInLocation(LH_DEKU_SCRUB_GROTTO_RIGHT, BOMBS_5, false, true); - PlaceItemInLocation(LH_DEKU_SCRUB_GROTTO_CENTER, DEKU_SEEDS_30, false, true); - PlaceItemInLocation(GV_DEKU_SCRUB_GROTTO_REAR, RED_POTION_REFILL, false, true); - PlaceItemInLocation(GV_DEKU_SCRUB_GROTTO_FRONT, GREEN_POTION_REFILL, false, true); - PlaceItemInLocation(LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, DEKU_NUTS_5, false, true); - PlaceItemInLocation(LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, DEKU_STICK_1, false, true); - PlaceItemInLocation(LW_DEKU_SCRUB_GROTTO_REAR, DEKU_SEEDS_30, false, true); - PlaceItemInLocation(COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RED_POTION_REFILL, false, true); - PlaceItemInLocation(COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, GREEN_POTION_REFILL, false, true); - PlaceItemInLocation(DMC_DEKU_SCRUB, BOMBS_5, false, true); - PlaceItemInLocation(DMC_DEKU_SCRUB_GROTTO_LEFT, DEKU_NUTS_5, false, true); - PlaceItemInLocation(DMC_DEKU_SCRUB_GROTTO_RIGHT, BOMBS_5, false, true); - PlaceItemInLocation(DMC_DEKU_SCRUB_GROTTO_CENTER, DEKU_SEEDS_30, false, true); - PlaceItemInLocation(GC_DEKU_SCRUB_GROTTO_LEFT, DEKU_NUTS_5, false, true); - PlaceItemInLocation(GC_DEKU_SCRUB_GROTTO_RIGHT, BOMBS_5, false, true); - PlaceItemInLocation(GC_DEKU_SCRUB_GROTTO_CENTER, DEKU_SEEDS_30, false, true); - PlaceItemInLocation(LLR_DEKU_SCRUB_GROTTO_LEFT, DEKU_NUTS_5, false, true); - PlaceItemInLocation(LLR_DEKU_SCRUB_GROTTO_RIGHT, BOMBS_5, false, true); - PlaceItemInLocation(LLR_DEKU_SCRUB_GROTTO_CENTER, DEKU_SEEDS_30, false, true); +static void PlaceVanillaDekuScrubItems(bool junkOneTimeScrubs) { + auto ctx = Rando::Context::GetInstance(); + if (junkOneTimeScrubs){ + ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_DEKU_SCRUB_GROTTO, RG_BLUE_RUPEE, false, true); + } + + ctx->PlaceItemInLocation(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, false, true); + ctx->PlaceItemInLocation(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, false, true); + ctx->PlaceItemInLocation(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, false, true); + ctx->PlaceItemInLocation(RC_GV_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RG_BUY_DEKU_NUTS_5, false, true); + ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_BUY_DEKU_STICK_1, false, true); + ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, false, true); + ctx->PlaceItemInLocation(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB, RG_BUY_BOMBS_535, false, true); + ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, false, true); + ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, false, true); + ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, false, true); + ctx->PlaceItemInLocation(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, false, true); + ctx->PlaceItemInLocation(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, false, true); + ctx->PlaceItemInLocation(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, false, true); + ctx->PlaceItemInLocation(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, false, true); + ctx->PlaceItemInLocation(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, false, true); + ctx->PlaceItemInLocation(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, false, true); //Dungeon Scrubs - if (DekuTree.IsMQ()) { - PlaceItemInLocation(DEKU_TREE_MQ_DEKU_SCRUB, DEKU_SHIELD, false, true); + if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) { + ctx->PlaceItemInLocation(RC_DEKU_TREE_MQ_DEKU_SCRUB, RG_BUY_DEKU_SHIELD, false, true); } - if (DodongosCavern.IsMQ()) { - PlaceItemInLocation(DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, DEKU_STICK_1, false, true); - PlaceItemInLocation(DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, DEKU_SEEDS_30, false, true); - PlaceItemInLocation(DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, DEKU_SHIELD, false, true); - PlaceItemInLocation(DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RED_POTION_REFILL, false, true); + if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) { + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_BUY_DEKU_STICK_1, false, true); + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_BUY_DEKU_SEEDS_30, false, true); + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_BUY_DEKU_SHIELD, false, true); + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_RED_POTION_REFILL, + false, true); } else { - PlaceItemInLocation(DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, DEKU_NUTS_5, false, true); - PlaceItemInLocation(DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, DEKU_STICK_1, false, true); - PlaceItemInLocation(DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, DEKU_SEEDS_30, false, true); - PlaceItemInLocation(DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, DEKU_SHIELD, false, true); + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_BUY_DEKU_NUTS_5, false, true); + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_BUY_DEKU_STICK_1, false, true); + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_BUY_DEKU_SEEDS_30, false, true); + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_BUY_DEKU_SHIELD, false, true); } - if (JabuJabusBelly.IsVanilla()) { - PlaceItemInLocation(JABU_JABUS_BELLY_DEKU_SCRUB, DEKU_NUTS_5); + if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsVanilla()) { + ctx->PlaceItemInLocation(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RG_BUY_DEKU_NUTS_5, false, true); } - if (GanonsCastle.IsMQ()) { - PlaceItemInLocation(GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, GREEN_POTION_REFILL, false, true); - PlaceItemInLocation(GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, BOMBS_5, false, true); - PlaceItemInLocation(GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, ARROWS_30, false, true); - PlaceItemInLocation(GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RED_POTION_REFILL, false, true); - PlaceItemInLocation(GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, DEKU_NUTS_5, false, true); + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) { + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_GREEN_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_BUY_ARROWS_30, false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_RED_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_BUY_DEKU_NUTS_5, false, true); } else { - PlaceItemInLocation(GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, BOMBS_5, false, true); - PlaceItemInLocation(GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, DEKU_SEEDS_30, false, true); - PlaceItemInLocation(GANONS_CASTLE_DEKU_SCRUB_RIGHT, RED_POTION_REFILL, false, true); - PlaceItemInLocation(GANONS_CASTLE_DEKU_SCRUB_LEFT, GREEN_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_DEKU_SEEDS_30, false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_RED_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_GREEN_POTION_REFILL, false, true); } } static void PlaceVanillaMapsAndCompasses() { - for (auto dungeon : dungeonList) { + auto ctx = Rando::Context::GetInstance(); + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { dungeon->PlaceVanillaMap(); dungeon->PlaceVanillaCompass(); } } static void PlaceVanillaSmallKeys() { - for (auto dungeon : dungeonList) { + auto ctx = Rando::Context::GetInstance(); + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { dungeon->PlaceVanillaSmallKeys(); } } static void PlaceVanillaBossKeys() { - for (auto dungeon : dungeonList) { + auto ctx = Rando::Context::GetInstance(); + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { dungeon->PlaceVanillaBossKey(); } } +// TODO: This feels like it could be moved to Dungeons class and probably shorten +// a few function call chains. Needs investigation. + +static void PlaceVanillaBeehiveRupees() { + auto ctx = Rando::Context::GetInstance(); + ctx->PlaceItemInLocation(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RG_BLUE_RUPEE, false, true); + + ctx->PlaceItemInLocation(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_SFM_STORMS_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LLR_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMT_COW_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_GC_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_DMC_HAMMER_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_STORMS_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_LH_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_COLOSSUS_GROTTO_BEEHIVE, RG_RED_RUPEE, false, true); +} static void PlaceVanillaCowMilk() { - PlaceItemInLocation(KF_LINKS_HOUSE_COW, MILK, false, true); - PlaceItemInLocation(HF_COW_GROTTO_COW, MILK, false, true); - PlaceItemInLocation(GV_COW, MILK, false, true); - PlaceItemInLocation(KAK_IMPAS_HOUSE_COW, MILK, false, true); - PlaceItemInLocation(DMT_COW_GROTTO_COW, MILK, false, true); - PlaceItemInLocation(LLR_STABLES_LEFT_COW, MILK, false, true); - PlaceItemInLocation(LLR_STABLES_RIGHT_COW, MILK, false, true); - PlaceItemInLocation(LLR_TOWER_LEFT_COW, MILK, false, true); - PlaceItemInLocation(LLR_TOWER_RIGHT_COW, MILK, false, true); - - if (JabuJabusBelly.IsMQ()) { - PlaceItemInLocation(JABU_JABUS_BELLY_MQ_COW, MILK, false, true); + auto ctx = Rando::Context::GetInstance(); + ctx->PlaceItemInLocation(RC_KF_LINKS_HOUSE_COW, RG_MILK, false, true); + ctx->PlaceItemInLocation(RC_HF_COW_GROTTO_COW, RG_MILK, false, true); + ctx->PlaceItemInLocation(RC_GV_COW, RG_MILK, false, true); + ctx->PlaceItemInLocation(RC_KAK_IMPAS_HOUSE_COW, RG_MILK, false, true); + ctx->PlaceItemInLocation(RC_DMT_COW_GROTTO_COW, RG_MILK, false, true); + ctx->PlaceItemInLocation(RC_LLR_STABLES_LEFT_COW, RG_MILK, false, true); + ctx->PlaceItemInLocation(RC_LLR_STABLES_RIGHT_COW, RG_MILK, false, true); + ctx->PlaceItemInLocation(RC_LLR_TOWER_LEFT_COW, RG_MILK, false, true); + ctx->PlaceItemInLocation(RC_LLR_TOWER_RIGHT_COW, RG_MILK, false, true); + + if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsMQ()) { + ctx->PlaceItemInLocation(RC_JABU_JABUS_BELLY_MQ_COW, RG_MILK, false, true); + } +} + +static void PlaceVanillaOverworldFish() { + auto ctx = Rando::Context::GetInstance(); + for (auto rc : Rando::StaticData::GetOverworldFishLocations()) { + ctx->PlaceItemInLocation(rc, RG_FISH, false, true); } } static void SetScarceItemPool() { - ReplaceMaxItem(PROGRESSIVE_BOMBCHUS, 3); - ReplaceMaxItem(BOMBCHU_5, 1); - ReplaceMaxItem(BOMBCHU_10, 2); - ReplaceMaxItem(BOMBCHU_20, 0); - ReplaceMaxItem(PROGRESSIVE_MAGIC_METER, 1); - ReplaceMaxItem(DOUBLE_DEFENSE, 0); - ReplaceMaxItem(PROGRESSIVE_STICK_UPGRADE, 1); - ReplaceMaxItem(PROGRESSIVE_NUT_UPGRADE, 1); - ReplaceMaxItem(PROGRESSIVE_BOW, 2); - ReplaceMaxItem(PROGRESSIVE_SLINGSHOT, 2); - ReplaceMaxItem(PROGRESSIVE_BOMB_BAG, 2); - ReplaceMaxItem(HEART_CONTAINER, 0); + ReplaceMaxItem(RG_PROGRESSIVE_BOMBCHUS, 3); + ReplaceMaxItem(RG_BOMBCHU_5, 1); + ReplaceMaxItem(RG_BOMBCHU_10, 2); + ReplaceMaxItem(RG_BOMBCHU_20, 0); + ReplaceMaxItem(RG_PROGRESSIVE_MAGIC_METER, 1); + ReplaceMaxItem(RG_DOUBLE_DEFENSE, 0); + ReplaceMaxItem(RG_PROGRESSIVE_STICK_UPGRADE, 1); + ReplaceMaxItem(RG_PROGRESSIVE_NUT_UPGRADE, 1); + ReplaceMaxItem(RG_PROGRESSIVE_BOW, 2); + ReplaceMaxItem(RG_PROGRESSIVE_SLINGSHOT, 2); + ReplaceMaxItem(RG_PROGRESSIVE_BOMB_BAG, 2); + ReplaceMaxItem(RG_HEART_CONTAINER, 0); } static void SetMinimalItemPool() { - ReplaceMaxItem(PROGRESSIVE_BOMBCHUS, 1); - ReplaceMaxItem(BOMBCHU_5, 1); - ReplaceMaxItem(BOMBCHU_10, 0); - ReplaceMaxItem(BOMBCHU_20, 0); - ReplaceMaxItem(NAYRUS_LOVE, 0); - ReplaceMaxItem(PROGRESSIVE_MAGIC_METER, 1); - ReplaceMaxItem(DOUBLE_DEFENSE, 0); - ReplaceMaxItem(PROGRESSIVE_STICK_UPGRADE, 0); - ReplaceMaxItem(PROGRESSIVE_NUT_UPGRADE, 0); - ReplaceMaxItem(PROGRESSIVE_BOW, 1); - ReplaceMaxItem(PROGRESSIVE_SLINGSHOT, 1); - ReplaceMaxItem(PROGRESSIVE_BOMB_BAG, 1); - ReplaceMaxItem(PIECE_OF_HEART, 0); + auto ctx = Rando::Context::GetInstance(); + ReplaceMaxItem(RG_PROGRESSIVE_BOMBCHUS, 1); + ReplaceMaxItem(RG_BOMBCHU_5, 1); + ReplaceMaxItem(RG_BOMBCHU_10, 0); + ReplaceMaxItem(RG_BOMBCHU_20, 0); + ReplaceMaxItem(RG_NAYRUS_LOVE, 0); + ReplaceMaxItem(RG_PROGRESSIVE_MAGIC_METER, 1); + ReplaceMaxItem(RG_DOUBLE_DEFENSE, 0); + ReplaceMaxItem(RG_PROGRESSIVE_STICK_UPGRADE, 0); + ReplaceMaxItem(RG_PROGRESSIVE_NUT_UPGRADE, 0); + ReplaceMaxItem(RG_PROGRESSIVE_BOW, 1); + ReplaceMaxItem(RG_PROGRESSIVE_SLINGSHOT, 1); + ReplaceMaxItem(RG_PROGRESSIVE_BOMB_BAG, 1); + ReplaceMaxItem(RG_PIECE_OF_HEART, 0); // Need an extra heart container when starting with 1 heart to be able to reach 3 hearts - ReplaceMaxItem(HEART_CONTAINER, (StartingHearts.Value() == 18)? 1 : 0); + ReplaceMaxItem(RG_HEART_CONTAINER, (ctx->GetOption(RSK_STARTING_HEARTS).Value() == 18)? 1 : 0); } void GenerateItemPool() { - + //RANDOTODO proper removal of items not in pool or logically relevant instead of dummy checks. + auto ctx = Rando::Context::GetInstance(); ItemPool.clear(); PendingJunkPool.clear(); //Initialize ice trap models to always major items - IceTrapModels = { - GI_SHIELD_MIRROR, - GI_BOOMERANG, - GI_LENS, - GI_HAMMER, - GI_BOOTS_IRON, - GI_BOOTS_HOVER, - GI_STONE_OF_AGONY, - GI_DINS_FIRE, - GI_FARORES_WIND, - GI_NAYRUS_LOVE, - GI_ARROW_FIRE, - GI_ARROW_ICE, - GI_ARROW_LIGHT, - 0xB8, //Double defense - GI_CLAIM_CHECK, - 0x80, //Progressive hookshot - 0x81, //Progressive strength - 0x82, //Progressive bomb bag - 0x83, //Progressive bow - 0x84, //Progressive slingshot - 0x85, //Progressive wallet - 0x86, //Progressive scale - 0x8A, //Progressive magic + ctx->possibleIceTrapModels = { + RG_MIRROR_SHIELD, + RG_BOOMERANG, + RG_LENS_OF_TRUTH, + RG_MEGATON_HAMMER, + RG_IRON_BOOTS, + RG_HOVER_BOOTS, + RG_STONE_OF_AGONY, + RG_DINS_FIRE, + RG_FARORES_WIND, + RG_NAYRUS_LOVE, + RG_FIRE_ARROWS, + RG_ICE_ARROWS, + RG_LIGHT_ARROWS, + RG_DOUBLE_DEFENSE, //Double defense + RG_CLAIM_CHECK, + RG_PROGRESSIVE_HOOKSHOT, //Progressive hookshot + RG_PROGRESSIVE_STRENGTH, //Progressive strength + RG_PROGRESSIVE_BOMB_BAG, //Progressive bomb bag + RG_PROGRESSIVE_BOW, //Progressive bow + RG_PROGRESSIVE_SLINGSHOT, //Progressive slingshot + RG_PROGRESSIVE_WALLET, //Progressive wallet + RG_PROGRESSIVE_SCALE, //Progressive scale + RG_PROGRESSIVE_MAGIC_METER, //Progressive magic }; //Check song shuffle and dungeon reward shuffle just for ice traps - if (ShuffleSongs.Is(SONGSHUFFLE_ANYWHERE)) { + if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_ANYWHERE)) { //Push item ids for songs - IceTrapModels.push_back(0xC1); - IceTrapModels.push_back(0xC2); - IceTrapModels.push_back(0xC3); - IceTrapModels.push_back(0xC4); - IceTrapModels.push_back(0xC5); - IceTrapModels.push_back(0xC6); - IceTrapModels.push_back(0xBB); - IceTrapModels.push_back(0xBC); - IceTrapModels.push_back(0xBD); - IceTrapModels.push_back(0xBE); - IceTrapModels.push_back(0xBF); - IceTrapModels.push_back(0xC0); - } - if (ShuffleRewards.Is(REWARDSHUFFLE_ANYWHERE)) { + ctx->possibleIceTrapModels.push_back(RG_ZELDAS_LULLABY); + ctx->possibleIceTrapModels.push_back(RG_EPONAS_SONG); + ctx->possibleIceTrapModels.push_back(RG_SARIAS_SONG); + ctx->possibleIceTrapModels.push_back(RG_SUNS_SONG); + ctx->possibleIceTrapModels.push_back(RG_SONG_OF_TIME); + ctx->possibleIceTrapModels.push_back(RG_SONG_OF_STORMS); + ctx->possibleIceTrapModels.push_back(RG_MINUET_OF_FOREST); + ctx->possibleIceTrapModels.push_back(RG_BOLERO_OF_FIRE); + ctx->possibleIceTrapModels.push_back(RG_SERENADE_OF_WATER); + ctx->possibleIceTrapModels.push_back(RG_REQUIEM_OF_SPIRIT); + ctx->possibleIceTrapModels.push_back(RG_NOCTURNE_OF_SHADOW); + ctx->possibleIceTrapModels.push_back(RG_PRELUDE_OF_LIGHT); + } + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_ANYWHERE)) { //Push item ids for dungeon rewards - IceTrapModels.push_back(0xCB); - IceTrapModels.push_back(0xCC); - IceTrapModels.push_back(0xCD); - IceTrapModels.push_back(0xCE); - IceTrapModels.push_back(0xCF); - IceTrapModels.push_back(0xD0); - IceTrapModels.push_back(0xD1); - IceTrapModels.push_back(0xD2); - IceTrapModels.push_back(0xD3); - } - - if (TriforceHunt.Is(TRIFORCE_HUNT_ON)) { - IceTrapModels.push_back(0xDF); - AddItemToMainPool(TRIFORCE_PIECE, Settings::TriforceHuntTotal.Value()); - PlaceItemInLocation(TRIFORCE_COMPLETED, TRIFORCE); // Win condition - PlaceItemInLocation(GANON, GetJunkItem(), false, true); + ctx->possibleIceTrapModels.push_back(RG_KOKIRI_EMERALD); + ctx->possibleIceTrapModels.push_back(RG_GORON_RUBY); + ctx->possibleIceTrapModels.push_back(RG_ZORA_SAPPHIRE); + ctx->possibleIceTrapModels.push_back(RG_FOREST_MEDALLION); + ctx->possibleIceTrapModels.push_back(RG_FIRE_MEDALLION); + ctx->possibleIceTrapModels.push_back(RG_WATER_MEDALLION); + ctx->possibleIceTrapModels.push_back(RG_SPIRIT_MEDALLION); + ctx->possibleIceTrapModels.push_back(RG_SHADOW_MEDALLION); + ctx->possibleIceTrapModels.push_back(RG_LIGHT_MEDALLION); + } + + if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { + ctx->possibleIceTrapModels.push_back(RG_TRIFORCE_PIECE); + AddItemToMainPool(RG_TRIFORCE_PIECE, (ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Value() + 1)); + ctx->PlaceItemInLocation(RC_TRIFORCE_COMPLETED, RG_TRIFORCE); // Win condition + ctx->PlaceItemInLocation(RC_GANON, GetJunkItem(), false, true); } else { - PlaceItemInLocation(GANON, TRIFORCE); // Win condition + ctx->PlaceItemInLocation(RC_GANON, RG_TRIFORCE); // Win condition } //Fixed item locations - PlaceItemInLocation(HC_ZELDAS_LETTER, ZELDAS_LETTER); - PlaceItemInLocation(MARKET_BOMBCHU_BOWLING_BOMBCHUS, BOMBCHU_DROP); + ctx->PlaceItemInLocation(RC_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER); - if (ShuffleKokiriSword) { - AddItemToMainPool(KOKIRI_SWORD); - IceTrapModels.push_back(GI_SWORD_KOKIRI); + if (ctx->GetOption(RSK_SHUFFLE_KOKIRI_SWORD)) { + AddItemToMainPool(RG_KOKIRI_SWORD); + ctx->possibleIceTrapModels.push_back(RG_KOKIRI_SWORD); } else { - PlaceItemInLocation(KF_KOKIRI_SWORD_CHEST, KOKIRI_SWORD, false, true); + if (!ctx->GetOption(RSK_STARTING_KOKIRI_SWORD)) { + ctx->PlaceItemInLocation(RC_KF_KOKIRI_SWORD_CHEST, RG_KOKIRI_SWORD, false, true); + } } - if (ShuffleMasterSword) { - AddItemToMainPool(MASTER_SWORD); - IceTrapModels.push_back(0xE0); //Master Sword without the GI enum + if (ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { + AddItemToMainPool(RG_MASTER_SWORD); + ctx->possibleIceTrapModels.push_back(RG_MASTER_SWORD); //Master Sword without the GI enum } else { - PlaceItemInLocation(TOT_MASTER_SWORD, MASTER_SWORD, false, true); + if (!ctx->GetOption(RSK_STARTING_MASTER_SWORD)) { + ctx->PlaceItemInLocation(RC_TOT_MASTER_SWORD, RG_MASTER_SWORD, false, true); + } } - if (ShuffleWeirdEgg) { - AddItemToMainPool(WEIRD_EGG); - IceTrapModels.push_back(GI_WEIRD_EGG); + if (ctx->GetOption(RSK_SHUFFLE_WEIRD_EGG)) { + AddItemToMainPool(RG_WEIRD_EGG); + ctx->possibleIceTrapModels.push_back(RG_WEIRD_EGG); } else { - PlaceItemInLocation(HC_MALON_EGG, WEIRD_EGG, false, true); + ctx->PlaceItemInLocation(RC_HC_MALON_EGG, RG_WEIRD_EGG, false, true); } - if (ShuffleOcarinas) { - AddItemToMainPool(PROGRESSIVE_OCARINA, 2); - if (ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) { - AddItemToPool(PendingJunkPool, PROGRESSIVE_OCARINA); + if (ctx->GetOption(RSK_SHUFFLE_OCARINA)) { + AddItemToMainPool(RG_PROGRESSIVE_OCARINA, 2); + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + AddItemToPool(PendingJunkPool, RG_PROGRESSIVE_OCARINA); } - IceTrapModels.push_back(0x8B); //Progressive ocarina + ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_OCARINA); //Progressive ocarina + } else { + if (ctx->GetOption(RSK_STARTING_OCARINA).Is(RO_STARTING_OCARINA_OFF)) { + ctx->PlaceItemInLocation(RC_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, false, true); + ctx->PlaceItemInLocation(RC_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, false, true); + } else { + if (ctx->GetOption(RSK_STARTING_OCARINA).IsNot(RO_STARTING_OCARINA_TIME)) { + ctx->PlaceItemInLocation(RC_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, false, true); + } + } + } + + if (ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS)) { + AddItemToMainPool(RG_OCARINA_A_BUTTON); + AddItemToMainPool(RG_OCARINA_C_UP_BUTTON); + AddItemToMainPool(RG_OCARINA_C_DOWN_BUTTON); + AddItemToMainPool(RG_OCARINA_C_LEFT_BUTTON); + AddItemToMainPool(RG_OCARINA_C_RIGHT_BUTTON); + + //TODO: Re-add when custom models work with ice traps + ctx->possibleIceTrapModels.push_back(RG_OCARINA_A_BUTTON); + ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_UP_BUTTON); + ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_DOWN_BUTTON); + ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_LEFT_BUTTON); + ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_RIGHT_BUTTON); + } + + if (ctx->GetOption(RSK_SKELETON_KEY)) { + AddItemToMainPool(RG_SKELETON_KEY); + } + + if (ctx->GetOption(RSK_SHUFFLE_SWIM)) { + AddItemToMainPool(RG_PROGRESSIVE_SCALE); + } + + if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { + //32 total beehive locations + AddItemToMainPool(RG_RED_RUPEE, 23); + AddItemToMainPool(RG_BLUE_RUPEE, 9); } else { - PlaceItemInLocation(LW_GIFT_FROM_SARIA, PROGRESSIVE_OCARINA, false, true); - PlaceItemInLocation(HF_OCARINA_OF_TIME_ITEM, PROGRESSIVE_OCARINA, false, true); + PlaceVanillaBeehiveRupees(); } - if (ShuffleCows) { + if (ctx->GetOption(RSK_SHUFFLE_COWS)) { //9 total cow locations for (uint8_t i = 0; i < 9; i++) { AddItemToMainPool(GetJunkItem()); } //extra location for Jabu MQ - if (JabuJabusBelly.IsMQ()) { + if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsMQ()) { AddItemToMainPool(GetJunkItem()); } } else { PlaceVanillaCowMilk(); } - if (ShuffleMagicBeans) { - AddItemToMainPool(MAGIC_BEAN_PACK); - if (ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) { - AddItemToPool(PendingJunkPool, MAGIC_BEAN_PACK); + auto fsMode = ctx->GetOption(RSK_FISHSANITY); + if (fsMode.IsNot(RO_FISHSANITY_OFF)) { + if (fsMode.Is(RO_FISHSANITY_POND) || fsMode.Is(RO_FISHSANITY_BOTH)) { + // 17 max child pond fish + uint8_t pondCt = ctx->GetOption(RSK_FISHSANITY_POND_COUNT).GetSelectedOptionIndex(); + for (uint8_t i = 0; i < pondCt; i++) { + AddItemToMainPool(GetJunkItem()); + } + + if (ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)) { + // 16 max adult pond fish, have to reduce to 16 if every fish is enabled + if (pondCt > 16) + pondCt = 16; + for (uint8_t i = 0; i < pondCt; i++) { + AddItemToMainPool(GetJunkItem()); + } + } + } + // 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::GetOverworldFishLocations().size(); i++) + AddItemToMainPool(GetJunkItem()); + } else { + PlaceVanillaOverworldFish(); + } + + if (fsMode.Is(RO_FISHSANITY_HYRULE_LOACH)) { + AddItemToMainPool(RG_PURPLE_RUPEE); + } else { + ctx->PlaceItemInLocation(RC_LH_HYRULE_LOACH, RG_PURPLE_RUPEE, false, true); + } + } else { + PlaceVanillaOverworldFish(); + } + + if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE)) { + AddItemToMainPool(RG_FISHING_POLE); + ctx->possibleIceTrapModels.push_back(RG_FISHING_POLE); + } + + if (ctx->GetOption(RSK_INFINITE_UPGRADES).Is(RO_INF_UPGRADES_PROGRESSIVE)) { + AddItemToMainPool(RG_PROGRESSIVE_BOMB_BAG); + AddItemToMainPool(RG_PROGRESSIVE_BOW); + AddItemToMainPool(RG_PROGRESSIVE_NUT_UPGRADE); + AddItemToMainPool(RG_PROGRESSIVE_SLINGSHOT); + AddItemToMainPool(RG_PROGRESSIVE_STICK_UPGRADE); + AddItemToMainPool(RG_PROGRESSIVE_MAGIC_METER); + AddItemToMainPool(RG_PROGRESSIVE_WALLET); + } + + if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) { + AddItemToMainPool(RG_MAGIC_BEAN_PACK); + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + AddItemToPool(PendingJunkPool, RG_MAGIC_BEAN_PACK); } - IceTrapModels.push_back(0xC9); //Magic bean pack + ctx->possibleIceTrapModels.push_back(RG_MAGIC_BEAN_PACK); //Magic bean pack } else { - PlaceItemInLocation(ZR_MAGIC_BEAN_SALESMAN, MAGIC_BEAN, false, true); + ctx->PlaceItemInLocation(RC_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, false, true); } - if (ShuffleMerchants.IsNot(SHUFFLEMERCHANTS_OFF)) { - if (!ProgressiveGoronSword) { - AddItemToMainPool(GIANTS_KNIFE); + if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) { + if (/*!ProgressiveGoronSword TODO: Implement Progressive Goron Sword*/true) { + AddItemToMainPool(RG_GIANTS_KNIFE); } - if (BombchusInLogic) { - AddItemToMainPool(PROGRESSIVE_BOMBCHUS); + if (ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC)) { + AddItemToMainPool(RG_PROGRESSIVE_BOMBCHUS); } else { - AddItemToMainPool(BOMBCHU_10); + AddItemToMainPool(RG_BOMBCHU_10); } } else { - PlaceItemInLocation(KAK_GRANNYS_SHOP, BLUE_POTION_REFILL, false, true); - PlaceItemInLocation(GC_MEDIGORON, GIANTS_KNIFE, false, true); - PlaceItemInLocation(WASTELAND_BOMBCHU_SALESMAN, BOMBCHU_10, false, true); + ctx->PlaceItemInLocation(RC_KAK_GRANNYS_SHOP, RG_BLUE_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_GC_MEDIGORON, RG_GIANTS_KNIFE, false, true); + ctx->PlaceItemInLocation(RC_WASTELAND_BOMBCHU_SALESMAN, RG_BOMBCHU_10, false, true); } - if (ShuffleFrogSongRupees) { - AddItemToMainPool(PURPLE_RUPEE, 5); - } else { - PlaceItemInLocation(ZR_FROGS_ZELDAS_LULLABY, PURPLE_RUPEE, false, true); - PlaceItemInLocation(ZR_FROGS_EPONAS_SONG, PURPLE_RUPEE, false, true); - PlaceItemInLocation(ZR_FROGS_SARIAS_SONG, PURPLE_RUPEE, false, true); - PlaceItemInLocation(ZR_FROGS_SUNS_SONG, PURPLE_RUPEE, false, true); - PlaceItemInLocation(ZR_FROGS_SONG_OF_TIME, PURPLE_RUPEE, false, true); - } - - if (ShuffleAdultTradeQuest) { - AddItemToMainPool(POCKET_EGG); - AddItemToMainPool(COJIRO); - AddItemToMainPool(ODD_MUSHROOM); - AddItemToMainPool(ODD_POTION); - AddItemToMainPool(POACHERS_SAW); - AddItemToMainPool(BROKEN_SWORD); - AddItemToMainPool(PRESCRIPTION); - AddItemToMainPool(EYEBALL_FROG); - AddItemToMainPool(EYEDROPS); + if (ctx->GetOption(RSK_SHUFFLE_FROG_SONG_RUPEES)) { + AddItemToMainPool(RG_PURPLE_RUPEE, 5); } else { - PlaceItemInLocation(KAK_TRADE_POCKET_CUCCO, COJIRO, false, true); - PlaceItemInLocation(LW_TRADE_COJIRO, ODD_MUSHROOM, false, true); - PlaceItemInLocation(KAK_TRADE_ODD_MUSHROOM, ODD_POTION, false, true); - PlaceItemInLocation(LW_TRADE_ODD_POTION, POACHERS_SAW, false, true); - PlaceItemInLocation(GV_TRADE_SAW, BROKEN_SWORD, false, true); - PlaceItemInLocation(DMT_TRADE_BROKEN_SWORD, PRESCRIPTION, false, true); - PlaceItemInLocation(ZD_TRADE_PRESCRIPTION, EYEBALL_FROG, false, true); - PlaceItemInLocation(LH_TRADE_FROG, EYEDROPS, false, true); - PlaceItemInLocation(DMT_TRADE_EYEDROPS, CLAIM_CHECK, false, true); - } - AddItemToMainPool(CLAIM_CHECK); - - if (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_SINGLE_KEYS)) { - AddItemToMainPool(TREASURE_GAME_SMALL_KEY, 6); // 6 individual keys - } else if (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_PACK)) { - AddItemToMainPool(TREASURE_GAME_SMALL_KEY); // 1 key which will behave as a pack of 6 + ctx->PlaceItemInLocation(RC_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_FROGS_SUNS_SONG, RG_PURPLE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_FROGS_SONG_OF_TIME, RG_PURPLE_RUPEE, false, true); + } + + if (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE)) { + AddItemToMainPool(RG_POCKET_EGG); + AddItemToMainPool(RG_COJIRO); + AddItemToMainPool(RG_ODD_MUSHROOM); + AddItemToMainPool(RG_ODD_POTION); + AddItemToMainPool(RG_POACHERS_SAW); + AddItemToMainPool(RG_BROKEN_SWORD); + AddItemToMainPool(RG_PRESCRIPTION); + AddItemToMainPool(RG_EYEBALL_FROG); + AddItemToMainPool(RG_EYEDROPS); + } + AddItemToMainPool(RG_CLAIM_CHECK); + + if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS)) { + AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY, 6); // 6 individual keys + } else if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK)) { + AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY); // 1 key which will behave as a pack of 6 } else { - PlaceItemInLocation(MARKET_TREASURE_CHEST_GAME_ITEM_1, TREASURE_GAME_SMALL_KEY, false, true); - PlaceItemInLocation(MARKET_TREASURE_CHEST_GAME_ITEM_2, TREASURE_GAME_SMALL_KEY, false, true); - PlaceItemInLocation(MARKET_TREASURE_CHEST_GAME_ITEM_3, TREASURE_GAME_SMALL_KEY, false, true); - PlaceItemInLocation(MARKET_TREASURE_CHEST_GAME_ITEM_4, TREASURE_GAME_SMALL_KEY, false, true); - PlaceItemInLocation(MARKET_TREASURE_CHEST_GAME_ITEM_5, TREASURE_GAME_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_GREEN_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_GREEN_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_BLUE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_RED_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, RG_TREASURE_GAME_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, RG_TREASURE_GAME_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, RG_TREASURE_GAME_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, RG_TREASURE_GAME_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RG_TREASURE_GAME_SMALL_KEY, false, true); }; - if (Tokensanity.Is(TOKENSANITY_OFF)) { - for (uint32_t loc : GetLocations(allLocations, Category::cSkulltula)) { - PlaceItemInLocation(loc, GOLD_SKULLTULA_TOKEN, false, true); + if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) { + for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { + ctx->PlaceItemInLocation(loc, RG_GOLD_SKULLTULA_TOKEN, false, true); } - } else if (Tokensanity.Is(TOKENSANITY_DUNGEONS)) { - for (uint32_t loc : GetLocations(allLocations, Category::cSkulltula)) { - if (Location(loc)->IsOverworld()) { - PlaceItemInLocation(loc, GOLD_SKULLTULA_TOKEN, false, true); + } else if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_DUNGEONS)) { + 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 { - AddItemToMainPool(GOLD_SKULLTULA_TOKEN); + AddItemToMainPool(RG_GOLD_SKULLTULA_TOKEN); } } - } else if (Tokensanity.Is(TOKENSANITY_OVERWORLD)) { - for (uint32_t loc : GetLocations(allLocations, Category::cSkulltula)) { - if (Location(loc)->IsDungeon()) { - PlaceItemInLocation(loc, GOLD_SKULLTULA_TOKEN, false, true); + } else if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OVERWORLD)) { + 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 { - AddItemToMainPool(GOLD_SKULLTULA_TOKEN); + AddItemToMainPool(RG_GOLD_SKULLTULA_TOKEN); } } } else { - AddItemToMainPool(GOLD_SKULLTULA_TOKEN, 100); + AddItemToMainPool(RG_GOLD_SKULLTULA_TOKEN, 100); } - if (Shuffle100GSReward) { - if (Tokensanity.IsNot(TOKENSANITY_OFF) && ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) { - AddItemToPool(PendingJunkPool, GOLD_SKULLTULA_TOKEN, 10); + if (ctx->GetOption(RSK_SHUFFLE_100_GS_REWARD)) { + if (ctx->GetOption(RSK_SHUFFLE_TOKENS).IsNot(RO_TOKENSANITY_OFF) && ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + AddItemToPool(PendingJunkPool, RG_GOLD_SKULLTULA_TOKEN, 10); } - AddItemToMainPool(HUGE_RUPEE); + AddItemToMainPool(RG_HUGE_RUPEE); } else { - PlaceItemInLocation(KAK_100_GOLD_SKULLTULA_REWARD, HUGE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, false, true); } - if (BombchusInLogic) { - AddItemToMainPool(PROGRESSIVE_BOMBCHUS, 5); + if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { + AddItemToMainPool(RG_GOHMA_SOUL); + AddItemToMainPool(RG_KING_DODONGO_SOUL); + AddItemToMainPool(RG_BARINADE_SOUL); + AddItemToMainPool(RG_PHANTOM_GANON_SOUL); + AddItemToMainPool(RG_VOLVAGIA_SOUL); + AddItemToMainPool(RG_MORPHA_SOUL); + AddItemToMainPool(RG_BONGO_BONGO_SOUL); + AddItemToMainPool(RG_TWINROVA_SOUL); + + ctx->possibleIceTrapModels.push_back(RG_GOHMA_SOUL); + ctx->possibleIceTrapModels.push_back(RG_KING_DODONGO_SOUL); + ctx->possibleIceTrapModels.push_back(RG_BARINADE_SOUL); + ctx->possibleIceTrapModels.push_back(RG_PHANTOM_GANON_SOUL); + ctx->possibleIceTrapModels.push_back(RG_VOLVAGIA_SOUL); + ctx->possibleIceTrapModels.push_back(RG_MORPHA_SOUL); + ctx->possibleIceTrapModels.push_back(RG_BONGO_BONGO_SOUL); + ctx->possibleIceTrapModels.push_back(RG_TWINROVA_SOUL); + if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) { + AddItemToMainPool(RG_GANON_SOUL); + ctx->possibleIceTrapModels.push_back(RG_GANON_SOUL); + } + } + + if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET)) { + AddItemToMainPool(RG_PROGRESSIVE_WALLET); + } + + if (ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET)) { + AddItemToMainPool(RG_PROGRESSIVE_WALLET); + } + + if (ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG)) { + AddItemToMainPool(RG_PROGRESSIVE_STICK_UPGRADE); + } + + if (ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG)) { + AddItemToMainPool(RG_PROGRESSIVE_NUT_UPGRADE); + } + + if (ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC)) { + AddItemToMainPool(RG_PROGRESSIVE_BOMBCHUS, 5); } else { - AddItemToMainPool(BOMBCHU_5); - AddItemToMainPool(BOMBCHU_10, 3); - AddItemToMainPool(BOMBCHU_20); + AddItemToMainPool(RG_BOMBCHU_5); + AddItemToMainPool(RG_BOMBCHU_10, 3); + AddItemToMainPool(RG_BOMBCHU_20); } //Ice Traps - AddItemToMainPool(ICE_TRAP); - if (GerudoTrainingGrounds.IsVanilla()) { - AddItemToMainPool(ICE_TRAP); + AddItemToMainPool(RG_ICE_TRAP); + if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUNDS)->IsVanilla()) { + AddItemToMainPool(RG_ICE_TRAP); } - if (GanonsCastle.IsVanilla()) { - AddItemToMainPool(ICE_TRAP, 4); + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla()) { + AddItemToMainPool(RG_ICE_TRAP, 4); } //Gerudo Fortress - if (GerudoFortress.Is(GERUDOFORTRESS_OPEN)) { - PlaceItemInLocation(GF_NORTH_F1_CARPENTER, RECOVERY_HEART, false, true); - PlaceItemInLocation(GF_NORTH_F2_CARPENTER, RECOVERY_HEART, false, true); - PlaceItemInLocation(GF_SOUTH_F1_CARPENTER, RECOVERY_HEART, false, true); - PlaceItemInLocation(GF_SOUTH_F2_CARPENTER, RECOVERY_HEART, false, true); - } else if (GerudoKeys.IsNot(GERUDOKEYS_VANILLA)) { - if (GerudoFortress.Is(GERUDOFORTRESS_FAST)) { - AddItemToMainPool(GERUDO_FORTRESS_SMALL_KEY); - PlaceItemInLocation(GF_NORTH_F2_CARPENTER, RECOVERY_HEART, false, true); - PlaceItemInLocation(GF_SOUTH_F1_CARPENTER, RECOVERY_HEART, false, true); - PlaceItemInLocation(GF_SOUTH_F2_CARPENTER, RECOVERY_HEART, false, true); + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN)) { + ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); + } else if (ctx->GetOption(RSK_GERUDO_KEYS).IsNot(RO_GERUDO_KEYS_VANILLA)) { + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST)) { + AddItemToMainPool(RG_GERUDO_FORTRESS_SMALL_KEY); + ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); } else { //Only add key ring if 4 Fortress keys necessary - if (RingFortress) { - AddItemToMainPool(GERUDO_FORTRESS_KEY_RING); + if (ctx->GetOption(RSK_KEYRINGS_GERUDO_FORTRESS)) { + AddItemToMainPool(RG_GERUDO_FORTRESS_KEY_RING); //Add junk to make up for missing keys for (uint8_t i = 0; i < 3; i++) { AddItemToMainPool(GetJunkItem()); } } else { - AddItemToMainPool(GERUDO_FORTRESS_SMALL_KEY, 4); + AddItemToMainPool(RG_GERUDO_FORTRESS_SMALL_KEY, 4); } } - if (ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) { - if (RingFortress && GerudoFortress.Is(GERUDOFORTRESS_NORMAL)) { - AddItemToPool(PendingJunkPool, GERUDO_FORTRESS_KEY_RING); + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + if (ctx->GetOption(RSK_KEYRINGS_GERUDO_FORTRESS) && ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_NORMAL)) { + AddItemToPool(PendingJunkPool, RG_GERUDO_FORTRESS_KEY_RING); } else { - AddItemToPool(PendingJunkPool, GERUDO_FORTRESS_SMALL_KEY); + AddItemToPool(PendingJunkPool, RG_GERUDO_FORTRESS_SMALL_KEY); } } } else { - if (GerudoFortress.Is(GERUDOFORTRESS_FAST)) { - PlaceItemInLocation(GF_NORTH_F1_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, false, true); - PlaceItemInLocation(GF_NORTH_F2_CARPENTER, RECOVERY_HEART, false, true); - PlaceItemInLocation(GF_SOUTH_F1_CARPENTER, RECOVERY_HEART, false, true); - PlaceItemInLocation(GF_SOUTH_F2_CARPENTER, RECOVERY_HEART, false, true); + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST)) { + ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); } else { - PlaceItemInLocation(GF_NORTH_F1_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, false, true); - PlaceItemInLocation(GF_NORTH_F2_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, false, true); - PlaceItemInLocation(GF_SOUTH_F1_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, false, true); - PlaceItemInLocation(GF_SOUTH_F2_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); } } //Gerudo Membership Card - if (ShuffleGerudoToken && GerudoFortress.IsNot(GERUDOFORTRESS_OPEN)) { - AddItemToMainPool(GERUDO_MEMBERSHIP_CARD); - IceTrapModels.push_back(GI_GERUDO_CARD); - } else if (ShuffleGerudoToken) { - AddItemToPool(PendingJunkPool, GERUDO_MEMBERSHIP_CARD); - PlaceItemInLocation(GF_GERUDO_MEMBERSHIP_CARD, ICE_TRAP, false, true); + if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_OPEN)) { + AddItemToMainPool(RG_GERUDO_MEMBERSHIP_CARD); + ctx->possibleIceTrapModels.push_back(RG_GERUDO_MEMBERSHIP_CARD); + } else if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { + AddItemToPool(PendingJunkPool, RG_GERUDO_MEMBERSHIP_CARD); + ctx->PlaceItemInLocation(RC_GF_GERUDO_MEMBERSHIP_CARD, RG_ICE_TRAP, false, true); } else { - PlaceItemInLocation(GF_GERUDO_MEMBERSHIP_CARD, GERUDO_MEMBERSHIP_CARD, false, true); + ctx->PlaceItemInLocation(RC_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, false, true); } //Keys //For key rings, need to add as many junk items as "missing" keys - if (KeyRings.IsNot(KEYRINGS_OFF)) { + if (ctx->GetOption(RSK_KEYRINGS).IsNot(RO_KEYRINGS_OFF)) { uint8_t ringJunkAmt = 0; - for (auto dungeon : dungeonList) { + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { if (dungeon->HasKeyRing()) { ringJunkAmt += dungeon->GetSmallKeyCount() - 1; } @@ -912,102 +1095,112 @@ void GenerateItemPool() { } } - if (ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) { - if (ShuffleGerudoToken) { - AddItemToPool(PendingJunkPool, GERUDO_MEMBERSHIP_CARD); + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { + AddItemToPool(PendingJunkPool, RG_GERUDO_MEMBERSHIP_CARD); + } + + if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE)) { + AddItemToPool(PendingJunkPool, RG_FISHING_POLE); } //Plentiful small keys - if (Keysanity.Is(KEYSANITY_ANYWHERE) || Keysanity.Is(KEYSANITY_ANY_DUNGEON) || Keysanity.Is(KEYSANITY_OVERWORLD)) { - if (BottomOfTheWell.HasKeyRing()) { - AddItemToPool(PendingJunkPool, BOTTOM_OF_THE_WELL_KEY_RING); + if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON) || ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { + if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_BOTTOM_OF_THE_WELL_KEY_RING); } else { - AddItemToPool(PendingJunkPool, BOTTOM_OF_THE_WELL_SMALL_KEY); + AddItemToPool(PendingJunkPool, RG_BOTTOM_OF_THE_WELL_SMALL_KEY); } - if (ForestTemple.HasKeyRing()) { - AddItemToPool(PendingJunkPool, FOREST_TEMPLE_KEY_RING); + if (ctx->GetDungeon(Rando::FOREST_TEMPLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_FOREST_TEMPLE_KEY_RING); } else { - AddItemToPool(PendingJunkPool, FOREST_TEMPLE_SMALL_KEY); + AddItemToPool(PendingJunkPool, RG_FOREST_TEMPLE_SMALL_KEY); } - if (FireTemple.HasKeyRing()) { - AddItemToPool(PendingJunkPool, FIRE_TEMPLE_KEY_RING); + if (ctx->GetDungeon(Rando::FIRE_TEMPLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_FIRE_TEMPLE_KEY_RING); } else { - AddItemToPool(PendingJunkPool, FIRE_TEMPLE_SMALL_KEY); + AddItemToPool(PendingJunkPool, RG_FIRE_TEMPLE_SMALL_KEY); } - if (WaterTemple.HasKeyRing()) { - AddItemToPool(PendingJunkPool, WATER_TEMPLE_KEY_RING); + if (ctx->GetDungeon(Rando::WATER_TEMPLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_WATER_TEMPLE_KEY_RING); } else { - AddItemToPool(PendingJunkPool, WATER_TEMPLE_SMALL_KEY); + AddItemToPool(PendingJunkPool, RG_WATER_TEMPLE_SMALL_KEY); } - if (SpiritTemple.HasKeyRing()) { - AddItemToPool(PendingJunkPool, SPIRIT_TEMPLE_KEY_RING); + if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_SPIRIT_TEMPLE_KEY_RING); } else { - AddItemToPool(PendingJunkPool, SPIRIT_TEMPLE_SMALL_KEY); + AddItemToPool(PendingJunkPool, RG_SPIRIT_TEMPLE_SMALL_KEY); } - if (ShadowTemple.HasKeyRing()) { - AddItemToPool(PendingJunkPool, SHADOW_TEMPLE_KEY_RING); + if (ctx->GetDungeon(Rando::SHADOW_TEMPLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_SHADOW_TEMPLE_KEY_RING); } else { - AddItemToPool(PendingJunkPool, SHADOW_TEMPLE_SMALL_KEY); + AddItemToPool(PendingJunkPool, RG_SHADOW_TEMPLE_SMALL_KEY); } - if (GerudoTrainingGrounds.HasKeyRing()) { - AddItemToPool(PendingJunkPool, GERUDO_TRAINING_GROUNDS_KEY_RING); + if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUNDS)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_GERUDO_TRAINING_GROUNDS_KEY_RING); } else { - AddItemToPool(PendingJunkPool, GERUDO_TRAINING_GROUNDS_SMALL_KEY); + AddItemToPool(PendingJunkPool, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY); } - if (GanonsCastle.HasKeyRing()) { - AddItemToPool(PendingJunkPool, GANONS_CASTLE_KEY_RING); + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_GANONS_CASTLE_KEY_RING); } else { - AddItemToPool(PendingJunkPool, GANONS_CASTLE_SMALL_KEY); + AddItemToPool(PendingJunkPool, RG_GANONS_CASTLE_SMALL_KEY); } } - if (BossKeysanity.Is(BOSSKEYSANITY_ANYWHERE) || BossKeysanity.Is(BOSSKEYSANITY_ANY_DUNGEON) || BossKeysanity.Is(BOSSKEYSANITY_OVERWORLD)) { - AddItemToPool(PendingJunkPool, FOREST_TEMPLE_BOSS_KEY); - AddItemToPool(PendingJunkPool, FIRE_TEMPLE_BOSS_KEY); - AddItemToPool(PendingJunkPool, WATER_TEMPLE_BOSS_KEY); - AddItemToPool(PendingJunkPool, SPIRIT_TEMPLE_BOSS_KEY); - AddItemToPool(PendingJunkPool, SHADOW_TEMPLE_BOSS_KEY); + if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON) || ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { + AddItemToPool(PendingJunkPool, RG_FOREST_TEMPLE_BOSS_KEY); + AddItemToPool(PendingJunkPool, RG_FIRE_TEMPLE_BOSS_KEY); + AddItemToPool(PendingJunkPool, RG_WATER_TEMPLE_BOSS_KEY); + AddItemToPool(PendingJunkPool, RG_SPIRIT_TEMPLE_BOSS_KEY); + AddItemToPool(PendingJunkPool, RG_SHADOW_TEMPLE_BOSS_KEY); } - if (GanonsBossKey.Is(GANONSBOSSKEY_ANYWHERE) || GanonsBossKey.Is(GANONSBOSSKEY_ANY_DUNGEON) || GanonsBossKey.Is(GANONSBOSSKEY_OVERWORLD)) { - AddItemToPool(PendingJunkPool, GANONS_CASTLE_BOSS_KEY); + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANYWHERE) || ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANY_DUNGEON) || ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OVERWORLD)) { + AddItemToPool(PendingJunkPool, RG_GANONS_CASTLE_BOSS_KEY); } } //Shopsanity - if (Settings::Shopsanity.Is(SHOPSANITY_OFF) || Settings::Shopsanity.Is(SHOPSANITY_ZERO)) { + if ( + ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || + ( + ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT) && + ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ZERO_ITEMS) + ) + ) { AddItemsToPool(ItemPool, normalRupees); - } else { //Shopsanity 1-4, random + } else { AddItemsToPool(ItemPool, shopsanityRupees); //Shopsanity gets extra large rupees } //Scrubsanity - if (Settings::Scrubsanity.IsNot(SCRUBSANITY_OFF)) { + if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) { //Deku Tree - if (DekuTree.IsMQ()) { - AddItemToMainPool(DEKU_SHIELD); + if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) { + AddItemToMainPool(RG_DEKU_SHIELD); } //Dodongos Cavern - AddItemToMainPool(DEKU_STICK_1); - AddItemToMainPool(DEKU_SHIELD); - if (DodongosCavern.IsMQ()) { - AddItemToMainPool(RECOVERY_HEART); + AddItemToMainPool(RG_DEKU_STICK_1); + AddItemToMainPool(RG_DEKU_SHIELD); + if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) { + AddItemToMainPool(RG_RECOVERY_HEART); } else { - AddItemToMainPool(DEKU_NUTS_5); + AddItemToMainPool(RG_DEKU_NUTS_5); } //Jabu Jabus Belly - if (JabuJabusBelly.IsVanilla()) { - AddItemToMainPool(DEKU_NUTS_5); + if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsVanilla()) { + AddItemToMainPool(RG_DEKU_NUTS_5); } //Ganons Castle - AddItemToMainPool(BOMBS_5); - AddItemToMainPool(RECOVERY_HEART); - AddItemToMainPool(BLUE_RUPEE); - if (GanonsCastle.IsMQ()) { - AddItemToMainPool(DEKU_NUTS_5); + AddItemToMainPool(RG_BOMBS_5); + AddItemToMainPool(RG_RECOVERY_HEART); + AddItemToMainPool(RG_BLUE_RUPEE); + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) { + AddItemToMainPool(RG_DEKU_NUTS_5); } //Overworld Scrubs @@ -1016,91 +1209,94 @@ void GenerateItemPool() { //I'm not sure what this is for, but it was in ootr so I copied it for (uint8_t i = 0; i < 7; i++) { if (Random(0, 3)) { - AddItemToMainPool(ARROWS_30); + AddItemToMainPool(RG_ARROWS_30); } else { - AddItemToMainPool(DEKU_SEEDS_30); + AddItemToMainPool(RG_DEKU_SEEDS_30); } } } else { - PlaceVanillaDekuScrubItems(); + PlaceVanillaDekuScrubItems(ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF)); } AddItemsToPool(ItemPool, alwaysItems); AddItemsToPool(ItemPool, dungeonRewards); //Dungeon pools - if (DekuTree.IsMQ()) { + if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) { AddItemsToPool(ItemPool, DT_MQ); } else { AddItemsToPool(ItemPool, DT_Vanilla); } - if (DodongosCavern.IsMQ()) { + if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) { AddItemsToPool(ItemPool, DC_MQ); } else { AddItemsToPool(ItemPool, DC_Vanilla); } - if (JabuJabusBelly.IsMQ()) { + if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsMQ()) { AddItemsToPool(ItemPool, JB_MQ); } - if (ForestTemple.IsMQ()) { + if (ctx->GetDungeon(Rando::FOREST_TEMPLE)->IsMQ()) { AddItemsToPool(ItemPool, FoT_MQ); } else { AddItemsToPool(ItemPool, FoT_Vanilla); } - if (FireTemple.IsMQ()) { + if (ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsMQ()) { AddItemsToPool(ItemPool, FiT_MQ); } else { AddItemsToPool(ItemPool, FiT_Vanilla); } - if (SpiritTemple.IsMQ()) { + if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsMQ()) { AddItemsToPool(ItemPool, SpT_MQ); } else { AddItemsToPool(ItemPool, SpT_Vanilla); } - if (ShadowTemple.IsMQ()) { + if (ctx->GetDungeon(Rando::SHADOW_TEMPLE)->IsMQ()) { AddItemsToPool(ItemPool, ShT_MQ); } else { AddItemsToPool(ItemPool, ShT_Vanilla); } - if (BottomOfTheWell.IsVanilla()) { + if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla()) { AddItemsToPool(ItemPool, BW_Vanilla); } - if (GerudoTrainingGrounds.IsMQ()) { + if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUNDS)->IsMQ()) { AddItemsToPool(ItemPool, GTG_MQ); } else { AddItemsToPool(ItemPool, GTG_Vanilla); } - if (GanonsCastle.IsMQ()) { + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) { AddItemsToPool(ItemPool, GC_MQ); } else { AddItemsToPool(ItemPool, GC_Vanilla); } uint8_t rutoBottles = 1; - if (ZorasFountain.Is(ZORASFOUNTAIN_OPEN)) { + if (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN)) { rutoBottles = 0; } //Add 4 total bottles uint8_t bottleCount = 4; - std::vector bottles; + std::vector bottles; bottles.assign(normalBottles.begin(), normalBottles.end()); - IceTrapModels.push_back(ItemTable(RandomElement(bottles)).GetItemID()); //Get one random bottle type for ice traps + ctx->possibleIceTrapModels.push_back( + Rando::StaticData::RetrieveItem(RandomElement(bottles)).GetRandomizerGet()); // Get one random bottle type for ice traps for (uint8_t i = 0; i < bottleCount; i++) { if (i >= rutoBottles) { - if ((i == bottleCount - 1) && ShuffleMerchants.IsNot(SHUFFLEMERCHANTS_OFF)) { - AddItemToMainPool(BOTTLE_WITH_BLUE_POTION); + if ((i == bottleCount - 1) && + (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL))) { + AddItemToMainPool(RG_BOTTLE_WITH_BLUE_POTION); } else { AddRandomBottle(bottles); } } else { - AddItemToMainPool(RUTOS_LETTER); + AddItemToMainPool(RG_RUTOS_LETTER); } } //add extra songs only if song shuffle is anywhere AddItemsToPool(ItemPool, songList); - if (ShuffleSongs.Is(SONGSHUFFLE_ANYWHERE) && ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) { + if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_ANYWHERE) && ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { AddItemsToPool(PendingJunkPool, songList); } @@ -1111,25 +1307,25 @@ void GenerateItemPool() { | advancement items that haven't been placed yet for placing higher priority | items like stones/medallions.*/ - if (MapsAndCompasses.Is(MAPSANDCOMPASSES_VANILLA)) { + if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { PlaceVanillaMapsAndCompasses(); } else { - for (auto dungeon : dungeonList) { - if (dungeon->GetMap() != NONE) { + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (dungeon->GetMap() != RG_NONE) { AddItemToMainPool(dungeon->GetMap()); } - if (dungeon->GetCompass() != NONE) { + if (dungeon->GetCompass() != RG_NONE) { AddItemToMainPool(dungeon->GetCompass()); } } } - if (Keysanity.Is(KEYSANITY_VANILLA)) { + if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { PlaceVanillaSmallKeys(); } else { - for (auto dungeon : dungeonList) { - if (dungeon->HasKeyRing() && Keysanity.IsNot(KEYSANITY_START_WITH)) { + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (dungeon->HasKeyRing() && ctx->GetOption(RSK_KEYSANITY).IsNot(RO_DUNGEON_ITEM_LOC_STARTWITH)) { AddItemToMainPool(dungeon->GetKeyRing()); } else { if (dungeon->GetSmallKeyCount() > 0) { @@ -1139,75 +1335,75 @@ void GenerateItemPool() { } } - if (BossKeysanity.Is(BOSSKEYSANITY_VANILLA)) { + if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { PlaceVanillaBossKeys(); } else { - AddItemToMainPool(FOREST_TEMPLE_BOSS_KEY); - AddItemToMainPool(FIRE_TEMPLE_BOSS_KEY); - AddItemToMainPool(WATER_TEMPLE_BOSS_KEY); - AddItemToMainPool(SPIRIT_TEMPLE_BOSS_KEY); - AddItemToMainPool(SHADOW_TEMPLE_BOSS_KEY); - } - - if (GanonsBossKey.Is(GANONSBOSSKEY_FINAL_GS_REWARD)) { - PlaceItemInLocation(KAK_100_GOLD_SKULLTULA_REWARD, GANONS_CASTLE_BOSS_KEY); - } else if (GanonsBossKey.Value() >= GANONSBOSSKEY_LACS_VANILLA && GanonsBossKey.IsNot(GANONSBOSSKEY_TRIFORCE_HUNT)) { - PlaceItemInLocation(TOT_LIGHT_ARROWS_CUTSCENE, GANONS_CASTLE_BOSS_KEY); - } else if (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA)) { - PlaceItemInLocation(GANONS_TOWER_BOSS_KEY_CHEST, GANONS_CASTLE_BOSS_KEY); + AddItemToMainPool(RG_FOREST_TEMPLE_BOSS_KEY); + AddItemToMainPool(RG_FIRE_TEMPLE_BOSS_KEY); + AddItemToMainPool(RG_WATER_TEMPLE_BOSS_KEY); + AddItemToMainPool(RG_SPIRIT_TEMPLE_BOSS_KEY); + AddItemToMainPool(RG_SHADOW_TEMPLE_BOSS_KEY); + } + + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) { + ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_GANONS_CASTLE_BOSS_KEY); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Value() >= RO_GANON_BOSS_KEY_LACS_VANILLA && ctx->GetOption(RSK_GANONS_BOSS_KEY).IsNot(RO_GANON_BOSS_KEY_TRIFORCE_HUNT)) { + ctx->PlaceItemInLocation(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_GANONS_CASTLE_BOSS_KEY); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_VANILLA)) { + ctx->PlaceItemInLocation(RC_GANONS_TOWER_BOSS_KEY_CHEST, RG_GANONS_CASTLE_BOSS_KEY); } else { - AddItemToMainPool(GANONS_CASTLE_BOSS_KEY); + AddItemToMainPool(RG_GANONS_CASTLE_BOSS_KEY); } - if (ItemPoolValue.Is(ITEMPOOL_PLENTIFUL)) { + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { AddItemsToPool(ItemPool, easyItems); } else { AddItemsToPool(ItemPool, normalItems); } - if (!ShuffleKokiriSword) { - ReplaceMaxItem(KOKIRI_SWORD, 0); + if (!ctx->GetOption(RSK_SHUFFLE_KOKIRI_SWORD)) { + ReplaceMaxItem(RG_KOKIRI_SWORD, 0); } - if (!ShuffleMasterSword) { - ReplaceMaxItem(MASTER_SWORD, 0); + if (!ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { + ReplaceMaxItem(RG_MASTER_SWORD, 0); } - if (ProgressiveGoronSword) { - ReplaceMaxItem(BIGGORON_SWORD, 0); - AddItemToMainPool(PROGRESSIVE_GORONSWORD, 2); - IceTrapModels.push_back(0xD4); // Progressive Goron Sword + if (/*ProgressiveGoronSword TODO: Implement Setting*/false) { + ReplaceMaxItem(RG_BIGGORON_SWORD, 0); + AddItemToMainPool(RG_PROGRESSIVE_GORONSWORD, 2); + ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_GORONSWORD); // Progressive Goron Sword } else { - IceTrapModels.push_back(GI_SWORD_BGS); + ctx->possibleIceTrapModels.push_back(RG_BIGGORON_SWORD); } //Replace ice traps with junk from the pending junk pool if necessary - if (IceTrapValue.Is(ICETRAPS_OFF)) { - ReplaceMaxItem(ICE_TRAP, 0); + if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_OFF)) { + ReplaceMaxItem(RG_ICE_TRAP, 0); } //Replace all junk items with ice traps for onslaught mode - else if (IceTrapValue.Is(ICETRAPS_ONSLAUGHT)) { + else if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_ONSLAUGHT)) { for (uint8_t i = 0; i < JunkPoolItems.size() - 3; i++) { // -3 Omits Huge Rupees and Deku Nuts 10 ReplaceMaxItem(JunkPoolItems[i], 0); } } - if (ItemPoolValue.Is(ITEMPOOL_SCARCE)) { + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_SCARCE)) { SetScarceItemPool(); - } else if (ItemPoolValue.Is(ITEMPOOL_MINIMAL)) { + } else if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_MINIMAL)) { SetMinimalItemPool(); - } else if (RemoveDoubleDefense) { - ReplaceMaxItem(DOUBLE_DEFENSE, 0); + } else if (/*RemoveDoubleDefense TODO: Implement setting*/ false) { + ReplaceMaxItem(RG_DOUBLE_DEFENSE, 0); } //this feels ugly and there's probably a better way, but //it replaces random junk with pending junk. bool junkSet; - for (uint32_t pendingJunk : PendingJunkPool) { + for (RandomizerGet pendingJunk : PendingJunkPool) { junkSet = false; - for (uint32_t& item : ItemPool) { - for (uint32_t junk : JunkPoolItems) { - if (item == junk && item != HUGE_RUPEE && item != DEKU_NUTS_10) { + for (RandomizerGet& item : ItemPool) { + for (RandomizerGet junk : JunkPoolItems) { + if (item == junk && item != RG_HUGE_RUPEE && item != RG_DEKU_NUTS_10) { item = pendingJunk; junkSet = true; break; diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.hpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.hpp index d71e4cb2fa9..4ef5830011e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.hpp @@ -1,18 +1,16 @@ #pragma once -#include "keys.hpp" - #include #include #include +#include "../randomizerTypes.h" class ItemLocation; -void AddItemToPool(std::vector& pool, const uint32_t item, size_t count = 1); -uint32_t GetJunkItem(); -void PlaceJunkInExcludedLocation(const uint32_t il); +void AddItemToPool(std::vector& pool, const RandomizerGet item, size_t count = 1); +RandomizerGet GetJunkItem(); +void PlaceJunkInExcludedLocation(const RandomizerCheck il); void GenerateItemPool(); void AddJunk(); -extern std::vector ItemPool; -extern std::vector IceTrapModels; +extern std::vector ItemPool; diff --git a/soh/soh/Enhancements/randomizer/3drando/keys.hpp b/soh/soh/Enhancements/randomizer/3drando/keys.hpp index 95d31070e43..e69de29bb2d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/keys.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/keys.hpp @@ -1,1835 +0,0 @@ -#pragma once - -#include - -using HintKey = uint32_t; -using ItemKey = uint32_t; -using LocationKey = uint32_t; -using AreaKey = uint32_t; - -typedef enum { - NONE, - KOKIRI_SWORD, - MASTER_SWORD, - GIANTS_KNIFE, - BIGGORON_SWORD, - DEKU_SHIELD, - HYLIAN_SHIELD, - MIRROR_SHIELD, - GORON_TUNIC, - ZORA_TUNIC, - IRON_BOOTS, - HOVER_BOOTS, - WEIRD_EGG, - ZELDAS_LETTER, - BOOMERANG, - LENS_OF_TRUTH, - MEGATON_HAMMER, - STONE_OF_AGONY, - DINS_FIRE, - FARORES_WIND, - NAYRUS_LOVE, - FIRE_ARROWS, - ICE_ARROWS, - LIGHT_ARROWS, - GERUDO_MEMBERSHIP_CARD, - MAGIC_BEAN, - MAGIC_BEAN_PACK, - DOUBLE_DEFENSE, - GOLD_SKULLTULA_TOKEN, - - POCKET_EGG, - POCKET_CUCCO, - COJIRO, - ODD_MUSHROOM, - ODD_POTION, - POACHERS_SAW, - BROKEN_SWORD, - PRESCRIPTION, - EYEBALL_FROG, - EYEDROPS, - CLAIM_CHECK, - - PROGRESSIVE_HOOKSHOT, - PROGRESSIVE_STRENGTH, - PROGRESSIVE_BOMB_BAG, - PROGRESSIVE_BOW, - PROGRESSIVE_SLINGSHOT, - PROGRESSIVE_WALLET, - PROGRESSIVE_SCALE, - PROGRESSIVE_NUT_UPGRADE, - PROGRESSIVE_STICK_UPGRADE, - PROGRESSIVE_MAGIC_METER, - PROGRESSIVE_OCARINA, - PROGRESSIVE_BOMBCHUS, - PROGRESSIVE_GORONSWORD, - - //Keys just used for logic - BOW, - SLINGSHOT, - HOOKSHOT, - LONGSHOT, - SILVER_GAUNTLETS, - GOLDEN_GAUNTLETS, - SILVER_SCALE, - GOLD_SCALE, - SCARECROW, - DISTANT_SCARECROW, - STICKS, - - EMPTY_BOTTLE, - BOTTLE_WITH_MILK, - BOTTLE_WITH_RED_POTION, - BOTTLE_WITH_GREEN_POTION, - BOTTLE_WITH_BLUE_POTION, - BOTTLE_WITH_FAIRY, - BOTTLE_WITH_FISH, - BOTTLE_WITH_BLUE_FIRE, - BOTTLE_WITH_BUGS, - BOTTLE_WITH_POE, - BOTTLE_WITH_BIG_POE, - RUTOS_LETTER, - - ZELDAS_LULLABY, - EPONAS_SONG, - SARIAS_SONG, - SUNS_SONG, - SONG_OF_TIME, - SONG_OF_STORMS, - MINUET_OF_FOREST, - BOLERO_OF_FIRE, - SERENADE_OF_WATER, - REQUIEM_OF_SPIRIT, - NOCTURNE_OF_SHADOW, - PRELUDE_OF_LIGHT, - - MAP, - DEKU_TREE_MAP, - DODONGOS_CAVERN_MAP, - JABU_JABUS_BELLY_MAP, - FOREST_TEMPLE_MAP, - FIRE_TEMPLE_MAP, - WATER_TEMPLE_MAP, - SPIRIT_TEMPLE_MAP, - SHADOW_TEMPLE_MAP, - BOTTOM_OF_THE_WELL_MAP, - ICE_CAVERN_MAP, - - COMPASS, - DEKU_TREE_COMPASS, - DODONGOS_CAVERN_COMPASS, - JABU_JABUS_BELLY_COMPASS, - FOREST_TEMPLE_COMPASS, - FIRE_TEMPLE_COMPASS, - WATER_TEMPLE_COMPASS, - SPIRIT_TEMPLE_COMPASS, - SHADOW_TEMPLE_COMPASS, - BOTTOM_OF_THE_WELL_COMPASS, - ICE_CAVERN_COMPASS, - - BOSS_KEY, - FOREST_TEMPLE_BOSS_KEY, - FIRE_TEMPLE_BOSS_KEY, - WATER_TEMPLE_BOSS_KEY, - SPIRIT_TEMPLE_BOSS_KEY, - SHADOW_TEMPLE_BOSS_KEY, - GANONS_CASTLE_BOSS_KEY, - - SMALL_KEY, - FOREST_TEMPLE_SMALL_KEY, - FIRE_TEMPLE_SMALL_KEY, - WATER_TEMPLE_SMALL_KEY, - SPIRIT_TEMPLE_SMALL_KEY, - SHADOW_TEMPLE_SMALL_KEY, - BOTTOM_OF_THE_WELL_SMALL_KEY, - GERUDO_TRAINING_GROUNDS_SMALL_KEY, - GERUDO_FORTRESS_SMALL_KEY, - GANONS_CASTLE_SMALL_KEY, - TREASURE_GAME_SMALL_KEY, - - FOREST_TEMPLE_KEY_RING, - FIRE_TEMPLE_KEY_RING, - WATER_TEMPLE_KEY_RING, - SPIRIT_TEMPLE_KEY_RING, - SHADOW_TEMPLE_KEY_RING, - BOTTOM_OF_THE_WELL_KEY_RING, - GERUDO_TRAINING_GROUNDS_KEY_RING, - GERUDO_FORTRESS_KEY_RING, - GANONS_CASTLE_KEY_RING, - - KOKIRI_EMERALD, - GORON_RUBY, - ZORA_SAPPHIRE, - FOREST_MEDALLION, - FIRE_MEDALLION, - WATER_MEDALLION, - SPIRIT_MEDALLION, - SHADOW_MEDALLION, - LIGHT_MEDALLION, - - RECOVERY_HEART, - GREEN_RUPEE, - GREG_RUPEE, - BLUE_RUPEE, - RED_RUPEE, - PURPLE_RUPEE, - HUGE_RUPEE, - PIECE_OF_HEART, - HEART_CONTAINER, - ICE_TRAP, - MILK, - - BOMBS_5, - BOMBS_10, - BOMBS_20, - BOMBCHU_5, - BOMBCHU_10, - BOMBCHU_20, - BOMBCHU_DROP, - ARROWS_5, - ARROWS_10, - ARROWS_30, - DEKU_NUTS_5, - DEKU_NUTS_10, - DEKU_SEEDS_30, - DEKU_STICK_1, - RED_POTION_REFILL, - GREEN_POTION_REFILL, - BLUE_POTION_REFILL, - - TREASURE_GAME_HEART, - TREASURE_GAME_GREEN_RUPEE, - - TRIFORCE, - TRIFORCE_PIECE, - TRIFORCE_COMPLETED, - EPONA, - HINT, - - //SHOP ITEMS - BUY_DEKU_NUT_5, - BUY_ARROWS_30, - BUY_ARROWS_50, - BUY_BOMBS_525, - BUY_DEKU_NUT_10, - BUY_DEKU_STICK_1, - BUY_BOMBS_10, - BUY_FISH, - BUY_RED_POTION_30, - BUY_GREEN_POTION, - BUY_BLUE_POTION, - BUY_HYLIAN_SHIELD, - BUY_DEKU_SHIELD, - BUY_GORON_TUNIC, - BUY_ZORA_TUNIC, - BUY_HEART, - BUY_BOMBCHU_10, - BUY_BOMBCHU_20, - BUY_DEKU_SEEDS_30, - SOLD_OUT, - BUY_BLUE_FIRE, - BUY_BOTTLE_BUG, - BUY_POE, - BUY_FAIRYS_SPIRIT, - BUY_ARROWS_10, - BUY_BOMBS_20, - BUY_BOMBS_30, - BUY_BOMBS_535, - BUY_RED_POTION_40, - BUY_RED_POTION_50, - - //ITEMLOCATIONS - - //DUNGEON REWARDS - LINKS_POCKET, - QUEEN_GOHMA, - KING_DODONGO, - BARINADE, - PHANTOM_GANON, - VOLVAGIA, - MORPHA, - BONGO_BONGO, - TWINROVA, - GANON, - - //SONGS - SONG_FROM_IMPA, - SONG_FROM_MALON, - SONG_FROM_SARIA, - SONG_FROM_COMPOSERS_GRAVE, - SONG_FROM_OCARINA_OF_TIME, - SONG_FROM_WINDMILL, - SHEIK_IN_FOREST, - SHEIK_IN_CRATER, - SHEIK_IN_ICE_CAVERN, - SHEIK_AT_COLOSSUS, - SHEIK_IN_KAKARIKO, - SHEIK_AT_TEMPLE, - -//// Overworld -// Kokiri Forest - KF_MIDOS_TOP_LEFT_CHEST, - KF_MIDOS_TOP_RIGHT_CHEST, - KF_MIDOS_BOTTOM_LEFT_CHEST, - KF_MIDOS_BOTTOM_RIGHT_CHEST, - KF_KOKIRI_SWORD_CHEST, - KF_STORMS_GROTTO_CHEST, - KF_LINKS_HOUSE_COW, - KF_GS_KNOW_IT_ALL_HOUSE, - KF_GS_BEAN_PATCH, - KF_GS_HOUSE_OF_TWINS, - KF_SHOP_ITEM_1, - KF_SHOP_ITEM_2, - KF_SHOP_ITEM_3, - KF_SHOP_ITEM_4, - KF_SHOP_ITEM_5, - KF_SHOP_ITEM_6, - KF_SHOP_ITEM_7, - KF_SHOP_ITEM_8, -//LOST_WOODS - LW_GIFT_FROM_SARIA, - LW_OCARINA_MEMORY_GAME, - LW_TARGET_IN_WOODS, - LW_NEAR_SHORTCUTS_GROTTO_CHEST, - DEKU_THEATER_SKULL_MASK, - DEKU_THEATER_MASK_OF_TRUTH, - LW_SKULL_KID, - LW_TRADE_COJIRO, - LW_TRADE_ODD_POTION, - LW_DEKU_SCRUB_NEAR_BRIDGE, - LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, - LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, - LW_DEKU_SCRUB_GROTTO_FRONT, - LW_DEKU_SCRUB_GROTTO_REAR, - LW_GS_BEAN_PATCH_NEAR_BRIDGE, - LW_GS_BEAN_PATCH_NEAR_THEATER, - LW_GS_ABOVE_THEATER, -//SACRED_FOREST_MEADOW - SFM_WOLFOS_GROTTO_CHEST, - SFM_DEKU_SCRUB_GROTTO_FRONT, - SFM_DEKU_SCRUB_GROTTO_REAR, - SFM_GS, -//HYRULE_FIELD - HF_OCARINA_OF_TIME_ITEM, - HF_NEAR_MARKET_GROTTO_CHEST, - HF_TEKTITE_GROTTO_FREESTANDING_POH, - HF_SOUTHEAST_GROTTO_CHEST, - HF_OPEN_GROTTO_CHEST, - HF_DEKU_SCRUB_GROTTO, - HF_COW_GROTTO_COW, - HF_GS_COW_GROTTO, - HF_GS_NEAR_KAK_GROTTO, -//MARKET - MARKET_SHOOTING_GALLERY_REWARD, - MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, - MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, - MARKET_BOMBCHU_BOWLING_BOMBCHUS, - MARKET_LOST_DOG, - MARKET_TREASURE_CHEST_GAME_REWARD, - MARKET_TREASURE_CHEST_GAME_ITEM_1, - MARKET_TREASURE_CHEST_GAME_ITEM_2, - MARKET_TREASURE_CHEST_GAME_ITEM_3, - MARKET_TREASURE_CHEST_GAME_ITEM_4, - MARKET_TREASURE_CHEST_GAME_ITEM_5, - MARKET_10_BIG_POES, - MARKET_GS_GUARD_HOUSE, - MARKET_BAZAAR_ITEM_1, - MARKET_BAZAAR_ITEM_2, - MARKET_BAZAAR_ITEM_3, - MARKET_BAZAAR_ITEM_4, - MARKET_BAZAAR_ITEM_5, - MARKET_BAZAAR_ITEM_6, - MARKET_BAZAAR_ITEM_7, - MARKET_BAZAAR_ITEM_8, - MARKET_POTION_SHOP_ITEM_1, - MARKET_POTION_SHOP_ITEM_2, - MARKET_POTION_SHOP_ITEM_3, - MARKET_POTION_SHOP_ITEM_4, - MARKET_POTION_SHOP_ITEM_5, - MARKET_POTION_SHOP_ITEM_6, - MARKET_POTION_SHOP_ITEM_7, - MARKET_POTION_SHOP_ITEM_8, - MARKET_BOMBCHU_SHOP_ITEM_1, - MARKET_BOMBCHU_SHOP_ITEM_2, - MARKET_BOMBCHU_SHOP_ITEM_3, - MARKET_BOMBCHU_SHOP_ITEM_4, - MARKET_BOMBCHU_SHOP_ITEM_5, - MARKET_BOMBCHU_SHOP_ITEM_6, - MARKET_BOMBCHU_SHOP_ITEM_7, - MARKET_BOMBCHU_SHOP_ITEM_8, - TOT_MASTER_SWORD, - TOT_LIGHT_ARROWS_CUTSCENE, -//HYRULE_CASTLE - HC_MALON_EGG, - HC_ZELDAS_LETTER, - HC_GREAT_FAIRY_REWARD, - HC_GS_TREE, - HC_GS_STORMS_GROTTO, -//LON_LON_RANCH - LLR_TALONS_CHICKENS, - LLR_FREESTANDING_POH, - LLR_DEKU_SCRUB_GROTTO_LEFT, - LLR_DEKU_SCRUB_GROTTO_CENTER, - LLR_DEKU_SCRUB_GROTTO_RIGHT, - LLR_STABLES_LEFT_COW, - LLR_STABLES_RIGHT_COW, - LLR_TOWER_LEFT_COW, - LLR_TOWER_RIGHT_COW, - LLR_GS_HOUSE_WINDOW, - LLR_GS_TREE, - LLR_GS_RAIN_SHED, - LLR_GS_BACK_WALL, -//KAKARIKO - KAK_ANJU_AS_CHILD, - KAK_ANJU_AS_ADULT, - KAK_TRADE_POCKET_CUCCO, - KAK_IMPAS_HOUSE_FREESTANDING_POH, - KAK_WINDMILL_FREESTANDING_POH, - KAK_MAN_ON_ROOF, - KAK_OPEN_GROTTO_CHEST, - KAK_REDEAD_GROTTO_CHEST, - KAK_SHOOTING_GALLERY_REWARD, - KAK_TRADE_ODD_MUSHROOM, - KAK_GRANNYS_SHOP, - KAK_10_GOLD_SKULLTULA_REWARD, - KAK_20_GOLD_SKULLTULA_REWARD, - KAK_30_GOLD_SKULLTULA_REWARD, - KAK_40_GOLD_SKULLTULA_REWARD, - KAK_50_GOLD_SKULLTULA_REWARD, - KAK_100_GOLD_SKULLTULA_REWARD, - KAK_IMPAS_HOUSE_COW, - KAK_GS_TREE, - KAK_GS_GUARDS_HOUSE, - KAK_GS_WATCHTOWER, - KAK_GS_SKULLTULA_HOUSE, - KAK_GS_HOUSE_UNDER_CONSTRUCTION, - KAK_GS_ABOVE_IMPAS_HOUSE, - KAK_BAZAAR_ITEM_1, - KAK_BAZAAR_ITEM_2, - KAK_BAZAAR_ITEM_3, - KAK_BAZAAR_ITEM_4, - KAK_BAZAAR_ITEM_5, - KAK_BAZAAR_ITEM_6, - KAK_BAZAAR_ITEM_7, - KAK_BAZAAR_ITEM_8, - KAK_POTION_SHOP_ITEM_1, - KAK_POTION_SHOP_ITEM_2, - KAK_POTION_SHOP_ITEM_3, - KAK_POTION_SHOP_ITEM_4, - KAK_POTION_SHOP_ITEM_5, - KAK_POTION_SHOP_ITEM_6, - KAK_POTION_SHOP_ITEM_7, - KAK_POTION_SHOP_ITEM_8, -//GRAVEYARD - GRAVEYARD_SHIELD_GRAVE_CHEST, - GRAVEYARD_HEART_PIECE_GRAVE_CHEST, - GRAVEYARD_COMPOSERS_GRAVE_CHEST, - GRAVEYARD_FREESTANDING_POH, - GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, - GRAVEYARD_HOOKSHOT_CHEST, - GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, - GRAVEYARD_GS_BEAN_PATCH, - GRAVEYARD_GS_WALL, -//DEATH_MOUNTAIN_TRAIL - DMT_FREESTANDING_POH, - DMT_CHEST, - DMT_STORMS_GROTTO_CHEST, - DMT_GREAT_FAIRY_REWARD, - DMT_TRADE_BROKEN_SWORD, - DMT_TRADE_EYEDROPS, - DMT_TRADE_CLAIM_CHECK, - DMT_COW_GROTTO_COW, - DMT_GS_NEAR_KAK, - DMT_GS_BEAN_PATCH, - DMT_GS_ABOVE_DODONGOS_CAVERN, - DMT_GS_FALLING_ROCKS_PATH, -//GORON_CITY - GC_DARUNIAS_JOY, - GC_POT_FREESTANDING_POH, - GC_ROLLING_GORON_AS_CHILD, - GC_ROLLING_GORON_AS_ADULT, - GC_MEDIGORON, - GC_MAZE_LEFT_CHEST, - GC_MAZE_RIGHT_CHEST, - GC_MAZE_CENTER_CHEST, - GC_DEKU_SCRUB_GROTTO_LEFT, - GC_DEKU_SCRUB_GROTTO_CENTER, - GC_DEKU_SCRUB_GROTTO_RIGHT, - GC_GS_CENTER_PLATFORM, - GC_GS_BOULDER_MAZE, - GC_SHOP_ITEM_1, - GC_SHOP_ITEM_2, - GC_SHOP_ITEM_3, - GC_SHOP_ITEM_4, - GC_SHOP_ITEM_5, - GC_SHOP_ITEM_6, - GC_SHOP_ITEM_7, - GC_SHOP_ITEM_8, -//DEATH_MOUNTAIN_CRATER - DMC_VOLCANO_FREESTANDING_POH, - DMC_WALL_FREESTANDING_POH, - DMC_UPPER_GROTTO_CHEST, - DMC_GREAT_FAIRY_REWARD, - DMC_DEKU_SCRUB, - DMC_DEKU_SCRUB_GROTTO_LEFT, - DMC_DEKU_SCRUB_GROTTO_CENTER, - DMC_DEKU_SCRUB_GROTTO_RIGHT, - DMC_GS_CRATE, - DMC_GS_BEAN_PATCH, -//ZORA'S_RIVER - ZR_MAGIC_BEAN_SALESMAN, - ZR_OPEN_GROTTO_CHEST, - ZR_FROGS_ZELDAS_LULLABY, - ZR_FROGS_EPONAS_SONG, - ZR_FROGS_SARIAS_SONG, - ZR_FROGS_SUNS_SONG, - ZR_FROGS_SONG_OF_TIME, - ZR_FROGS_IN_THE_RAIN, - ZR_FROGS_OCARINA_GAME, - ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, - ZR_NEAR_DOMAIN_FREESTANDING_POH, - ZR_DEKU_SCRUB_GROTTO_FRONT, - ZR_DEKU_SCRUB_GROTTO_REAR, - ZR_GS_TREE, - ZR_GS_LADDER, - ZR_GS_NEAR_RAISED_GROTTOS, - ZR_GS_ABOVE_BRIDGE, -//ZORA'S_DOMAIN - ZD_DIVING_MINIGAME, - ZD_CHEST, - ZD_KING_ZORA_THAWED, - ZD_TRADE_PRESCRIPTION, - ZD_GS_FROZEN_WATERFALL, - ZD_SHOP_ITEM_1, - ZD_SHOP_ITEM_2, - ZD_SHOP_ITEM_3, - ZD_SHOP_ITEM_4, - ZD_SHOP_ITEM_5, - ZD_SHOP_ITEM_6, - ZD_SHOP_ITEM_7, - ZD_SHOP_ITEM_8, -//ZORA'S_FOUNTAIN - ZF_GREAT_FAIRY_REWARD, - ZF_ICEBERG_FREESTANDING_POH, - ZF_BOTTOM_FREESTANDING_POH, - ZF_GS_ABOVE_THE_LOG, - ZF_GS_TREE, - ZF_GS_HIDDEN_CAVE, -//LAKE_HYLIA - LH_UNDERWATER_ITEM, - LH_CHILD_FISHING, - LH_ADULT_FISHING, - LH_LAB_DIVE, - LH_TRADE_FROG, - LH_FREESTANDING_POH, - LH_SUN, - LH_DEKU_SCRUB_GROTTO_LEFT, - LH_DEKU_SCRUB_GROTTO_CENTER, - LH_DEKU_SCRUB_GROTTO_RIGHT, - LH_GS_BEAN_PATCH, - LH_GS_LAB_WALL, - LH_GS_SMALL_ISLAND, - LH_GS_LAB_CRATE, - LH_GS_TREE, -//GERUDO_VALLEY - GV_CRATE_FREESTANDING_POH, - GV_WATERFALL_FREESTANDING_POH, - GV_CHEST, - GV_TRADE_SAW, - GV_DEKU_SCRUB_GROTTO_FRONT, - GV_DEKU_SCRUB_GROTTO_REAR, - GV_COW, - GV_GS_SMALL_BRIDGE, - GV_GS_BEAN_PATCH, - GV_GS_BEHIND_TENT, - GV_GS_PILLAR, -//GERUDO'S_FORTRESS - GF_NORTH_F1_CARPENTER, - GF_NORTH_F2_CARPENTER, - GF_SOUTH_F1_CARPENTER, - GF_SOUTH_F2_CARPENTER, - GF_GERUDO_MEMBERSHIP_CARD, - GF_CHEST, - GF_HBA_1000_POINTS, - GF_HBA_1500_POINTS, - GF_GS_TOP_FLOOR, - GF_GS_ARCHERY_RANGE, -//WASTELAND - WASTELAND_BOMBCHU_SALESMAN, - WASTELAND_CHEST, - WASTELAND_GS, -//COLOSSUS - COLOSSUS_GREAT_FAIRY_REWARD, - COLOSSUS_FREESTANDING_POH, - COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, - COLOSSUS_DEKU_SCRUB_GROTTO_REAR, - COLOSSUS_GS_BEAN_PATCH, - COLOSSUS_GS_TREE, - COLOSSUS_GS_HILL, -//OUTSIDE_GANON'S_CASTLE - OGC_GREAT_FAIRY_REWARD, - OGC_GS, - -////DUNGEONS -//DEKU_TREE_VANILLA - DEKU_TREE_MAP_CHEST, - DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, - DEKU_TREE_SLINGSHOT_CHEST, - DEKU_TREE_COMPASS_CHEST, - DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, - DEKU_TREE_BASEMENT_CHEST, - DEKU_TREE_GS_COMPASS_ROOM, - DEKU_TREE_GS_BASEMENT_VINES, - DEKU_TREE_GS_BASEMENT_GATE, - DEKU_TREE_GS_BASEMENT_BACK_ROOM, -//DEKU_TREE_MQ - DEKU_TREE_MQ_MAP_CHEST, - DEKU_TREE_MQ_SLINGSHOT_CHEST, - DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, - DEKU_TREE_MQ_COMPASS_CHEST, - DEKU_TREE_MQ_BASEMENT_CHEST, - DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, - DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, - DEKU_TREE_MQ_DEKU_SCRUB, - DEKU_TREE_MQ_GS_LOBBY, - DEKU_TREE_MQ_GS_COMPASS_ROOM, - DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, - DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, -//DEKU_TREE_SHARED - DEKU_TREE_QUEEN_GOHMA_HEART, -//DODONGO'S_CAVERN_VANILLA - DODONGOS_CAVERN_MAP_CHEST, - DODONGOS_CAVERN_COMPASS_CHEST, - DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, - DODONGOS_CAVERN_BOMB_BAG_CHEST, - DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, - DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, - DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, - DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, - DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, - DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, - DODONGOS_CAVERN_GS_SCARECROW, - DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, - DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, - DODONGOS_CAVERN_GS_BACK_ROOM, -//DODONGO'S_CAVERN_MQ - DODONGOS_CAVERN_MQ_MAP_CHEST, - DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, - DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, - DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, - DODONGOS_CAVERN_MQ_COMPASS_CHEST, - DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, - DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, - DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, - DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, - DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, - DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, - DODONGOS_CAVERN_MQ_GS_BACK_AREA, -//DODONGO'S_CAVERN_SHARED - DODONGOS_CAVERN_BOSS_ROOM_CHEST, - DODONGOS_CAVERN_KING_DODONGO_HEART, -//JABU_JABU'S_BELLY_VANILLA - JABU_JABUS_BELLY_BOOMERANG_CHEST, - JABU_JABUS_BELLY_MAP_CHEST, - JABU_JABUS_BELLY_COMPASS_CHEST, - JABU_JABUS_BELLY_DEKU_SCRUB, - JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, - JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, - JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, - JABU_JABUS_BELLY_GS_NEAR_BOSS, -//JABU_JABU'S_BELLY_MQ - JABU_JABUS_BELLY_MQ_MAP_CHEST, - JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, - JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, - JABU_JABUS_BELLY_MQ_COMPASS_CHEST, - JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, - JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, - JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, - JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, - JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, - JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, - JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, - JABU_JABUS_BELLY_MQ_COW, - JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, - JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, - JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, - JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, -//JABU_JABU'S_BELLY_SHARED - JABU_JABUS_BELLY_BARINADE_HEART, -//BOTTOM_OF_THE_WELL_VANILLA - BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, - BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, - BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, - BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, - BOTTOM_OF_THE_WELL_FREESTANDING_KEY, - BOTTOM_OF_THE_WELL_COMPASS_CHEST, - BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, - BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, - BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, - BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, - BOTTOM_OF_THE_WELL_MAP_CHEST, - BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, - BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, - BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, - BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, - BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, - BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, -//BOTTOM_OF_THE_WELL_MQ - BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, - BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, - BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, - BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, - BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, - BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, - BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, - BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, -//FOREST_TEMPLE_VANILLA - FOREST_TEMPLE_FIRST_ROOM_CHEST, - FOREST_TEMPLE_FIRST_STALFOS_CHEST, - FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, - FOREST_TEMPLE_MAP_CHEST, - FOREST_TEMPLE_WELL_CHEST, - FOREST_TEMPLE_EYE_SWITCH_CHEST, - FOREST_TEMPLE_BOSS_KEY_CHEST, - FOREST_TEMPLE_FLOORMASTER_CHEST, - FOREST_TEMPLE_RED_POE_CHEST, - FOREST_TEMPLE_BOW_CHEST, - FOREST_TEMPLE_BLUE_POE_CHEST, - FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, - FOREST_TEMPLE_BASEMENT_CHEST, - FOREST_TEMPLE_GS_FIRST_ROOM, - FOREST_TEMPLE_GS_LOBBY, - FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, - FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, - FOREST_TEMPLE_GS_BASEMENT, -//FOREST_TEMPLE_MQ - FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, - FOREST_TEMPLE_MQ_WOLFOS_CHEST, - FOREST_TEMPLE_MQ_WELL_CHEST, - FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, - FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, - FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, - FOREST_TEMPLE_MQ_REDEAD_CHEST, - FOREST_TEMPLE_MQ_MAP_CHEST, - FOREST_TEMPLE_MQ_BOW_CHEST, - FOREST_TEMPLE_MQ_COMPASS_CHEST, - FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, - FOREST_TEMPLE_MQ_BASEMENT_CHEST, - FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, - FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, - FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, - FOREST_TEMPLE_MQ_GS_WELL, - FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, -//FOREST_TEMPLE_SHARED - FOREST_TEMPLE_PHANTOM_GANON_HEART, -//FIRE_TEMPLE_VANILLA - FIRE_TEMPLE_NEAR_BOSS_CHEST, - FIRE_TEMPLE_FLARE_DANCER_CHEST, - FIRE_TEMPLE_BOSS_KEY_CHEST, - FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, - FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, - FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, - FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, - FIRE_TEMPLE_MAP_CHEST, - FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, - FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, - FIRE_TEMPLE_SCARECROW_CHEST, - FIRE_TEMPLE_COMPASS_CHEST, - FIRE_TEMPLE_MEGATON_HAMMER_CHEST, - FIRE_TEMPLE_HIGHEST_GORON_CHEST, - FIRE_TEMPLE_GS_BOSS_KEY_LOOP, - FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, - FIRE_TEMPLE_GS_BOULDER_MAZE, - FIRE_TEMPLE_GS_SCARECROW_CLIMB, - FIRE_TEMPLE_GS_SCARECROW_TOP, -//FIRE_TEMPLE_MQ - FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, - FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, - FIRE_TEMPLE_MQ_MAP_CHEST, - FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, - FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, - FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, - FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, - FIRE_TEMPLE_MQ_COMPASS_CHEST, - FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, - FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, - FIRE_TEMPLE_MQ_FREESTANDING_KEY, - FIRE_TEMPLE_MQ_CHEST_ON_FIRE, - FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, - FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, - FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, - FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, - FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, -//FIRE_TEMPLE_SHARED - FIRE_TEMPLE_VOLVAGIA_HEART, -//WATER_TEMPLE_VANILLA - WATER_TEMPLE_COMPASS_CHEST, - WATER_TEMPLE_MAP_CHEST, - WATER_TEMPLE_CRACKED_WALL_CHEST, - WATER_TEMPLE_TORCHES_CHEST, - WATER_TEMPLE_BOSS_KEY_CHEST, - WATER_TEMPLE_CENTRAL_PILLAR_CHEST, - WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, - WATER_TEMPLE_LONGSHOT_CHEST, - WATER_TEMPLE_RIVER_CHEST, - WATER_TEMPLE_DRAGON_CHEST, - WATER_TEMPLE_GS_BEHIND_GATE, - WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, - WATER_TEMPLE_GS_CENTRAL_PILLAR, - WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, - WATER_TEMPLE_GS_RIVER, -//WATER_TEMPLE_MQ - WATER_TEMPLE_MQ_LONGSHOT_CHEST, - WATER_TEMPLE_MQ_MAP_CHEST, - WATER_TEMPLE_MQ_COMPASS_CHEST, - WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, - WATER_TEMPLE_MQ_BOSS_KEY_CHEST, - WATER_TEMPLE_MQ_FREESTANDING_KEY, - WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, - WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, - WATER_TEMPLE_MQ_GS_RIVER, - WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, - WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, -//WATER_TEMPLE_SHARED - WATER_TEMPLE_MORPHA_HEART, -//SHADOW_TEMPLE_VANILLA - SHADOW_TEMPLE_MAP_CHEST, - SHADOW_TEMPLE_HOVER_BOOTS_CHEST, - SHADOW_TEMPLE_COMPASS_CHEST, - SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, - SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, - SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, - SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, - SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, - SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, - SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, - SHADOW_TEMPLE_FREESTANDING_KEY, - SHADOW_TEMPLE_WIND_HINT_CHEST, - SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, - SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, - SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, - SHADOW_TEMPLE_BOSS_KEY_CHEST, - SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, - SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, - SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, - SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, - SHADOW_TEMPLE_GS_NEAR_SHIP, - SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, -//SHADOW_TEMPLE_MQ - SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, - SHADOW_TEMPLE_MQ_MAP_CHEST, - SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, - SHADOW_TEMPLE_MQ_COMPASS_CHEST, - SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, - SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, - SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, - SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, - SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, - SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, - SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, - SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, - SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, - SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, - SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, - SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, - SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, - SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, - SHADOW_TEMPLE_MQ_FREESTANDING_KEY, - SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, - SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, - SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, - SHADOW_TEMPLE_MQ_GS_AFTER_WIND, - SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, - SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, -//SHADOW_TEMPLE_SHARED - SHADOW_TEMPLE_BONGO_BONGO_HEART, -//SPIRIT_TEMPLE_SHARED -//VANILLA_AND_MQ_LOCATIONS_ARE_MIXED_TO_ENSURE_THE_POSITIONS_OF_S - SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, - SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, - SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, - SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, - SPIRIT_TEMPLE_MAP_CHEST, - SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, - SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, - SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, - SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, - SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, - SPIRIT_TEMPLE_MQ_MAP_CHEST, - SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, - SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, - SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, - SPIRIT_TEMPLE_MQ_COMPASS_CHEST, - SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, - SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, - SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, - SPIRIT_TEMPLE_COMPASS_CHEST, - SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, - SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, - SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, - SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, - SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, - SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, - SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, - SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, - SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, - SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, - SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, - SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, - SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, - SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, - SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, - SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, - SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, - SPIRIT_TEMPLE_BOSS_KEY_CHEST, - SPIRIT_TEMPLE_TOPMOST_CHEST, - SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, - SPIRIT_TEMPLE_GS_METAL_FENCE, - SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, - SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, - SPIRIT_TEMPLE_GS_LOBBY, - SPIRIT_TEMPLE_GS_BOULDER_ROOM, - SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, - SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, - SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, - SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, - SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, - SPIRIT_TEMPLE_TWINROVA_HEART, -//ICE_CAVERN_VANILLA - ICE_CAVERN_MAP_CHEST, - ICE_CAVERN_COMPASS_CHEST, - ICE_CAVERN_FREESTANDING_POH, - ICE_CAVERN_IRON_BOOTS_CHEST, - ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, - ICE_CAVERN_GS_HEART_PIECE_ROOM, - ICE_CAVERN_GS_PUSH_BLOCK_ROOM, -//ICE_CAVERN_MQ - ICE_CAVERN_MQ_MAP_CHEST, - ICE_CAVERN_MQ_COMPASS_CHEST, - ICE_CAVERN_MQ_FREESTANDING_POH, - ICE_CAVERN_MQ_IRON_BOOTS_CHEST, - ICE_CAVERN_MQ_GS_RED_ICE, - ICE_CAVERN_MQ_GS_ICE_BLOCK, - ICE_CAVERN_MQ_GS_SCARECROW, -//GERUDO_TRAINING_GROUNDS_VANILLA - GERUDO_TRAINING_GROUNDS_LOBBY_LEFT_CHEST, - GERUDO_TRAINING_GROUNDS_LOBBY_RIGHT_CHEST, - GERUDO_TRAINING_GROUNDS_STALFOS_CHEST, - GERUDO_TRAINING_GROUNDS_BEFORE_HEAVY_BLOCK_CHEST, - GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FIRST_CHEST, - GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_SECOND_CHEST, - GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_THIRD_CHEST, - GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FOURTH_CHEST, - GERUDO_TRAINING_GROUNDS_EYE_STATUE_CHEST, - GERUDO_TRAINING_GROUNDS_NEAR_SCARECROW_CHEST, - GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_CLEAR_CHEST, - GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_SWITCH_CHEST, - GERUDO_TRAINING_GROUNDS_FREESTANDING_KEY, - GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_CENTRAL_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_SIDE_CHEST, - GERUDO_TRAINING_GROUNDS_UNDERWATER_SILVER_RUPEE_CHEST, - GERUDO_TRAINING_GROUNDS_BEAMOS_CHEST, - GERUDO_TRAINING_GROUNDS_HIDDEN_CEILING_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_PATH_FIRST_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_PATH_SECOND_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_PATH_THIRD_CHEST, - GERUDO_TRAINING_GROUNDS_MAZE_PATH_FINAL_CHEST, -//GERUDO_TRAINING_GROUNDS_MQ - GERUDO_TRAINING_GROUNDS_MQ_LOBBY_LEFT_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_LOBBY_RIGHT_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_FIRST_IRON_KNUCKLE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_BEFORE_HEAVY_BLOCK_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_HEAVY_BLOCK_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_EYE_STATUE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_ICE_ARROWS_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_SECOND_IRON_KNUCKLE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_FLAME_CIRCLE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_CENTRAL_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_SIDE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER_SILVER_RUPEE_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_DINOLFOS_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_HIDDEN_CEILING_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_FIRST_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_THIRD_CHEST, - GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_SECOND_CHEST, -//GANON'S_CASTLE_VANILLA - GANONS_CASTLE_FOREST_TRIAL_CHEST, - GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, - GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, - GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, - GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, - GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, - GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, - GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, - GANONS_CASTLE_DEKU_SCRUB_LEFT, - GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, - GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, - GANONS_CASTLE_DEKU_SCRUB_RIGHT, -//GANON'S_CASTLE_MQ - GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, - GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, - GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, - GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, - GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, - GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, - GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, - GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, - GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, - GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, - GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, - GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, - GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, -//GANON'S_CASTLE_SHARED - GANONS_TOWER_BOSS_KEY_CHEST, - -////EVENTS_AND_DROPS - PIERRE, - DELIVER_RUTOS_LETTER, - MASTER_SWORD_PEDESTAL, - DEKU_BABA_STICKS, - DEKU_BABA_NUTS, - STICK_POT, - NUT_POT, - NUT_CRATE, - BLUE_FIRE, - LONE_FISH, - FISH_GROUP, - BUG_ROCK, - BUG_SHRUB, - WANDERING_BUGS, - FAIRY_POT, - FREE_FAIRIES, - WALL_FAIRY, - BUTTERFLY_FAIRY, - GOSSIP_STONE_FAIRY, - BEAN_PLANT_FAIRY, - FAIRY_POND, - BIG_POE_KILL, - - //HINT LOACTIONS - DMC_GOSSIP_STONE, - DMT_GOSSIP_STONE, - COLOSSUS_GOSSIP_STONE, - DODONGOS_CAVERN_GOSSIP_STONE, - GV_GOSSIP_STONE, - GC_MAZE_GOSSIP_STONE, - GC_MEDIGORON_GOSSIP_STONE, - GRAVEYARD_GOSSIP_STONE, - HC_MALON_GOSSIP_STONE, - HC_ROCK_WALL_GOSSIP_STONE, - HC_STORMS_GROTTO_GOSSIP_STONE, - HF_COW_GROTTO_GOSSIP_STONE, - KF_DEKU_TREE_GOSSIP_STONE_LEFT, - KF_DEKU_TREE_GOSSIP_STONE_RIGHT, - KF_GOSSIP_STONE, - LH_LAB_GOSSIP_STONE, - LH_GOSSIP_STONE_SOUTHEAST, - LH_GOSSIP_STONE_SOUTHWEST, - LW_GOSSIP_STONE, - SFM_MAZE_GOSSIP_STONE_LOWER, - SFM_MAZE_GOSSIP_STONE_UPPER, - SFM_SARIA_GOSSIP_STONE, - TOT_GOSSIP_STONE_LEFT, - TOT_GOSSIP_STONE_LEFT_CENTER, - TOT_GOSSIP_STONE_RIGHT, - TOT_GOSSIP_STONE_RIGHT_CENTER, - ZD_GOSSIP_STONE, - ZF_FAIRY_GOSSIP_STONE, - ZF_JABU_GOSSIP_STONE, - ZR_NEAR_GROTTOS_GOSSIP_STONE, - ZR_NEAR_DOMAIN_GOSSIP_STONE, - HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, - HF_SOUTHEAST_GROTTO_GOSSIP_STONE, - HF_OPEN_GROTTO_GOSSIP_STONE, - KAK_OPEN_GROTTO_GOSSIP_STONE, - ZR_OPEN_GROTTO_GOSSIP_STONE, - KF_STORMS_GROTTO_GOSSIP_STONE, - LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, - DMT_STORMS_GROTTO_GOSSIP_STONE, - DMC_UPPER_GROTTO_GOSSIP_STONE, - GANONDORF_HINT, - - //ENTRANCES - DESERT_COLOSSUS_TO_COLOSSUS_GROTTO, - GV_GROTTO_LEDGE_TO_GV_OCTOROK_GROTTO, - GC_GROTTO_PLATFORM_TO_GC_GROTTO, - GERUDO_FORTRESS_TO_GF_STORMS_GROTTO, - ZORAS_DOMAIN_TO_ZD_STORMS_GROTTO, - HYRULE_CASTLE_GROUNDS_TO_HC_STORMS_GROTTO, - GV_FORTRESS_SIDE_TO_GV_STORMS_GROTTO, - DESERT_COLOSSUS_TO_COLOSSUS_GREAT_FAIRY_FOUNTAIN, - GANONS_CASTLE_GROUNDS_TO_OGC_GREAT_FAIRY_FOUNTAIN, - ZORAS_FOUNTAIN_TO_ZF_GREAT_FAIRY_FOUNTAIN, - GV_FORTRESS_SIDE_TO_GV_CARPENTER_TENT, - GRAVEYARD_WARP_PAD_REGION_TO_SHADOW_TEMPLE_ENTRYWAY, - LAKE_HYLIA_TO_WATER_TEMPLE_LOBBY, - GERUDO_FORTRESS_TO_GERUDO_TRAINING_GROUNDS_LOBBY, - ZORAS_FOUNTAIN_TO_JABU_JABUS_BELLY_BEGINNING, - KAKARIKO_VILLAGE_TO_BOTTOM_OF_THE_WELL, - - //EXITS - HYRULE_CASTLE, - OUTSIDE_GANONS_CASTLE, - DEATH_MOUNTAIN_CRATER, - - //AREAS - MARKER_AREAS_START, // Used for area key count - - ROOT, - ROOT_EXITS, - CHILD_SPAWN, - ADULT_SPAWN, - MINUET_OF_FOREST_WARP, - BOLERO_OF_FIRE_WARP, - SERENADE_OF_WATER_WARP, - REQUIEM_OF_SPIRIT_WARP, - NOCTURNE_OF_SHADOW_WARP, - PRELUDE_OF_LIGHT_WARP, - KOKIRI_FOREST, - KF_LINKS_HOUSE, - KF_MIDOS_HOUSE, - KF_SARIAS_HOUSE, - KF_HOUSE_OF_TWINS, - KF_KNOW_IT_ALL_HOUSE, - KF_KOKIRI_SHOP, - KF_OUTSIDE_DEKU_TREE, - KF_STORMS_GROTTO, - THE_LOST_WOODS, - LW_BRIDGE_FROM_FOREST, - LW_BRIDGE, - LW_FOREST_EXIT, - LW_BEYOND_MIDO, - LW_NEAR_SHORTCUTS_GROTTO, - DEKU_THEATER, - LW_SCRUBS_GROTTO, - SFM_ENTRYWAY, - SACRED_FOREST_MEADOW, - SFM_WOLFOS_GROTTO, - SFM_FAIRY_GROTTO, - SFM_STORMS_GROTTO, - HYRULE_FIELD, - HF_SOUTHEAST_GROTTO, - HF_OPEN_GROTTO, - HF_INSIDE_FENCE_GROTTO, - HF_COW_GROTTO, - HF_NEAR_MARKET_GROTTO, - HF_FAIRY_GROTTO, - HF_NEAR_KAK_GROTTO, - HF_TEKTITE_GROTTO, - LAKE_HYLIA, - LH_FISHING_ISLAND, - LH_OWL_FLIGHT, - LH_LAB, - LH_FISHING_HOLE, - LH_GROTTO, - GERUDO_VALLEY, - GV_UPPER_STREAM, - GV_LOWER_STREAM, - GV_GROTTO_LEDGE, - GV_CRATE_LEDGE, - GV_OCTOROK_GROTTO, - GV_FORTRESS_SIDE, - GV_CARPENTER_TENT, - GV_STORMS_GROTTO, - GERUDO_FORTRESS, - GF_OUTSIDE_GATE, - GF_STORMS_GROTTO, - WASTELAND_NEAR_FORTRESS, - HAUNTED_WASTELAND, - WASTELAND_NEAR_COLOSSUS, - DESERT_COLOSSUS, - DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY, - COLOSSUS_GREAT_FAIRY_FOUNTAIN, - COLOSSUS_GROTTO, - MARKET_ENTRANCE, - THE_MARKET, - MARKET_GUARD_HOUSE, - MARKET_BAZAAR, - MARKET_MASK_SHOP, - MARKET_SHOOTING_GALLERY, - MARKET_BOMBCHU_BOWLING, - MARKET_TREASURE_CHEST_GAME, - MARKET_POTION_SHOP, - MARKET_BACK_ALLEY, - MARKET_BOMBCHU_SHOP, - MARKET_DOG_LADY_HOUSE, - MARKET_MAN_IN_GREEN_HOUSE, - TOT_ENTRANCE, - TEMPLE_OF_TIME, - TOT_BEYOND_DOOR_OF_TIME, - CASTLE_GROUNDS, - CASTLE_GROUNDS_FROM_GANONS_CASTLE, - HYRULE_CASTLE_GROUNDS, - HC_GARDEN, - HC_GREAT_FAIRY_FOUNTAIN, - HC_STORMS_GROTTO, - GANONS_CASTLE_GROUNDS, - OGC_GREAT_FAIRY_FOUNTAIN, - GANONS_CASTLE_LEDGE, - KAKARIKO_VILLAGE, - KAK_CARPENTER_BOSS_HOUSE, - KAK_HOUSE_OF_SKULLTULA, - KAK_IMPAS_HOUSE, - KAK_IMPAS_LEDGE, - KAK_IMPAS_HOUSE_BACK, - KAK_IMPAS_HOUSE_NEAR_COW, - KAK_WINDMILL, - KAK_BAZAAR, - KAK_SHOOTING_GALLERY, - KAK_POTION_SHOP_FRONT, - KAK_POTION_SHOP_BACK, - KAK_ROOFTOP, - KAK_IMPAS_ROOFTOP, - KAK_BEHIND_GATE, - KAK_BACKYARD, - KAK_ODD_POTION_BUILDING, - KAK_REDEAD_GROTTO, - KAK_OPEN_GROTTO, - THE_GRAVEYARD, - GRAVEYARD_DAMPES_GRAVE, - GRAVEYARD_DAMPES_HOUSE, - GRAVEYARD_SHIELD_GRAVE, - GRAVEYARD_COMPOSERS_GRAVE, - GRAVEYARD_HEART_PIECE_GRAVE, - GRAVEYARD_WARP_PAD_REGION, - DEATH_MOUNTAIN_TRAIL, - DEATH_MOUNTAIN_SUMMIT, - DMT_OWL_FLIGHT, - DMT_GREAT_FAIRY_FOUNTAIN, - DMT_COW_GROTTO, - DMT_STORMS_GROTTO, - GORON_CITY, - GC_WOODS_WARP, - GC_DARUNIAS_CHAMBER, - GC_GROTTO_PLATFORM, - GC_SHOP, - GC_GROTTO, - DMC_UPPER_LOCAL, - DMC_CENTRAL_LOCAL, - DMC_LOWER_LOCAL, - DMC_LOWER_NEARBY, - DMC_UPPER_NEARBY, - DMC_CENTRAL_NEARBY, - DMC_LADDER_AREA_NEARBY, - DMC_UPPER_GROTTO, - DMC_HAMMER_GROTTO, - DMC_GREAT_FAIRY_FOUNTAIN, - ZR_FRONT, - ZORAS_RIVER, - ZR_BEHIND_WATERFALL, - ZR_OPEN_GROTTO, - ZR_FAIRY_GROTTO, - ZR_STORMS_GROTTO, - ZORAS_DOMAIN, - ZD_BEHIND_KING_ZORA, - ZD_SHOP, - ZD_STORMS_GROTTO, - ZORAS_FOUNTAIN, - ZF_GREAT_FAIRY_FOUNTAIN, - LON_LON_RANCH, - LLR_TALONS_HOUSE, - LLR_STABLES, - LLR_TOWER, - LLR_GROTTO, - - DEKU_TREE_ENTRYWAY, - DODONGOS_CAVERN_ENTRYWAY, - JABU_JABUS_BELLY_ENTRYWAY, - FOREST_TEMPLE_ENTRYWAY, - FIRE_TEMPLE_ENTRYWAY, - WATER_TEMPLE_ENTRYWAY, - SPIRIT_TEMPLE_ENTRYWAY, - SHADOW_TEMPLE_ENTRYWAY, - BOTTOM_OF_THE_WELL_ENTRYWAY, - ICE_CAVERN_ENTRYWAY, - GERUDO_TRAINING_GROUNDS_ENTRYWAY, - GANONS_CASTLE_ENTRYWAY, - - DEKU_TREE_LOBBY, - DEKU_TREE_2F_MIDDLE_ROOM, - DEKU_TREE_SLINGSHOT_ROOM, - DEKU_TREE_COMPASS_ROOM, - DEKU_TREE_BASEMENT_LOWER, - DEKU_TREE_BASEMENT_SCRUB_ROOM, - DEKU_TREE_BASEMENT_WATER_ROOM, - DEKU_TREE_BASEMENT_TORCH_ROOM, - DEKU_TREE_BASEMENT_BACK_LOBBY, - DEKU_TREE_BASEMENT_BACK_ROOM, - DEKU_TREE_BASEMENT_UPPER, - DEKU_TREE_OUTSIDE_BOSS_ROOM, - - DEKU_TREE_MQ_LOBBY, - DEKU_TREE_MQ_COMPASS_ROOM, - DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, - DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, - DEKU_TREE_MQ_BASEMENT_BACK_ROOM, - DEKU_TREE_MQ_BASEMENT_LEDGE, - DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, - - DEKU_TREE_BOSS_ENTRYWAY, - DEKU_TREE_BOSS_ROOM, - - DODONGOS_CAVERN_BEGINNING, - DODONGOS_CAVERN_LOBBY, - DODONGOS_CAVERN_LOBBY_SWITCH, - DODONGOS_CAVERN_SE_CORRIDOR, - DODONGOS_CAVERN_SE_ROOM, - DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, - DODONGOS_CAVERN_LOWER_LIZALFOS, - DODONGOS_CAVERN_DODONGO_ROOM, - DODONGOS_CAVERN_NEAR_DODONGO_ROOM, - DODONGOS_CAVERN_STAIRS_LOWER, - DODONGOS_CAVERN_STAIRS_UPPER, - DODONGOS_CAVERN_COMPASS_ROOM, - DODONGOS_CAVERN_ARMOS_ROOM, - DODONGOS_CAVERN_BOMB_ROOM_LOWER, - DODONGOS_CAVERN_2F_SIDE_ROOM, - DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, - DODONGOS_CAVERN_UPPER_LIZALFOS, - DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, - DODONGOS_CAVERN_BOMB_ROOM_UPPER, - DODONGOS_CAVERN_FAR_BRIDGE, - DODONGOS_CAVERN_BOSS_AREA, - DODONGOS_CAVERN_BACK_ROOM, - - DODONGOS_CAVERN_MQ_BEGINNING, - DODONGOS_CAVERN_MQ_LOBBY, - DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, - DODONGOS_CAVERN_MQ_BOMB_BAG_AREA, - DODONGOS_CAVERN_MQ_BOSS_AREA, - - DODONGOS_CAVERN_BOSS_ENTRYWAY, - DODONGOS_CAVERN_BOSS_ROOM, - - JABU_JABUS_BELLY_BEGINNING, - JABU_JABUS_BELLY_LIFT_MIDDLE, - JABU_JABUS_BELLY_MAIN_UPPER, - JABU_JABUS_BELLY_MAIN_LOWER, - JABU_JABUS_BELLY_SHABOMB_CORRIDOR, - JABU_JABUS_BELLY_LOWER_SIDE_ROOM, - JABU_JABUS_BELLY_LIFT_LOWER, - JABU_JABUS_BELLY_FORKED_CORRIDOR, - JABU_JABUS_BELLY_BOOMERANG_ROOM, - JABU_JABUS_BELLY_MAP_ROOM, - JABU_JABUS_BELLY_COMPASS_ROOM, - JABU_JABUS_BELLY_BLUE_TENTACLE, - JABU_JABUS_BELLY_GREEN_TENTACLE, - JABU_JABUS_BELLY_BIGOCTO_ROOM, - JABU_JABUS_BELLY_ABOVE_BIGOCTO, - JABU_JABUS_BELLY_LIFT_UPPER, - JABU_JABUS_BELLY_NEAR_BOSS_ROOM, - - JABU_JABUS_BELLY_MQ_BEGINNING, - JABU_JABUS_BELLY_MQ_MAIN, - JABU_JABUS_BELLY_MQ_DEPTHS, - JABU_JABUS_BELLY_MQ_BOSS_AREA, - - JABU_JABUS_BELLY_BOSS_ENTRYWAY, - JABU_JABUS_BELLY_BOSS_ROOM, - - FOREST_TEMPLE_FIRST_ROOM, - FOREST_TEMPLE_SOUTH_CORRIDOR, - FOREST_TEMPLE_LOBBY, - FOREST_TEMPLE_NORTH_CORRIDOR, - FOREST_TEMPLE_LOWER_STALFOS, - FOREST_TEMPLE_NW_OUTDOORS_LOWER, - FOREST_TEMPLE_NW_OUTDOORS_UPPER, - FOREST_TEMPLE_NE_OUTDOORS_LOWER, - FOREST_TEMPLE_NE_OUTDOORS_UPPER, - FOREST_TEMPLE_MAP_ROOM, - FOREST_TEMPLE_SEWER, - FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, - FOREST_TEMPLE_FLOORMASTER_ROOM, - FOREST_TEMPLE_WEST_CORRIDOR, - FOREST_TEMPLE_BLOCK_PUSH_ROOM, - FOREST_TEMPLE_NW_CORRIDOR_TWISTED, - FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED, - FOREST_TEMPLE_RED_POE_ROOM, - FOREST_TEMPLE_UPPER_STALFOS, - FOREST_TEMPLE_BLUE_POE_ROOM, - FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED, - FOREST_TEMPLE_NE_CORRIDOR_TWISTED, - FOREST_TEMPLE_FROZEN_EYE_ROOM, - FOREST_TEMPLE_FALLING_ROOM, - FOREST_TEMPLE_GREEN_POE_ROOM, - FOREST_TEMPLE_EAST_CORRIDOR, - FOREST_TEMPLE_BOSS_REGION, - - FOREST_TEMPLE_MQ_LOBBY, - FOREST_TEMPLE_MQ_CENTRAL_AREA, - FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE, - FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, - FOREST_TEMPLE_MQ_NW_OUTDOORS, - FOREST_TEMPLE_MQ_NE_OUTDOORS, - FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, - FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, - FOREST_TEMPLE_MQ_BOW_REGION, - FOREST_TEMPLE_MQ_FALLING_ROOM, - FOREST_TEMPLE_MQ_BOSS_REGION, - - FOREST_TEMPLE_BOSS_ENTRYWAY, - FOREST_TEMPLE_BOSS_ROOM, - - FIRE_TEMPLE_FIRST_ROOM, - FIRE_TEMPLE_NEAR_BOSS_ROOM, - FIRE_TEMPLE_LOOP_ENEMIES, - FIRE_TEMPLE_LOOP_TILES, - FIRE_TEMPLE_LOOP_FLARE_DANCER, - FIRE_TEMPLE_LOOP_HAMMER_SWITCH, - FIRE_TEMPLE_LOOP_GORON_ROOM, - FIRE_TEMPLE_LOOP_EXIT, - FIRE_TEMPLE_BIG_LAVA_ROOM, - FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON, - FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES, - FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON, - FIRE_TEMPLE_FIRE_PILLAR_ROOM, - FIRE_TEMPLE_SHORTCUT_ROOM, - FIRE_TEMPLE_SHORTCUT_CLIMB, - FIRE_TEMPLE_BOULDER_MAZE_LOWER, - FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM, - FIRE_TEMPLE_EAST_CENTRAL_ROOM, - FIRE_TEMPLE_FIRE_WALL_CHASE, - FIRE_TEMPLE_MAP_AREA, - FIRE_TEMPLE_BOULDER_MAZE_UPPER, - FIRE_TEMPLE_SCARECROW_ROOM, - FIRE_TEMPLE_EAST_PEAK, - FIRE_TEMPLE_CORRIDOR, - FIRE_TEMPLE_FIRE_MAZE_ROOM, - FIRE_TEMPLE_FIRE_MAZE_UPPER, - FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM, - FIRE_TEMPLE_WEST_CENTRAL_LOWER, - FIRE_TEMPLE_WEST_CENTRAL_UPPER, - FIRE_TEMPLE_LATE_FIRE_MAZE, - FIRE_TEMPLE_UPPER_FLARE_DANCER, - FIRE_TEMPLE_WEST_CLIMB, - FIRE_TEMPLE_WEST_PEAK, - FIRE_TEMPLE_HAMMER_RETURN_PATH, - FIRE_TEMPLE_ABOVE_FIRE_MAZE, - - FIRE_TEMPLE_MQ_LOWER, - FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR, - FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, - FIRE_TEMPLE_MQ_LOWER_MAZE, - FIRE_TEMPLE_MQ_UPPER_MAZE, - FIRE_TEMPLE_MQ_UPPER, - - FIRE_TEMPLE_BOSS_ENTRYWAY, - FIRE_TEMPLE_BOSS_ROOM, - - WATER_TEMPLE_LOBBY, - WATER_TEMPLE_EAST_LOWER, - WATER_TEMPLE_MAP_ROOM, - WATER_TEMPLE_CRACKED_WALL, - WATER_TEMPLE_TORCH_ROOM, - WATER_TEMPLE_NORTH_LOWER, - WATER_TEMPLE_BOULDERS_LOWER, - WATER_TEMPLE_BLOCK_ROOM, - WATER_TEMPLE_JETS_ROOM, - WATER_TEMPLE_BOULDERS_UPPER, - WATER_TEMPLE_BOSS_KEY_ROOM, - WATER_TEMPLE_SOUTH_LOWER, - WATER_TEMPLE_WEST_LOWER, - WATER_TEMPLE_DRAGON_ROOM, - WATER_TEMPLE_CENTRAL_PILLAR_LOWER, - WATER_TEMPLE_CENTRAL_PILLAR_UPPER, - WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, - WATER_TEMPLE_EAST_MIDDLE, - WATER_TEMPLE_WEST_MIDDLE, - WATER_TEMPLE_HIGH_WATER, - WATER_TEMPLE_BLOCK_CORRIDOR, - WATER_TEMPLE_FALLING_PLATFORM_ROOM, - WATER_TEMPLE_DRAGON_PILLARS_ROOM, - WATER_TEMPLE_DARK_LINK_ROOM, - WATER_TEMPLE_LONGSHOT_ROOM, - WATER_TEMPLE_RIVER, - WATER_TEMPLE_PRE_BOSS_ROOM, - - WATER_TEMPLE_MQ_LOBBY, - WATER_TEMPLE_MQ_DIVE, - WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS, - WATER_TEMPLE_MQ_DARK_LINK_REGION, - WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS, - - WATER_TEMPLE_BOSS_ENTRYWAY, - WATER_TEMPLE_BOSS_ROOM, - - SPIRIT_TEMPLE_LOBBY, - SPIRIT_TEMPLE_CHILD, - SPIRIT_TEMPLE_CHILD_CLIMB, - SPIRIT_TEMPLE_EARLY_ADULT, - SPIRIT_TEMPLE_CENTRAL_CHAMBER, - SPIRIT_TEMPLE_OUTDOOR_HANDS, - SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR, - SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, - SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, - - SPIRIT_TEMPLE_MQ_LOBBY, - SPIRIT_TEMPLE_MQ_CHILD, - SPIRIT_TEMPLE_MQ_ADULT, - SPIRIT_TEMPLE_MQ_SHARED, - SPIRIT_TEMPLE_MQ_LOWER_ADULT, - SPIRIT_TEMPLE_MQ_BOSS_AREA, - SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, - SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, - SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, - - SPIRIT_TEMPLE_BOSS_ENTRYWAY, - SPIRIT_TEMPLE_BOSS_ROOM, - - SHADOW_TEMPLE_BEGINNING, - SHADOW_TEMPLE_FIRST_BEAMOS, - SHADOW_TEMPLE_HUGE_PIT, - SHADOW_TEMPLE_WIND_TUNNEL, - SHADOW_TEMPLE_BEYOND_BOAT, - - SHADOW_TEMPLE_MQ_ENTRYWAY, - SHADOW_TEMPLE_MQ_BEGINNING, - SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, - SHADOW_TEMPLE_MQ_FIRST_BEAMOS, - SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, - SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, - SHADOW_TEMPLE_MQ_WIND_TUNNEL, - SHADOW_TEMPLE_MQ_BEYOND_BOAT, - SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, - - SHADOW_TEMPLE_BOSS_ENTRYWAY, - SHADOW_TEMPLE_BOSS_ROOM, - - BOTTOM_OF_THE_WELL_MAIN_AREA, - - BOTTOM_OF_THE_WELL_MQ_PERIMETER, - BOTTOM_OF_THE_WELL_MQ_MIDDLE, - - ICE_CAVERN_BEGINNING, - ICE_CAVERN_MAIN, - - ICE_CAVERN_MQ_BEGINNING, - ICE_CAVERN_MQ_MAP_ROOM, - ICE_CAVERN_MQ_IRON_BOOTS_REGION, - ICE_CAVERN_MQ_COMPASS_ROOM, - - GERUDO_TRAINING_GROUNDS_LOBBY, - GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE, - GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT, - GERUDO_TRAINING_GROUNDS_LAVA_ROOM, - GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, - GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, - GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER, - GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM, - GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM, - - GERUDO_TRAINING_GROUNDS_MQ_LOBBY, - GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, - GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, - GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE, - GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM, - GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS, - GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT, - - GANONS_CASTLE_LOBBY, - GANONS_CASTLE_MAIN, - GANONS_CASTLE_DEKU_SCRUBS, - GANONS_CASTLE_FOREST_TRIAL, - GANONS_CASTLE_FIRE_TRIAL, - GANONS_CASTLE_WATER_TRIAL, - GANONS_CASTLE_SHADOW_TRIAL, - GANONS_CASTLE_SPIRIT_TRIAL, - GANONS_CASTLE_LIGHT_TRIAL, - GANONS_CASTLE_TOWER, - - GANONS_CASTLE_MQ_LOBBY, - GANONS_CASTLE_MQ_MAIN, - GANONS_CASTLE_MQ_DEKU_SCRUBS, - GANONS_CASTLE_MQ_FOREST_TRIAL, - GANONS_CASTLE_MQ_FIRE_TRIAL, - GANONS_CASTLE_MQ_WATER_TRIAL, - GANONS_CASTLE_MQ_SHADOW_TRIAL, - GANONS_CASTLE_MQ_SPIRIT_TRIAL, - GANONS_CASTLE_MQ_LIGHT_TRIAL, - - MARKER_AREAS_END, // Used for area key count - - //DUNGEONS - DEKU_TREE, - DODONGOS_CAVERN, - JABU_JABUS_BELLY, - FOREST_TEMPLE, - FIRE_TEMPLE, - WATER_TEMPLE, - SPIRIT_TEMPLE, - SHADOW_TEMPLE, - BOTTOM_OF_THE_WELL, - ICE_CAVERN, - GERUDO_TRAINING_GROUNDS, - GANONS_CASTLE, - - //HINTS - PREFIX, - WAY_OF_THE_HERO, - PLUNDERING, - FOOLISH, - CAN_BE_FOUND_AT, - HOARDS, - - JUNK02, - JUNK03, - JUNK04, - JUNK05, - JUNK06, - JUNK07, - JUNK08, - JUNK09, - JUNK10, - JUNK11, - JUNK12, - JUNK13, - JUNK14, - JUNK15, - JUNK16, - JUNK17, - JUNK18, - JUNK19, - JUNK20, - JUNK21, - JUNK22, - JUNK23, - JUNK24, - JUNK25, - JUNK26, - JUNK27, - JUNK28, - JUNK29, - JUNK30, - JUNK31, - JUNK32, - JUNK33, - JUNK34, - JUNK35, - JUNK36, - JUNK37, - JUNK38, - JUNK39, - JUNK40, - JUNK41, - JUNK42, - JUNK43, - JUNK44, - JUNK45, - JUNK46, - JUNK47, - JUNK48, - JUNK49, - JUNK50, - JUNK51, - JUNK52, - JUNK53, - JUNK54, - JUNK55, - JUNK56, - JUNK57, - JUNK58, - JUNK59, - JUNK60, - JUNK61, - JUNK62, - JUNK63, - JUNK64, - JUNK65, - JUNK66, - JUNK67, - JUNK68, - JUNK69, - JUNK70, - JUNK71, - JUNK72, - JUNK73, - JUNK74, - JUNK75, - JUNK76, - JUNK77, - JUNK78, - JUNK79, - JUNK80, - JUNK81, - - JUNK_WTC_1, - JUNK_WTC_2, - JUNK_WTC_3, - JUNK_WTC_4, - JUNK_WTC_5, - JUNK_WTC_6, - JUNK_WTC_7, - JUNK_WTC_8, - JUNK_WTC_9, - JUNK_WTC_10, - JUNK_WTC_11, - JUNK_WTC_12, - - JUNK_SEI_1, - JUNK_SEI_2, - JUNK_SEI_3, - JUNK_SEI_4, - JUNK_SEI_5, - JUNK_SEI_6, - JUNK_SEI_7, - JUNK_SEI_8, - JUNK_SEI_9, - JUNK_SEI_10, - JUNK_SEI_11, - JUNK_SEI_12, - JUNK_SEI_13, - JUNK_SEI_14, - JUNK_SEI_15, - JUNK_SEI_16, - JUNK_SEI_17, - JUNK_SEI_18, - JUNK_SEI_19, - JUNK_SEI_20, - JUNK_SEI_21, - JUNK_SEI_22, - JUNK_SEI_23, - JUNK_SEI_24, - JUNK_SEI_25, - JUNK_SEI_26, - JUNK_SEI_27, - JUNK_SEI_28, - JUNK_SEI_29, - - JUNK_OTR_MEANS_1, - JUNK_OTR_MEANS_2, - JUNK_OTR_MEANS_3, - JUNK_OTR_MEANS_4, - JUNK_OTR_MEANS_5, - JUNK_OTR_MEANS_6, - JUNK_OTR_MEANS_7, - JUNK_OTR_MEANS_8, - JUNK_OTR_MEANS_9, - JUNK_OTR_MEANS_10, - JUNK_OTR_MEANS_11, - JUNK_OTR_MEANS_12, - JUNK_OTR_MEANS_13, - JUNK_OTR_MEANS_14, - JUNK_OTR_MEANS_15, - JUNK_OTR_MEANS_16, - JUNK_OTR_MEANS_17, - JUNK_OTR_MEANS_18, - JUNK_OTR_MEANS_19, - JUNK_OTR_MEANS_20, - JUNK_OTR_MEANS_21, - JUNK_OTR_MEANS_22, - JUNK_OTR_MEANS_23, - JUNK_OTR_MEANS_24, - JUNK_OTR_MEANS_25, - JUNK_OTR_MEANS_26, - JUNK_OTR_MEANS_27, - JUNK_OTR_MEANS_28, - JUNK_OTR_MEANS_29, - JUNK_OTR_MEANS_30, - - JUNK_MISC_1, - JUNK_MISC_2, - JUNK_MISC_3, - JUNK_MISC_4, - JUNK_MISC_5, - JUNK_MISC_6, - JUNK_MISC_7, - JUNK_MISC_8, - JUNK_MISC_9, - JUNK_MISC_10, - JUNK_MISC_11, - JUNK_MISC_12, - JUNK_MISC_13, - JUNK_MISC_14, - JUNK_MISC_15, - JUNK_MISC_16, - JUNK_MISC_17, - - JUNK_SG_1, - JUNK_SG_2, - JUNK_SG_3, - JUNK_SG_4, - JUNK_SG_5, - JUNK_SG_6, - JUNK_SG_7, - JUNK_SG_8, - - BRIDGE_OPEN_HINT, - BRIDGE_VANILLA_HINT, - BRIDGE_STONES_HINT, - BRIDGE_MEDALLIONS_HINT, - BRIDGE_REWARDS_HINT, - BRIDGE_DUNGEONS_HINT, - BRIDGE_TOKENS_HINT, - BRIDGE_GREG_HINT, - - GANON_BK_START_WITH_HINT, - GANON_BK_VANILLA_HINT, - GANON_BK_OWN_DUNGEON_HINT, - GANON_BK_OVERWORLD_HINT, - GANON_BK_ANY_DUNGEON_HINT, - GANON_BK_ANYWHERE_HINT, - GANON_BK_TRIFORCE_HINT, - GANON_BK_SKULLTULA_HINT, - - LACS_VANILLA_HINT, - LACS_STONES_HINT, - LACS_MEDALLIONS_HINT, - LACS_REWARDS_HINT, - LACS_DUNGEONS_HINT, - LACS_TOKENS_HINT, - - SIX_TRIALS, - ZERO_TRIALS, - FOUR_TO_FIVE_TRIALS, - ONE_TO_THREE_TRIALS, - - SPIRITUAL_STONE_TEXT_START, - CHILD_ALTAR_TEXT_END_DOTOPEN, - CHILD_ALTAR_TEXT_END_DOTSONGONLY, - CHILD_ALTAR_TEXT_END_DOTCLOSED, - ADULT_ALTAR_TEXT_START, - ADULT_ALTAR_TEXT_END, - - VALIDATION_LINE, - LIGHT_ARROW_LOCATION_HINT, - MASTER_SWORD_LOCATION_HINT, - DAMPE_DIARY, - YOUR_POCKET, - - GANON_LINE01, - GANON_LINE02, - GANON_LINE03, - GANON_LINE04, - GANON_LINE05, - GANON_LINE06, - GANON_LINE07, - GANON_LINE08, - GANON_LINE09, - GANON_LINE10, - GANON_LINE11, - - MEDIGORON_DIALOG_FIRST, - MEDIGORON_DIALOG_SECOND, - CARPET_SALESMAN_DIALOG_FIRST, - CARPET_SALESMAN_DIALOG_SECOND, - CARPET_SALESMAN_DIALOG_THIRD, - CARPET_SALESMAN_DIALOG_FOURTH, - GRANNY_DIALOG, - - KEY_ENUM_MAX, -} Key; \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp index 684dd16e184..c1c3391e24e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp @@ -1,53 +1,44 @@ #include "location_access.hpp" -#include "dungeon.hpp" -#include "item_list.hpp" -#include "item_location.hpp" +#include "../dungeon.h" +#include "../static_data.h" +#include "../context.h" #include "item_pool.hpp" -#include "logic.hpp" -#include "settings.hpp" #include "spoiler_log.hpp" -#include "trial.hpp" -#include "entrance.hpp" +#include "../trial.h" +#include "../entrance.h" +#include "soh/Enhancements/debugger/performanceTimer.h" #include -#include - -using namespace Logic; -using namespace Settings; //generic grotto event list -std::vector grottoEvents = { - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairy;}}), - EventAccess(&ButterflyFairy, {[]{return ButterflyFairy || (CanUse(STICKS));}}), - EventAccess(&BugShrub, {[]{return CanCutShrubs;}}), - EventAccess(&LoneFish, {[]{return true;}}), -}; +std::vector grottoEvents; //set the logic to be a specific age and time of day and see if the condition still holds bool LocationAccess::CheckConditionAtAgeTime(bool& age, bool& time) const { - IsChild = false; - IsAdult = false; - AtDay = false; - AtNight = false; + logic->IsChild = false; + logic->IsAdult = false; + logic->AtDay = false; + logic->AtNight = false; time = true; age = true; - UpdateHelpers(); return GetConditionsMet(); } bool LocationAccess::ConditionsMet() const { - - Area* parentRegion = AreaTable(Location(location)->GetParentRegionKey()); + //WARNING enterance validation can run this after resetting the access for sphere 0 validation + //When refactoring ToD access, either fix the above or do not assume that we + //have any access at all just because this is being run + Region* parentRegion = RegionTable(Rando::Context::GetInstance()->GetItemLocation(location)->GetParentRegionKey()); bool conditionsMet = false; - if ((parentRegion->childDay && CheckConditionAtAgeTime(IsChild, AtDay)) || - (parentRegion->childNight && CheckConditionAtAgeTime(IsChild, AtNight)) || - (parentRegion->adultDay && CheckConditionAtAgeTime(IsAdult, AtDay)) || - (parentRegion->adultNight && CheckConditionAtAgeTime(IsAdult, AtNight))) { + if ((parentRegion->childDay && CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) || + (parentRegion->childNight && CheckConditionAtAgeTime(logic->IsChild, logic->AtNight)) || + (parentRegion->adultDay && CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay)) || + (parentRegion->adultNight && CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight))) { conditionsMet = true; } @@ -55,99 +46,93 @@ bool LocationAccess::ConditionsMet() const { } bool LocationAccess::CanBuy() const { - //Not a shop location, don't need to check if buyable - if (!(Location(location)->IsCategory(Category::cShop))) { - return true; - } - - //Check if wallet is large enough to buy item - bool SufficientWallet = true; - if (Location(location)->GetPrice() > 500) { - SufficientWallet = ProgressiveWallet >= 3; - } else if (Location(location)->GetPrice() > 200) { - SufficientWallet = ProgressiveWallet >= 2; - } else if (Location(location)->GetPrice() > 99) { - SufficientWallet = ProgressiveWallet >= 1; - } + return CanBuyAnother(location); +} - bool OtherCondition = true; - uint32_t placed = Location(location)->GetPlacedItemKey(); - //Need bottle to buy bottle items, only logically relevant bottle items included here - if (placed == BUY_BLUE_FIRE || placed == BUY_BOTTLE_BUG || placed == BUY_FISH || placed == BUY_FAIRYS_SPIRIT) { - OtherCondition = HasBottle; - } - //If bombchus in logic, need to have found chus to buy; if not just need bomb bag - else if (placed == BUY_BOMBCHU_10 || placed == BUY_BOMBCHU_20) { - OtherCondition = (!BombchusInLogic && Bombs) || (BombchusInLogic && FoundBombchus); +bool CanBuyAnother(RandomizerCheck rc) { + uint16_t price = ctx->GetItemLocation(rc)->GetPrice(); + + if (price > 500) { + return logic->HasItem(RG_TYCOON_WALLET); + } else if (price > 200) { + return logic->HasItem(RG_GIANT_WALLET); + } else if (price > 99) { + return logic->HasItem(RG_ADULT_WALLET); + } else if (price > 0) { + return logic->HasItem(RG_CHILD_WALLET); } - - return SufficientWallet && OtherCondition; + return true; } -Area::Area() = default; -Area::Area(std::string regionName_, std::string scene_, uint32_t hintKey_, +Region::Region() = default; +Region::Region(std::string regionName_, std::string scene_, std::set areas, bool timePass_, std::vector events_, std::vector locations_, - std::list exits_) + std::list exits_) : regionName(std::move(regionName_)), scene(std::move(scene_)), - hintKey(hintKey_), + areas(areas), timePass(timePass_), events(std::move(events_)), locations(std::move(locations_)), exits(std::move(exits_)) {} -Area::~Area() = default; - -bool Area::UpdateEvents(SearchMode mode) { +Region::~Region() = default; - if (timePass && mode != SearchMode::TimePassAccess) { +void Region::ApplyTimePass(){ + if (timePass) { + StartPerformanceTimer(PT_TOD_ACCESS); if (Child()) { childDay = true; childNight = true; - AreaTable(ROOT)->childDay = true; - AreaTable(ROOT)->childNight = true; + RegionTable(RR_ROOT)->childDay = true; + RegionTable(RR_ROOT)->childNight = true; } if (Adult()) { adultDay = true; adultNight = true; - AreaTable(ROOT)->adultDay = true; - AreaTable(ROOT)->adultNight = true; + RegionTable(RR_ROOT)->adultDay = true; + RegionTable(RR_ROOT)->adultNight = true; } + StopPerformanceTimer(PT_TOD_ACCESS); } +} +bool Region::UpdateEvents() { 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; } - if ((childDay && event.CheckConditionAtAgeTime(IsChild, AtDay)) || - (childNight && event.CheckConditionAtAgeTime(IsChild, AtNight)) || - (adultDay && event.CheckConditionAtAgeTime(IsAdult, AtDay)) || - (adultNight && event.CheckConditionAtAgeTime(IsAdult, AtNight))) { + if ((childDay && event.CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) || + (childNight && event.CheckConditionAtAgeTime(logic->IsChild, logic->AtNight)) || + (adultDay && event.CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay)) || + (adultNight && event.CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight))) { event.EventOccurred(); eventsUpdated = true; } } + StopPerformanceTimer(PT_EVENT_ACCESS); return eventsUpdated; } -void Area::AddExit(uint32_t parentKey, uint32_t newExitKey, ConditionFn condition) { - Entrance newExit = Entrance(newExitKey, {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(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(uint32_t exitToBePrimary) { +void Region::SetAsPrimary(RandomizerRegion exitToBePrimary) { for (auto& exit : exits) { if (exit.Getuint32_t() == exitToBePrimary) { exit.SetAsPrimary(); @@ -156,22 +141,22 @@ void Area::SetAsPrimary(uint32_t exitToBePrimary) { } } -Entrance* Area::GetExit(uint32_t 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 (Logic::MagicBean || Logic::MagicBeanPack) && 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; @@ -179,7 +164,7 @@ bool Area::AllAccountedFor() const { } for (const LocationAccess& loc : locations) { - if (!(Location(loc.GetLocation())->IsAddedToPool())) { + if (!(Rando::Context::GetInstance()->GetItemLocation(loc.GetLocation())->IsAddedToPool())) { return false; } } @@ -193,23 +178,23 @@ bool Area::AllAccountedFor() const { return AllAccess(); } -bool Area::CheckAllAccess(const uint32_t exitKey) { +bool Region::CheckAllAccess(const RandomizerRegion exitKey) { if (!AllAccess()) { return false; } - for (Entrance& exit : exits) { - if (exit.Getuint32_t() == exitKey) { - return exit.CheckConditionAtAgeTime(Logic::IsChild, Logic::AtDay) && - exit.CheckConditionAtAgeTime(Logic::IsChild, Logic::AtNight) && - exit.CheckConditionAtAgeTime(Logic::IsAdult, Logic::AtDay) && - exit.CheckConditionAtAgeTime(Logic::IsAdult, Logic::AtNight); + for (Rando::Entrance& exit : exits) { + if (exit.GetConnectedRegionKey() == exitKey) { + return exit.CheckConditionAtAgeTime(logic->IsChild, logic->AtDay) && + exit.CheckConditionAtAgeTime(logic->IsChild, logic->AtNight) && + exit.CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay) && + exit.CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight); } } return false; } -void Area::ResetVariables() { +void Region::ResetVariables() { childDay = false; childNight = false; adultDay = false; @@ -220,131 +205,142 @@ void Area::ResetVariables() { } } -std::array areaTable; +std::array areaTable; -bool Here(const uint32_t area, ConditionFn condition) { - return areaTable[area].HereCheck(condition); +bool Here(const RandomizerRegion region, ConditionFn condition) { + return areaTable[region].Here(condition); } -bool CanPlantBean(const uint32_t area) { - return areaTable[area].CanPlantBeanCheck(); +bool CanPlantBean(const RandomizerRegion region) { + return areaTable[region].CanPlantBeanCheck(); } -bool BothAges(const uint32_t area) { - return areaTable[area].BothAgesCheck(); +bool BothAges(const RandomizerRegion region) { + return areaTable[region].BothAgesCheck(); } -bool ChildCanAccess(const uint32_t area) { - return areaTable[area].Child(); +bool ChildCanAccess(const RandomizerRegion region) { + return areaTable[region].Child(); } -bool AdultCanAccess(const uint32_t area) { - return areaTable[area].Adult(); +bool AdultCanAccess(const RandomizerRegion region) { + return areaTable[region].Adult(); } -bool HasAccessTo(const uint32_t area) { - return areaTable[area].HasAccess(); +bool HasAccessTo(const RandomizerRegion region) { + return areaTable[region].HasAccess(); } - - -void AreaTable_Init() { +Rando::Context* ctx; +std::shared_ptr logic; + +void RegionTable_Init() { + using namespace Rando; + ctx = Context::GetInstance().get(); + logic = ctx->GetLogic(); //RANDOTODO do not hardcode, instead allow accepting a Logic class somehow + grottoEvents = { + EventAccess(&logic->GossipStoneFairy, { [] { return logic->CallGossipFairy(); } }), + EventAccess(&logic->ButterflyFairy, { [] { return logic->ButterflyFairy || (logic->CanUse(RG_STICKS)); } }), + EventAccess(&logic->BugShrub, { [] { return logic->CanCutShrubs(); } }), + EventAccess(&logic->LoneFish, { [] { return true; } }), + }; //Clear the array from any previous playthrough attempts. This is important so that //locations which appear in both MQ and Vanilla dungeons don't get set in both areas. - areaTable.fill(Area("Invalid Area", "Invalid Area", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, {})); + areaTable.fill(Region("Invalid Region", "Invalid Region", {}, NO_DAY_NIGHT_CYCLE, {}, {}, {})); //name, scene, hint text, events, locations, exits - areaTable[ROOT] = Area("Root", "", LINKS_POCKET, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ROOT] = Region("Root", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(LINKS_POCKET, {[]{return true;}}), - LocationAccess(TRIFORCE_COMPLETED, { [] { return CanCompleteTriforce;}}), + LOCATION(RC_LINKS_POCKET, true), + LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Value();), + LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)), }, { //Exits - Entrance(ROOT_EXITS, {[]{return true;}}) + Entrance(RR_ROOT_EXITS, {[]{return true;}}) }); - areaTable[ROOT_EXITS] = Area("Root Exits", "", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_ROOT_EXITS] = Region("Root Exits", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(CHILD_SPAWN, {[]{return IsChild;}}), - Entrance(ADULT_SPAWN, {[]{return IsAdult;}}), - Entrance(MINUET_OF_FOREST_WARP, {[]{return CanPlay(MinuetOfForest);}}), - Entrance(BOLERO_OF_FIRE_WARP, {[]{return CanPlay(BoleroOfFire) && CanLeaveForest;}}), - Entrance(SERENADE_OF_WATER_WARP, {[]{return CanPlay(SerenadeOfWater) && CanLeaveForest;}}), - Entrance(NOCTURNE_OF_SHADOW_WARP, {[]{return CanPlay(NocturneOfShadow) && CanLeaveForest;}}), - Entrance(REQUIEM_OF_SPIRIT_WARP, {[]{return CanPlay(RequiemOfSpirit) && CanLeaveForest;}}), - Entrance(PRELUDE_OF_LIGHT_WARP, {[]{return CanPlay(PreludeOfLight) && CanLeaveForest;}}), + Entrance(RR_CHILD_SPAWN, {[]{return logic->IsChild;}}), + Entrance(RR_ADULT_SPAWN, {[]{return logic->IsAdult;}}), + Entrance(RR_MINUET_OF_FOREST_WARP, {[]{return logic->CanUse(RG_MINUET_OF_FOREST);}}), + Entrance(RR_BOLERO_OF_FIRE_WARP, {[]{return logic->CanUse(RG_BOLERO_OF_FIRE) && logic->CanLeaveForest();}}), + Entrance(RR_SERENADE_OF_WATER_WARP, {[]{return logic->CanUse(RG_SERENADE_OF_WATER) && logic->CanLeaveForest();}}), + Entrance(RR_NOCTURNE_OF_SHADOW_WARP, {[]{return logic->CanUse(RG_NOCTURNE_OF_SHADOW) && logic->CanLeaveForest();}}), + Entrance(RR_REQUIEM_OF_SPIRIT_WARP, {[]{return logic->CanUse(RG_REQUIEM_OF_SPIRIT) && logic->CanLeaveForest();}}), + Entrance(RR_PRELUDE_OF_LIGHT_WARP, {[]{return logic->CanUse(RG_PRELUDE_OF_LIGHT) && logic->CanLeaveForest();}}), }); - areaTable[CHILD_SPAWN] = Area("Child Spawn", "", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_CHILD_SPAWN] = Region("Child Spawn", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(KF_LINKS_HOUSE, {[]{return true;}}), + Entrance(RR_KF_LINKS_HOUSE, {[]{return true;}}), }); - areaTable[ADULT_SPAWN] = Area("Adult Spawn", "", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_ADULT_SPAWN] = Region("Adult Spawn", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(TEMPLE_OF_TIME, {[]{return true;}}), + Entrance(RR_TEMPLE_OF_TIME, {[]{return true;}}), }); - areaTable[MINUET_OF_FOREST_WARP] = Area("Minuet of Forest Warp", "", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_MINUET_OF_FOREST_WARP] = Region("Minuet of Forest Warp", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(SACRED_FOREST_MEADOW, {[]{return true;}}), + Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), }); - areaTable[BOLERO_OF_FIRE_WARP] = Area("Bolero of Fire Warp", "", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_BOLERO_OF_FIRE_WARP] = Region("Bolero of Fire Warp", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(DMC_CENTRAL_LOCAL, {[]{return true;}}), + Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return true;}}), }); - areaTable[SERENADE_OF_WATER_WARP] = Area("Serenade of Water Warp", "", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_SERENADE_OF_WATER_WARP] = Region("Serenade of Water Warp", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(LAKE_HYLIA, {[]{return true;}}), + Entrance(RR_LAKE_HYLIA, {[]{return true;}}), }); - areaTable[REQUIEM_OF_SPIRIT_WARP] = Area("Requiem of Spirit Warp", "", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_REQUIEM_OF_SPIRIT_WARP] = Region("Requiem of Spirit Warp", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(DESERT_COLOSSUS, {[]{return true;}}), + Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), }); - areaTable[NOCTURNE_OF_SHADOW_WARP] = Area("Nocturne of Shadow Warp", "", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_NOCTURNE_OF_SHADOW_WARP] = Region("Nocturne of Shadow Warp", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(GRAVEYARD_WARP_PAD_REGION, {[]{return true;}}), + Entrance(RR_GRAVEYARD_WARP_PAD_REGION, {[]{return true;}}), }); - areaTable[PRELUDE_OF_LIGHT_WARP] = Area("Prelude of Light Warp", "", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_PRELUDE_OF_LIGHT_WARP] = Region("Prelude of Light Warp", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(TEMPLE_OF_TIME, {[]{return true;}}), + 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 = ROOT; i <= GANONS_CASTLE; i++) { + for (uint32_t i = RR_ROOT; i <= RR_GANONS_CASTLE; i++) { for (LocationAccess& locPair : areaTable[i].locations) { - uint32_t location = locPair.GetLocation(); - Location(location)->SetParentRegion(i); + RandomizerCheck location = locPair.GetLocation(); + Rando::Context::GetInstance()->GetItemLocation(location)->SetParentRegion((RandomizerRegion)i); } for (Entrance& exit : areaTable[i].exits) { - exit.SetParentRegion(i); + exit.SetParentRegion((RandomizerRegion)i); exit.SetName(); exit.GetConnectedRegion()->entrances.push_front(&exit); } @@ -358,74 +354,114 @@ void AreaTable_Init() { */ } -namespace Areas { +void ReplaceFirstInString(std::string& s, std::string const& toReplace, std::string const& replaceWith) { + size_t pos = s.find(toReplace); + if (pos == std::string::npos) { + return; + } + s.replace(pos, toReplace.length(), replaceWith); +} - const auto GetAllAreas() { - static const size_t areaCount = MARKER_AREAS_END - (MARKER_AREAS_START + 1); +void ReplaceAllInString(std::string& s, std::string const& toReplace, std::string const& replaceWith) { + std::string buf; + size_t pos = 0; + size_t prevPos; - static std::array allAreas = {}; + buf.reserve(s.size()); + + while (true) { + prevPos = pos; + pos = s.find(toReplace, pos); + if (pos == std::string::npos) { + break; + } + buf.append(s, prevPos, pos - prevPos); + buf += replaceWith; + pos += toReplace.size(); + } + + buf.append(s, prevPos, s.size() - prevPos); + s.swap(buf); +} + +std::string CleanCheckConditionString(std::string condition) { + ReplaceAllInString(condition, "logic->", ""); + ReplaceAllInString(condition, "ctx->", ""); + ReplaceAllInString(condition, ".Value()", ""); + ReplaceAllInString(condition, "GetSaveContext()->", ""); + return condition; +} + +namespace Regions { + + const auto GetAllRegions() { + static const size_t regionCount = RR_MAX - (RR_NONE + 1); + + static std::array allRegions = {}; static bool intialized = false; if (!intialized) { - for (size_t i = 0; i < areaCount; i++) { - allAreas[i] = (MARKER_AREAS_START + 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() { - for (const uint32_t area : GetAllAreas()) { - AreaTable(area)->ResetVariables(); + auto ctx = Rando::Context::GetInstance(); + for (const RandomizerRegion region : GetAllRegions()) { + RegionTable(region)->ResetVariables(); } - if(Settings::HasNightStart) { - if(Settings::ResolvedStartingAge == AGE_CHILD) { - AreaTable(ROOT)->childNight = true; + if(/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) { + if(ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { + RegionTable(RR_ROOT)->childNight = true; } else { - AreaTable(ROOT)->adultNight = true; + RegionTable(RR_ROOT)->adultNight = true; } } else { - if(Settings::ResolvedStartingAge == AGE_CHILD) { - AreaTable(ROOT)->childDay = true; + if(ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { + RegionTable(RR_ROOT)->childDay = true; } else { - AreaTable(ROOT)->adultDay = true; + RegionTable(RR_ROOT)->adultDay = true; } } } //Reset exits and clear items from locations void ResetAllLocations() { - for (const uint32_t area : GetAllAreas()) { - AreaTable(area)->ResetVariables(); + auto ctx = Rando::Context::GetInstance(); + for (const RandomizerRegion region : GetAllRegions()) { + RegionTable(region)->ResetVariables(); //Erase item from every location in this exit - for (LocationAccess& locPair : AreaTable(area)->locations) { - uint32_t location = locPair.GetLocation(); - Location(location)->ResetVariables(); + for (LocationAccess& locPair : RegionTable(region)->locations) { + RandomizerCheck location = locPair.GetLocation(); + Rando::Context::GetInstance()->GetItemLocation(location)->ResetVariables(); } } - if(Settings::HasNightStart) { - if(Settings::ResolvedStartingAge == AGE_CHILD) { - AreaTable(ROOT)->childNight = true; + if (/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) { + if(ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { + RegionTable(RR_ROOT)->childNight = true; } else { - AreaTable(ROOT)->adultNight = true; + RegionTable(RR_ROOT)->adultNight = true; } - } else { - if(Settings::ResolvedStartingAge == AGE_CHILD) { - AreaTable(ROOT)->childDay = true; + } else { + if(ctx->GetSettings()->ResolvedStartingAge() == RO_AGE_CHILD) { + RegionTable(RR_ROOT)->childDay = true; } else { - AreaTable(ROOT)->adultDay = true; + RegionTable(RR_ROOT)->adultDay = true; } } } bool HasTimePassAccess(uint8_t age) { - for (const uint32_t areaKey : GetAllAreas()) { - auto area = AreaTable(areaKey); - if (area->timePass && ((age == AGE_CHILD && area->Child()) || (age == 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; } } @@ -441,24 +477,24 @@ namespace Areas { worldGraph.open (str + ".dot"); worldGraph << "digraph {\n\tcenter=true;\n"; - for (const uint32_t 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"; @@ -482,21 +518,21 @@ namespace Areas { worldGraph.close(); } -} //namespace Areas +} //namespace Regions -Area* AreaTable(const uint32_t areaKey) { - if (areaKey > KEY_ENUM_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(EntranceType type, bool onlyPrimary /*= true*/) { - std::vector entrancesToShuffle = {}; - for (uint32_t area : Areas::GetAllAreas()) { - for (auto& exit: AreaTable(area)->exits) { - if ((exit.GetType() == type || type == EntranceType::All) && (exit.IsPrimary() || !onlyPrimary) && exit.GetType() != EntranceType::None) { +std::vector GetShuffleableEntrances(Rando::EntranceType type, bool onlyPrimary /*= true*/) { + std::vector entrancesToShuffle = {}; + 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); } } @@ -505,9 +541,9 @@ std::vector GetShuffleableEntrances(EntranceType type, bool onlyPrima } // Get the specific entrance by name -Entrance* GetEntrance(const std::string name) { - for (uint32_t area : Areas::GetAllAreas()) { - for (auto& exit : AreaTable(area)->exits) { +Rando::Entrance* GetEntrance(const std::string name) { + 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 672a97f5c19..3961418c6ae 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp @@ -3,18 +3,21 @@ #include #include #include +#include -#include "logic.hpp" -#include "hint_list.hpp" -#include "keys.hpp" -#include "fill.hpp" +#include "../randomizerTypes.h" +#include "../context.h" +#include "../logic.h" typedef bool (*ConditionFn)(); +// I hate this but every alternative I can think of right now is worse +extern Rando::Context* ctx; +extern std::shared_ptr logic; + class EventAccess { public: - explicit EventAccess(bool* event_, std::vector conditions_met_) : event(event_) { conditions_met.resize(2); @@ -24,11 +27,12 @@ class EventAccess { } bool ConditionsMet() const { - if (Settings::Logic.Is(LOGIC_NONE) || Settings::Logic.Is(LOGIC_VANILLA)) { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) { return true; - } else if (Settings::Logic.Is(LOGIC_GLITCHLESS)) { + } else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { return conditions_met[0](); - } else if (Settings::Logic.Is(LOGIC_GLITCHED)) { + } else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) { if (conditions_met[0]()) { return true; } else if (conditions_met[1] != NULL) { @@ -40,15 +44,14 @@ class EventAccess { bool CheckConditionAtAgeTime(bool& age, bool& time) { - Logic::IsChild = false; - Logic::IsAdult = false; - Logic::AtDay = false; - Logic::AtNight = false; + logic->IsChild = false; + logic->IsAdult = false; + logic->AtDay = false; + logic->AtNight = false; time = true; age = true; - Logic::UpdateHelpers(); return ConditionsMet(); } @@ -65,12 +68,24 @@ class EventAccess { std::vector conditions_met; }; +std::string CleanCheckConditionString(std::string condition); + +#define LOCATION(check, condition) LocationAccess(check, {[]{return condition;}}, CleanCheckConditionString(#condition)) + //this class is meant to hold an item location with a boolean function to determine its accessibility from a specific area class LocationAccess { public: - explicit LocationAccess(uint32_t location_, std::vector conditions_met_) - : location(location_) { + explicit LocationAccess(RandomizerCheck location_, std::vector conditions_met_) + : location(location_), condition_str("") { + conditions_met.resize(2); + for (size_t i = 0; i < conditions_met_.size(); i++) { + conditions_met[i] = conditions_met_[i]; + } + } + + explicit LocationAccess(RandomizerCheck location_, std::vector conditions_met_, std::string condition_str_) + : location(location_), condition_str(condition_str_) { conditions_met.resize(2); for (size_t i = 0; i < conditions_met_.size(); i++) { conditions_met[i] = conditions_met_[i]; @@ -78,11 +93,12 @@ class LocationAccess { } bool GetConditionsMet() const { - if (Settings::Logic.Is(LOGIC_NONE) || Settings::Logic.Is(LOGIC_VANILLA)) { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) { return true; - } else if (Settings::Logic.Is(LOGIC_GLITCHLESS)) { + } else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { return conditions_met[0](); - } else if (Settings::Logic.Is(LOGIC_GLITCHED)) { + } else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) { if (conditions_met[0]()) { return true; } else if (conditions_met[1] != NULL) { @@ -96,39 +112,48 @@ class LocationAccess { bool ConditionsMet() const; - uint32_t GetLocation() const { + RandomizerCheck GetLocation() const { return location; } -private: - uint32_t location; + std::string GetConditionStr() const { + return condition_str; + } + +protected: + RandomizerCheck location; std::vector conditions_met; + std::string condition_str; //Makes sure shop locations are buyable bool CanBuy() const; }; -class Entrance; -enum class EntranceType; +bool CanBuyAnother(RandomizerCheck rc); -class Area { +namespace Rando { + class Entrance; + enum class EntranceType; +} + +class Region { public: - Area(); - Area(std::string regionName_, std::string scene_, uint32_t hintKey_, + Region(); + Region(std::string regionName_, std::string scene_, std::set areas, bool timePass_, std::vector events_, std::vector locations_, - std::list exits_); - ~Area(); + std::list exits_); + ~Region(); std::string regionName; std::string scene; - uint32_t hintKey; - bool timePass; + std::set areas; + bool timePass; std::vector events; std::vector locations; - std::list exits; - std::list entrances; + std::list exits; + std::list entrances; //^ The above exits are now stored in a list instead of a vector because //the entrance randomization algorithm plays around with pointers to these //entrances a lot. By putting the entrances in a list, we don't have to @@ -139,17 +164,19 @@ class Area { bool childNight = false; bool adultDay = false; bool adultNight = false; - bool addedToPool = false; + bool addedToPool = false;; + + void ApplyTimePass(); - bool UpdateEvents(SearchMode mode); + bool UpdateEvents(); - void AddExit(uint32_t parentKey, uint32_t newExitKey, ConditionFn condition); + void AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition); - void RemoveExit(Entrance* exitToRemove); + void RemoveExit(Rando::Entrance* exitToRemove); - void SetAsPrimary(uint32_t exitToBePrimary); + void SetAsPrimary(RandomizerRegion exitToBePrimary); - Entrance* GetExit(uint32_t exit); + Rando::Entrance* GetExit(RandomizerRegion exit); bool Child() const { return childDay || childNight; @@ -172,34 +199,36 @@ class Area { } //Check to see if an exit can be access as both ages at both times of day - bool CheckAllAccess(uint32_t exitKey); + bool CheckAllAccess(RandomizerRegion exitKey); + + std::set GetAllAreas() const{ + return areas; + } - const HintText& GetHint() const { - return Hint(hintKey); + void ReplaceAreas(std::set newAreas) { + areas = newAreas; } //Here checks conditional access based on whether or not both ages have //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; - bool pastChild = Logic::IsChild; + bool pastAdult = logic->IsAdult; + bool pastChild = logic->IsChild; //set age access as this areas ages - Logic::IsChild = Child(); - Logic::IsAdult = Adult(); + logic->IsChild = Child(); + logic->IsAdult = Adult(); - //update helpers and check condition as well as having at least child or adult access - Logic::UpdateHelpers(); - bool hereVal = condition() && (Logic::IsAdult || Logic::IsChild); + //heck condition as well as having at least child or adult access + bool hereVal = condition() && (logic->IsAdult || logic->IsChild); //set back age variables - Logic::IsChild = pastChild; - Logic::IsAdult = pastAdult; - Logic::UpdateHelpers(); + logic->IsChild = pastChild; + logic->IsAdult = pastAdult; return hereVal; } @@ -214,24 +243,23 @@ class Area { "Child Night: " + std::to_string(childNight) + "\t" "Adult Day: " + std::to_string(adultDay) + "\t" "Adult Night: " + std::to_string(adultNight); - //CitraPrint(message); } }; -extern std::array areaTable; +extern std::array areaTable; extern std::vector grottoEvents; -bool Here(const AreaKey area, ConditionFn condition); -bool CanPlantBean(const AreaKey area); -bool BothAges(const AreaKey area); -bool ChildCanAccess(const AreaKey area); -bool AdultCanAccess(const AreaKey area); -bool HasAccessTo(const AreaKey area); +bool Here(const RandomizerRegion region, ConditionFn condition); //RANDOTODO make a less stupid way to check own at either age than self referncing with this +bool CanPlantBean(const RandomizerRegion region); +bool BothAges(const RandomizerRegion region); +bool ChildCanAccess(const RandomizerRegion region); +bool AdultCanAccess(const RandomizerRegion region); +bool HasAccessTo(const RandomizerRegion region); #define DAY_NIGHT_CYCLE true #define NO_DAY_NIGHT_CYCLE false -namespace Areas { +namespace Regions { extern void AccessReset(); extern void ResetAllLocations(); @@ -239,29 +267,29 @@ namespace Areas { extern void DumpWorldGraph(std::string str); } //namespace Exits -void AreaTable_Init(); -Area* AreaTable(const uint32_t areaKey); -std::vector GetShuffleableEntrances(EntranceType type, bool onlyPrimary = true); -Entrance* GetEntrance(const std::string name); +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 6dce03ee132..9d06b9f7ebe 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 @@ -1,86 +1,85 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_BottomOfTheWell() { +void RegionTable_Init_BottomOfTheWell() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[BOTTOM_OF_THE_WELL_ENTRYWAY] = Area("Bottom of the Well Entryway", "Bottom of the Well", 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(BOTTOM_OF_THE_WELL_MAIN_AREA, {[]{return Dungeon::BottomOfTheWell.IsVanilla() && IsChild && (CanChildAttack || Nuts);}}), - Entrance(BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return Dungeon::BottomOfTheWell.IsMQ() && IsChild;}}), - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_BOTTOM_OF_THE_WELL_MAIN_AREA, {[]{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() && logic->IsChild && (logic->CanAttack() || logic->CanUse(RG_NUTS));}}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ() && logic->IsChild;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::BottomOfTheWell.IsVanilla()) { - areaTable[BOTTOM_OF_THE_WELL_MAIN_AREA] = Area("Bottom of the Well Main Area", "Bottom of the Well", BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla()) { + areaTable[RR_BOTTOM_OF_THE_WELL_MAIN_AREA] = Region("Bottom of the Well Main Region", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&StickPot, {[]{return true;}}), - EventAccess(&NutPot, {[]{return true;}}), + EventAccess(&logic->StickPot, {[]{return true;}}), + EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LocationAccess(BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, {[]{return LogicLensBotw || CanUse(LENS_OF_TRUTH);}}), - LocationAccess(BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, {[]{return HasExplosives;}}), - LocationAccess(BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, {[]{return LogicLensBotw || CanUse(LENS_OF_TRUTH);}}), - LocationAccess(BOTTOM_OF_THE_WELL_COMPASS_CHEST, {[]{return LogicLensBotw || CanUse(LENS_OF_TRUTH);}}), - LocationAccess(BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, {[]{return LogicLensBotw || CanUse(LENS_OF_TRUTH);}}), - LocationAccess(BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, {[]{return (LogicLensBotw || CanUse(LENS_OF_TRUTH)) && HasExplosives;}}), - LocationAccess(BOTTOM_OF_THE_WELL_FREESTANDING_KEY, {[]{return Sticks || CanUse(DINS_FIRE);}}), - LocationAccess(BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, {[]{return CanPlay(ZeldasLullaby) && (KokiriSword || (Sticks && LogicChildDeadhand));}}), - LocationAccess(BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, {[]{return CanPlay(ZeldasLullaby) && (LogicLensBotw || CanUse(LENS_OF_TRUTH));}}), - LocationAccess(BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, {[]{return CanPlay(ZeldasLullaby);}}), - LocationAccess(BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, {[]{return CanPlay(ZeldasLullaby);}}), - LocationAccess(BOTTOM_OF_THE_WELL_MAP_CHEST, {[]{return HasExplosives || (((SmallKeys(BOTTOM_OF_THE_WELL, 3) && (LogicLensBotw || CanUse(LENS_OF_TRUTH))) || CanUse(DINS_FIRE) || (Sticks && LogicBotwBasement)) && GoronBracelet);}}), - LocationAccess(BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, {[]{return SmallKeys(BOTTOM_OF_THE_WELL, 3) && (LogicLensBotw || CanUse(LENS_OF_TRUTH));}}), - LocationAccess(BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, {[]{return SmallKeys(BOTTOM_OF_THE_WELL, 3) && (LogicLensBotw || CanUse(LENS_OF_TRUTH));}}), - LocationAccess(BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, {[]{return Boomerang && (LogicLensBotw || CanUse(LENS_OF_TRUTH)) && SmallKeys(BOTTOM_OF_THE_WELL, 3);}}), - LocationAccess(BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, {[]{return Boomerang && (LogicLensBotw || CanUse(LENS_OF_TRUTH)) && SmallKeys(BOTTOM_OF_THE_WELL, 3);}}), - LocationAccess(BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, {[]{return SmallKeys(BOTTOM_OF_THE_WELL, 3) && (LogicLensBotw || CanUse(LENS_OF_TRUTH)) && Boomerang;}}), + LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_LEFT_FAKE_WALL_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives()), + LOCATION(RC_BOTTOM_OF_THE_WELL_RIGHT_BOTTOM_FAKE_WALL_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_BOTTOM_OF_THE_WELL_COMPASS_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_BOTTOM_OF_THE_WELL_CENTER_SKULLTULA_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_BOTTOM_OF_THE_WELL_BACK_LEFT_BOMBABLE_CHEST, (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), + LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_ZELDAS_LULLABY)) && logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_BOTTOM_OF_THE_WELL_LENS_OF_TRUTH_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_KOKIRI_SWORD) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_CHILD_DEADHAND)))), + LOCATION(RC_BOTTOM_OF_THE_WELL_INVISIBLE_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasExplosives() || (((logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))) || logic->CanUse(RG_DINS_FIRE) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_BASEMENT))) && logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, logic->CanUse(RG_BOOMERANG) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3)), + LOCATION(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, logic->CanUse(RG_BOOMERANG) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3)), + LOCATION(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_BOOMERANG)), }, { //Exits - Entrance(BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return true;}}), + Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return true;}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::BottomOfTheWell.IsMQ()) { - areaTable[BOTTOM_OF_THE_WELL_MQ_PERIMETER] = Area("Bottom of the Well MQ Perimeter", "Bottom of the Well", BOTTOM_OF_THE_WELL, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ()) { + //RANDOTODO double check the CanAttacks when rewriting, i assumed CanChildAttack was the only one called because of the initial crawlspace + areaTable[RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER] = Region("Bottom of the Well MQ Perimeter", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, { //Events - //EventAccess(&WallFairy, {[]{return WallFairy || Slingshot;}}), + //EventAccess(&WallFairy, {[]{return WallFairy || logic->Slingshot;}}), }, { //Locations - LocationAccess(BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, {[]{return KokiriSword || (Sticks && LogicChildDeadhand);}}), - LocationAccess(BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, {[]{return HasExplosives || (LogicBotwMQDeadHandKey && Boomerang);}}), - //Trick: HasExplosives || (LogicBotWMQDeadHandKey && Boomerang) - LocationAccess(BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, {[]{return CanChildAttack;}}), - LocationAccess(BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, {[]{return CanChildAttack && SmallKeys(BOTTOM_OF_THE_WELL, 2);}}), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COMPASS_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_CHILD_DEADHAND))), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_FREESTANDING_KEY, logic->HasExplosives() || (ctx->GetTrickOption(RT_BOTW_MQ_DEADHAND_KEY) && logic->CanUse(RG_BOOMERANG))), + //Trick: logic->HasExplosives() || (LogicBotWMQDeadHandKey && logic->CanUse(RG_BOOMERANG)) + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, logic->CanAttack()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, logic->CanAttack() && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2)), }, { //Exits - Entrance(BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return true;}}), - Entrance(BOTTOM_OF_THE_WELL_MQ_MIDDLE, {[]{return CanPlay(ZeldasLullaby) || (LogicBotwMQPits && HasExplosives);}}), - //Trick: CanPlay(ZeldasLullaby) || (LogicBotWMQPits && HasExplosives) + Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return true;}}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) || (ctx->GetTrickOption(RT_BOTW_MQ_PITS) && logic->HasExplosives());}}), + //Trick: logic->CanUse(RG_ZELDAS_LULLABY) || (LogicBotWMQPits && logic->HasExplosives()) }); - areaTable[BOTTOM_OF_THE_WELL_MQ_MIDDLE] = Area("Bottom of the Well MQ Middle", "Bottom of the Well", 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 - LocationAccess(BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, {[]{return true;}}), - LocationAccess(BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, {[]{return HasExplosives && SmallKeys(BOTTOM_OF_THE_WELL, 2);}}), - LocationAccess(BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, {[]{return true;}}), - LocationAccess(BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, {[]{return CanChildAttack && (LogicBotwMQPits || HasExplosives);}}), - //Trick: CanChildAttack && (LogicBotWMQPits || HasExplosives) + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_LENS_OF_TRUTH_CHEST, logic->HasExplosives() && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->CanAttack() && (ctx->GetTrickOption(RT_BOTW_MQ_PITS) || logic->HasExplosives())), + //Trick: logic->CanChildAttack && (LogicBotWMQPits || logic->HasExplosives()) }, { //Exits - Entrance(BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return true;}}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return true;}}), }); } } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp index dab5ceb3669..6cc423e941c 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 @@ -1,273 +1,289 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" +#include "../../entrance.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_CastleTown() { - areaTable[MARKET_ENTRANCE] = Area("Market Entrance", "Market Entrance", 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(HYRULE_FIELD, {[]{return IsAdult || AtDay;}}), - Entrance(THE_MARKET, {[]{return true;}}), - Entrance(MARKET_GUARD_HOUSE, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return logic->IsAdult || logic->AtDay;}}), + Entrance(RR_THE_MARKET, {[]{return true;}}), + Entrance(RR_MARKET_GUARD_HOUSE, {[]{return true;}}), }); - areaTable[THE_MARKET] = Area("Market", "Market", THE_MARKET, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_THE_MARKET] = Region("Market", "Market", {RA_THE_MARKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(MARKET_ENTRANCE, {[]{return true;}}), - Entrance(TOT_ENTRANCE, {[]{return true;}}), - Entrance(CASTLE_GROUNDS, {[]{return true;}}), - Entrance(MARKET_BAZAAR, {[]{return IsChild && AtDay;}}), - Entrance(MARKET_MASK_SHOP, {[]{return IsChild && AtDay;}}), - Entrance(MARKET_SHOOTING_GALLERY, {[]{return IsChild && AtDay;}}), - Entrance(MARKET_BOMBCHU_BOWLING, {[]{return IsChild;}}), - Entrance(MARKET_TREASURE_CHEST_GAME, {[]{return IsChild && AtNight;}}), - Entrance(MARKET_POTION_SHOP, {[]{return IsChild && AtDay;}}), - Entrance(MARKET_BACK_ALLEY, {[]{return IsChild;}}), + Entrance(RR_MARKET_ENTRANCE, {[]{return true;}}), + Entrance(RR_TOT_ENTRANCE, {[]{return true;}}), + Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), + Entrance(RR_MARKET_BAZAAR, {[]{return logic->IsChild && logic->AtDay;}}), + Entrance(RR_MARKET_MASK_SHOP, {[]{return logic->IsChild && logic->AtDay;}}), + Entrance(RR_MARKET_SHOOTING_GALLERY, {[]{return logic->IsChild && logic->AtDay;}}), + Entrance(RR_MARKET_BOMBCHU_BOWLING, {[]{return logic->IsChild;}}), + Entrance(RR_MARKET_TREASURE_CHEST_GAME, {[]{return logic->IsChild && logic->AtNight;}}), + Entrance(RR_MARKET_POTION_SHOP, {[]{return logic->IsChild && logic->AtDay;}}), + Entrance(RR_MARKET_BACK_ALLEY, {[]{return logic->IsChild;}}), }); - areaTable[MARKET_BACK_ALLEY] = Area("Market Back Alley", "Market", 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(THE_MARKET, {[]{return true;}}), - Entrance(MARKET_BOMBCHU_SHOP, {[]{return AtNight;}}), - Entrance(MARKET_DOG_LADY_HOUSE, {[]{return true;}}), - Entrance(MARKET_MAN_IN_GREEN_HOUSE, {[]{return AtNight;}}), + Entrance(RR_THE_MARKET, {[]{return true;}}), + Entrance(RR_MARKET_BOMBCHU_SHOP, {[]{return logic->AtNight;}}), + Entrance(RR_MARKET_DOG_LADY_HOUSE, {[]{return true;}}), + Entrance(RR_MARKET_MAN_IN_GREEN_HOUSE, {[]{return logic->AtNight;}}), }); - areaTable[TOT_ENTRANCE] = Area("ToT Entrance", "ToT Entrance", THE_MARKET, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_TOT_ENTRANCE] = Region("ToT Entrance", "ToT Entrance", {RA_THE_MARKET}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), }, { //Locations - LocationAccess(TOT_GOSSIP_STONE_LEFT, {[]{return true;}}), - LocationAccess(TOT_GOSSIP_STONE_LEFT_CENTER, {[]{return true;}}), - LocationAccess(TOT_GOSSIP_STONE_RIGHT_CENTER, {[]{return true;}}), - LocationAccess(TOT_GOSSIP_STONE_RIGHT, {[]{return true;}}), + LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE, true), + LOCATION(RC_TOT_LEFT_CENTER_GOSSIP_STONE, true), + LOCATION(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, true), + LOCATION(RC_TOT_RIGHTMOST_GOSSIP_STONE, true), }, { //Exits - Entrance(THE_MARKET, {[]{return true;}}), - Entrance(TEMPLE_OF_TIME, {[]{return true;}}), + Entrance(RR_THE_MARKET, {[]{return true;}}), + Entrance(RR_TEMPLE_OF_TIME, {[]{return true;}}), }); - areaTable[TEMPLE_OF_TIME] = Area("Temple of Time", "Temple of Time", 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 - LocationAccess(TOT_LIGHT_ARROWS_CUTSCENE, {[]{return IsAdult && CanTriggerLACS;}}), + LOCATION(RC_TOT_LIGHT_ARROWS_CUTSCENE, logic->IsAdult && logic->CanTriggerLACS()), + LOCATION(RC_ALTAR_HINT_CHILD, logic->IsChild), + LOCATION(RC_ALTAR_HINT_ADULT, logic->IsAdult), + LOCATION(RC_TOT_SHEIK_HINT, logic->IsAdult), }, { //Exits - Entrance(TOT_ENTRANCE, {[]{return true;}}), - Entrance(TOT_BEYOND_DOOR_OF_TIME, {[]{return OpenDoorOfTime.Is(OPENDOOROFTIME_OPEN) || (CanPlay(SongOfTime) && (OpenDoorOfTime.Is(OPENDOOROFTIME_SONGONLY) || (HasAllStones && OcarinaOfTime)));}}), + Entrance(RR_TOT_ENTRANCE, {[]{return true;}}), + Entrance(RR_TOT_BEYOND_DOOR_OF_TIME, {[]{return ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_OPEN) || (logic->CanUse(RG_SONG_OF_TIME) && (ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_SONGONLY) || (logic->StoneCount() == 3 && logic->HasItem(RG_OCARINA_OF_TIME))));}}), }); - areaTable[TOT_BEYOND_DOOR_OF_TIME] = Area("Beyond Door of Time", "Beyond Door of Time", 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(&TimeTravel, {[]{return true;}}), + //EventAccess(&logic->TimeTravel, {[]{return true;}}), }, { //Locations - LocationAccess(TOT_MASTER_SWORD, {[]{return IsAdult;}}), - LocationAccess(SHEIK_AT_TEMPLE, {[]{return ForestMedallion && IsAdult;}}), + LOCATION(RC_TOT_MASTER_SWORD, logic->IsAdult), + LOCATION(RC_GIFT_FROM_SAGES, logic->IsAdult), + LOCATION(RC_SHEIK_AT_TEMPLE, logic->HasItem(RG_FOREST_MEDALLION) && logic->IsAdult), }, { //Exits - Entrance(TEMPLE_OF_TIME, {[]{return true;}}), + Entrance(RR_TEMPLE_OF_TIME, {[]{return true;}}), }); - areaTable[CASTLE_GROUNDS] = Area("Castle Grounds", "Castle Grounds", CASTLE_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, {}, { +//With multi-area support {RA_CASTLE_GROUNDS} is not strictly required anymore, as any interior here could inherit both +//{RA_HYRULE_CASTLE} and {RA_OUTSIDE_GANONS_CASTLE}, but an setting to merge the latter 2 into the former may be preffered + areaTable[RR_CASTLE_GROUNDS] = Region("Castle Grounds", "Castle Grounds", {RA_CASTLE_GROUNDS}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(THE_MARKET, {[]{return true;}}), - Entrance(HYRULE_CASTLE_GROUNDS, {[]{return IsChild;}}), - Entrance(GANONS_CASTLE_GROUNDS, {[]{return IsAdult;}}), + Entrance(RR_THE_MARKET, {[]{return true;}}), + Entrance(RR_HYRULE_CASTLE_GROUNDS, {[]{return logic->IsChild;}}), + Entrance(RR_GANONS_CASTLE_GROUNDS, {[]{return logic->IsAdult;}}), }); - areaTable[HYRULE_CASTLE_GROUNDS] = Area("Hyrule Castle Grounds", "Castle Grounds", HYRULE_CASTLE, DAY_NIGHT_CYCLE, { + areaTable[RR_HYRULE_CASTLE_GROUNDS] = Region("Hyrule Castle Grounds", "Castle Grounds", {RA_HYRULE_CASTLE}, DAY_NIGHT_CYCLE, { //Events - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairy;}}), - EventAccess(&ButterflyFairy, {[]{return ButterflyFairy || CanUse(STICKS);}}), - EventAccess(&BugRock, {[]{return true;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), + EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), + EventAccess(&logic->BugRock, {[]{return true;}}), }, { //Locations - LocationAccess(HC_MALON_EGG, {[]{return true;}}), - LocationAccess(HC_GS_TREE, {[]{return CanChildAttack;}}), - LocationAccess(HC_MALON_GOSSIP_STONE, {[]{return true;}}), - LocationAccess(HC_ROCK_WALL_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_HC_MALON_EGG, true), + LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanAttack()), + LOCATION(RC_HC_MALON_GOSSIP_STONE, true), + LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true), }, { //Exits - Entrance(CASTLE_GROUNDS, {[]{return true;}}), - Entrance(HC_GARDEN, {[]{return WeirdEgg || !ShuffleWeirdEgg;}}), - Entrance(HC_GREAT_FAIRY_FOUNTAIN, {[]{return CanBlastOrSmash;}}), - Entrance(HC_STORMS_GROTTO, {[]{return CanOpenStormGrotto;}}), + Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), + Entrance(RR_HC_GARDEN, {[]{return logic->CanUse(RG_WEIRD_EGG) || !ctx->GetOption(RSK_SHUFFLE_WEIRD_EGG);}}), + Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, {[]{return logic->BlastOrSmash();}}), + Entrance(RR_HC_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); - areaTable[HC_GARDEN] = Area("HC Garden", "Castle Grounds", HYRULE_CASTLE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_HC_GARDEN] = Region("HC Garden", "Castle Grounds", {RA_HYRULE_CASTLE}, NO_DAY_NIGHT_CYCLE, { //Events }, { //Locations - LocationAccess(HC_ZELDAS_LETTER, {[]{return true;}}), - LocationAccess(SONG_FROM_IMPA, {[]{return true;}}), + LOCATION(RC_HC_ZELDAS_LETTER, true), + LOCATION(RC_SONG_FROM_IMPA, true), }, { //Exits - Entrance(HYRULE_CASTLE_GROUNDS, {[]{return true;}}), + Entrance(RR_HYRULE_CASTLE_GROUNDS, {[]{return true;}}), }); - areaTable[HC_GREAT_FAIRY_FOUNTAIN] = Area("HC Great Fairy Fountain", "HC Great Fairy Fountain", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_HC_GREAT_FAIRY_FOUNTAIN] = Region("HC Great Fairy Fountain", "HC Great Fairy Fountain", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(HC_GREAT_FAIRY_REWARD, {[]{return CanPlay(ZeldasLullaby);}}), + LOCATION(RC_HC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits - Entrance(CASTLE_GROUNDS, {[]{return true;}}), + Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), }); - areaTable[HC_STORMS_GROTTO] = Area("HC Storms Grotto", "HC Storms Grotto", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_HC_STORMS_GROTTO] = Region("HC Storms Grotto", "HC Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&NutPot, {[]{return NutPot || CanBlastOrSmash;}}), - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || (CanBlastOrSmash && CanSummonGossipFairy);}}), - EventAccess(&WanderingBugs, {[]{return WanderingBugs || CanBlastOrSmash;}}), + EventAccess(&logic->NutPot, {[]{return logic->NutPot || logic->BlastOrSmash();}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CanBreakMudWalls() && logic->CallGossipFairy();}}), + EventAccess(&logic->WanderingBugs, {[]{return logic->WanderingBugs || logic->BlastOrSmash();}}), }, { //Locations - LocationAccess(HC_GS_STORMS_GROTTO, {[]{return (CanBlastOrSmash && HookshotOrBoomerang) || (Boomerang && LogicCastleStormsGS);}}), - LocationAccess(HC_STORMS_GROTTO_GOSSIP_STONE, {[]{return CanBlastOrSmash;}}), + LOCATION(RC_HC_GS_STORMS_GROTTO, (logic->BlastOrSmash() && logic->HookshotOrBoomerang()) || (logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_HC_STORMS_GS))), + LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE, logic->BlastOrSmash()), }, { //Exits - Entrance(CASTLE_GROUNDS, {[]{return true;}}), + Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), }); - areaTable[GANONS_CASTLE_GROUNDS] = Area("Ganon's Castle Grounds", "Castle Grounds", OUTSIDE_GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, { - EventAccess(&BuiltRainbowBridge, {[]{return CanBuildRainbowBridge;}}), + areaTable[RR_GANONS_CASTLE_GROUNDS] = Region("Ganon's Castle Grounds", "Castle Grounds", {RA_OUTSIDE_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { + EventAccess(&logic->BuiltRainbowBridge, {[]{return logic->CanBuildRainbowBridge();}}), }, { - //Locations //the terrain was lowered such that you can't get this GS with a simple sword slash - LocationAccess(OGC_GS, {[]{return CanJumpslash || CanUseProjectile - || (CanShield && CanUse(MEGATON_HAMMER)) || CanUse(DINS_FIRE);}}), + //Locations + LOCATION(RC_OGC_GS, logic->CanJumpslash() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), }, { //Exits - Entrance(CASTLE_GROUNDS, {[]{return AtNight;}}), - Entrance(OGC_GREAT_FAIRY_FOUNTAIN, {[]{return CanUse(GOLDEN_GAUNTLETS) && AtNight;}}), - Entrance(GANONS_CASTLE_LEDGE, {[]{return BuiltRainbowBridge;}}), + Entrance(RR_CASTLE_GROUNDS, {[]{return logic->AtNight;}}), + Entrance(RR_OGC_GREAT_FAIRY_FOUNTAIN, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->AtNight;}}), + Entrance(RR_GANONS_CASTLE_LEDGE, {[]{return logic->BuiltRainbowBridge;}}), }); - areaTable[OGC_GREAT_FAIRY_FOUNTAIN] = Area("OGC Great Fairy Fountain", "OGC Great Fairy Fountain", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_OGC_GREAT_FAIRY_FOUNTAIN] = Region("OGC Great Fairy Fountain", "OGC Great Fairy Fountain", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(OGC_GREAT_FAIRY_REWARD, {[]{return CanPlay(ZeldasLullaby);}}), + LOCATION(RC_OGC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits - Entrance(CASTLE_GROUNDS, {[]{return true;}}), + Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), }); - areaTable[CASTLE_GROUNDS_FROM_GANONS_CASTLE] = Area("Castle Grounds From Ganon's Castle", "Castle Grounds From Ganon's Castle", NONE, 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(HYRULE_CASTLE_GROUNDS, { [] { return IsChild; }}), - Entrance(GANONS_CASTLE_LEDGE, { [] { return IsAdult; }}), + Entrance(RR_HYRULE_CASTLE_GROUNDS, { [] { return logic->IsChild; }}), + Entrance(RR_GANONS_CASTLE_LEDGE, { [] { return logic->IsAdult; }}), }); - areaTable[GANONS_CASTLE_LEDGE] = Area("Ganon's Castle Ledge", "OGC Ganon's Castle Ledge", 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(GANONS_CASTLE_GROUNDS, {[]{return BuiltRainbowBridge;}}), - Entrance(GANONS_CASTLE_ENTRYWAY, {[]{return IsAdult;}}), + Entrance(RR_GANONS_CASTLE_GROUNDS, {[]{return logic->BuiltRainbowBridge;}}), + Entrance(RR_GANONS_CASTLE_ENTRYWAY, {[]{return logic->IsAdult;}}), }); - areaTable[MARKET_GUARD_HOUSE] = Area("Market Guard House", "Market Guard House", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_GUARD_HOUSE] = Region("Market Guard House", "Market Guard House", {}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->CanEmptyBigPoes, {[]{return logic->IsAdult;}}), + }, { //Locations - LocationAccess(MARKET_10_BIG_POES, {[]{return IsAdult && BigPoeKill;}}), - LocationAccess(MARKET_GS_GUARD_HOUSE, {[]{return IsChild;}}), + LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && logic->BigPoeKill), + LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), }, { //Exits - Entrance(MARKET_ENTRANCE, {[]{return true;}}), + Entrance(RR_MARKET_ENTRANCE, {[]{return true;}}), }); - areaTable[MARKET_BAZAAR] = Area("Market Bazaar", "Market Bazaar", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_BAZAAR] = Region("Market Bazaar", "Market Bazaar", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(MARKET_BAZAAR_ITEM_1, {[]{return true;}}), - LocationAccess(MARKET_BAZAAR_ITEM_2, {[]{return true;}}), - LocationAccess(MARKET_BAZAAR_ITEM_3, {[]{return true;}}), - LocationAccess(MARKET_BAZAAR_ITEM_4, {[]{return true;}}), - LocationAccess(MARKET_BAZAAR_ITEM_5, {[]{return true;}}), - LocationAccess(MARKET_BAZAAR_ITEM_6, {[]{return true;}}), - LocationAccess(MARKET_BAZAAR_ITEM_7, {[]{return true;}}), - LocationAccess(MARKET_BAZAAR_ITEM_8, {[]{return true;}}), + LOCATION(RC_MARKET_BAZAAR_ITEM_1, true), + LOCATION(RC_MARKET_BAZAAR_ITEM_2, true), + LOCATION(RC_MARKET_BAZAAR_ITEM_3, true), + LOCATION(RC_MARKET_BAZAAR_ITEM_4, true), + LOCATION(RC_MARKET_BAZAAR_ITEM_5, true), + LOCATION(RC_MARKET_BAZAAR_ITEM_6, true), + LOCATION(RC_MARKET_BAZAAR_ITEM_7, true), + LOCATION(RC_MARKET_BAZAAR_ITEM_8, true), }, { //Exits - Entrance(THE_MARKET, {[]{return true;}}), + Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[MARKET_MASK_SHOP] = Area("Market Mask Shop", "Market Mask Shop", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_MARKET_MASK_SHOP] = Region("Market Mask Shop", "Market Mask Shop", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&SkullMask, {[]{return SkullMask || (ZeldasLetter && (CompleteMaskQuest || ChildCanAccess(KAKARIKO_VILLAGE)));}}), - EventAccess(&MaskOfTruth, {[]{return MaskOfTruth || (SkullMask && (CompleteMaskQuest || (ChildCanAccess(THE_LOST_WOODS) && CanPlay(SariasSong) && AreaTable(THE_GRAVEYARD)->childDay && ChildCanAccess(HYRULE_FIELD) && HasAllStones)));}}), - }, {}, { + EventAccess(&logic->SkullMask, {[]{return logic->SkullMask || (logic->HasItem(RG_ZELDAS_LETTER) && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE)));}}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link's pocket + EventAccess(&logic->MaskOfTruth, {[]{return logic->MaskOfTruth || (logic->SkullMask && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && RegionTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->StoneCount() == 3)));}}), + }, { + LOCATION(RC_MASK_SHOP_HINT, true), + }, { //Exits - Entrance(THE_MARKET, {[]{return true;}}), + Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[MARKET_SHOOTING_GALLERY] = Area("Market Shooting Gallery", "Market Shooting Gallery", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_SHOOTING_GALLERY] = Region("Market Shooting Gallery", "Market Shooting Gallery", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(MARKET_SHOOTING_GALLERY_REWARD, {[]{return IsChild;}}), + LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->HasItem(RG_CHILD_WALLET)), }, { //Exits - Entrance(THE_MARKET, {[]{return true;}}), + Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[MARKET_BOMBCHU_BOWLING] = Area("Market Bombchu Bowling", "Market Bombchu Bowling", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_BOMBCHU_BOWLING] = Region("Market Bombchu Bowling", "Market Bombchu Bowling", {}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->CouldPlayBowling, {[]{return (logic->HasItem(RG_CHILD_WALLET));}}), + }, { //Locations - LocationAccess(MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, {[]{return CanPlayBowling;}}), - LocationAccess(MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, {[]{return CanPlayBowling;}}), - LocationAccess(MARKET_BOMBCHU_BOWLING_BOMBCHUS, {[]{return CanPlayBowling;}}), + LOCATION(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled()), + LOCATION(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled()), }, { //Exits - Entrance(THE_MARKET, {[]{return true;}}), + Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[MARKET_POTION_SHOP] = Area("Market Potion Shop", "Market Potion Shop", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_POTION_SHOP] = Region("Market Potion Shop", "Market Potion Shop", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(MARKET_POTION_SHOP_ITEM_1, {[]{return true;}}), - LocationAccess(MARKET_POTION_SHOP_ITEM_2, {[]{return true;}}), - LocationAccess(MARKET_POTION_SHOP_ITEM_3, {[]{return true;}}), - LocationAccess(MARKET_POTION_SHOP_ITEM_4, {[]{return true;}}), - LocationAccess(MARKET_POTION_SHOP_ITEM_5, {[]{return true;}}), - LocationAccess(MARKET_POTION_SHOP_ITEM_6, {[]{return true;}}), - LocationAccess(MARKET_POTION_SHOP_ITEM_7, {[]{return true;}}), - LocationAccess(MARKET_POTION_SHOP_ITEM_8, {[]{return true;}}), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_1, true), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_2, true), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_3, true), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_4, true), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_5, true), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_6, true), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_7, true), + LOCATION(RC_MARKET_POTION_SHOP_ITEM_8, true), }, { //Exits - Entrance(THE_MARKET, {[]{return true;}}), + Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[MARKET_TREASURE_CHEST_GAME] = Area("Market Treasure Chest Game", "Market Treasure Chest Game", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_TREASURE_CHEST_GAME] = Region("Market Treasure Chest Game", "Market Treasure Chest Game", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(MARKET_TREASURE_CHEST_GAME_REWARD, {[]{return (CanUse(LENS_OF_TRUTH) && !ShuffleChestMinigame) || (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_SINGLE_KEYS) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 6)) || (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_PACK) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 1));}}), - LocationAccess(MARKET_TREASURE_CHEST_GAME_ITEM_1, {[]{return (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_SINGLE_KEYS) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 1)) || (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_PACK) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 1)) || (CanUse(LENS_OF_TRUTH) && !ShuffleChestMinigame);}}), - LocationAccess(MARKET_TREASURE_CHEST_GAME_ITEM_2, {[]{return (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_SINGLE_KEYS) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 2)) || (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_PACK) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 1)) || (CanUse(LENS_OF_TRUTH) && !ShuffleChestMinigame);}}), - LocationAccess(MARKET_TREASURE_CHEST_GAME_ITEM_3, {[]{return (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_SINGLE_KEYS) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 3)) || (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_PACK) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 1)) || (CanUse(LENS_OF_TRUTH) && !ShuffleChestMinigame);}}), - LocationAccess(MARKET_TREASURE_CHEST_GAME_ITEM_4, {[]{return (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_SINGLE_KEYS) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 4)) || (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_PACK) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 1)) || (CanUse(LENS_OF_TRUTH) && !ShuffleChestMinigame);}}), - LocationAccess(MARKET_TREASURE_CHEST_GAME_ITEM_5, {[]{return (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_SINGLE_KEYS) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 5)) || (ShuffleChestMinigame.Is(SHUFFLECHESTMINIGAME_PACK) && SmallKeys(MARKET_TREASURE_CHEST_GAME, 1)) || (CanUse(LENS_OF_TRUTH) && !ShuffleChestMinigame);}}), + LOCATION(RC_GREG_HINT, true), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && ((logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), + LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), }, { //Exits - Entrance(THE_MARKET, {[]{return true;}}), + Entrance(RR_THE_MARKET, {[]{return true;}}), }); - areaTable[MARKET_BOMBCHU_SHOP] = Area("Market Bombchu Shop", "Market Bombchu Shop", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_BOMBCHU_SHOP] = Region("Market Bombchu Shop", "Market Bombchu Shop", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(MARKET_BOMBCHU_SHOP_ITEM_1, {[]{return true;}}), - LocationAccess(MARKET_BOMBCHU_SHOP_ITEM_2, {[]{return true;}}), - LocationAccess(MARKET_BOMBCHU_SHOP_ITEM_3, {[]{return true;}}), - LocationAccess(MARKET_BOMBCHU_SHOP_ITEM_4, {[]{return true;}}), - LocationAccess(MARKET_BOMBCHU_SHOP_ITEM_5, {[]{return true;}}), - LocationAccess(MARKET_BOMBCHU_SHOP_ITEM_6, {[]{return true;}}), - LocationAccess(MARKET_BOMBCHU_SHOP_ITEM_7, {[]{return true;}}), - LocationAccess(MARKET_BOMBCHU_SHOP_ITEM_8, {[]{return true;}}), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_1, true), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_2, true), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_3, true), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_4, true), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_5, true), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_6, true), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_7, true), + LOCATION(RC_MARKET_BOMBCHU_SHOP_ITEM_8, true), }, { //Exits - Entrance(MARKET_BACK_ALLEY, {[]{return true;}}), + Entrance(RR_MARKET_BACK_ALLEY, {[]{return true;}}), }); - areaTable[MARKET_DOG_LADY_HOUSE] = Area("Market Dog Lady House", "Market Dog Lady House", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_MARKET_DOG_LADY_HOUSE] = Region("Market Dog Lady House", "Market Dog Lady House", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(MARKET_LOST_DOG, {[]{return IsChild && AtNight;}}), + LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight), }, { //Exits - Entrance(MARKET_BACK_ALLEY, {[]{return true;}}), + Entrance(RR_MARKET_BACK_ALLEY, {[]{return true;}}), }); - areaTable[MARKET_MAN_IN_GREEN_HOUSE] = Area("Market Man in Green House", "Market Man in Green House", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_MARKET_MAN_IN_GREEN_HOUSE] = Region("Market Man in Green House", "Market Man in Green House", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(MARKET_BACK_ALLEY, {[]{return true;}}), + 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 19960f1be87..e914230fbba 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 @@ -1,260 +1,266 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" +#include "../../entrance.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_DeathMountain() { - areaTable[DEATH_MOUNTAIN_TRAIL] = Area("Death Mountain", "Death Mountain", DEATH_MOUNTAIN_TRAIL, DAY_NIGHT_CYCLE, { +void RegionTable_Init_DeathMountain() { + areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Region("Death Mountain", "Death Mountain", {RA_DEATH_MOUNTAIN_TRAIL}, DAY_NIGHT_CYCLE, { //Events - EventAccess(&BeanPlantFairy, {[]{return BeanPlantFairy || (CanPlantBean(DEATH_MOUNTAIN_TRAIL) && CanPlay(SongOfStorms) && (HasExplosives || GoronBracelet));}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)));}}), }, { //Locations - LocationAccess(DMT_CHEST, {[]{return CanBlastOrSmash || (LogicDMTBombable && IsChild && GoronBracelet);}}), - LocationAccess(DMT_FREESTANDING_POH, {[]{return CanTakeDamage || CanUse(HOVER_BOOTS) || (IsAdult && CanPlantBean(DEATH_MOUNTAIN_TRAIL) && (HasExplosives || GoronBracelet));}}), - LocationAccess(DMT_GS_BEAN_PATCH, {[]{return CanPlantBugs && (HasExplosives || GoronBracelet || (LogicDMTSoilGS && (CanTakeDamage || CanUse(HOVER_BOOTS)) && CanUse(BOOMERANG)));}}), - LocationAccess(DMT_GS_NEAR_KAK, {[]{return CanBlastOrSmash;}}), - LocationAccess(DMT_GS_ABOVE_DODONGOS_CAVERN, {[]{return IsAdult && AtNight && (CanUse(MEGATON_HAMMER) || (LogicDMTGSLowerHookshot && CanUse(HOOKSHOT)) || (LogicDMTGSLowerBean && CanPlantBean(DEATH_MOUNTAIN_TRAIL)) || (LogicDMTGSLowerHovers && CanUse(HOVER_BOOTS)) || LogicDMTGSLowerJS) && CanGetNightTimeGS;}}), + LOCATION(RC_DMT_CHEST, logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_FREESTANDING_POH, logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)))), + LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))), + LOCATION(RC_DMT_GS_NEAR_KAK, logic->BlastOrSmash()), + LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DMT_HOOKSHOT_LOWER_GS) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_DMT_JS_LOWER_GS)) && logic->CanGetNightTimeGS()), }, { //Exits - Entrance(KAK_BEHIND_GATE, {[]{return true;}}), - Entrance(GORON_CITY, {[]{return true;}}), - Entrance(DEATH_MOUNTAIN_SUMMIT, {[]{return Here(DEATH_MOUNTAIN_TRAIL, []{return CanBlastOrSmash;}) || (IsAdult && ((CanPlantBean(DEATH_MOUNTAIN_TRAIL) && GoronBracelet) || (HoverBoots && LogicDMTClimbHovers)));}}), - Entrance(DODONGOS_CAVERN_ENTRYWAY, {[]{return HasExplosives || GoronBracelet || IsAdult;}}), - Entrance(DMT_STORMS_GROTTO, {[]{return CanOpenStormGrotto;}}), + Entrance(RR_KAK_BEHIND_GATE, {[]{return true;}}), + Entrance(RR_GORON_CITY, {[]{return true;}}), + Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return Here(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->BlastOrSmash();}) || (logic->IsAdult && ((CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->HasItem(RG_GORONS_BRACELET)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_DMT_CLIMB_HOVERS))));}}), + Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, {[]{return logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->IsAdult;}}), + Entrance(RR_DMT_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); - areaTable[DEATH_MOUNTAIN_SUMMIT] = Area("Death Mountain Summit", "Death Mountain", 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(&PrescriptionAccess, {[]{return PrescriptionAccess || (IsAdult && (BrokenSwordAccess || BrokenSword));}}), - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairy;}}), - EventAccess(&BugRock, {[]{return BugRock || IsChild;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), + EventAccess(&logic->BugRock, {[]{return logic->BugRock || logic->IsChild;}}), }, { //Locations - LocationAccess(DMT_TRADE_BROKEN_SWORD, {[]{return IsAdult && BrokenSword;}}), - LocationAccess(DMT_TRADE_EYEDROPS, {[]{return IsAdult && Eyedrops;}}), - LocationAccess(DMT_TRADE_CLAIM_CHECK, {[]{return IsAdult && ClaimCheck;}}), - LocationAccess(DMT_GS_FALLING_ROCKS_PATH, {[]{return IsAdult && AtNight && (CanUse(MEGATON_HAMMER) || LogicDMTGSUpper) && CanGetNightTimeGS;}}), - LocationAccess(DMT_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->CanUse(RG_BROKEN_SWORD)), + LOCATION(RC_DMT_TRADE_EYEDROPS, logic->IsAdult && logic->CanUse(RG_EYEDROPS)), + LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->CanUse(RG_CLAIM_CHECK)), + LOCATION(RC_DMT_GS_FALLING_ROCKS_PATH, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || ctx->GetTrickOption(RT_DMT_UPPER_GS)) && logic->CanGetNightTimeGS()), + LOCATION(RC_DMT_GOSSIP_STONE, true), }, { //Exits - Entrance(DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), - Entrance(DMC_UPPER_LOCAL, {[]{return true;}}), - Entrance(DMT_OWL_FLIGHT, {[]{return IsChild;}}), - Entrance(DMT_COW_GROTTO, {[]{return Here(DEATH_MOUNTAIN_SUMMIT, []{return CanBlastOrSmash;});}}), - Entrance(DMT_GREAT_FAIRY_FOUNTAIN, {[]{return Here(DEATH_MOUNTAIN_SUMMIT, []{return CanBlastOrSmash;});}}), + Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), + Entrance(RR_DMC_UPPER_LOCAL, {[]{return true;}}), + Entrance(RR_DMT_OWL_FLIGHT, {[]{return logic->IsChild;}}, false), + Entrance(RR_DMT_COW_GROTTO, {[]{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->BlastOrSmash();});}}), + Entrance(RR_DMT_GREAT_FAIRY_FOUNTAIN, {[]{return Here(RR_DEATH_MOUNTAIN_SUMMIT, []{return logic->BlastOrSmash();});}}), }); - areaTable[DMT_OWL_FLIGHT] = Area("DMT Owl Flight", "Death Mountain", 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(KAK_IMPAS_ROOFTOP, {[]{return true;}}), + Entrance(RR_KAK_IMPAS_ROOFTOP, {[]{return true;}}), }); - areaTable[DMT_COW_GROTTO] = Area("DMT Cow Grotto", "DMT Cow Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DMT_COW_GROTTO] = Region("DMT Cow Grotto", "DMT Cow Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(DMT_COW_GROTTO_COW, {[]{return CanPlay(EponasSong);}}), + LOCATION(RC_DMT_COW_GROTTO_COW, logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_DMT_COW_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), + Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), }); - areaTable[DMT_STORMS_GROTTO] = Area("DMT Storms Grotto", "DMT Storms Grotto", NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_DMT_STORMS_GROTTO] = Region("DMT Storms Grotto", "DMT Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(DMT_STORMS_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(DMT_STORMS_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_DMT_STORMS_GROTTO_CHEST, true), + LOCATION(RC_DMT_STORMS_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), + Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), }); - areaTable[DMT_GREAT_FAIRY_FOUNTAIN] = Area("DMT Great Fairy Fountain", "DMT Great Fairy Fountain", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DMT_GREAT_FAIRY_FOUNTAIN] = Region("DMT Great Fairy Fountain", "DMT Great Fairy Fountain", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(DMT_GREAT_FAIRY_REWARD, {[]{return CanPlay(ZeldasLullaby);}}), + LOCATION(RC_DMT_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits - Entrance(DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), + Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), }); - areaTable[GORON_CITY] = Area("Goron City", "Goron City", GORON_CITY, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GORON_CITY] = Region("Goron City", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairyWithoutSuns;}}), - EventAccess(&StickPot, {[]{return StickPot || IsChild;}}), - EventAccess(&BugRock, {[]{return BugRock || (CanBlastOrSmash || CanUse(SILVER_GAUNTLETS));}}), - EventAccess(&GoronCityChildFire, {[]{return GoronCityChildFire || (IsChild && CanUse(DINS_FIRE));}}), - EventAccess(&GCWoodsWarpOpen, {[]{return GCWoodsWarpOpen || (CanBlastOrSmash || CanUse(DINS_FIRE) || CanUse(BOW) || GoronBracelet || GoronCityChildFire);}}), - EventAccess(&GCDaruniasDoorOpenChild, {[]{return GCDaruniasDoorOpenChild || (IsChild && CanPlay(ZeldasLullaby));}}), - EventAccess(&StopGCRollingGoronAsAdult, {[]{return StopGCRollingGoronAsAdult || (IsAdult && (GoronBracelet || HasExplosives || Bow || (LogicGoronCityLinkGoronDins && CanUse(DINS_FIRE))));}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), + EventAccess(&logic->StickPot, {[]{return logic->StickPot || logic->IsChild;}}), + EventAccess(&logic->BugRock, {[]{return logic->BugRock || (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS));}}), + EventAccess(&logic->GoronCityChildFire, {[]{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_DINS_FIRE));}}), + EventAccess(&logic->GCWoodsWarpOpen, {[]{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire);}}), + EventAccess(&logic->GCDaruniasDoorOpenChild, {[]{return logic->GCDaruniasDoorOpenChild || (logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY));}}), + EventAccess(&logic->StopGCRollingGoronAsAdult, {[]{return logic->StopGCRollingGoronAsAdult || (logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && logic->CanUse(RG_DINS_FIRE))));}}), }, { //Locations - LocationAccess(GC_MAZE_LEFT_CHEST, {[]{return CanUse(MEGATON_HAMMER) || CanUse(SILVER_GAUNTLETS) || (LogicGoronCityLeftMost && HasExplosives && CanUse(HOVER_BOOTS));}}), - LocationAccess(GC_MAZE_CENTER_CHEST, {[]{return CanBlastOrSmash || CanUse(SILVER_GAUNTLETS);}}), - LocationAccess(GC_MAZE_RIGHT_CHEST, {[]{return CanBlastOrSmash || CanUse(SILVER_GAUNTLETS);}}), - LocationAccess(GC_POT_FREESTANDING_POH, {[]{return IsChild && GoronCityChildFire && (Bombs || (GoronBracelet && LogicGoronCityPotWithStrength) || (HasBombchus && LogicGoronCityPot));}}), - LocationAccess(GC_ROLLING_GORON_AS_CHILD, {[]{return IsChild && (HasExplosives || (GoronBracelet && LogicChildRollingWithStrength));}}), - LocationAccess(GC_ROLLING_GORON_AS_ADULT, {[]{return StopGCRollingGoronAsAdult;}}), - LocationAccess(GC_GS_BOULDER_MAZE, {[]{return IsChild && CanBlastOrSmash;}}), - LocationAccess(GC_GS_CENTER_PLATFORM, {[]{return CanAdultAttack;}}), - LocationAccess(GC_MEDIGORON, {[]{return IsAdult && AdultsWallet && (CanBlastOrSmash || GoronBracelet);}}), - LocationAccess(GC_MAZE_GOSSIP_STONE, {[]{return CanBlastOrSmash || CanUse(SILVER_GAUNTLETS);}}), - LocationAccess(GC_MEDIGORON_GOSSIP_STONE, {[]{return CanBlastOrSmash || GoronBracelet;}}), + LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_GC_MAZE_CENTER_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_RIGHT_CHEST, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_POT_FREESTANDING_POH, logic->IsChild && logic->GoronCityChildFire && (logic->CanUse(RG_BOMB_BAG) || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_POT_STRENGTH)) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_GC_POT)))), + LOCATION(RC_GC_ROLLING_GORON_AS_CHILD, logic->IsChild && (logic->HasExplosives() || (logic->HasItem(RG_GORONS_BRACELET) && ctx->GetTrickOption(RT_GC_ROLLING_STRENGTH)))), + LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->StopGCRollingGoronAsAdult), + LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->IsAdult && logic->CanAttack()), + LOCATION(RC_GC_MEDIGORON, logic->IsAdult && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits - Entrance(DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), - Entrance(GC_WOODS_WARP, {[]{return GCWoodsWarpOpen;}}), - Entrance(GC_SHOP, {[]{return (IsAdult && StopGCRollingGoronAsAdult) || (IsChild && (CanBlastOrSmash || GoronBracelet || GoronCityChildFire || CanUse(BOW)));}}), - Entrance(GC_DARUNIAS_CHAMBER, {[]{return (IsAdult && StopGCRollingGoronAsAdult) || (IsChild && GCDaruniasDoorOpenChild);}}), - Entrance(GC_GROTTO_PLATFORM, {[]{return IsAdult && ((CanPlay(SongOfTime) && ((EffectiveHealth > 2) || CanUse(GORON_TUNIC) || CanUse(LONGSHOT) || CanUse(NAYRUS_LOVE))) || (EffectiveHealth > 1 && CanUse(GORON_TUNIC) && CanUse(HOOKSHOT)) || (CanUse(NAYRUS_LOVE) && CanUse(HOOKSHOT)) || (EffectiveHealth > 2 && CanUse(HOOKSHOT) && LogicGoronCityGrotto));}}), + Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), + Entrance(RR_GC_WOODS_WARP, {[]{return logic->GCWoodsWarpOpen;}}), + Entrance(RR_GC_SHOP, {[]{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire || logic->CanUse(RG_FAIRY_BOW)));}}), + Entrance(RR_GC_DARUNIAS_CHAMBER, {[]{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && logic->GCDaruniasDoorOpenChild);}}), + Entrance(RR_GC_GROTTO_PLATFORM, {[]{return logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && ((logic->EffectiveHealth() > 2) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_NAYRUS_LOVE))) || (logic->EffectiveHealth() > 1 && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_HOOKSHOT)) || (logic->EffectiveHealth() > 2 && logic->CanUse(RG_HOOKSHOT) && ctx->GetTrickOption(RT_GC_GROTTO)));}}), }); - areaTable[GC_WOODS_WARP] = Area("GC Woods Warp", "Goron City", 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(&GCWoodsWarpOpen, {[]{return GCWoodsWarpOpen || (CanBlastOrSmash || CanUse(DINS_FIRE));}}), + EventAccess(&logic->GCWoodsWarpOpen, {[]{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE));}}), }, {}, { //Exits - Entrance(GORON_CITY, {[]{return CanLeaveForest && GCWoodsWarpOpen;}}), - Entrance(THE_LOST_WOODS, {[]{return true;}}), + Entrance(RR_GORON_CITY, {[]{return logic->CanLeaveForest() && logic->GCWoodsWarpOpen;}}), + Entrance(RR_THE_LOST_WOODS, {[]{return true;}}), }); - areaTable[GC_DARUNIAS_CHAMBER] = Area("GC Darunias Chamber", "Goron City", 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(&GoronCityChildFire, {[]{return GoronCityChildFire || (IsChild && CanUse(STICKS));}}), + EventAccess(&logic->GoronCityChildFire, {[]{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_STICKS));}}), }, { //Locations - LocationAccess(GC_DARUNIAS_JOY, {[]{return IsChild && CanPlay(SariasSong);}}), + LOCATION(RC_GC_DARUNIAS_JOY, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), }, { //Exits - Entrance(GORON_CITY, {[]{return true;}}), - Entrance(DMC_LOWER_LOCAL, {[]{return IsAdult;}}), + Entrance(RR_GORON_CITY, {[]{return true;}}), + Entrance(RR_DMC_LOWER_LOCAL, {[]{return logic->IsAdult;}}), }); - areaTable[GC_GROTTO_PLATFORM] = Area("GC Grotto Platform", "Goron City", 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(GC_GROTTO, {[]{return true;}}), - Entrance(GORON_CITY, {[]{return EffectiveHealth > 2 || CanUse(GORON_TUNIC) || CanUse(NAYRUS_LOVE) || ((IsChild || CanPlay(SongOfTime)) && CanUse(LONGSHOT));}}), + 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[GC_SHOP] = Area("GC Shop", "GC Shop", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GC_SHOP] = Region("GC Shop", "GC Shop", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GC_SHOP_ITEM_1, {[]{return true;}}), - LocationAccess(GC_SHOP_ITEM_2, {[]{return true;}}), - LocationAccess(GC_SHOP_ITEM_3, {[]{return true;}}), - LocationAccess(GC_SHOP_ITEM_4, {[]{return true;}}), - LocationAccess(GC_SHOP_ITEM_5, {[]{return true;}}), - LocationAccess(GC_SHOP_ITEM_6, {[]{return true;}}), - LocationAccess(GC_SHOP_ITEM_7, {[]{return true;}}), - LocationAccess(GC_SHOP_ITEM_8, {[]{return true;}}), + LOCATION(RC_GC_SHOP_ITEM_1, true), + LOCATION(RC_GC_SHOP_ITEM_2, true), + LOCATION(RC_GC_SHOP_ITEM_3, true), + LOCATION(RC_GC_SHOP_ITEM_4, true), + LOCATION(RC_GC_SHOP_ITEM_5, true), + LOCATION(RC_GC_SHOP_ITEM_6, true), + LOCATION(RC_GC_SHOP_ITEM_7, true), + LOCATION(RC_GC_SHOP_ITEM_8, true), }, { //Exits - Entrance(GORON_CITY, {[]{return true;}}), + Entrance(RR_GORON_CITY, {[]{return true;}}), }); - areaTable[GC_GROTTO] = Area("GC Grotto", "GC Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GC_GROTTO] = Region("GC Grotto", "GC Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GC_DEKU_SCRUB_GROTTO_LEFT, {[]{return CanStunDeku;}}), - LocationAccess(GC_DEKU_SCRUB_GROTTO_RIGHT, {[]{return CanStunDeku;}}), - LocationAccess(GC_DEKU_SCRUB_GROTTO_CENTER, {[]{return CanStunDeku;}}), + LOCATION(RC_GC_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku()), + LOCATION(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku()), + LOCATION(RC_GC_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku()), + LOCATION(RC_GC_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(GC_GROTTO_PLATFORM, {[]{return true;}}), + Entrance(RR_GC_GROTTO_PLATFORM, {[]{return true;}}), }); - areaTable[DMC_UPPER_NEARBY] = Area("DMC Upper Nearby", "Death Mountain Crater", 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(DMC_UPPER_LOCAL, {[]{return FireTimer >= 48;}}), - Entrance(DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), - Entrance(DMC_UPPER_GROTTO, {[]{return Here(DMC_UPPER_NEARBY, []{return CanBlastOrSmash && (FireTimer >= 8 || Hearts >= 3);});}}) + 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->BlastOrSmash() && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);});}}) }); - areaTable[DMC_UPPER_LOCAL] = Area("DMC Upper Local", "Death Mountain Crater", 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(&GossipStoneFairy, {[]{return GossipStoneFairy || (HasExplosives && CanSummonGossipFairyWithoutSuns && (FireTimer >= 16 || Hearts >= 3));}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || (logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3));}}), }, { //Locations - LocationAccess(DMC_WALL_FREESTANDING_POH, {[]{return FireTimer >= 16 || Hearts >= 3;}}), - LocationAccess(DMC_GS_CRATE, {[]{return (FireTimer >= 8 || Hearts >= 3) && IsChild && CanChildAttack;}}), - LocationAccess(DMC_GOSSIP_STONE, {[]{return HasExplosives && (FireTimer >= 16 || Hearts >= 3);}}), + LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer() >= 16 || logic->Hearts() >= 3), + LOCATION(RC_DMC_GS_CRATE, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->IsChild && logic->CanAttack()), + LOCATION(RC_DMC_GOSSIP_STONE, logic->HasExplosives() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), }, { //Exits - Entrance(DMC_UPPER_NEARBY, {[]{return true;}}), - Entrance(DMC_LADDER_AREA_NEARBY, {[]{return FireTimer >= 16 || Hearts >= 3;}}), - Entrance(DMC_CENTRAL_NEARBY, {[]{return IsAdult && CanUse(GORON_TUNIC) && CanUse(DISTANT_SCARECROW) && ((EffectiveHealth > 2) || (Fairy && ShuffleDungeonEntrances.IsNot(SHUFFLEDUNGEONS_OFF)) || CanUse(NAYRUS_LOVE));}}), - Entrance(DMC_LOWER_NEARBY, {[]{return false;}}), + Entrance(RR_DMC_UPPER_NEARBY, {[]{return true;}}), + Entrance(RR_DMC_LADDER_AREA_NEARBY, {[]{return logic->FireTimer() >= 16 || logic->Hearts() >= 3;}}), + Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_DISTANT_SCARECROW) && ((logic->EffectiveHealth() > 2) || (logic->CanUse(RG_BOTTLE_WITH_FAIRY) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || logic->CanUse(RG_NAYRUS_LOVE));}}), + Entrance(RR_DMC_LOWER_NEARBY, {[]{return false;}}), }); - areaTable[DMC_LADDER_AREA_NEARBY] = Area("DMC Ladder Area Nearby", "Death Mountain Crater", 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 - LocationAccess(DMC_DEKU_SCRUB, {[]{return IsChild && CanStunDeku;}}), + LOCATION(RC_DMC_DEKU_SCRUB, logic->IsChild && logic->CanStunDeku()), }, { //Exits - Entrance(DMC_UPPER_NEARBY, {[]{return Hearts >= 3;}}), - Entrance(DMC_LOWER_NEARBY, {[]{return Hearts >= 3 && (CanUse(HOVER_BOOTS) || (LogicCraterBoulderJS && IsAdult && CanUse(MEGATON_HAMMER)) || (LogicCraterBoulderSkip && IsAdult));}}), + Entrance(RR_DMC_UPPER_NEARBY, {[]{return logic->Hearts() >= 3;}}), + Entrance(RR_DMC_LOWER_NEARBY, {[]{return logic->Hearts() >= 3 && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DMC_BOULDER_JS) && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)) || (ctx->GetTrickOption(RT_DMC_BOULDER_SKIP) && logic->IsAdult));}}), }); - areaTable[DMC_LOWER_NEARBY] = Area("DMC Lower Nearby", "Death Mountain Crater", 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(DMC_LOWER_LOCAL, {[]{return FireTimer >= 48;}}), - Entrance(GC_DARUNIAS_CHAMBER, {[]{return true;}}), - Entrance(DMC_GREAT_FAIRY_FOUNTAIN, {[]{return CanUse(MEGATON_HAMMER);}}), - Entrance(DMC_HAMMER_GROTTO, {[]{return IsAdult && CanUse(MEGATON_HAMMER);}}), + Entrance(RR_DMC_LOWER_LOCAL, {[]{return logic->FireTimer() >= 48;}}), + Entrance(RR_GC_DARUNIAS_CHAMBER, {[]{return true;}}), + Entrance(RR_DMC_GREAT_FAIRY_FOUNTAIN, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), + Entrance(RR_DMC_HAMMER_GROTTO, {[]{return logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER);}}), }); - areaTable[DMC_LOWER_LOCAL] = Area("DMC Lower Local", "Death Mountain Crater", 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(DMC_LOWER_NEARBY, {[]{return true;}}), - Entrance(DMC_LADDER_AREA_NEARBY, {[]{return FireTimer >= 8 || Hearts >= 3;}}), - Entrance(DMC_CENTRAL_NEARBY, {[]{return (CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT)) && (FireTimer >= 8 || Hearts >= 3);}}), - Entrance(DMC_CENTRAL_LOCAL, {[]{return (CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT) || (IsAdult && CanShield && LogicCraterBoleroJump)) && FireTimer >= 24;}}), + Entrance(RR_DMC_LOWER_NEARBY, {[]{return true;}}), + Entrance(RR_DMC_LADDER_AREA_NEARBY, {[]{return logic->FireTimer() >= 8 || logic->Hearts() >= 3;}}), + Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);}}), + Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanShield() && ctx->GetTrickOption(RT_DMC_BOLERO_JUMP))) && logic->FireTimer() >= 24;}}), }); - areaTable[DMC_CENTRAL_NEARBY] = Area("DMC Central Nearby", "Death Mountain Crater", 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 - LocationAccess(DMC_VOLCANO_FREESTANDING_POH, {[]{return IsAdult && Hearts >= 3 && (CanPlantBean(DMC_CENTRAL_LOCAL) || (LogicCraterBeanPoHWithHovers && HoverBoots));}}), - LocationAccess(SHEIK_IN_CRATER, {[]{return IsAdult && (FireTimer >= 8 || Hearts >= 3);}}), + LOCATION(RC_DMC_VOLCANO_FREESTANDING_POH, logic->IsAdult && logic->Hearts() >= 3 && (CanPlantBean(RR_DMC_CENTRAL_LOCAL) || (ctx->GetTrickOption(RT_DMC_HOVER_BEAN_POH) && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_SHEIK_IN_CRATER, logic->IsAdult && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), }, { //Exits - Entrance(DMC_CENTRAL_LOCAL, {[]{return FireTimer >= 48;}}), + Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return logic->FireTimer() >= 48;}}), }); - areaTable[DMC_CENTRAL_LOCAL] = Area("DMC Central Local", "Death Mountain Crater", 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(&BeanPlantFairy, {[]{return BeanPlantFairy || (CanPlantBean(DMC_CENTRAL_LOCAL) && CanPlay(SongOfStorms));}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_DMC_CENTRAL_LOCAL) && logic->CanUse(RG_SONG_OF_STORMS));}}), }, { //Locations - LocationAccess(DMC_GS_BEAN_PATCH, {[]{return (FireTimer >= 8 || Hearts >= 3) && CanPlantBugs && CanChildAttack;}}), + LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull() && logic->CanAttack()), }, { //Exits - Entrance(DMC_CENTRAL_NEARBY, {[]{return true;}}), - Entrance(DMC_LOWER_NEARBY, {[]{return (IsAdult && CanPlantBean(DMC_CENTRAL_LOCAL)) || CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT);}}), - Entrance(DMC_UPPER_NEARBY, {[]{return IsAdult && CanPlantBean(DMC_CENTRAL_LOCAL);}}), - Entrance(FIRE_TEMPLE_ENTRYWAY, {[]{return (IsChild && Hearts >= 3 && ShuffleDungeonEntrances.IsNot(SHUFFLEDUNGEONS_OFF)) || (IsAdult && FireTimer >= 24);}}), + Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return true;}}), + Entrance(RR_DMC_LOWER_NEARBY, {[]{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_DMC_UPPER_NEARBY, {[]{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL);}}), + Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return (logic->IsChild && logic->Hearts() >= 3 && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || (logic->IsAdult && logic->FireTimer() >= 24);}}), }); - areaTable[DMC_GREAT_FAIRY_FOUNTAIN] = Area("DMC Great Fairy Fountain", "DMC Great Fairy Fountain", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DMC_GREAT_FAIRY_FOUNTAIN] = Region("DMC Great Fairy Fountain", "DMC Great Fairy Fountain", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(DMC_GREAT_FAIRY_REWARD, {[]{return CanPlay(ZeldasLullaby);}}), + LOCATION(RC_DMC_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits - Entrance(DMC_LOWER_LOCAL, {[]{return true;}}), + Entrance(RR_DMC_LOWER_LOCAL, {[]{return true;}}), }); - areaTable[DMC_UPPER_GROTTO] = Area("DMC Upper Grotto", "DMC Upper Grotto", NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_DMC_UPPER_GROTTO] = Region("DMC Upper Grotto", "DMC Upper Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(DMC_UPPER_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(DMC_UPPER_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_DMC_UPPER_GROTTO_CHEST, true), + LOCATION(RC_DMC_UPPER_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(DMC_UPPER_LOCAL, {[]{return true;}}), + Entrance(RR_DMC_UPPER_LOCAL, {[]{return true;}}), }); - areaTable[DMC_HAMMER_GROTTO] = Area("DMC Hammer Grotto", "DMC Hammer Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DMC_HAMMER_GROTTO] = Region("DMC Hammer Grotto", "DMC Hammer Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(DMC_DEKU_SCRUB_GROTTO_LEFT, {[]{return CanStunDeku;}}), - LocationAccess(DMC_DEKU_SCRUB_GROTTO_RIGHT, {[]{return CanStunDeku;}}), - LocationAccess(DMC_DEKU_SCRUB_GROTTO_CENTER, {[]{return CanStunDeku;}}), + LOCATION(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku()), + LOCATION(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku()), + LOCATION(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku()), + LOCATION(RC_DMC_HAMMER_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(DMC_LOWER_LOCAL, {[]{return true;}}), + Entrance(RR_DMC_LOWER_LOCAL, {[]{return true;}}), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_deku_tree.cpp index c1231b29e52..1a4ccbe00be 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 @@ -1,272 +1,275 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_DekuTree() { +void RegionTable_Init_DekuTree() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[DEKU_TREE_ENTRYWAY] = Area("Deku Tree Entryway", "Deku Tree", 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(DEKU_TREE_LOBBY, {[]{return Dungeon::DekuTree.IsVanilla();}}), - Entrance(DEKU_TREE_MQ_LOBBY, {[]{return Dungeon::DekuTree.IsMQ();}}), - Entrance(KF_OUTSIDE_DEKU_TREE, {[]{return true;}}), + Entrance(RR_DEKU_TREE_LOBBY, {[]{return ctx->GetDungeon(DEKU_TREE)->IsVanilla();}}), + Entrance(RR_DEKU_TREE_MQ_LOBBY, {[]{return ctx->GetDungeon(DEKU_TREE)->IsMQ();}}), + Entrance(RR_KF_OUTSIDE_DEKU_TREE, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::DekuTree.IsVanilla()) { - areaTable[DEKU_TREE_LOBBY] = Area("Deku Tree Lobby", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(DEKU_TREE)->IsVanilla()) { + areaTable[RR_DEKU_TREE_LOBBY] = Region("Deku Tree Lobby", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), + 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));}}), }, { //Locations - LocationAccess(DEKU_TREE_MAP_CHEST, {[]{return true;}}), + LOCATION(RC_DEKU_TREE_MAP_CHEST, true), }, { //Exits - Entrance(DEKU_TREE_ENTRYWAY, {[]{return true;}}), - Entrance(DEKU_TREE_2F_MIDDLE_ROOM, {[]{return true;}}), - Entrance(DEKU_TREE_COMPASS_ROOM, {[]{return true;}}), - Entrance(DEKU_TREE_BASEMENT_LOWER, {[]{return Here(DEKU_TREE_LOBBY, []{return CanAdultAttack || CanChildAttack || Nuts;});}}), - Entrance(DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return false;}}), - Entrance(DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;}}), + Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, {[]{return true;}}), + Entrance(RR_DEKU_TREE_COMPASS_ROOM, {[]{return true;}}), + Entrance(RR_DEKU_TREE_BASEMENT_LOWER, {[]{return Here(RR_DEKU_TREE_LOBBY, []{return logic->CanAttack() || logic->CanUse(RG_NUTS);});}}), + Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return false;}}), + Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;}}), }); - areaTable[DEKU_TREE_2F_MIDDLE_ROOM] = Area("Deku Tree 2F Middle Room", "Deku Tree", 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(DEKU_TREE_LOBBY, {[]{return Here(DEKU_TREE_2F_MIDDLE_ROOM, []{return HasShield || CanUse(MEGATON_HAMMER);});}}), - Entrance(DEKU_TREE_SLINGSHOT_ROOM,{[]{return Here(DEKU_TREE_2F_MIDDLE_ROOM, []{return HasShield || CanUse(MEGATON_HAMMER);});}}), + Entrance(RR_DEKU_TREE_LOBBY, {[]{return Here(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return logic->CanReflectNuts() || logic->CanUse(RG_MEGATON_HAMMER);});}}), + Entrance(RR_DEKU_TREE_SLINGSHOT_ROOM,{[]{return Here(RR_DEKU_TREE_2F_MIDDLE_ROOM, []{return logic->CanReflectNuts() || logic->CanUse(RG_MEGATON_HAMMER);});}}), }); - areaTable[DEKU_TREE_SLINGSHOT_ROOM] = Area("Deku Tree Slingshot Room", "Deku Tree", 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 - LocationAccess(DEKU_TREE_SLINGSHOT_CHEST, {[]{return true;}}), - LocationAccess(DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, {[]{return true;}}), + LOCATION(RC_DEKU_TREE_SLINGSHOT_CHEST, true), + LOCATION(RC_DEKU_TREE_SLINGSHOT_ROOM_SIDE_CHEST, true), }, { //Exits - Entrance(DEKU_TREE_2F_MIDDLE_ROOM, {[]{return CanUse(SLINGSHOT) || CanUse(HOVER_BOOTS);}}), + Entrance(RR_DEKU_TREE_2F_MIDDLE_ROOM, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}), }); - areaTable[DEKU_TREE_COMPASS_ROOM] = Area("Deku Tree Compass Room", "Deku Tree", 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(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), + 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));}}), }, { //Locations - LocationAccess(DEKU_TREE_COMPASS_CHEST, {[]{return true;}}), - LocationAccess(DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, {[]{return true;}}), - LocationAccess(DEKU_TREE_GS_COMPASS_ROOM, {[]{return CanAdultAttack || CanChildAttack;}}), + LOCATION(RC_DEKU_TREE_COMPASS_CHEST, true), + LOCATION(RC_DEKU_TREE_COMPASS_ROOM_SIDE_CHEST, true), + LOCATION(RC_DEKU_TREE_GS_COMPASS_ROOM, logic->CanAttack()), }, { //Exits - Entrance(DEKU_TREE_LOBBY, {[]{return HasFireSourceWithTorch || CanUse(BOW);}}), - Entrance(DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;}}), + Entrance(RR_DEKU_TREE_LOBBY, {[]{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}}), + Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return false;}}), }); - areaTable[DEKU_TREE_BASEMENT_LOWER] = Area("Deku Tree Basement Lower", "Deku Tree", 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(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || Boomerang);}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}, - /*Glitched*/[]{return CanUse(MEGATON_HAMMER);}}), + 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));}, + /*Glitched*/[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), }, { //Locations - LocationAccess(DEKU_TREE_BASEMENT_CHEST, {[]{return true;}}), - LocationAccess(DEKU_TREE_GS_BASEMENT_GATE, {[]{return CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOOMERANG) || HasExplosives || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(DINS_FIRE);}}), - LocationAccess(DEKU_TREE_GS_BASEMENT_VINES, {[]{return CanUseProjectile || CanUse(DINS_FIRE) || (LogicDekuBasementGS && CanJumpslash);}}), + LOCATION(RC_DEKU_TREE_BASEMENT_CHEST, true), + LOCATION(RC_DEKU_TREE_GS_BASEMENT_GATE, logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_DEKU_TREE_GS_BASEMENT_VINES, logic->CanUseProjectile() || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) && logic->CanJumpslash())), }, { //Exits - Entrance(DEKU_TREE_LOBBY, {[]{return true;}}), - Entrance(DEKU_TREE_BASEMENT_SCRUB_ROOM, {[]{return Here(DEKU_TREE_BASEMENT_LOWER, []{return HasFireSourceWithTorch || CanUse(BOW);});}}), - Entrance(DEKU_TREE_BASEMENT_UPPER, {[]{return IsAdult || LogicDekuB1Skip || HasAccessTo(DEKU_TREE_BASEMENT_UPPER);}}), - Entrance(DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return false;}}), + Entrance(RR_DEKU_TREE_LOBBY, {[]{return true;}}), + Entrance(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, {[]{return Here(RR_DEKU_TREE_BASEMENT_LOWER, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}}), + Entrance(RR_DEKU_TREE_BASEMENT_UPPER, {[]{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || HasAccessTo(RR_DEKU_TREE_BASEMENT_UPPER);}}), + Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return false;}}), }); - areaTable[DEKU_TREE_BASEMENT_SCRUB_ROOM] = Area("Deku Tree Basement Scrub Room", "Deku Tree", 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(DEKU_TREE_BASEMENT_LOWER, {[]{return true;}}), - Entrance(DEKU_TREE_BASEMENT_WATER_ROOM, {[]{return Here(DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return CanUse(SLINGSHOT) || CanUse(BOW);});}}), + 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[DEKU_TREE_BASEMENT_WATER_ROOM] = Area("Deku Tree Basement Water Room", "Deku Tree", 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(DEKU_TREE_BASEMENT_SCRUB_ROOM, {[]{return true;}}), - Entrance(DEKU_TREE_BASEMENT_TORCH_ROOM, {[]{return true;}}), + Entrance(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, {[]{return true;}}), + Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_BACK, {[]{return logic->HasItem(RG_BRONZE_SCALE) || ctx->GetTrickOption(RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG);}}), }); - areaTable[DEKU_TREE_BASEMENT_TORCH_ROOM] = Area("Deku Tree Basement Torch Room", "Deku Tree", 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->HasItem(RG_BRONZE_SCALE) || ctx->GetTrickOption(RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG);}}), + Entrance(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, {[]{return true;}}), + }); + + areaTable[RR_DEKU_TREE_BASEMENT_TORCH_ROOM] = Region("Deku Tree Basement Torch Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), + 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));}}), }, {}, { //Exits - Entrance(DEKU_TREE_BASEMENT_WATER_ROOM, {[]{return true;}}), - Entrance(DEKU_TREE_BASEMENT_BACK_LOBBY, {[]{return Here(DEKU_TREE_BASEMENT_TORCH_ROOM, []{return HasFireSourceWithTorch || CanUse(BOW);});}}), + Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_BACK, {[]{return true;}}), + Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, {[]{return Here(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}}), }); - areaTable[DEKU_TREE_BASEMENT_BACK_LOBBY] = Area("Deku Tree Basement Back Lobby", "Deku Tree", 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(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (Here(DEKU_TREE_BASEMENT_BACK_LOBBY, []{return HasFireSourceWithTorch || CanUse(BOW);}) && - (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE)));}}), + EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && + (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE)));}}), }, {}, { //Exits - Entrance(DEKU_TREE_BASEMENT_TORCH_ROOM, {[]{return true;}}), - Entrance(DEKU_TREE_BASEMENT_BACK_ROOM, {[]{return Here(DEKU_TREE_BASEMENT_BACK_LOBBY, []{return HasFireSourceWithTorch || CanUse(Bow);}) && - Here(DEKU_TREE_BASEMENT_BACK_LOBBY, []{return CanBlastOrSmash;});}}), - Entrance(DEKU_TREE_BASEMENT_UPPER, {[]{return Here(DEKU_TREE_BASEMENT_BACK_LOBBY, []{return HasFireSourceWithTorch || CanUse(Bow);}) && IsChild;}}), + Entrance(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, {[]{return true;}}), + Entrance(RR_DEKU_TREE_BASEMENT_BACK_ROOM, {[]{return Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && + Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->BlastOrSmash();});}}), + Entrance(RR_DEKU_TREE_BASEMENT_UPPER, {[]{return Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && logic->IsChild;}}), }); - areaTable[DEKU_TREE_BASEMENT_BACK_ROOM] = Area("Deku Tree Basement Back Room", "Deku Tree", 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 - LocationAccess(DEKU_TREE_GS_BASEMENT_BACK_ROOM, {[]{return HookshotOrBoomerang;}}), + LOCATION(RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM, logic->HookshotOrBoomerang()), }, { //Exits - Entrance(DEKU_TREE_BASEMENT_BACK_LOBBY, {[]{return true;}}), + Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, {[]{return true;}}), }); - areaTable[DEKU_TREE_BASEMENT_UPPER] = Area("Deku Tree Basement Upper", "Deku Tree", 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(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), + 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));}}), }, {}, { //Exits - Entrance(DEKU_TREE_BASEMENT_LOWER, {[]{return true;}}), - Entrance(DEKU_TREE_BASEMENT_BACK_LOBBY, {[]{return IsChild;}}), - Entrance(DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return Here(DEKU_TREE_BASEMENT_UPPER, []{return HasFireSourceWithTorch || (LogicDekuB1WebsWithBow && IsAdult && CanUse(BOW));});}}), + Entrance(RR_DEKU_TREE_BASEMENT_LOWER, {[]{return true;}}), + Entrance(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, {[]{return logic->IsChild;}}), + Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return Here(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_DEKU_B1_BOW_WEBS) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));});}}), }); - areaTable[DEKU_TREE_OUTSIDE_BOSS_ROOM] = Area("Deku Tree Outside Boss Room", "Deku Tree", 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(DEKU_TREE_BASEMENT_UPPER, {[]{return true;}}), - Entrance(DEKU_TREE_BOSS_ENTRYWAY, {[]{return Here(DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return HasShield;});}}), + Entrance(RR_DEKU_TREE_BASEMENT_UPPER, {[]{return true;}}), + Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return (logic->HasItem(RG_BRONZE_SCALE) || Here(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return logic->CanUse(RG_IRON_BOOTS);})) && Here(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return logic->CanReflectNuts();});}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::DekuTree.IsMQ()) { - areaTable[DEKU_TREE_MQ_LOBBY] = Area("Deku Tree MQ Lobby", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(DEKU_TREE)->IsMQ()) { + areaTable[RR_DEKU_TREE_MQ_LOBBY] = Region("Deku Tree MQ Lobby", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), + 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));}}), }, { //Locations - LocationAccess(DEKU_TREE_MQ_MAP_CHEST, {[]{return true;}}), - LocationAccess(DEKU_TREE_MQ_SLINGSHOT_CHEST, {[]{return CanAdultAttack || CanChildAttack;}}), - LocationAccess(DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, {[]{return HasFireSourceWithTorch || (IsAdult && CanUse(BOW));}}), - LocationAccess(DEKU_TREE_MQ_BASEMENT_CHEST, {[]{return HasFireSourceWithTorch || (IsAdult && CanUse(BOW));}}), - LocationAccess(DEKU_TREE_MQ_GS_LOBBY, {[]{return CanAdultAttack || CanChildAttack;}}), + LOCATION(RC_DEKU_TREE_MQ_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, logic->CanAttack()), + LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, logic->HasFireSourceWithTorch() || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW))), + LOCATION(RC_DEKU_TREE_MQ_BASEMENT_CHEST, logic->HasFireSourceWithTorch() || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW))), + LOCATION(RC_DEKU_TREE_MQ_GS_LOBBY, logic->CanAttack()), }, { //Exits - Entrance(DEKU_TREE_ENTRYWAY, {[]{return true;}}), - Entrance(DEKU_TREE_MQ_COMPASS_ROOM, {[]{return Here(DEKU_TREE_MQ_LOBBY, []{return (IsChild && CanUse(SLINGSHOT)) || (IsAdult && CanUse(BOW));}) && - Here(DEKU_TREE_MQ_LOBBY, []{return HasFireSourceWithTorch || (IsAdult && CanUse(BOW));});}}), - Entrance(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return Here(DEKU_TREE_MQ_LOBBY, []{return (IsChild && CanUse(SLINGSHOT)) || (IsAdult && CanUse(BOW));}) && - Here(DEKU_TREE_MQ_LOBBY, []{return HasFireSourceWithTorch;});}}), - Entrance(DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return LogicDekuB1Skip || Here(DEKU_TREE_MQ_LOBBY, []{return IsAdult;});}}), + Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_DEKU_TREE_MQ_COMPASS_ROOM, {[]{return Here(RR_DEKU_TREE_MQ_LOBBY, []{return (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}) && + Here(RR_DEKU_TREE_MQ_LOBBY, []{return logic->HasFireSourceWithTorch() || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));});}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return Here(RR_DEKU_TREE_MQ_LOBBY, []{return (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}) && + Here(RR_DEKU_TREE_MQ_LOBBY, []{return logic->HasFireSourceWithTorch();});}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return ctx->GetTrickOption(RT_DEKU_B1_SKIP) || Here(RR_DEKU_TREE_MQ_LOBBY, []{return logic->IsAdult;});}}), }); - areaTable[DEKU_TREE_MQ_COMPASS_ROOM] = Area("Deku Tree MQ Compass Room", "Deku Tree", 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 - LocationAccess(DEKU_TREE_MQ_COMPASS_CHEST, {[]{return true;}}), - LocationAccess(DEKU_TREE_MQ_GS_COMPASS_ROOM, {[]{return HookshotOrBoomerang && - Here(DEKU_TREE_MQ_COMPASS_ROOM, []{return HasBombchus || - (Bombs && (CanPlay(SongOfTime) || IsAdult)) || - (IsAdult && CanUse(MEGATON_HAMMER) && (CanPlay(SongOfTime) || LogicDekuMQCompassGS));});}}), + LOCATION(RC_DEKU_TREE_MQ_COMPASS_CHEST, true), + LOCATION(RC_DEKU_TREE_MQ_GS_COMPASS_ROOM, logic->HookshotOrBoomerang() && + Here(RR_DEKU_TREE_MQ_COMPASS_ROOM, []{return logic->CanUse(RG_BOMBCHU_5) || + (logic->CanUse(RG_BOMB_BAG) && (logic->CanUse(RG_SONG_OF_TIME) || logic->IsAdult)) || + (logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS)));})), }, { //Exits - Entrance(DEKU_TREE_MQ_LOBBY, {[]{return true;}}), + Entrance(RR_DEKU_TREE_MQ_LOBBY, {[]{return true;}}), }); - areaTable[DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT] = Area("Deku Tree MQ Basement Water Room Front", "Deku Tree", 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 - LocationAccess(DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, {[]{return true;}}), + LOCATION(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, true), }, { //Exits - Entrance(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, {[]{return LogicDekuMQLog || (IsChild && (DekuShield || HylianShield)) || - (IsAdult && (CanUse(LONGSHOT) || (CanUse(HOOKSHOT) && CanUse(IRON_BOOTS))));}}), - Entrance(DEKU_TREE_MQ_LOBBY, {[]{return true;}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, {[]{return ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && (logic->CanUse(RG_DEKU_SHIELD) || logic->HasItem(RG_HYLIAN_SHIELD))) || + (logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS))));}}), + Entrance(RR_DEKU_TREE_MQ_LOBBY, {[]{return true;}}), }); - areaTable[DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK] = Area("Deku Tree MQ Basement Water Room Front", "Deku Tree", 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 - LocationAccess(DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, {[]{return CanPlay(SongOfTime);}}), + LOCATION(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, logic->CanUse(RG_SONG_OF_TIME)), }, { //Exits - Entrance(DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return Here(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return (IsChild && CanUse(STICKS)) || CanUse(DINS_FIRE) || - Here(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return IsAdult && CanUse(FIRE_ARROWS);});}) && - Here(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || - CanUseProjectile || (Nuts && CanUse(STICKS));});}}), - Entrance(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return true;}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return (logic->IsChild && logic->CanUse(RG_STICKS)) || logic->CanUse(RG_DINS_FIRE) || + Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS);});}) && + Here(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, []{return logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || + logic->CanUseProjectile() || (logic->CanUse(RG_NUTS) && logic->CanUse(RG_STICKS));});}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return true;}}), }); - areaTable[DEKU_TREE_MQ_BASEMENT_BACK_ROOM] = Area("Deku Tree MQ Basement Back Room", "Deku Tree", 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 - LocationAccess(DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, {[]{return (IsAdult && CanUse(LONGSHOT)) || (CanPlay(SongOfTime) && HookshotOrBoomerang);}}), - LocationAccess(DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, {[]{return HasFireSourceWithTorch && HookshotOrBoomerang;}}), + LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (logic->CanUse(RG_SONG_OF_TIME) && logic->HookshotOrBoomerang())), + LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, logic->HasFireSourceWithTorch() && logic->HookshotOrBoomerang()), }, { //Exits - Entrance(DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return IsChild;}}), - Entrance(DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, {[]{return (IsChild && CanUse(KOKIRI_SWORD)) || CanUseProjectile || (Nuts && (IsChild && CanUse(STICKS)));}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return logic->IsChild;}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK, {[]{return (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUseProjectile() || (logic->CanUse(RG_NUTS) && (logic->IsChild && logic->CanUse(RG_STICKS)));}}), }); - areaTable[DEKU_TREE_MQ_BASEMENT_LEDGE] = Area("Deku Tree MQ Basement Ledge", "Deku Tree", 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 - LocationAccess(DEKU_TREE_MQ_DEKU_SCRUB, {[]{return CanStunDeku;}}), + LOCATION(RC_DEKU_TREE_MQ_DEKU_SCRUB, logic->CanStunDeku()), }, { //Exits - Entrance(DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return IsChild;}}), - Entrance(DEKU_TREE_MQ_LOBBY, {[]{return true;}}), - Entrance(DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, - { [] { return Here(DEKU_TREE_MQ_BASEMENT_LEDGE, [] { return HasFireSourceWithTorch; }); } }), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM, {[]{return logic->IsChild;}}), + Entrance(RR_DEKU_TREE_MQ_LOBBY, {[]{return true;}}), + Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, + { [] { return Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, [] { return logic->HasFireSourceWithTorch(); }); } }), }); - areaTable[DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] = - Area("Deku Tree MQ Outside Boss Room", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] = + Region("Deku Tree MQ Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(DEKU_TREE_MQ_BASEMENT_LEDGE, { [] { return true; } }), - Entrance(DEKU_TREE_BOSS_ENTRYWAY, - { [] { return Here(DEKU_TREE_MQ_BASEMENT_LEDGE, [] { return HasShield; }); } }), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{ return true; }}), + Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return (logic->HasItem(RG_BRONZE_SCALE) || Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->CanUse(RG_IRON_BOOTS);})) && Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, [] { return logic->CanReflectNuts(); }); } }), }); } /*--------------------------- | BOSS ROOM | ---------------------------*/ - areaTable[DEKU_TREE_BOSS_ENTRYWAY] = - Area("Deku Tree Boss Entryway", "Deku Tree", DEKU_TREE, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_DEKU_TREE_BOSS_ENTRYWAY] = + Region("Deku Tree Boss Entryway", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(DEKU_TREE_OUTSIDE_BOSS_ROOM, { [] { return Dungeon::DekuTree.IsVanilla(); } }), - Entrance(DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, { [] { return Dungeon::DekuTree.IsMQ(); } }), - Entrance(DEKU_TREE_BOSS_ROOM, { [] { return true; } }), + Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, { [] { return ctx->GetDungeon(DEKU_TREE)->IsVanilla(); } }), + Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, { [] { return ctx->GetDungeon(DEKU_TREE)->IsMQ(); } }), + Entrance(RR_DEKU_TREE_BOSS_ROOM, { [] { return true; } }), }); - areaTable[DEKU_TREE_BOSS_ROOM] = - Area("Deku Tree Boss Room", "Deku Tree", NONE, NO_DAY_NIGHT_CYCLE, + areaTable[RR_DEKU_TREE_BOSS_ROOM] = + Region("Deku Tree Boss Room", "Deku Tree", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&DekuTreeClear, { [] { - return DekuTreeClear || - (CanJumpslash && (Nuts || CanUse(SLINGSHOT) || CanUse(BOW) || - HookshotOrBoomerang)); + EventAccess(&logic->DekuTreeClear, { [] { + return logic->DekuTreeClear || (logic->HasBossSoul(RG_GOHMA_SOUL) && + (logic->CanJumpslash() && (logic->CanUse(RG_NUTS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || + logic->HookshotOrBoomerang()))); }}), }, { // Locations - LocationAccess(QUEEN_GOHMA, { [] { return DekuTreeClear; } }), - LocationAccess(DEKU_TREE_QUEEN_GOHMA_HEART, { [] { return DekuTreeClear; } }), + LOCATION(RC_QUEEN_GOHMA, logic->DekuTreeClear), + LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_HEART, logic->DekuTreeClear), }, { // Exits - Entrance(DEKU_TREE_BOSS_ENTRYWAY, { [] { return true; } }), - Entrance(KF_OUTSIDE_DEKU_TREE, { [] { return DekuTreeClear; } }), + Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, { [] { return true; } }), + Entrance(RR_KF_OUTSIDE_DEKU_TREE, { [] { return logic->DekuTreeClear; } }, false), }); } 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 dc88b1b2c7d..8262a45e2a7 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 @@ -1,314 +1,472 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_DodongosCavern() { +void RegionTable_Init_DodongosCavern() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[DODONGOS_CAVERN_ENTRYWAY] = Area("Dodongos Cavern Entryway", "Dodongos Cavern", 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(DODONGOS_CAVERN_BEGINNING, {[]{return Dungeon::DodongosCavern.IsVanilla();}}), - Entrance(DODONGOS_CAVERN_MQ_BEGINNING, {[]{return Dungeon::DodongosCavern.IsMQ();}}), - Entrance(DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_BEGINNING, {[]{return ctx->GetDungeon(DODONGOS_CAVERN)->IsVanilla();}}), + Entrance(RR_DODONGOS_CAVERN_MQ_BEGINNING, {[]{return ctx->GetDungeon(DODONGOS_CAVERN)->IsMQ();}}), + Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::DodongosCavern.IsVanilla()) { - areaTable[DODONGOS_CAVERN_BEGINNING] = Area("Dodongos Cavern Beginning", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(DODONGOS_CAVERN)->IsVanilla()) { + areaTable[RR_DODONGOS_CAVERN_BEGINNING] = Region("Dodongos Cavern Beginning", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(DODONGOS_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_LOBBY, {[]{return Here(DODONGOS_CAVERN_BEGINNING, []{return CanBlastOrSmash || GoronBracelet;});}}), + Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_BEGINNING, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[DODONGOS_CAVERN_LOBBY] = Area("Dodongos Cavern Lobby", "Dodongos Cavern", 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(&GossipStoneFairy, {[]{return GossipStoneFairy || (CanSummonGossipFairy && Here(DODONGOS_CAVERN_LOBBY, []{return CanBlastOrSmash || GoronBracelet;}));}}), + EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}), }, { //Locations - LocationAccess(DODONGOS_CAVERN_MAP_CHEST, {[]{return Here(DODONGOS_CAVERN_LOBBY, []{return CanBlastOrSmash || GoronBracelet;});}}), - LocationAccess(DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, {[]{return CanStunDeku || GoronBracelet;}}), - LocationAccess(DODONGOS_CAVERN_GOSSIP_STONE, {[]{return Here(DODONGOS_CAVERN_LOBBY, []{return CanBlastOrSmash || GoronBracelet;});}}), + LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), + LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, logic->CanStunDeku() || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), }, { //Exits - Entrance(DODONGOS_CAVERN_BEGINNING, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_LOBBY_SWITCH, {[]{return IsAdult;}}), - Entrance(DODONGOS_CAVERN_SE_CORRIDOR, {[]{return Here(DODONGOS_CAVERN_LOBBY, []{return CanBlastOrSmash || GoronBracelet;});}}), - Entrance(DODONGOS_CAVERN_STAIRS_LOWER, {[]{return HasAccessTo(DODONGOS_CAVERN_LOBBY_SWITCH);}}), - Entrance(DODONGOS_CAVERN_FAR_BRIDGE, {[]{return HasAccessTo(DODONGOS_CAVERN_FAR_BRIDGE);}}), - Entrance(DODONGOS_CAVERN_BOSS_AREA, {[]{return Here(DODONGOS_CAVERN_FAR_BRIDGE, []{return HasExplosives;});}}), - Entrance(DODONGOS_CAVERN_BOSS_ENTRYWAY,{[]{return false;}}), + 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->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), + Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, {[]{return HasAccessTo(RR_DODONGOS_CAVERN_LOBBY_SWITCH);}}), + Entrance(RR_DODONGOS_CAVERN_FAR_BRIDGE, {[]{return HasAccessTo(RR_DODONGOS_CAVERN_FAR_BRIDGE);}}), + Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, {[]{return Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->HasExplosives();});}}), + Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY,{[]{return false;}}), }); - areaTable[DODONGOS_CAVERN_LOBBY_SWITCH] = Area("Dodongos Cavern Lobby Switch", "Dodongos Cavern", 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(DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_DODONGO_ROOM, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_SE_CORRIDOR] = Area("Dodongos Cavern SE Corridor", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_GS_SCARECROW, {[]{return CanUse(SCARECROW) || (IsAdult && CanUse(LONGSHOT)) || (LogicDCScarecrowGS && (CanAdultAttack || CanChildAttack));}}), + LOCATION(RC_DODONGOS_CAVERN_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DC_SCARECROW_GS) && (logic->CanAttack()))), }, { //Exits - Entrance(DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_SE_ROOM, {[]{return Here(DODONGOS_CAVERN_SE_CORRIDOR, []{return CanBlastOrSmash || CanAdultAttack || CanChildAttack || (CanTakeDamage && CanShield);});}}), - Entrance(DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), + //Shield seems to be in logic to drop a pot on thier head as they hit you to blow up the wall + Entrance(RR_DODONGOS_CAVERN_SE_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_SE_CORRIDOR, []{return logic->BlastOrSmash() || logic->CanAttack() || (logic->TakeDamage() && logic->CanShield());});}}), + Entrance(RR_DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_SE_ROOM] = Area("Dodongos Cavern SE Room", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, {[]{return CanAdultAttack || CanChildAttack;}}), + LOCATION(RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, logic->CanAttack()), }, { //Exits - Entrance(DODONGOS_CAVERN_SE_CORRIDOR, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_SE_CORRIDOR, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS] = Area("Dodongos Cavern Near Lower Lizalfos", "Dodongos Cavern", 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(DODONGOS_CAVERN_SE_CORRIDOR, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_SE_CORRIDOR, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_LOWER_LIZALFOS] = Area("Dodongos Cavern Lower Lizalfos", "Dodongos Cavern", 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(DODONGOS_CAVERN_NEAR_LOWER_LIZALFOS, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || - CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || HasExplosives;});}}), - Entrance(DODONGOS_CAVERN_DODONGO_ROOM, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || - CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || HasExplosives;});}}), + 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();});}}), + Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || + logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives();});}}), }); - areaTable[DODONGOS_CAVERN_DODONGO_ROOM] = Area("Dodongos Cavern Dodongo Room", "Dodongos Cavern", 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(DODONGOS_CAVERN_LOBBY_SWITCH, {[]{return HasFireSourceWithTorch;}}), - Entrance(DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_NEAR_DODONGO_ROOM, {[]{return Here(DODONGOS_CAVERN_DODONGO_ROOM, []{return CanBlastOrSmash || GoronBracelet;});}}), + 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->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[DODONGOS_CAVERN_NEAR_DODONGO_ROOM] = Area("Dodongos Cavern Near Dodongo Room", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, {[]{return CanStunDeku;}}), + LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, logic->CanStunDeku()), }, { //Exits - Entrance(DODONGOS_CAVERN_DODONGO_ROOM, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_DODONGO_ROOM, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_STAIRS_LOWER] = Area("Dodongos Cavern Stairs Lower", "Dodongos Cavern", 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(DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_STAIRS_UPPER, {[]{return HasExplosives || GoronBracelet || CanUse(DINS_FIRE) || (LogicDCStaircase && CanUse(BOW));}}), - Entrance(DODONGOS_CAVERN_COMPASS_ROOM, {[]{return Here(DODONGOS_CAVERN_STAIRS_LOWER, []{return CanBlastOrSmash || GoronBracelet;});}}), + Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_STAIRS_UPPER, {[]{return logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DC_STAIRCASE) && logic->CanUse(RG_FAIRY_BOW));}}), + Entrance(RR_DODONGOS_CAVERN_COMPASS_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_STAIRS_LOWER, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[DODONGOS_CAVERN_STAIRS_UPPER] = Area("Dodongos Cavern Stairs Upper", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, {[]{return Here(DODONGOS_CAVERN_FAR_BRIDGE, []{return HookshotOrBoomerang;}) || CanUse(LONGSHOT);}}), - LocationAccess(DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, {[]{return IsAdult || CanChildAttack || (HasAccessTo(DODONGOS_CAVERN_STAIRS_LOWER) && CanUse(LONGSHOT) && LogicDCVinesGS);}}), + LOCATION(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->HookshotOrBoomerang();}) || logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, logic->IsAdult || logic->CanAttack() || (HasAccessTo(RR_DODONGOS_CAVERN_STAIRS_LOWER) && logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_DC_VINES_GS))), }, { //Exits - Entrance(DODONGOS_CAVERN_STAIRS_LOWER, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_ARMOS_ROOM, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_ARMOS_ROOM, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_COMPASS_ROOM] = Area("Dodongos Cavern Compass Room", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_COMPASS_CHEST, {[]{return true;}}), + LOCATION(RC_DODONGOS_CAVERN_COMPASS_CHEST, true), }, { //Exits - Entrance(DODONGOS_CAVERN_STAIRS_LOWER, {[]{return CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || HasExplosives || GoronBracelet;}}), + Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, {[]{return logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET);}}), }); - areaTable[DODONGOS_CAVERN_ARMOS_ROOM] = Area("Dodongos Cavern Armos Room", "Dodongos Cavern", 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(DODONGOS_CAVERN_STAIRS_UPPER, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_STAIRS_UPPER, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_BOMB_ROOM_LOWER] = Area("Dodongos Cavern Bomb Room Lower", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, {[]{return true;}}), + LOCATION(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, true), }, { //Exits - Entrance(DODONGOS_CAVERN_2F_SIDE_ROOM, {[]{return Here(DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return CanBlastOrSmash || (LogicDCScrubRoom && GoronBracelet);});}}), - Entrance(DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, {[]{return Here(DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return CanBlastOrSmash || GoronBracelet;});}}), - Entrance(DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return (IsAdult && LogicDCJump) || CanUse(HOVER_BOOTS) || (IsAdult && CanUse(LONGSHOT));}}), + Entrance(RR_DODONGOS_CAVERN_2F_SIDE_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DC_SCRUB_ROOM) && logic->HasItem(RG_GORONS_BRACELET));});}}), + Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), + Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return (logic->IsAdult && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT));}}), }); - areaTable[DODONGOS_CAVERN_2F_SIDE_ROOM] = Area("Dodongos Cavern 2F Side Room", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, {[]{return CanStunDeku;}}), - LocationAccess(DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, {[]{return CanStunDeku;}}), + LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, logic->CanStunDeku()), + LOCATION(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, logic->CanStunDeku()), }, { //Exits - Entrance(DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM] = Area("Dodongos Cavern First Slingshot Room", "Dodongos Cavern", 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(DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_UPPER_LIZALFOS, {[]{return CanUse(SLINGSHOT) || CanUse(BOW) || LogicDCSlingshotSkip;}}), + Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_DC_SLINGSHOT_SKIP);}}), }); - areaTable[DODONGOS_CAVERN_UPPER_LIZALFOS] = Area("Dodongos Cavern Upper Lizalfos", "Dodongos Cavern", 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(DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || - CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || HasExplosives;});}}), - Entrance(DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, {[]{return Here(DODONGOS_CAVERN_LOWER_LIZALFOS, []{return CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || - CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || HasExplosives;});}}), + Entrance(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || + logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives();});}}), + Entrance(RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || + logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives();});}}), }); - areaTable[DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM] = Area("Dodongos Cavern Second Slingshot Room", "Dodongos Cavern", 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(DODONGOS_CAVERN_UPPER_LIZALFOS, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return CanUse(SLINGSHOT) || CanUse(BOW) || LogicDCSlingshotSkip;}}), + 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) || ctx->GetTrickOption(RT_DC_SLINGSHOT_SKIP);}}), }); - areaTable[DODONGOS_CAVERN_BOMB_ROOM_UPPER] = Area("Dodongos Cavern Bomb Room Upper", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_BOMB_BAG_CHEST, {[]{return true;}}), + LOCATION(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, true), }, { //Exits - Entrance(DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_FAR_BRIDGE, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_FAR_BRIDGE, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_FAR_BRIDGE] = Area("Dodongos Cavern Far Bridge", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, {[]{return Here(DODONGOS_CAVERN_FAR_BRIDGE, []{return CanBlastOrSmash;});}}), + LOCATION(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->BlastOrSmash();})), }, { //Exits - Entrance(DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_BOSS_AREA] = Area("Dodongos Cavern Boss Area", "Dodongos Cavern", 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(&FairyPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), }, {}, { //Exits - Entrance(DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_BACK_ROOM, {[]{return Here(DODONGOS_CAVERN_BOSS_AREA, []{return CanBlastOrSmash;});}}), - Entrance(DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_BACK_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOSS_AREA, []{return logic->BlastOrSmash();});}}), + Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}), }); - areaTable[DODONGOS_CAVERN_BACK_ROOM] = Area("Dodongos Cavern Back Room", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_GS_BACK_ROOM, {[]{return CanAdultAttack || CanChildAttack;}}), + LOCATION(RC_DODONGOS_CAVERN_GS_BACK_ROOM, logic->CanAttack()), }, { //Exits - Entrance(DODONGOS_CAVERN_BOSS_AREA, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, {[]{return true;}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::DodongosCavern.IsMQ()) { - areaTable[DODONGOS_CAVERN_MQ_BEGINNING] = Area("Dodongos Cavern MQ Beginning", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(DODONGOS_CAVERN)->IsMQ()) { + areaTable[RR_DODONGOS_CAVERN_MQ_BEGINNING] = Region("Dodongos Cavern MQ Beginning", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(DODONGOS_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(DODONGOS_CAVERN_MQ_LOBBY, {[]{return Here(DODONGOS_CAVERN_MQ_BEGINNING, []{return CanBlastOrSmash || GoronBracelet;});}}), + Entrance(RR_DODONGOS_CAVERN_ENTRYWAY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_MQ_BEGINNING, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[DODONGOS_CAVERN_MQ_LOBBY] = Area("Dodongos Cavern MQ Lobby", "Dodongos Cavern", 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(&DekuBabaSticks, {[]{return DekuBabaSticks || (IsAdult || KokiriSword || Boomerang);}}), - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairy;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->CanUse(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}), }, { //Locations - LocationAccess(DODONGOS_CAVERN_MQ_MAP_CHEST, {[]{return true;}}), - LocationAccess(DODONGOS_CAVERN_MQ_COMPASS_CHEST, {[]{return CanAdultAttack || CanChildAttack || Nuts;}}), - LocationAccess(DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, {[]{return (IsChild && CanUse(STICKS)) || HasFireSource;}}), - LocationAccess(DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, {[]{return CanBlastOrSmash || (IsChild && CanUse(STICKS)) || CanUse(DINS_FIRE) || (IsAdult && (LogicDCJump || HoverBoots || Hookshot));}}), - LocationAccess(DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, {[]{return CanPlay(SongOfTime) && (CanChildAttack || CanAdultAttack);}}), - LocationAccess(DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, {[]{return (IsChild && CanUse(STICKS)) || HasFireSource;}}), - LocationAccess(DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, {[]{return CanBlastOrSmash;}}), - LocationAccess(DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, {[]{return CanStunDeku;}}), - LocationAccess(DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, {[]{return CanStunDeku;}}), - LocationAccess(DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, {[]{return CanStunDeku;}}), - LocationAccess(DODONGOS_CAVERN_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->CanUse(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku()), + LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku()), + LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls() || logic->CanUse(RG_GORONS_BRACELET);})), }, { //Exits - Entrance(DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(DODONGOS_CAVERN_MQ_LOBBY, []{return CanBlastOrSmash || (((IsChild && CanUse(STICKS)) || CanUse(DINS_FIRE)) && CanTakeDamage);});}}), - Entrance(DODONGOS_CAVERN_MQ_BOMB_BAG_AREA, {[]{return IsAdult || (Here(DODONGOS_CAVERN_MQ_LOBBY, []{return IsAdult;}) && HasExplosives) || (LogicDCMQChildBombs && CanJumpslash && CanTakeDamage);}}), - //Trick: IsAdult || HasExplosives || (LogicDCMQChildBombs && (KokiriSword || Sticks) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO)) - Entrance(DODONGOS_CAVERN_MQ_BOSS_AREA, {[]{return HasExplosives || (GoronBracelet && ((IsAdult && LogicDCMQEyesAdult) || (IsChild && LogicDCMQEyesChild)) && ((IsChild && (CanUse(STICKS))) || CanUse(DINS_FIRE) || (IsAdult && (LogicDCJump || Hammer || HoverBoots || Hookshot))));}}), - //Trick: HasExplosives || (LogicDCMQEyes && GoronBracelet && (IsAdult || LogicDCMQChildBack) && ((IsChild && CanUse(STICKS)) || CanUse(DINS_FIRE) || (IsAdult && (LogicDCJump || Hammer || HoverBoots || Hookshot)))) + Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->CanUse(RG_GORONS_BRACELET);});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->CanUse(RG_GORONS_BRACELET);});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || + Here(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, []{return logic->HasItem(RG_GORONS_BRACELET) && logic->TakeDamage();});}}), //strength 1 and bunny speed works too + Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return logic->IsAdult;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, {[]{return Here(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, []{return logic->HasExplosives() || (logic->ClearMQDCUpperLobbyRocks && logic->HasItem(RG_GORONS_BRACELET) && + ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || + (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));});}}), }); - areaTable[DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE] = Area("Dodongos Cavern MQ Lower Right Side", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE] = Region("Dodongos Cavern MQ Mouth Side Bridge", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}}), + }, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return logic->ClearMQDCUpperLobbyRocks;}}), + //Bunny hood jump + jumpslash can also make it directly from the raising platform + Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DC_MQ_CHILD_BOMBS) && logic->CanJumpslash() && logic->TakeDamage());}}), //RANDOTODO is this possible with equip swapped hammer? + //it is possible to use bunny hood speed, hovers and a jumpslash to go between here and the other bridge (included with TORCH_ROOM_LOWER), but this would be a trick + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER] = Region("Dodongos Cavern MQ Stairs Lower", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { + //Events + //EventAccess(&logic->CanClimbDCStairs, {[]{return logic->HasExplosives || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DC_STAIRCASE) && logic->CanUse(RG_FAIRY_BOW));}}), + }, {}, { + //Exits + //This is possible with sticks and shield, igniting a first flower by "touch" then very quickly crouch stabbing in a way that cuts the corner to light the 3rd bomb on the other side, but that's a trick + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE) || + (ctx->GetTrickOption(RT_DC_STAIRCASE) && logic->CanUse(RG_FAIRY_BOW));});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL, {[]{return Here(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return logic->CanBreakMudWalls();});}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL] = Region("Dodongos Cavern MQ Stairs Past Mud Wall", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->DekuBabaSticks, {[]{return logic->CanGetDekuBabaSticks();}}), + //EventAccess(&logic->CanClimbDCStairs, {[]{return logic->CanUse(RG_GORONS_BRACELET) && (logic->CanUse(RG_STICKS));}}), + }, { //Locations - LocationAccess(DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, {[]{return CanStunDeku;}}), + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), }, { //Exits - Entrance(DODONGOS_CAVERN_MQ_BOMB_BAG_AREA, {[]{return (Here(DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return IsAdult && CanUse(BOW);}) || GoronBracelet || - CanUse(DINS_FIRE) || HasExplosives) && - IsChild && CanUse(SLINGSHOT);}}), + 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_STAIRS_UPPER] = Region("Dodongos Cavern MQ Stairs Upper", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, logic->CanStunDeku()), + }, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_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_STAIRS_PAST_BIG_SKULLTULAS] = Region("Dodongos Cavern MQ Past Big Skulltulas", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->CanUse(RG_HOVER_BOOTS);}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return logic->TakeDamage();}}), + //If some case comes up where you can directly (void?)warp here without going through Dodongo room or climbing up from below, + //the commented out logic is to handle going down and reclimbing to get silver rupees. A new eventVar will need decalring to handle this. + /*(logic->CanPassEnemy(RE_BIG_SKULLTULA) || CanUse(RG_HOVER_BOOTS)) && logic->CanClimbDCStairs;*/ + Entrance(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, {[]{return true;}}),//if we add BONKO or other crate logic, logic for silver rupees goes here }); - areaTable[DODONGOS_CAVERN_MQ_BOMB_BAG_AREA] = Area("Dodongos Cavern MQ Bomb Bag Area", "Dodongos Cavern", 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 - LocationAccess(DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, {[]{return true;}}), - LocationAccess(DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, {[]{return (Here(DODONGOS_CAVERN_MQ_BOMB_BAG_AREA, []{return IsAdult && CanUse(BOW);}) || GoronBracelet || CanUse(DINS_FIRE) || HasExplosives) && HookshotOrBoomerang;}}), + LOCATION(RC_DODONGOS_CAVERN_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_DODONGO) || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits - Entrance(DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_BIG_SKULLTULAS, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, []{return logic->CanKillEnemy(RE_DODONGO) || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[DODONGOS_CAVERN_MQ_BOSS_AREA] = Area("Dodongos Cavern MQ BossArea", "Dodongos Cavern", 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(&FairyPot, {[]{return true;}}), + EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return (((logic->IsAdult /*or bunny hood jump*/) && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_STICKS);}}), + }, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return logic->TakeDamage();}}), + Entrance(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM, {[]{return logic->HasFireSourceWithTorch();}}),//torch checks here need strength 0 with sticks when that is implemented + Entrance(RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, []{return logic->HasFireSourceWithTorch();});}}), //Includes an implied CanPass(RE_BIG_SKULLTULA) + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return ((logic->IsAdult /*or bunny hood jump*/) && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, {[]{return logic->CanUse(RG_STICKS) && logic->HasItem(RG_GORONS_BRACELET);}}), //Implies access to RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM from here + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM] = Region("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}}), + Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, {[]{return (logic->HasFireSource() && logic->HasItem(RG_GORONS_BRACELET)) || logic->CanBreakMudWalls();}}), //Requires stregnth 0, If you can somehow warp into this room, add logic->CanPassEnemy(RE_BIG_SKULLTULA) + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_LARVAE_ROOM] = 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 }, { + //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_UPPER_LIZALFOS] = Region("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, {[]{return true;}}), - LocationAccess(DODONGOS_CAVERN_MQ_GS_BACK_AREA, {[]{return true;}}), + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, logic->BlastOrSmash()), //Implied CanGetEnemyDrop(RE_GOLD_SKULLTULA) }, { //Exits - Entrance(DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}), + //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_TWO_FIRES_ROOM] = Region("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, {[]{return logic->IsAdult || (Here(RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, []{return logic->BlastOrSmash() || (logic->CanAttack() && logic->HasItem(RG_GORONS_BRACELET));}));}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER] = Region("Dodongos Cavern MQ Torch Puzzle Upper", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return logic->CanDetonateUprightBombFlower() || logic->CanUse(RG_MEGATON_HAMMER);}}), + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, true), + }, { + //Exits + 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] = 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->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->CanStunDeku()), + }, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CanHitEyeTargets();}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS] = Region("Dodongos Cavern MQ Lower Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { + //When you add wonder item logic for behind the lavafall, use Here(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS) to account for jumping down instead of an exit + //because the doors are sealed when entering from the top and you can't spawn the lower lizalfos + }, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_POES_ROOM] = Region("Dodongos Cavern MQ Poes Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, true), //If you can get to the locked part of POES_ROOM without a way to open it or passing the chest, this will need it's own room + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);}) && //could be a seperate room if it gets busy + logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT, true))), //Implies you can avoid/kill the enemies with what you use on the skull, if this assumption is broken, add + //&& (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);}) || (logic->CanAvoidEnemy(RE_FIRE_KEESE) && logic->CanAvoidEnemy(RE_MAD_SCRUB))) + }, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}}), + Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_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))) + }, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_POES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);});}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH] = Region("Dodongos Cavern MQ Behind Mouth", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return true;}}), + //using pots to get past the fire is in default logic. if stregnth 0 gets added, this will need to be: + //stregnth 0 || explosives, or projectiles if str0 isn't needed to pull graves (it's a narrow shot though, may be trick worthy) + Entrance(RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE, {[]{return logic->IsAdult;}}), + }); + + areaTable[RR_DODONGOS_CAVERN_MQ_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_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_BACK_SWITCH_GRAVE] = Region("Dodongos Cavern MQ BossArea", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->FairyPot, {[]{return true;}}), + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) || logic->HasItem(RG_GORONS_BRACELET) || //even if you somehow warp to BACK_BEHIND_FIRE, if you can kill the skull at range, you can get to BEHIND_MOUTH + Here(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT)) || + (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) /* || bunny jumps*/);})), + }, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, {[]{return true;}}), + Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, {[]{return true;}}), //if strength 0 prevents grave pulls, add it here + }); + } /*--------------------------- | BOSS ROOM | ---------------------------*/ - areaTable[DODONGOS_CAVERN_BOSS_ENTRYWAY] = - Area("Dodongos Cavern Boss Entryway", "Dodongos Cavern", DODONGOS_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_DODONGOS_CAVERN_BOSS_ENTRYWAY] = + Region("Dodongos Cavern Boss Entryway", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(DODONGOS_CAVERN_BOSS_AREA, { [] { return Dungeon::DodongosCavern.IsVanilla(); } }), - Entrance(DODONGOS_CAVERN_MQ_BOSS_AREA, { [] { return Dungeon::DodongosCavern.IsMQ(); } }), - Entrance(DODONGOS_CAVERN_BOSS_ROOM, { [] { return true; } }), + Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, { [] { return ctx->GetDungeon(DODONGOS_CAVERN)->IsVanilla(); } }), + Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, { [] { return ctx->GetDungeon(DODONGOS_CAVERN)->IsMQ(); } }), + Entrance(RR_DODONGOS_CAVERN_BOSS_ROOM, { [] { return true; } }), }); - areaTable[DODONGOS_CAVERN_BOSS_ROOM] = - Area("Dodongos Cavern Boss Room", "Dodongos Cavern", NONE, NO_DAY_NIGHT_CYCLE, + areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = + Region("Dodongos Cavern Boss Room", "Dodongos Cavern", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&DodongosCavernClear, + EventAccess(&logic->DodongosCavernClear, { [] { - return DodongosCavernClear || - (Here(DODONGOS_CAVERN_BOSS_ROOM, - [] { return HasExplosives || (CanUse(MEGATON_HAMMER) && LogicDCHammerFloor); }) && - (Bombs || GoronBracelet) && CanJumpslash); /*todo add chu kill to tricks*/ + return logic->DodongosCavernClear || (logic->HasBossSoul(RG_KING_DODONGO_SOUL) && + (Here(RR_DODONGOS_CAVERN_BOSS_ROOM, + [] { return logic->HasExplosives() || (logic->CanUse(RG_MEGATON_HAMMER) && ctx->GetTrickOption(RT_DC_HAMMER_FLOOR)); }) && + (logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CanJumpslash())); /*todo add chu kill to tricks*/ }}), }, { // Locations - LocationAccess(DODONGOS_CAVERN_BOSS_ROOM_CHEST, { [] { return true; } }), - LocationAccess(DODONGOS_CAVERN_KING_DODONGO_HEART, { [] { return DodongosCavernClear; } }), - LocationAccess(KING_DODONGO, { [] { return DodongosCavernClear; } }), + LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, logic->DodongosCavernClear), + LOCATION(RC_KING_DODONGO, logic->DodongosCavernClear), }, { // Exits - Entrance(DODONGOS_CAVERN_BOSS_ENTRYWAY, { [] { return true; } }), - Entrance(DEATH_MOUNTAIN_TRAIL, { [] { return DodongosCavernClear; } }), + Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, { [] { return true; } }), + Entrance(RR_DEATH_MOUNTAIN_TRAIL, { [] { return logic->DodongosCavernClear; } }, false), }); } 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 10702887264..61fac306bf9 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 @@ -1,425 +1,424 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_FireTemple() { +void RegionTable_Init_FireTemple() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[FIRE_TEMPLE_ENTRYWAY] = Area("Fire Temple Entryway", "Fire Temple", 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(FIRE_TEMPLE_FIRST_ROOM, {[]{return Dungeon::FireTemple.IsVanilla();}}), - Entrance(FIRE_TEMPLE_MQ_LOWER, {[]{return Dungeon::FireTemple.IsMQ();}}), - Entrance(DMC_CENTRAL_LOCAL, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla();}}), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER, {[]{return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ();}}), + Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::FireTemple.IsVanilla()) { - areaTable[FIRE_TEMPLE_FIRST_ROOM] = Area("Fire Temple First Room", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla()) { + areaTable[RR_FIRE_TEMPLE_FIRST_ROOM] = Region("Fire Temple First Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { }, { //Exits - Entrance(FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(FIRE_TEMPLE_NEAR_BOSS_ROOM, {[]{return FireTimer >= 24;}}), - Entrance(FIRE_TEMPLE_LOOP_ENEMIES, {[]{return Here(FIRE_TEMPLE_FIRST_ROOM, []{return CanUse(MEGATON_HAMMER);}) && (SmallKeys(FIRE_TEMPLE, 8) || !IsKeysanity);}}), - Entrance(FIRE_TEMPLE_LOOP_EXIT, {[]{return true;}}), - Entrance(FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return SmallKeys(FIRE_TEMPLE, 2) && FireTimer >= 24;}}), + Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, {[]{return logic->FireTimer() >= 24;}}), + Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, {[]{return Here(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsKeysanity);}}), + Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 2) && logic->FireTimer() >= 24;}}), }); - areaTable[FIRE_TEMPLE_NEAR_BOSS_ROOM] = Area("Fire Temple Near Boss Room", "Fire Temple", 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(&FairyPot, {[]{return FairyPot || (CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT));}}), + EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), }, { //Locations - LocationAccess(FIRE_TEMPLE_NEAR_BOSS_CHEST, {[]{return true;}}), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, true), }, { //Exits - Entrance(FIRE_TEMPLE_FIRST_ROOM, {[]{return true;}}), - Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyFireTemple && ((IsAdult && (LogicFireBossDoorJump || Here(FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return CanUse(MEGATON_HAMMER);}))) || CanUse(HOVER_BOOTS));}}), + Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_FIRE_TEMPLE_BOSS_KEY) && ((logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || Here(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return logic->CanUse(RG_MEGATON_HAMMER);}))) || logic->CanUse(RG_HOVER_BOOTS));}}), }); - areaTable[FIRE_TEMPLE_LOOP_ENEMIES] = Area("Fire Temple Loop Enemies", "Fire Temple", 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(FIRE_TEMPLE_FIRST_ROOM, {[]{return SmallKeys(FIRE_TEMPLE, 8) || !IsKeysanity;}}), - Entrance(FIRE_TEMPLE_LOOP_TILES, {[]{return Here(FIRE_TEMPLE_LOOP_ENEMIES, []{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);});}}), + 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[FIRE_TEMPLE_LOOP_TILES] = Area("Fire Temple Loop Tiles", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_GS_BOSS_KEY_LOOP, {[]{return CanAdultAttack || CanChildAttack;}}), + LOCATION(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, logic->CanAttack()), }, { //Exits - Entrance(FIRE_TEMPLE_LOOP_ENEMIES, {[]{return true;}}), - Entrance(FIRE_TEMPLE_LOOP_FLARE_DANCER, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_LOOP_FLARE_DANCER] = Area("Fire Temple Loop Flare Dancer", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_FLARE_DANCER_CHEST, {[]{return (HasExplosives || CanUse(MEGATON_HAMMER)) && IsAdult;}}), + LOCATION(RC_FIRE_TEMPLE_FLARE_DANCER_CHEST, (logic->HasExplosives() || logic->CanUse(RG_MEGATON_HAMMER)) && logic->IsAdult), }, { //Exits - Entrance(FIRE_TEMPLE_LOOP_TILES, {[]{return true;}}), - Entrance(FIRE_TEMPLE_LOOP_HAMMER_SWITCH, {[]{return Here(FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT) || (HasExplosives && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || - CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(BOOMERANG)));});}}), + Entrance(RR_FIRE_TEMPLE_LOOP_TILES, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, {[]{return Here(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || + logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG)));});}}), }); - areaTable[FIRE_TEMPLE_LOOP_HAMMER_SWITCH] = Area("Fire Temple Loop Hammer Switch", "Fire Temple", 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(&FireLoopSwitch, {[]{return FireLoopSwitch || CanUse(MEGATON_HAMMER);}}), + EventAccess(&logic->FireLoopSwitch, {[]{return logic->FireLoopSwitch || logic->CanUse(RG_MEGATON_HAMMER);}}), }, {}, { //Exits - Entrance(FIRE_TEMPLE_LOOP_FLARE_DANCER, {[]{return true;}}), - Entrance(FIRE_TEMPLE_LOOP_GORON_ROOM, {[]{return FireLoopSwitch;}}), + Entrance(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, {[]{return logic->FireLoopSwitch;}}), }); - areaTable[FIRE_TEMPLE_LOOP_GORON_ROOM] = Area("Fire Temple Loop Goron Room", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_BOSS_KEY_CHEST, {[]{return true;}}), + LOCATION(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, true), }, { //Exits - Entrance(FIRE_TEMPLE_LOOP_HAMMER_SWITCH, {[]{return FireLoopSwitch;}}), - Entrance(FIRE_TEMPLE_LOOP_EXIT, {[]{return FireLoopSwitch;}}), + Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, {[]{return logic->FireLoopSwitch;}}), + Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, {[]{return logic->FireLoopSwitch;}}), }); - areaTable[FIRE_TEMPLE_LOOP_EXIT] = Area("Fire Temple Loop Exit", "Fire Temple", 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(FIRE_TEMPLE_FIRST_ROOM, {[]{return true;}}), - Entrance(FIRE_TEMPLE_LOOP_GORON_ROOM, {[]{return FireLoopSwitch;}}), + Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, {[]{return logic->FireLoopSwitch;}}), }); - areaTable[FIRE_TEMPLE_BIG_LAVA_ROOM] = Area("Fire Temple Big Lava Room", "Fire Temple", 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(FIRE_TEMPLE_FIRST_ROOM, {[]{return SmallKeys(FIRE_TEMPLE, 2);}}), - Entrance(FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON, {[]{return true;}}), - Entrance(FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES, {[]{return IsAdult && (CanPlay(SongOfTime) || LogicFireSongOfTime);}}), - Entrance(FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON, {[]{return IsAdult && HasExplosives;}}), - Entrance(FIRE_TEMPLE_FIRE_PILLAR_ROOM, {[]{return SmallKeys(FIRE_TEMPLE, 3);}}), + Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 2);}}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES, {[]{return logic->IsAdult && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_FIRE_SOT));}}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON, {[]{return logic->IsAdult && logic->HasExplosives();}}), + Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}}), }); - areaTable[FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON] = Area("Fire Temple Big Lava Room North Goron", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, {[]{return true;}}), + LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, true), }, { //Exits - Entrance(FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_TILES] = Area("Fire Temple Big Lava Room North Tiles", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, {[]{return CanAdultAttack || HookshotOrBoomerang;}}), + //RANDOTODO check if child can reach + LOCATION(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, (logic->IsAdult && logic->CanAttack()) || logic->HookshotOrBoomerang()), }, { //Exits - Entrance(FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_BIG_LAVA_ROOM_SOUTH_GORON] = Area("Fire Temple Big Lava Room South Goron", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, {[]{return true;}}), + LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, true), }, { //Exits - Entrance(FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_FIRE_PILLAR_ROOM] = Area("Fire Temple Fire Pillar Room", "Fire Temple", 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(FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return SmallKeys(FIRE_TEMPLE, 3);}}), - Entrance(FIRE_TEMPLE_SHORTCUT_ROOM, {[]{return FireTimer >= 56 && SmallKeys(FIRE_TEMPLE, 4);}}), + 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[FIRE_TEMPLE_SHORTCUT_ROOM] = Area("Fire Temple Shortcut Room", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, {[]{return Here(FIRE_TEMPLE_SHORTCUT_CLIMB, []{return true;});}}), + LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, Here(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return true;})), }, { //Exits - Entrance(FIRE_TEMPLE_FIRE_PILLAR_ROOM, {[]{return SmallKeys(FIRE_TEMPLE, 4);}}), - Entrance(FIRE_TEMPLE_SHORTCUT_CLIMB, {[]{return Here(FIRE_TEMPLE_SHORTCUT_CLIMB, []{return true;});}}), - Entrance(FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return IsAdult && (GoronBracelet || LogicFireStrength) && (HasExplosives || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(SLINGSHOT));}}), + Entrance(RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 4);}}), + Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, {[]{return Here(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, []{return true;});}}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || ctx->GetTrickOption(RT_FIRE_STRENGTH)) && (logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT));}}), }); - areaTable[FIRE_TEMPLE_SHORTCUT_CLIMB] = Area("Fire Temple Shortcut Climb", "Fire Temple", 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(FIRE_TEMPLE_SHORTCUT_ROOM, {[]{return true;}}), - Entrance(FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_BOULDER_MAZE_LOWER] = Area("Fire Temple Boulder Maze Lower", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, {[]{return true;}}), - LocationAccess(FIRE_TEMPLE_GS_BOULDER_MAZE, {[]{return HasExplosives && (IsAdult || HookshotOrBoomerang);}}), + LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, logic->HasExplosives() && (logic->IsAdult || logic->HookshotOrBoomerang())), }, { //Exits - Entrance(FIRE_TEMPLE_SHORTCUT_ROOM, {[]{return true;}}), - Entrance(FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM, {[]{return true;}}), - Entrance(FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return SmallKeys(FIRE_TEMPLE, 5, 7);}}), - Entrance(FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return false;}}), + Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 5, 7);}}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return false;}}), }); - areaTable[FIRE_TEMPLE_BOULDER_MAZE_LOWER_SIDE_ROOM] = Area("Fire Temple Boulder Maze Lower Side Room", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, {[]{return true;}}), + LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, true), }, { //Exits - Entrance(FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_EAST_CENTRAL_ROOM] = Area("Fire Temple East Central Room", "Fire Temple", 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(FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return CanTakeDamage;}}), - Entrance(FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return SmallKeys(FIRE_TEMPLE, 5, 8);}}), - Entrance(FIRE_TEMPLE_FIRE_WALL_CHASE, {[]{return SmallKeys(FIRE_TEMPLE, 6, 8);}}), - Entrance(FIRE_TEMPLE_MAP_AREA, {[]{return CanUse(SLINGSHOT) || CanUse(BOW);}}), + Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return logic->TakeDamage();}}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 5, 8);}}), + Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 6, 8);}}), + Entrance(RR_FIRE_TEMPLE_MAP_AREA, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW);}}), }); - areaTable[FIRE_TEMPLE_FIRE_WALL_CHASE] = Area("Fire Temple Fire Wall Chase", "Fire Temple", 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(FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return FireTimer >= 24 && SmallKeys(FIRE_TEMPLE, 6, 8);}}), - Entrance(FIRE_TEMPLE_MAP_AREA, {[]{return IsAdult;}}), - Entrance(FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return FireTimer >= 24 && IsAdult;}}), - Entrance(FIRE_TEMPLE_CORRIDOR, {[]{return FireTimer >= 24 && IsAdult && SmallKeys(FIRE_TEMPLE, 7);}}), + Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return logic->FireTimer() >= 24 && logic->SmallKeys(RR_FIRE_TEMPLE, 6, 8);}}), + Entrance(RR_FIRE_TEMPLE_MAP_AREA, {[]{return logic->IsAdult;}}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return logic->FireTimer() >= 24 && logic->IsAdult;}}), + Entrance(RR_FIRE_TEMPLE_CORRIDOR, {[]{return logic->FireTimer() >= 24 && logic->IsAdult && logic->SmallKeys(RR_FIRE_TEMPLE, 7);}}), }); - areaTable[FIRE_TEMPLE_MAP_AREA] = Area("Fire Temple Map Area", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_MAP_CHEST, {[]{return true;}}), + LOCATION(RC_FIRE_TEMPLE_MAP_CHEST, true), }, { //Exits - Entrance(FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_BOULDER_MAZE_UPPER] = Area("Fire Temple Boulder Maze Upper", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, {[]{return true;}}), + LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, true), }, { //Exits - Entrance(FIRE_TEMPLE_SHORTCUT_CLIMB, {[]{return HasExplosives;}}), - Entrance(FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return true;}}), - Entrance(FIRE_TEMPLE_FIRE_WALL_CHASE, {[]{return true;}}), - Entrance(FIRE_TEMPLE_SCARECROW_ROOM, {[]{return CanUse(SCARECROW) || (LogicFireScarecrow && IsAdult && CanUse(LONGSHOT));}}), + Entrance(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, {[]{return logic->HasExplosives();}}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_SCARECROW_ROOM, {[]{return logic->CanUse(RG_SCARECROW) || (ctx->GetTrickOption(RT_FIRE_SCARECROW) && logic->IsAdult && logic->CanUse(RG_LONGSHOT));}}), }); - areaTable[FIRE_TEMPLE_SCARECROW_ROOM] = Area("Fire Temple Scarecrow Room", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_GS_SCARECROW_CLIMB, {[]{return CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOOMERANG) || HasExplosives || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(DINS_FIRE);}}), + LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)), }, { //Exits - Entrance(FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return true;}}), - Entrance(FIRE_TEMPLE_EAST_PEAK, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_EAST_PEAK, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_EAST_PEAK] = Area("Fire Temple East Peak", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_SCARECROW_CHEST, {[]{return true;}}), - LocationAccess(FIRE_TEMPLE_GS_SCARECROW_TOP, {[]{return CanUseProjectile;}}), + LOCATION(RC_FIRE_TEMPLE_SCARECROW_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, logic->CanUseProjectile()), }, { //Exits - Entrance(FIRE_TEMPLE_SCARECROW_ROOM, {[]{return true;}}), - Entrance(FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return CanTakeDamage;}}), + Entrance(RR_FIRE_TEMPLE_SCARECROW_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return logic->TakeDamage();}}), }); - areaTable[FIRE_TEMPLE_CORRIDOR] = Area("Fire Temple Corridor", "Fire Temple", 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(FIRE_TEMPLE_FIRE_WALL_CHASE, {[]{return SmallKeys(FIRE_TEMPLE, 7);}}), - Entrance(FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_FIRE_WALL_CHASE, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 7);}}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_FIRE_MAZE_ROOM] = Area("Fire Temple Fire Maze Room", "Fire Temple", 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(FIRE_TEMPLE_CORRIDOR, {[]{return true;}}), - Entrance(FIRE_TEMPLE_FIRE_MAZE_UPPER, {[]{return CanUse(HOVER_BOOTS);}}), - Entrance(FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM, {[]{return true;}}), - Entrance(FIRE_TEMPLE_WEST_CENTRAL_LOWER, {[]{return SmallKeys(FIRE_TEMPLE, 8);}}), - Entrance(FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return LogicFireFlameMaze || false;}}), + Entrance(RR_FIRE_TEMPLE_CORRIDOR, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, {[]{return logic->CanUse(RG_HOVER_BOOTS);}}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 8);}}), + Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return ctx->GetTrickOption(RT_FIRE_FLAME_MAZE) || false;}}), }); - areaTable[FIRE_TEMPLE_FIRE_MAZE_UPPER] = Area("Fire Temple Fire Maze Upper", "Fire Temple", 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(FIRE_TEMPLE_NEAR_BOSS_ROOM, {[]{return CanUse(MEGATON_HAMMER);}}), - Entrance(FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return true;}}), - Entrance(FIRE_TEMPLE_WEST_CENTRAL_UPPER, {[]{return CanUse(MEGATON_HAMMER);}}), + 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[FIRE_TEMPLE_FIRE_MAZE_SIDE_ROOM] = Area("Fire Temple Fire Maze Side Room", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_COMPASS_CHEST, {[]{return true;}}), + LOCATION(RC_FIRE_TEMPLE_COMPASS_CHEST, true), }, { //Exits - Entrance(FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_WEST_CENTRAL_LOWER] = Area("Fire Temple West Central Lower", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_HIGHEST_GORON_CHEST, {[]{return Here(FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return (CanPlay(SongOfTime) || LogicRustedSwitches) && CanUse(MEGATON_HAMMER);});}}), + LOCATION(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, Here(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, []{return (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER);})), }, { //Exits - Entrance(FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return SmallKeys(FIRE_TEMPLE, 8);}}), - Entrance(FIRE_TEMPLE_WEST_CENTRAL_UPPER, {[]{return IsAdult && CanPlay(SongOfTime);}}), - Entrance(FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 8);}}), + Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, {[]{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}}), + Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return true;}}), }); - areaTable[FIRE_TEMPLE_WEST_CENTRAL_UPPER] = Area("Fire Temple West Central Upper", "Fire Temple", 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(FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return false;}}), - Entrance(FIRE_TEMPLE_FIRE_MAZE_UPPER, {[]{return true;}}), - Entrance(FIRE_TEMPLE_WEST_CENTRAL_LOWER, {[]{return true;}}), + 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[FIRE_TEMPLE_LATE_FIRE_MAZE] = Area("Fire Temple Late Fire Maze", "Fire Temple", 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(FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return false;}}), - Entrance(FIRE_TEMPLE_WEST_CENTRAL_LOWER, {[]{return true;}}), - Entrance(FIRE_TEMPLE_UPPER_FLARE_DANCER, {[]{return HasExplosives;}}), + 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[FIRE_TEMPLE_UPPER_FLARE_DANCER] = Area("Fire Temple Upper Flare Dancer", "Fire Temple", 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(FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return Here(FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT) || (HasExplosives && ((CanUse(KOKIRI_SWORD)) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || - CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(BOOMERANG)));});}}), - Entrance(FIRE_TEMPLE_WEST_CLIMB, {[]{return Here(FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT) || (HasExplosives && ((CanUse(KOKIRI_SWORD)) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || - CanUse(SLINGSHOT) || CanUse(BOOMERANG)));});}}), + Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return Here(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && ((logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || + logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG)));});}}), + Entrance(RR_FIRE_TEMPLE_WEST_CLIMB, {[]{return Here(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && ((logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || + logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)));});}}), }); - areaTable[FIRE_TEMPLE_WEST_CLIMB] = Area("Fire Temple West Climb", "Fire Temple", 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(FIRE_TEMPLE_UPPER_FLARE_DANCER, {[]{return true;}}), - Entrance(FIRE_TEMPLE_WEST_PEAK, {[]{return CanUseProjectile;}}), + Entrance(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_WEST_PEAK, {[]{return logic->CanUseProjectile();}}), }); - areaTable[FIRE_TEMPLE_WEST_PEAK] = Area("Fire Temple West Peak", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_MEGATON_HAMMER_CHEST, {[]{return true;}}), + LOCATION(RC_FIRE_TEMPLE_MEGATON_HAMMER_CHEST, true), }, { //Exits - Entrance(FIRE_TEMPLE_WEST_CENTRAL_UPPER, {[]{return CanTakeDamage;}}), - Entrance(FIRE_TEMPLE_WEST_CLIMB, {[]{return true;}}), - Entrance(FIRE_TEMPLE_HAMMER_RETURN_PATH, {[]{return CanUse(MEGATON_HAMMER);}}), + Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_UPPER, {[]{return logic->TakeDamage();}}), + Entrance(RR_FIRE_TEMPLE_WEST_CLIMB, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_HAMMER_RETURN_PATH, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), }); - areaTable[FIRE_TEMPLE_HAMMER_RETURN_PATH] = Area("Fire Temple Hammer Return Path", "Fire Temple", 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(FIRE_TEMPLE_ABOVE_FIRE_MAZE, {[]{return CanUse(MEGATON_HAMMER);}}), + Entrance(RR_FIRE_TEMPLE_ABOVE_FIRE_MAZE, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), }); - areaTable[FIRE_TEMPLE_ABOVE_FIRE_MAZE] = Area("Fire Temple Above Fire Maze", "Fire Temple", 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(FIRE_TEMPLE_HAMMER_RETURN_PATH, {[]{return true;}}), - Entrance(FIRE_TEMPLE_FIRE_MAZE_UPPER, {[]{return CanUse(MEGATON_HAMMER);}}), + Entrance(RR_FIRE_TEMPLE_HAMMER_RETURN_PATH, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::FireTemple.IsMQ()) { - areaTable[FIRE_TEMPLE_MQ_LOWER] = Area("Fire Temple MQ Lower", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(FIRE_TEMPLE)->IsMQ()) { + areaTable[RR_FIRE_TEMPLE_MQ_LOWER] = Region("Fire Temple MQ Lower", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, {[]{return CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || Bombs || CanUse(DINS_FIRE);}}), - LocationAccess(FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, {[]{return IsAdult && (LogicFewerTunicRequirements || CanUse(GORON_TUNIC)) && (((CanUse(HOVER_BOOTS) || (LogicFireMQNearBoss && CanUse(BOW))) && HasFireSource) || (CanUse(HOOKSHOT) && CanUse(FIRE_ARROWS) || (CanUse(DINS_FIRE) && ((DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_QUADRUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OCTUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_SEXDECUPLE)) || CanUse(GORON_TUNIC) || CanUse(BOW) || CanUse(LONGSHOT)))));}}), - //Trick: IsAdult && (LogicFewerTunicRequirements || CanUse(GORON_TUNIC)) && (((CanUse(HOVER_BOOTS) || (LogicFireMQNearBoss && CanUse(BOW))) && HasFireSource) || (CanUse(HOOKSHOT) && CanUse(FIRE_ARROWS) || (CanUse(DINS_FIRE) && ((DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_QUADRUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OCTUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_SEXDECUPLE)) || CanUse(GORON_TUNIC) || CanUse(BOW) || CanUse(LONGSHOT))))) + LOCATION(RC_FIRE_TEMPLE_MQ_MAP_ROOM_SIDE_CHEST, logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->IsAdult && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_GORON_TUNIC)) && (((logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && logic->CanUse(RG_FAIRY_BOW))) && logic->HasFireSource()) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && ((ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_QUADRUPLE) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OCTUPLE) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_SEXDECUPLE)) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT)))))), + //Trick: logic->IsAdult && (LogicFewerTunicRequirements || logic->CanUse(RG_GORON_TUNIC)) && (((logic->CanUse(RG_HOVER_BOOTS) || (LogicFireMQNearBoss && logic->CanUse(RG_FAIRY_BOW))) && logic->HasFireSource()) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_DINS_FIRE) && ((DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_QUADRUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OCTUPLE) && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_SEXDECUPLE)) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT))))) }, { //Exits - Entrance(FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return IsAdult && CanUse(GORON_TUNIC) && CanUse(MEGATON_HAMMER) && BossKeyFireTemple && ((HasFireSource && (LogicFireBossDoorJump || HoverBoots)) || HasAccessTo(FIRE_TEMPLE_MQ_UPPER));}}), - Entrance(FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR, {[]{return SmallKeys(FIRE_TEMPLE, 5) && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD));}}), - Entrance(FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return IsAdult && FireTimer >= 24 && CanUse(MEGATON_HAMMER);}}), + Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_FIRE_TEMPLE_BOSS_KEY) && ((logic->HasFireSource() && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || HasAccessTo(RR_FIRE_TEMPLE_MQ_UPPER));}}), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 5) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD));}}), + Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return logic->IsAdult && logic->FireTimer() >= 24 && logic->CanUse(RG_MEGATON_HAMMER);}}), }); - areaTable[FIRE_TEMPLE_MQ_LOWER_LOCKED_DOOR] = Area("Fire Temple MQ Lower Locked Door", "Fire Temple", 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(&FairyPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations - LocationAccess(FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, {[]{return IsAdult && (CanUse(MEGATON_HAMMER) || CanUse(HOOKSHOT) || (HasExplosives && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(BOOMERANG))));}}), - LocationAccess(FIRE_TEMPLE_MQ_MAP_CHEST, {[]{return IsAdult && CanUse(MEGATON_HAMMER);}}), + LOCATION(RC_FIRE_TEMPLE_MQ_MEGATON_HAMMER_CHEST, logic->IsAdult && (logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG))))), + LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, {}); - areaTable[FIRE_TEMPLE_MQ_BIG_LAVA_ROOM] = Area("Fire Temple MQ Big Lava Room", "Fire Temple", 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(&FairyPot, {[]{return FairyPot || (HasFireSource && (Bow || LogicFireMQBKChest) && IsAdult && (CanUse(HOOKSHOT) || LogicFireSongOfTime));}}), - //Trick: HasFireSource && (Bow || LogicFireMQBKChest) && IsAdult && (CanUse(HOOKSHOT) || LogicFireSongOfTime) + EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_FIRE_MQ_BK_CHEST)) && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_FIRE_SOT)));}}), + //Trick: logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || LogicFireMQBKChest) && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || LogicFireSongOfTime) }, { //Locations - LocationAccess(FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, {[]{return HasFireSource && (Bow || LogicFireMQBKChest) && IsAdult && CanUse(HOOKSHOT);}}), - //Trick: HasFireSource && (Bow || LogicFireMQBKChest) && IsAdult && CanUse(HOOKSHOT) - LocationAccess(FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, {[]{return HasFireSource && HasExplosives && IsAdult && (CanUse(HOOKSHOT) || LogicFireMQBlockedChest);}}), - //Trick: HasFireSource && HasExplosives && IsAdult && (CanUse(HOOKSHOT) || LogicFireMQBlockedChest) - LocationAccess(FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, {[]{return true;}}), + LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_FIRE_MQ_BK_CHEST)) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)), + //Trick: logic->HasFireSource() && (logic->CanUse(RG_FAIRY_BOW) || LogicFireMQBKChest) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT) + LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->HasFireSource() && logic->HasExplosives() && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST))), + //Trick: logic->HasFireSource() && logic->HasExplosives() && logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || LogicFireMQBlockedChest) + LOCATION(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, true), }, { //Exits - Entrance(FIRE_TEMPLE_MQ_LOWER_MAZE, {[]{return IsAdult && CanUse(GORON_TUNIC) && SmallKeys(FIRE_TEMPLE, 2) && (HasFireSource || (LogicFireMQClimb && HoverBoots));}}), - //Trick: IsAdult && CanUse(GORON_TUNIC) && SmallKeys(FIRE_TEMPLE, 2) && (HasFireSource || (LogicFireMQClimb && HoverBoots)) + Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(RR_FIRE_TEMPLE, 2) && (logic->HasFireSource() || (ctx->GetTrickOption(RT_FIRE_MQ_CLIMB) && logic->CanUse(RG_HOVER_BOOTS)));}}), + //Trick: logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->SmallKeys(RR_FIRE_TEMPLE, 2) && (logic->HasFireSource() || (LogicFireMQClimb && logic->CanUse(RG_HOVER_BOOTS))) }); - areaTable[FIRE_TEMPLE_MQ_LOWER_MAZE] = Area("Fire Temple MQ Lower Maze", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CHEST, {[]{return CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD);}}), - LocationAccess(FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, {[]{return HasExplosives && (LogicFireMQMazeSideRoom || HasAccessTo(FIRE_TEMPLE_MQ_UPPER_MAZE));}}), - //Trick: HasExplosives && (LogicFireMQMazeSideRoom || FIRE_TEMPLE_MQ_UPPER_MAZE.Adult()) + 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() && (ctx->GetTrickOption(RT_FIRE_MQ_MAZE_SIDE_ROOM) || HasAccessTo(RR_FIRE_TEMPLE_MQ_UPPER_MAZE))), + //Trick: logic->HasExplosives() && (LogicFireMQMazeSideRoom || FIRE_TEMPLE_MQ_UPPER_MAZE.Adult()) }, { //Exits - Entrance(FIRE_TEMPLE_MQ_UPPER_MAZE, {[]{return (IsAdult && ((HasExplosives && CanUse(HOOKSHOT)) || (LogicFireMQMazeHovers && CanUse(HOVER_BOOTS)))) || LogicFireMQMazeJump;}}), - //Trick: (IsAdult && ((HasExplosives && CanUse(HOOKSHOT)) || (LogicFireMQMazeHovers && CanUse(HOVER_BOOTS)))) || LogicFireMQMazeJump + Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, {[]{return (logic->IsAdult && ((logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_FIRE_MQ_MAZE_HOVERS) && logic->CanUse(RG_HOVER_BOOTS)))) || ctx->GetTrickOption(RT_FIRE_MQ_MAZE_JUMP);}}), + //Trick: (logic->IsAdult && ((logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT)) || (LogicFireMQMazeHovers && logic->CanUse(RG_HOVER_BOOTS)))) || LogicFireMQMazeJump }); - areaTable[FIRE_TEMPLE_MQ_UPPER_MAZE] = Area("Fire Temple MQ Upper Maze", "Fire Temple", 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 || (IsAdult && (((CanPlay(SongOfTime) && CanUse(HOOKSHOT) && HasExplosives) || CanUse(LONGSHOT))));}}), - EventAccess(&FairyPot, {[]{return SmallKeys(FIRE_TEMPLE, 3);}}), + //EventAccess(&WallFairy, {[]{return WallFairy || (logic->IsAdult && (((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOOKSHOT) && logic->HasExplosives()) || logic->CanUse(RG_LONGSHOT))));}}), + EventAccess(&logic->FairyPot, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}}), }, { //Locations - LocationAccess(FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, {[]{return true;}}), - LocationAccess(FIRE_TEMPLE_MQ_COMPASS_CHEST, {[]{return HasExplosives;}}), - LocationAccess(FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, {[]{return IsAdult && ((CanPlay(SongOfTime) && CanUse(HOOKSHOT) && HasExplosives) || CanUse(LONGSHOT));}}), + LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_MQ_COMPASS_CHEST, logic->HasExplosives()), + LOCATION(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_HOOKSHOT) && logic->HasExplosives()) || logic->CanUse(RG_LONGSHOT))), }, { //Exits - Entrance(FIRE_TEMPLE_MQ_UPPER, {[]{return SmallKeys(FIRE_TEMPLE, 3) && IsAdult && ((CanUse(BOW) && CanUse(HOOKSHOT)) || CanUse(FIRE_ARROWS));}}), + 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[FIRE_TEMPLE_MQ_UPPER] = Area("Fire Temple MQ Upper", "Fire Temple", 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 - LocationAccess(FIRE_TEMPLE_MQ_FREESTANDING_KEY, {[]{return ((CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(SLINGSHOT) || CanUse(BOOMERANG)) && CanUse(HOOKSHOT)) || LogicFireMQFlameMaze;}}), - //Trick: (IsAdult && CanUse(HOOKSHOT)) || LogicFireMQFlameMaze - LocationAccess(FIRE_TEMPLE_MQ_CHEST_ON_FIRE, {[]{return ((IsAdult && CanUse(HOOKSHOT)) || LogicFireMQFlameMaze) && SmallKeys(FIRE_TEMPLE, 4);}}), - //Trick: ((IsAdult && CanUse(HOOKSHOT)) || LogicFireMQFlameMaze) && SmallKeys(FIRE_TEMPLE, 4) - LocationAccess(FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, {[]{return CanPlay(SongOfTime) || HoverBoots || LogicFireMQFlameMaze;}}), - //Trick: CanPlay(SongOfTime) || HoverBoots || LogicFireMQFlameMaze - LocationAccess(FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, {[]{return HasExplosives;}}), - LocationAccess(FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, {[]{return (IsAdult && CanUse(HOOKSHOT) && SmallKeys(FIRE_TEMPLE, 5)) || (LogicFireMQAboveMazeGS && IsAdult && CanUse(LONGSHOT));}}), - //Trick: (IsAdult && CanUse(HOOKSHOT) && SmallKeys(FIRE_TEMPLE, 5)) || (LogicFireMQAboveMazeGS && IsAdult && CanUse(LONGSHOT)) + LOCATION(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, ((logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)) && logic->CanUse(RG_HOOKSHOT)) || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)), + //Trick: (logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || LogicFireMQFlameMaze + LOCATION(RC_FIRE_TEMPLE_MQ_CHEST_ON_FIRE, ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)) && logic->SmallKeys(RR_FIRE_TEMPLE, 4)), + //Trick: ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || LogicFireMQFlameMaze) && logic->SmallKeys(RR_FIRE_TEMPLE, 4) + LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE)), + //Trick: logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS) || LogicFireMQFlameMaze + LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, logic->HasExplosives()), + LOCATION(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE, (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_FIRE_TEMPLE, 5)) || (ctx->GetTrickOption(RT_FIRE_MQ_ABOVE_MAZE_GS) && logic->IsAdult && logic->CanUse(RG_LONGSHOT))), + //Trick: (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_FIRE_TEMPLE, 5)) || (LogicFireMQAboveMazeGS && logic->IsAdult && logic->CanUse(RG_LONGSHOT)) }, {}); } /*--------------------------- | BOSS ROOM | ---------------------------*/ - areaTable[FIRE_TEMPLE_BOSS_ENTRYWAY] = - Area("Fire Temple Boss Entryway", "Fire Temple", FIRE_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_FIRE_TEMPLE_BOSS_ENTRYWAY] = + Region("Fire Temple Boss Entryway", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(FIRE_TEMPLE_NEAR_BOSS_ROOM, { [] { return Dungeon::FireTemple.IsVanilla() && false; } }), - Entrance(FIRE_TEMPLE_MQ_LOWER, { [] { return Dungeon::FireTemple.IsMQ() && false; } }), - Entrance(FIRE_TEMPLE_BOSS_ROOM, { [] { return true; } }), + Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, { [] { return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla() && false; } }), + Entrance(RR_FIRE_TEMPLE_MQ_LOWER, { [] { return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ() && false; } }), + Entrance(RR_FIRE_TEMPLE_BOSS_ROOM, { [] { return true; } }), }); - areaTable[FIRE_TEMPLE_BOSS_ROOM] = - Area("Fire Temple Boss Room", "Fire Temple", NONE, NO_DAY_NIGHT_CYCLE, + areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = + Region("Fire Temple Boss Room", "Fire Temple", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&FireTempleClear, - { [] { return FireTempleClear || (FireTimer >= 64 && CanUse(MEGATON_HAMMER)); }}), + EventAccess(&logic->FireTempleClear, + { [] { return logic->FireTempleClear || (logic->HasBossSoul(RG_VOLVAGIA_SOUL) && (logic->FireTimer() >= 64 && logic->CanUse(RG_MEGATON_HAMMER))); }}), }, { // Locations - LocationAccess(FIRE_TEMPLE_VOLVAGIA_HEART, { [] { return FireTempleClear; } }), - LocationAccess(VOLVAGIA, { [] { return FireTempleClear; } }), + LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleClear), + LOCATION(RC_VOLVAGIA, logic->FireTempleClear), }, { // Exits - Entrance(FIRE_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), - Entrance(DMC_CENTRAL_LOCAL, { [] { return FireTempleClear; } }), + Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(RR_DMC_CENTRAL_LOCAL, { [] { return logic->FireTempleClear; } }, false), }); } 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 16798906e5a..62718a27d4f 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 @@ -1,438 +1,435 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_ForestTemple() { +void RegionTable_Init_ForestTemple() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[FOREST_TEMPLE_ENTRYWAY] = Area("Forest Temple Entryway", "Forest Temple", 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(FOREST_TEMPLE_FIRST_ROOM, {[]{return Dungeon::ForestTemple.IsVanilla();}}), - Entrance(FOREST_TEMPLE_MQ_LOBBY, {[]{return Dungeon::ForestTemple.IsMQ();}}), - Entrance(SACRED_FOREST_MEADOW, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_FIRST_ROOM, {[]{return ctx->GetDungeon(FOREST_TEMPLE)->IsVanilla();}}), + Entrance(RR_FOREST_TEMPLE_MQ_LOBBY, {[]{return ctx->GetDungeon(FOREST_TEMPLE)->IsMQ();}}), + Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::ForestTemple.IsVanilla()) { - areaTable[FOREST_TEMPLE_FIRST_ROOM] = Area("Forest Temple First Room", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(FOREST_TEMPLE)->IsVanilla()) { + areaTable[RR_FOREST_TEMPLE_FIRST_ROOM] = Region("Forest Temple First Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FOREST_TEMPLE_FIRST_ROOM_CHEST, {[]{return true;}}), - LocationAccess(FOREST_TEMPLE_GS_FIRST_ROOM, {[]{return (IsAdult && Bombs) || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(BOOMERANG) || CanUse(SLINGSHOT) || HasBombchus || CanUse(DINS_FIRE) || (LogicForestFirstGS && (CanJumpslash || (IsChild && Bombs)));}}), + LOCATION(RC_FOREST_TEMPLE_FIRST_ROOM_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_GS_FIRST_ROOM, (logic->IsAdult && logic->CanUse(RG_BOMB_BAG)) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_FOREST_FIRST_GS) && (logic->CanJumpslash() || (logic->IsChild && logic->CanUse(RG_BOMB_BAG))))), }, { //Exits - Entrance(FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(FOREST_TEMPLE_SOUTH_CORRIDOR, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_SOUTH_CORRIDOR, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_SOUTH_CORRIDOR] = Area("Forest Temple South Corridor", "Forest Temple", 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(FOREST_TEMPLE_FIRST_ROOM, {[]{return true;}}), - Entrance(FOREST_TEMPLE_LOBBY, {[]{return CanAdultAttack || CanChildAttack || Nuts;}}), + Entrance(RR_FOREST_TEMPLE_FIRST_ROOM, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanAttack() || logic->CanUse(RG_NUTS);}}), }); - areaTable[FOREST_TEMPLE_LOBBY] = Area("Forest Temple Lobby", "Forest Temple", 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(&ForestTempleMeg, {[]{return ForestTempleMeg || (ForestTempleJoelle && ForestTempleBeth && ForestTempleAmy && CanUse(BOW));}}), + EventAccess(&logic->ForestTempleMeg, {[]{return logic->ForestTempleMeg || (logic->ForestTempleJoelle && logic->ForestTempleBeth && logic->ForestTempleAmy && logic->CanUse(RG_FAIRY_BOW));}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_GS_LOBBY, {[]{return HookshotOrBoomerang;}}), + LOCATION(RC_FOREST_TEMPLE_GS_LOBBY, logic->HookshotOrBoomerang()), }, { //Exits - Entrance(FOREST_TEMPLE_SOUTH_CORRIDOR, {[]{return true;}}), - Entrance(FOREST_TEMPLE_NORTH_CORRIDOR, {[]{return true;}}), - Entrance(FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return CanPlay(SongOfTime) || IsChild;}}), - Entrance(FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return CanUse(BOW) || CanUse(SLINGSHOT);}}), - Entrance(FOREST_TEMPLE_WEST_CORRIDOR, {[]{return SmallKeys(FOREST_TEMPLE, 1, 5);}}), - Entrance(FOREST_TEMPLE_EAST_CORRIDOR, {[]{return false;}}), - Entrance(FOREST_TEMPLE_BOSS_REGION, {[]{return ForestTempleMeg;}}), - Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return false;}}), + Entrance(RR_FOREST_TEMPLE_SOUTH_CORRIDOR, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NORTH_CORRIDOR, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild;}}), + Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}}), + Entrance(RR_FOREST_TEMPLE_WEST_CORRIDOR, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1, 5);}}), + Entrance(RR_FOREST_TEMPLE_EAST_CORRIDOR, {[]{return false;}}), + Entrance(RR_FOREST_TEMPLE_BOSS_REGION, {[]{return logic->ForestTempleMeg;}}), + Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return false;}}), }); - areaTable[FOREST_TEMPLE_NORTH_CORRIDOR] = Area("Forest Temple North Corridor", "Forest Temple", 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(FOREST_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(FOREST_TEMPLE_LOWER_STALFOS, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_LOWER_STALFOS, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_LOWER_STALFOS] = Area("Forest Temple Lower Stalfos", "Forest Temple", 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(&FairyPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_FIRST_STALFOS_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), + LOCATION(RC_FOREST_TEMPLE_FIRST_STALFOS_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits - Entrance(FOREST_TEMPLE_NORTH_CORRIDOR, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NORTH_CORRIDOR, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_NW_OUTDOORS_LOWER] = Area("Forest Temple NW Outdoors Lower", "Forest Temple", 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(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), + 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));}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, {[]{return CanUse(LONGSHOT) || Here(FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return HookshotOrBoomerang;});}}), + LOCATION(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, logic->CanUse(RG_LONGSHOT) || Here(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return logic->HookshotOrBoomerang();})), }, { //Exits - Entrance(FOREST_TEMPLE_LOBBY, {[]{return CanPlay(SongOfTime);}}), - Entrance(FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return false;}}), - Entrance(FOREST_TEMPLE_MAP_ROOM, {[]{return true;}}), - Entrance(FOREST_TEMPLE_SEWER, {[]{return GoldScale || CanUse(IRON_BOOTS) || HasAccessTo(FOREST_TEMPLE_NE_OUTDOORS_UPPER);}}), - Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return false;}}), + Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_SONG_OF_TIME);}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return false;}}), + Entrance(RR_FOREST_TEMPLE_MAP_ROOM, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_SEWER, {[]{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS) || HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER);}}), + Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return false;}}), }); - areaTable[FOREST_TEMPLE_NW_OUTDOORS_UPPER] = Area("Forest Temple NW Outdoors Upper", "Forest Temple", 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(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), + 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));}}), }, {}, { //Exits - Entrance(FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return true;}}), - Entrance(FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, {[]{return true;}}), - Entrance(FOREST_TEMPLE_FLOORMASTER_ROOM, {[]{return true;}}), - Entrance(FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_FLOORMASTER_ROOM, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_NE_OUTDOORS_LOWER] = Area("Forest Temple NE Outdoors Lower", "Forest Temple", 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(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), + 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));}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, {[]{return CanUse(HOOKSHOT) || HasAccessTo(FOREST_TEMPLE_FALLING_ROOM) || (HasAccessTo(FOREST_TEMPLE_NE_OUTDOORS_UPPER) && IsAdult && LogicForestOutdoorsLedge && HoverBoots);}}), - LocationAccess(FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, {[]{return CanUse(HOOKSHOT) || (LogicForestOutdoorEastGS && CanUse(BOOMERANG)) || Here(FOREST_TEMPLE_FALLING_ROOM, []{return CanUse(BOW) || CanUse(SLINGSHOT) || CanUse(DINS_FIRE) || HasExplosives;});}}), + LOCATION(RC_FOREST_TEMPLE_RAISED_ISLAND_COURTYARD_CHEST, logic->CanUse(RG_HOOKSHOT) || HasAccessTo(RR_FOREST_TEMPLE_FALLING_ROOM) || (HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER) && logic->IsAdult && ctx->GetTrickOption(RT_FOREST_OUTDOORS_LEDGE) && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_FOREST_OUTDOORS_EAST_GS) && logic->CanUse(RG_BOOMERANG)) || Here(RR_FOREST_TEMPLE_FALLING_ROOM, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_DINS_FIRE) || logic->HasExplosives();})), }, { //Exits - Entrance(FOREST_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return CanUse(LONGSHOT) || (LogicForestVines && CanUse(HOOKSHOT));}}), - Entrance(FOREST_TEMPLE_SEWER, {[]{return GoldScale || CanUse(IRON_BOOTS) || HasAccessTo(FOREST_TEMPLE_NE_OUTDOORS_UPPER);}}), - Entrance(FOREST_TEMPLE_FALLING_ROOM, {[]{return false;}}), + Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_VINES) && logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_FOREST_TEMPLE_SEWER, {[]{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS) || HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER);}}), + Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, {[]{return false;}}), }); - areaTable[FOREST_TEMPLE_NE_OUTDOORS_UPPER] = Area("Forest Temple NE Outdoors Upper", "Forest Temple", 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(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), + 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));}}), }, {}, { //Exits - Entrance(FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return true;}}), - Entrance(FOREST_TEMPLE_MAP_ROOM, {[]{return true;}}), - Entrance(FOREST_TEMPLE_FALLING_ROOM, {[]{return LogicForestDoorFrame && CanJumpslash && CanUse(HOVER_BOOTS) && CanUse(SCARECROW);}}), + Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_MAP_ROOM, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, {[]{return ctx->GetTrickOption(RT_FOREST_DOORFRAME) && logic->CanJumpslash() && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_SCARECROW);}}), }); - areaTable[FOREST_TEMPLE_MAP_ROOM] = Area("Forest Temple Map Room", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_MAP_CHEST, {[]{return Here(FOREST_TEMPLE_MAP_ROOM, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((CanJumpslash || CanUse(SLINGSHOT)) && (Nuts || HookshotOrBoomerang || CanShield));});}}), + LOCATION(RC_FOREST_TEMPLE_MAP_CHEST, logic->CanKillEnemy(RE_BLUE_BUBBLE)), }, { //Exits - Entrance(FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return Here(FOREST_TEMPLE_MAP_ROOM, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((CanJumpslash || CanUse(SLINGSHOT)) && (Nuts || HookshotOrBoomerang || CanShield));});}}), - Entrance(FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return Here(FOREST_TEMPLE_MAP_ROOM, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((CanJumpslash || CanUse(SLINGSHOT)) && (Nuts || HookshotOrBoomerang || CanShield));});}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->CanKillEnemy(RE_BLUE_BUBBLE);});}}), + Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER, {[]{return Here(RR_FOREST_TEMPLE_MAP_ROOM, []{return logic->CanKillEnemy(RE_BLUE_BUBBLE);});}}), }); - areaTable[FOREST_TEMPLE_SEWER] = Area("Forest Temple Sewer", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_WELL_CHEST, {[]{return HasAccessTo(FOREST_TEMPLE_NE_OUTDOORS_UPPER);}}), + LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER)), }, { //Exits - Entrance(FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return true;}}), - Entrance(FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST] = Area("Forest Temple Below Boss Key Chest", "Forest Temple", 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(FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return Here(FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return HasExplosives || CanUse(MEGATON_HAMMER) || CanUse(BOW) || ((CanJumpslash || CanUse(SLINGSHOT)) && (Nuts || HookshotOrBoomerang || CanShield));});}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return Here(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, []{return logic->CanKillEnemy(RE_BLUE_BUBBLE);});}}), }); - areaTable[FOREST_TEMPLE_FLOORMASTER_ROOM] = Area("Forest Temple Floormaster Room", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_FLOORMASTER_CHEST, {[]{return CanAdultDamage || CanChildDamage;}}), + LOCATION(RC_FOREST_TEMPLE_FLOORMASTER_CHEST, logic->CanDamage()), }, { //Exits - Entrance(FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_WEST_CORRIDOR] = Area("Forest Temple West Corridor", "Forest Temple", 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(FOREST_TEMPLE_LOBBY, {[]{return SmallKeys(FOREST_TEMPLE, 1, 5);}}), - Entrance(FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return CanAdultAttack || CanChildAttack || Nuts;}}), + Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1, 5);}}), + Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return logic->CanAttack() || logic->CanUse(RG_NUTS);}}), }); - areaTable[FOREST_TEMPLE_BLOCK_PUSH_ROOM] = Area("Forest Temple Block Push Room", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_EYE_SWITCH_CHEST, {[]{return GoronBracelet && (CanUse(BOW) || CanUse(SLINGSHOT));}}), + LOCATION(RC_FOREST_TEMPLE_EYE_SWITCH_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))), }, { //Exits - Entrance(FOREST_TEMPLE_WEST_CORRIDOR, {[]{return true;}}), - Entrance(FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return CanUse(HOVER_BOOTS) || (LogicForestOutsideBackdoor && CanJumpslash && GoronBracelet);}}), - Entrance(FOREST_TEMPLE_NW_CORRIDOR_TWISTED, {[]{return IsAdult && GoronBracelet && SmallKeys(FOREST_TEMPLE, 2);}}), - Entrance(FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED, {[]{return IsAdult && (CanUse(BOW) || CanUse(SLINGSHOT)) && GoronBracelet && SmallKeys(FOREST_TEMPLE, 2);}}), + Entrance(RR_FOREST_TEMPLE_WEST_CORRIDOR, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && logic->CanJumpslash() && logic->HasItem(RG_GORONS_BRACELET));}}), + Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, {[]{return logic->IsAdult && logic->HasItem(RG_GORONS_BRACELET) && logic->SmallKeys(RR_FOREST_TEMPLE, 2);}}), + Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED, {[]{return logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)) && logic->HasItem(RG_GORONS_BRACELET) && logic->SmallKeys(RR_FOREST_TEMPLE, 2);}}), }); - areaTable[FOREST_TEMPLE_NW_CORRIDOR_TWISTED] = Area("Forest Temple NW Corridor Twisted", "Forest Temple", 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(FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return SmallKeys(FOREST_TEMPLE, 2);}}), - Entrance(FOREST_TEMPLE_RED_POE_ROOM, {[]{return SmallKeys(FOREST_TEMPLE, 3);}}), + 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[FOREST_TEMPLE_NW_CORRIDOR_STRAIGHTENED] = Area("Forest Temple NW Corridor Straightened", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_BOSS_KEY_CHEST, {[]{return true;}}), + LOCATION(RC_FOREST_TEMPLE_BOSS_KEY_CHEST, true), }, { //Exits - Entrance(FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, {[]{return true;}}), - Entrance(FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return SmallKeys(FOREST_TEMPLE, 2);}}), + Entrance(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_BLOCK_PUSH_ROOM, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 2);}}), }); - areaTable[FOREST_TEMPLE_RED_POE_ROOM] = Area("Forest Temple Red Poe Room", "Forest Temple", 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(&ForestTempleJoelle, {[]{return ForestTempleJoelle || CanUse(BOW);}}), + EventAccess(&logic->ForestTempleJoelle, {[]{return logic->ForestTempleJoelle || logic->CanUse(RG_FAIRY_BOW);}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_RED_POE_CHEST, {[]{return ForestTempleJoelle;}}), + LOCATION(RC_FOREST_TEMPLE_RED_POE_CHEST, logic->ForestTempleJoelle), }, { //Exits - Entrance(FOREST_TEMPLE_NW_CORRIDOR_TWISTED, {[]{return SmallKeys(FOREST_TEMPLE, 3);}}), - Entrance(FOREST_TEMPLE_UPPER_STALFOS, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NW_CORRIDOR_TWISTED, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 3);}}), + Entrance(RR_FOREST_TEMPLE_UPPER_STALFOS, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_UPPER_STALFOS] = Area("Forest Temple Upper Stalfos", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_BOW_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), + 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)), }, { //Exits - Entrance(FOREST_TEMPLE_RED_POE_ROOM, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), - Entrance(FOREST_TEMPLE_BLUE_POE_ROOM, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), + Entrance(RR_FOREST_TEMPLE_RED_POE_ROOM, {[]{return logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER);}}), + 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[FOREST_TEMPLE_BLUE_POE_ROOM] = Area("Forest Temple Blue Poe Room", "Forest Temple", 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(&ForestTempleBeth, {[]{return ForestTempleBeth || CanUse(BOW);}}), + EventAccess(&logic->ForestTempleBeth, {[]{return logic->ForestTempleBeth || logic->CanUse(RG_FAIRY_BOW);}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_BLUE_POE_CHEST, {[]{return ForestTempleBeth;}}), + LOCATION(RC_FOREST_TEMPLE_BLUE_POE_CHEST, logic->ForestTempleBeth), }, { //Exits - Entrance(FOREST_TEMPLE_UPPER_STALFOS, {[]{return true;}}), - Entrance(FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED, {[]{return SmallKeys(FOREST_TEMPLE, 4);}}), + Entrance(RR_FOREST_TEMPLE_UPPER_STALFOS, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 4);}}), }); - areaTable[FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED] = Area("Forest Temple NE Corridor Straightened", "Forest Temple", 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(FOREST_TEMPLE_BLUE_POE_ROOM, {[]{return SmallKeys(FOREST_TEMPLE, 4);}}), - Entrance(FOREST_TEMPLE_FROZEN_EYE_ROOM, {[]{return SmallKeys(FOREST_TEMPLE, 5);}}), + 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[FOREST_TEMPLE_NE_CORRIDOR_TWISTED] = Area("Forest Temple NE Corridor Twisted", "Forest Temple", 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(FOREST_TEMPLE_FROZEN_EYE_ROOM, {[]{return SmallKeys(FOREST_TEMPLE, 5);}}), - Entrance(FOREST_TEMPLE_FALLING_ROOM, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_FROZEN_EYE_ROOM, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 5);}}), + Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_FROZEN_EYE_ROOM] = Area("Forest Temple Frozen Eye Room", "Forest Temple", 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(FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED, {[]{return SmallKeys(FOREST_TEMPLE, 5);}}), - Entrance(FOREST_TEMPLE_NE_CORRIDOR_TWISTED, {[]{return SmallKeys(FOREST_TEMPLE, 5) && (CanUse(BOW) || CanUse(DINS_FIRE));}}), + 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[FOREST_TEMPLE_FALLING_ROOM] = Area("Forest Temple Falling Room", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, {[]{return true;}}), + LOCATION(RC_FOREST_TEMPLE_FALLING_CEILING_ROOM_CHEST, true), }, { //Exits - Entrance(FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return true;}}), - Entrance(FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_NE_OUTDOORS_LOWER, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_GREEN_POE_ROOM] = Area("Forest Temple Green Poe Room", "Forest Temple", 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(&ForestTempleAmy, {[]{return ForestTempleAmy || CanUse(BOW);}}), + EventAccess(&logic->ForestTempleAmy, {[]{return logic->ForestTempleAmy || logic->CanUse(RG_FAIRY_BOW);}}), }, {}, { //Exits - Entrance(FOREST_TEMPLE_FALLING_ROOM, {[]{return true;}}), - Entrance(FOREST_TEMPLE_EAST_CORRIDOR, {[]{return ForestTempleAmy;}}), + Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_EAST_CORRIDOR, {[]{return logic->ForestTempleAmy;}}), }); - areaTable[FOREST_TEMPLE_EAST_CORRIDOR] = Area("Forest Temple East Corridor", "Forest Temple", 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(FOREST_TEMPLE_LOBBY, {[]{return CanAdultAttack || CanChildAttack || Nuts;}}), - Entrance(FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return CanAdultAttack || CanChildAttack || Nuts;}}), + Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanAttack() || logic->CanUse(RG_NUTS);}}), + Entrance(RR_FOREST_TEMPLE_GREEN_POE_ROOM, {[]{return logic->CanAttack() || logic->CanUse(RG_NUTS);}}), }); - areaTable[FOREST_TEMPLE_BOSS_REGION] = Area("Forest Temple Boss Region", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_BASEMENT_CHEST, {[]{return true;}}), - LocationAccess(FOREST_TEMPLE_GS_BASEMENT, {[]{return HookshotOrBoomerang;}}), + LOCATION(RC_FOREST_TEMPLE_BASEMENT_CHEST, true), + LOCATION(RC_FOREST_TEMPLE_GS_BASEMENT, logic->HookshotOrBoomerang()), }, { //Exits - Entrance(FOREST_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyForestTemple;}}), + Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_FOREST_TEMPLE_BOSS_KEY);}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::ForestTemple.IsMQ()) { - areaTable[FOREST_TEMPLE_MQ_LOBBY] = Area("Forest Temple MQ Lobby", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(FOREST_TEMPLE)->IsMQ()) { + areaTable[RR_FOREST_TEMPLE_MQ_LOBBY] = Region("Forest Temple MQ Lobby", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, {[]{return CanJumpslash || Bombs || Nuts || HookshotOrBoomerang || CanUse(DINS_FIRE) || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(HOVER_BOOTS);}}), - LocationAccess(FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, {[]{return HookshotOrBoomerang;}}), + LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, logic->CanJumpslash() || logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_NUTS) || logic->HookshotOrBoomerang() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, logic->HookshotOrBoomerang()), }, { //Exits - Entrance(FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return SmallKeys(FOREST_TEMPLE, 1) && (CanAdultAttack || CanChildAttack || Nuts);}}), + Entrance(RR_FOREST_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 1) && (logic->CanAttack() || logic->CanUse(RG_NUTS));}}), }); - areaTable[FOREST_TEMPLE_MQ_CENTRAL_AREA] = Area("Forest Temple MQ Central Area", "Forest Temple", 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(&FairyPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_MQ_WOLFOS_CHEST, {[]{return (CanPlay(SongOfTime) || IsChild) && (CanJumpslash || CanUse(DINS_FIRE) || CanUse(SLINGSHOT));}}), - LocationAccess(FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), + LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild) && (logic->CanJumpslash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_KOKIRI_SWORD))), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits - Entrance(FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return CanUse(BOW) || CanUse(SLINGSHOT);}}), - Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return CanUse(BOW) || CanUse(SLINGSHOT);}}), //This is as far as child can get - Entrance(FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE, {[]{return IsAdult && (GoronBracelet || (LogicForestMQBlockPuzzle && HasBombchus && IsAdult && CanUse(HOOKSHOT)));}}), - //Trick: IsAdult && (GoronBracelet || (LogicForestMQBlockPuzzle && HasBombchus && IsAdult && CanUse(HOOKSHOT))) - Entrance(FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return (LogicForestMQHallwaySwitchJS && IsAdult && CanUse(HOVER_BOOTS)) || (LogicForestMQHallwaySwitchBoomerang && CanUse(BOOMERANG)) || (LogicForestMQHallwaySwitchHookshot && IsAdult && CanUse(HOOKSHOT));}}), - //Trick (Hookshot trick not added to either n64 or oot3d rando as of yet, to enable in SoH needs uncommenting in randomizer_tricks.cpp): (LogicForestMQHallwaySwitchJS && IsAdult && CanUse(HOVER_BOOTS)) || (LogicForestMQHallwaySwitchHookshot && IsAdult && CanUse(HOOKSHOT)) - Entrance(FOREST_TEMPLE_MQ_BOSS_REGION, {[]{return ForestTempleJoAndBeth && ForestTempleAmyAndMeg;}}), + Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}}), + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT);}}), //This is as far as child can get + Entrance(RR_FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE, {[]{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_FOREST_MQ_BLOCK_PUZZLE) && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)));}}), + //Trick: logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || (LogicForestMQBlockPuzzle && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT))) + Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return (ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (ctx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || (ctx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT));}}), + //Trick (logic->Hookshot trick not added to either n64 or oot3d rando as of yet, to enable in SoH needs uncommenting in randomizer_tricks.cpp): (LogicForestMQHallwaySwitchJS && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (LogicForestMQHallwaySwitchHookshot && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) + Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, {[]{return logic->ForestTempleJoAndBeth && logic->ForestTempleAmyAndMeg;}}), }); - areaTable[FOREST_TEMPLE_MQ_AFTER_BLOCK_PUZZLE] = Area("Forest Temple MQ After Block Puzzle", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, {[]{return SmallKeys(FOREST_TEMPLE, 3);}}), + LOCATION(RC_FOREST_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(RR_FOREST_TEMPLE, 3)), }, { //Exits - Entrance(FOREST_TEMPLE_MQ_BOW_REGION, {[]{return SmallKeys(FOREST_TEMPLE, 4);}}), - Entrance(FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return SmallKeys(FOREST_TEMPLE, 3) || (LogicForestMQHallwaySwitchJS && ((IsAdult && CanUse(HOOKSHOT)) || (LogicForestOutsideBackdoor && (IsAdult || (IsChild && CanUse(STICKS))))));}}), - //Trick (Doing the hallway switch jumpslash as child requires sticks and has been added above): SmallKeys(FOREST_TEMPLE, 3) || (LogicForestMQHallwaySwitchJS && ((IsAdult && CanUse(HOOKSHOT)) || LogicForestOutsideBackdoor)) - Entrance(FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return SmallKeys(FOREST_TEMPLE, 2);}}), + Entrance(RR_FOREST_TEMPLE_MQ_BOW_REGION, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 4);}}), + Entrance(RR_FOREST_TEMPLE_MQ_OUTDOOR_LEDGE, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 3) || (ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_FOREST_OUTSIDE_BACKDOOR) && (logic->IsAdult || (logic->IsChild && logic->CanUse(RG_STICKS))))));}}), + //Trick (Doing the hallway switch jumpslash as child requires sticks and has been added above): logic->SmallKeys(RR_FOREST_TEMPLE, 3) || (LogicForestMQHallwaySwitchJS && ((logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || LogicForestOutsideBackdoor)) + Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 2);}}), }); - areaTable[FOREST_TEMPLE_MQ_OUTDOOR_LEDGE] = Area("Forest Temple MQ Outdoor Ledge", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_MQ_REDEAD_CHEST, {[]{return CanJumpslash;}}), + LOCATION(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, logic->CanJumpslash()), }, { //Exits - Entrance(FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_MQ_NW_OUTDOORS] = Area("Forest Temple MQ NW Outdoors", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, {[]{return CanAdultAttack || CanChildAttack;}}), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, logic->CanAttack()), }, { //Exits - Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return (IsAdult && (CanUse(IRON_BOOTS) || CanUse(LONGSHOT) || (LogicForestMQWellSwim && CanUse(HOOKSHOT)))) || ProgressiveScale >= 2;}}), - //Trick: (IsAdult && (CanUse(IRON_BOOTS) || CanUse(LONGSHOT) || (LogicForestMQWellSwim && CanUse(HOOKSHOT)))) || ProgressiveScale >= 2 - Entrance(FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, {[]{return IsAdult && CanUse(FIRE_ARROWS);}}), + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return (logic->IsAdult && (logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_MQ_WELL_SWIM) && logic->CanUse(RG_HOOKSHOT)))) || logic->HasItem(RG_GOLDEN_SCALE);}}), + //Trick: (logic->IsAdult && (logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (LogicForestMQWellSwim && logic->CanUse(RG_HOOKSHOT)))) || logic->ProgressiveScale >= 2 + Entrance(RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, {[]{return logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS);}}), }); - areaTable[FOREST_TEMPLE_MQ_NE_OUTDOORS] = Area("Forest Temple MQ NE Outdoors", "Forest Temple", 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(&DekuBabaSticks, {[]{return DekuBabaSticks || (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(BOOMERANG));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || HasExplosives || CanUse(DINS_FIRE));}}), + 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));}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_MQ_WELL_CHEST, {[]{return (IsAdult && CanUse(BOW)) || (IsChild && CanUse(SLINGSHOT));}}), - LocationAccess(FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, {[]{return HookshotOrBoomerang || (IsAdult && CanUse(FIRE_ARROWS) && (CanPlay(SongOfTime) || (CanUse(HOVER_BOOTS) && LogicForestDoorFrame)));}}), - LocationAccess(FOREST_TEMPLE_MQ_GS_WELL, {[]{return (IsAdult && ((CanUse(IRON_BOOTS) && CanUse(HOOKSHOT)) || CanUse(BOW))) || (IsChild && CanUse(SLINGSHOT));}}), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_CHEST, (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, logic->HookshotOrBoomerang() || (logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS) && (logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_FOREST_DOORFRAME))))), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_WELL, (logic->IsAdult && ((logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_FAIRY_BOW))) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT))), }, { //Exits - Entrance(FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, {[]{return IsAdult && CanUse(HOOKSHOT) && (CanUse(LONGSHOT) || CanUse(HOVER_BOOTS) || CanPlay(SongOfTime));}}), - Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return IsAdult && CanUse(LONGSHOT);}}), + Entrance(RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, {[]{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME));}}), + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return logic->IsAdult && logic->CanUse(RG_LONGSHOT);}}), }); - areaTable[FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES] = Area("Forest Temple MQ Outdoors Top Ledges", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, {[]{return true;}}), + LOCATION(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, true), }, { //Exits - Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return true;}}), - Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return LogicForestOutdoorsLedge && IsAdult && CanUse(HOVER_BOOTS);}}), - //Trick: LogicForestOutdoorsLedge && IsAdult && CanUse(HOVER_BOOTS) + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return ctx->GetTrickOption(RT_FOREST_OUTDOORS_LEDGE) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS);}}), + //Trick: LogicForestOutdoorsLedge && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) }); - areaTable[FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE] = Area("Forest Temple MQ NE Outdoors Ledge", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, {[]{return true;}}), + LOCATION(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_LOWER_CHEST, true), }, { //Exits - Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return true;}}), - Entrance(FOREST_TEMPLE_MQ_FALLING_ROOM, {[]{return CanPlay(SongOfTime);}}), + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_MQ_FALLING_ROOM, {[]{return logic->CanUse(RG_SONG_OF_TIME);}}), }); - areaTable[FOREST_TEMPLE_MQ_BOW_REGION] = Area("Forest Temple MQ Bow Region", "Forest Temple", 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(&ForestTempleJoAndBeth, {[]{return ForestTempleJoAndBeth || (IsAdult && CanUse(BOW));}}), + EventAccess(&logic->ForestTempleJoAndBeth, {[]{return logic->ForestTempleJoAndBeth || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_MQ_BOW_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER);}}), - LocationAccess(FOREST_TEMPLE_MQ_MAP_CHEST, {[]{return IsAdult && CanUse(BOW);}}), - LocationAccess(FOREST_TEMPLE_MQ_COMPASS_CHEST, {[]{return IsAdult && CanUse(BOW);}}), + LOCATION(RC_FOREST_TEMPLE_MQ_BOW_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_FOREST_TEMPLE_MQ_MAP_CHEST, logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - Entrance(FOREST_TEMPLE_MQ_FALLING_ROOM, {[]{return SmallKeys(FOREST_TEMPLE, 5) && ((IsAdult && CanUse(BOW)) || CanUse(DINS_FIRE));}}), + 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[FOREST_TEMPLE_MQ_FALLING_ROOM] = Area("Forest Temple MQ Falling Room", "Forest Temple", 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(&ForestTempleAmyAndMeg, {[]{return ForestTempleAmyAndMeg || (IsAdult && CanUse(BOW) && SmallKeys(FOREST_TEMPLE, 6));}}), + EventAccess(&logic->ForestTempleAmyAndMeg, {[]{return logic->ForestTempleAmyAndMeg || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && logic->SmallKeys(RR_FOREST_TEMPLE, 6));}}), }, { //Locations - LocationAccess(FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, {[]{return true;}}), + LOCATION(RC_FOREST_TEMPLE_MQ_FALLING_CEILING_ROOM_CHEST, true), }, { //Exits - Entrance(FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return true;}}), }); - areaTable[FOREST_TEMPLE_MQ_BOSS_REGION] = Area("Forest Temple MQ Boss Region", "Forest Temple", 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 - LocationAccess(FOREST_TEMPLE_MQ_BASEMENT_CHEST, {[]{return true;}}), + LOCATION(RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, true), }, { //Exits - Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyForestTemple;}}), + Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_FOREST_TEMPLE_BOSS_KEY);}}), }); } /*--------------------------- | BOSS ROOM | ---------------------------*/ - areaTable[FOREST_TEMPLE_BOSS_ENTRYWAY] = - Area("Forest Temple Boss Entryway", "Forest Temple", FOREST_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_FOREST_TEMPLE_BOSS_ENTRYWAY] = + Region("Forest Temple Boss Entryway", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(FOREST_TEMPLE_BOSS_REGION, { [] { return Dungeon::ForestTemple.IsVanilla() && false; } }), - Entrance(FOREST_TEMPLE_MQ_BOSS_REGION, { [] { return Dungeon::ForestTemple.IsMQ() && false; } }), - Entrance(FOREST_TEMPLE_BOSS_ROOM, { [] { return true; } }), + Entrance(RR_FOREST_TEMPLE_BOSS_REGION, { [] { return ctx->GetDungeon(FOREST_TEMPLE)->IsVanilla() && false; } }), + Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, { [] { return ctx->GetDungeon(FOREST_TEMPLE)->IsMQ() && false; } }), + Entrance(RR_FOREST_TEMPLE_BOSS_ROOM, { [] { return true; } }), }); - areaTable[FOREST_TEMPLE_BOSS_ROOM] = Area( - "Forest Temple Boss Room", "Forest Temple", NONE, NO_DAY_NIGHT_CYCLE, + areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region("Forest Temple Boss Room", "Forest Temple", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&ForestTempleClear, { [] { - return ForestTempleClear || ((CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && - (CanUse(HOOKSHOT) || CanUse(BOW) || CanUse(SLINGSHOT))); + EventAccess(&logic->ForestTempleClear, { [] { + return logic->ForestTempleClear || (logic->HasBossSoul(RG_PHANTOM_GANON_SOUL) && ((logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && + (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)))); } }), }, { // Locations - LocationAccess(FOREST_TEMPLE_PHANTOM_GANON_HEART, { [] { return ForestTempleClear; } }), - LocationAccess(PHANTOM_GANON, { [] { return ForestTempleClear; } }), + LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleClear), + LOCATION(RC_PHANTOM_GANON, logic->ForestTempleClear), }, { // Exits - Entrance(FOREST_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), - Entrance(SACRED_FOREST_MEADOW, { [] { return ForestTempleClear; } }), + Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(RR_SACRED_FOREST_MEADOW, { [] { return logic->ForestTempleClear; } }, false), }); } 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 007276ecbed..a572fa1dc55 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 @@ -1,225 +1,217 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" -#include "../trial.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" +#include "../../trial.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_GanonsCastle() { +void RegionTable_Init_GanonsCastle() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[GANONS_CASTLE_ENTRYWAY] = Area("Ganon's Castle Entryway", "Ganon's Castle", 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(GANONS_CASTLE_LOBBY, {[]{return Dungeon::GanonsCastle.IsVanilla();}}), - Entrance(GANONS_CASTLE_MQ_LOBBY, {[]{return Dungeon::GanonsCastle.IsMQ();}}), - Entrance(CASTLE_GROUNDS_FROM_GANONS_CASTLE, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_LOBBY, {[]{return ctx->GetDungeon(GANONS_CASTLE)->IsVanilla();}}), + Entrance(RR_GANONS_CASTLE_MQ_LOBBY, {[]{return ctx->GetDungeon(GANONS_CASTLE)->IsMQ();}}), + Entrance(RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::GanonsCastle.IsVanilla()) { - areaTable[GANONS_CASTLE_LOBBY] = Area("Ganon's Castle Lobby", "Ganon's Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, {}, { - //Exits - Entrance(GANONS_CASTLE_ENTRYWAY, {[]{return true;}}), - Entrance(GANONS_CASTLE_MAIN, {[]{return true;}}), - }); - - areaTable[GANONS_CASTLE_MAIN] = Area("Ganon's Castle Main", "Ganon's Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(GANONS_CASTLE)->IsVanilla()) { + areaTable[RR_GANONS_CASTLE_LOBBY] = Region("Ganon's Castle Lobby", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SHEIK_HINT_GC, true), + }, { //Exits - Entrance(GANONS_CASTLE_LOBBY, {[]{return true;}}), - Entrance(GANONS_CASTLE_FOREST_TRIAL, {[]{return true;}}), - Entrance(GANONS_CASTLE_FIRE_TRIAL, {[]{return true;}}), - Entrance(GANONS_CASTLE_WATER_TRIAL, {[]{return true;}}), - Entrance(GANONS_CASTLE_SHADOW_TRIAL, {[]{return true;}}), - Entrance(GANONS_CASTLE_SPIRIT_TRIAL, {[]{return true;}}), - Entrance(GANONS_CASTLE_LIGHT_TRIAL, {[]{return CanUse(GOLDEN_GAUNTLETS);}}), - Entrance(GANONS_CASTLE_TOWER, {[]{return (ForestTrialClear || Trial::ForestTrial.IsSkipped()) && - (FireTrialClear || Trial::FireTrial.IsSkipped()) && - (WaterTrialClear || Trial::WaterTrial.IsSkipped()) && - (ShadowTrialClear || Trial::ShadowTrial.IsSkipped()) && - (SpiritTrialClear || Trial::SpiritTrial.IsSkipped()) && - (LightTrialClear || Trial::LightTrial.IsSkipped());}}), - Entrance(GANONS_CASTLE_DEKU_SCRUBS, {[]{return LogicLensCastle || CanUse(LENS_OF_TRUTH);}}), + Entrance(RR_GANONS_CASTLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_FOREST_TRIAL, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_FIRE_TRIAL, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_WATER_TRIAL, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}), + Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && + (logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && + (logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && + (logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && + (logic->SpiritTrialClear || ctx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) && + (logic->LightTrialClear || ctx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}}), + Entrance(RR_GANONS_CASTLE_DEKU_SCRUBS, {[]{return ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH);}}), }); - areaTable[GANONS_CASTLE_DEKU_SCRUBS] = Area("Ganon's Castle Deku Scrubs", "Ganon's Castle", 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(&FreeFairies, {[]{return true;}}), + EventAccess(&logic->FreeFairies, {[]{return true;}}), }, { //Locations - LocationAccess(GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, {[]{return CanStunDeku;}}), - LocationAccess(GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, {[]{return CanStunDeku;}}), - LocationAccess(GANONS_CASTLE_DEKU_SCRUB_RIGHT, {[]{return CanStunDeku;}}), - LocationAccess(GANONS_CASTLE_DEKU_SCRUB_LEFT, {[]{return CanStunDeku;}}), + LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, logic->CanStunDeku()), }, {}); - areaTable[GANONS_CASTLE_FOREST_TRIAL] = Area("Ganon's Castle Forest Trial", "Ganon's Castle", 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(&ForestTrialClear, {[]{return CanUse(LIGHT_ARROWS) && (FireArrows || DinsFire);}}), + EventAccess(&logic->ForestTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_DINS_FIRE));}}), }, { //Locations - LocationAccess(GANONS_CASTLE_FOREST_TRIAL_CHEST, {[]{return CanAdultDamage || CanChildDamage;}}), + LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanDamage()), }, {}); - areaTable[GANONS_CASTLE_FIRE_TRIAL] = Area("Ganon's Castle Fire Trial", "Ganon's Castle", 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(&FireTrialClear, {[]{return CanUse(GORON_TUNIC) && CanUse(GOLDEN_GAUNTLETS) && CanUse(LIGHT_ARROWS) && CanUse(LONGSHOT);}}), + EventAccess(&logic->FireTrialClear, {[]{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_LONGSHOT);}}), }, {}, {}); - areaTable[GANONS_CASTLE_WATER_TRIAL] = Area("Ganon's Castle Water Trial", "Ganon's Castle", 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(&BlueFireAccess, {[]{return BlueFireAccess || HasBottle;}}), - EventAccess(&FairyPot, {[]{return FairyPot || BlueFire;}}), - EventAccess(&WaterTrialClear, {[]{return BlueFire && IsAdult && CanUse(MEGATON_HAMMER) && CanUse(LIGHT_ARROWS);}}), + EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || logic->HasBottle();}}), + EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || logic->BlueFire();}}), + EventAccess(&logic->WaterTrialClear, {[]{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_LIGHT_ARROWS);}}), }, { //Locations - LocationAccess(GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, {[]{return true;}}), - LocationAccess(GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, {[]{return true;}}), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, true), }, {}); - areaTable[GANONS_CASTLE_SHADOW_TRIAL] = Area("Ganon's Castle Shadow Trial", "Ganon's Castle", 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(&ShadowTrialClear, {[]{return CanUse(LIGHT_ARROWS) && CanUse(MEGATON_HAMMER) && ((FireArrows && (LogicLensCastle || CanUse(LENS_OF_TRUTH))) || (CanUse(LONGSHOT) && (CanUse(HOVER_BOOTS) || (DinsFire && (LogicLensCastle || CanUse(LENS_OF_TRUTH))))));}}), + EventAccess(&logic->ShadowTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MEGATON_HAMMER) && ((logic->CanUse(RG_FIRE_ARROWS) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))))));}}), }, { //Locations - LocationAccess(GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, {[]{return CanUse(FIRE_ARROWS) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || CanPlay(SongOfTime) || IsChild;}}), - LocationAccess(GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, {[]{return CanUse(FIRE_ARROWS) || (CanUse(LONGSHOT) && (CanUse(HOVER_BOOTS) || CanUse(DINS_FIRE)));}}), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))), }, {}); - areaTable[GANONS_CASTLE_SPIRIT_TRIAL] = Area("Ganon's Castle Spirit Trial", "Ganon's Castle", 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(&NutPot, {[]{return NutPot || (((LogicSpiritTrialHookshot && CanJumpslash) || CanUse(HOOKSHOT)) && HasBombchus && CanUse(BOW) && (CanUse(MIRROR_SHIELD) || (SunlightArrows && CanUse(LIGHT_ARROWS))));}}), - EventAccess(&SpiritTrialClear, {[]{return CanUse(LIGHT_ARROWS) && (CanUse(MIRROR_SHIELD) || SunlightArrows) && HasBombchus && ((LogicSpiritTrialHookshot && CanJumpslash) || CanUse(HOOKSHOT));}}), + EventAccess(&logic->NutPot, {[]{return logic->NutPot || (((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslash()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}}), + EventAccess(&logic->SpiritTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || ctx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->CanUse(RG_BOMBCHU_5) && ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslash()) || logic->CanUse(RG_HOOKSHOT));}}), }, { //Locations - LocationAccess(GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, {[]{return (LogicSpiritTrialHookshot || CanUse(HOOKSHOT)) && CanJumpslash;}}), - LocationAccess(GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, {[]{return (LogicSpiritTrialHookshot || CanUse(HOOKSHOT)) && HasBombchus && (LogicLensCastle || CanUse(LENS_OF_TRUTH));}}), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanJumpslash()), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), }, {}); - areaTable[GANONS_CASTLE_LIGHT_TRIAL] = Area("Ganon's Castle Light Trial", "Ganon's Castle", 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(&LightTrialClear, {[]{return CanUse(LIGHT_ARROWS) && CanUse(HOOKSHOT) && SmallKeys(GANONS_CASTLE, 2) && (LogicLensCastle || CanUse(LENS_OF_TRUTH));}}), + EventAccess(&logic->LightTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH));}}), }, { //Locations - LocationAccess(GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, {[]{return true;}}), - LocationAccess(GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, {[]{return true;}}), - LocationAccess(GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, {[]{return true;}}), - LocationAccess(GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, {[]{return true;}}), - LocationAccess(GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, {[]{return true;}}), - LocationAccess(GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, {[]{return true;}}), - LocationAccess(GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, {[]{return LogicLensCastle || CanUse(LENS_OF_TRUTH);}}), - LocationAccess(GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, {[]{return CanPlay(ZeldasLullaby) && SmallKeys(GANONS_CASTLE, 1);}}), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_LEFT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_LEFT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_LEFT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_FIRST_RIGHT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_SECOND_RIGHT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_GANONS_CASTLE, 1)), }, {}); } - areaTable[GANONS_CASTLE_TOWER] = Area("Ganon's Castle Tower", "Ganons Castle", 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 - LocationAccess(GANONS_TOWER_BOSS_KEY_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), - LocationAccess(GANONDORF_HINT, {[]{return BossKeyGanonsCastle && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD));}}), - LocationAccess(GANON, {[]{return BossKeyGanonsCastle && CanUse(LIGHT_ARROWS) && CanUse(MASTER_SWORD);}}), + 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->HasItem(RG_GANONS_CASTLE_BOSS_KEY) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), + LOCATION(RC_GANON, logic->HasBossSoul(RG_GANON_SOUL) && logic->HasItem(RG_GANONS_CASTLE_BOSS_KEY) && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MASTER_SWORD)), }, {}); /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::GanonsCastle.IsMQ()) { - areaTable[GANONS_CASTLE_MQ_LOBBY] = Area("Ganon's Castle MQ Lobby", "Ganons Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, {}, { - //Exits - Entrance(GANONS_CASTLE_ENTRYWAY, {[]{return true;}}), - Entrance(GANONS_CASTLE_MQ_MAIN, {[]{return (CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER)) || ((HasExplosives || Nuts || CanUse(BOOMERANG)) && CanJumpslash);}}), - }); - - areaTable[GANONS_CASTLE_MQ_MAIN] = Area("Ganon's Castle MQ Main", "Ganons Castle", GANONS_CASTLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(GANONS_CASTLE)->IsMQ()) { + areaTable[RR_GANONS_CASTLE_MQ_LOBBY] = Region("Ganon's Castle MQ Lobby", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SHEIK_HINT_MQ_GC, true), + }, { //Exits - Entrance(GANONS_CASTLE_MQ_LOBBY, {[]{return true;}}), - Entrance(GANONS_CASTLE_MQ_FOREST_TRIAL, {[]{return true;}}), - Entrance(GANONS_CASTLE_MQ_FIRE_TRIAL, {[]{return true;}}), - Entrance(GANONS_CASTLE_MQ_WATER_TRIAL, {[]{return true;}}), - Entrance(GANONS_CASTLE_MQ_SHADOW_TRIAL, {[]{return true;}}), - Entrance(GANONS_CASTLE_MQ_SPIRIT_TRIAL, {[]{return true;}}), - Entrance(GANONS_CASTLE_MQ_LIGHT_TRIAL, {[]{return CanUse(GOLDEN_GAUNTLETS);}}), - Entrance(GANONS_CASTLE_TOWER, {[]{return (ForestTrialClear || Trial::ForestTrial.IsSkipped()) && - (FireTrialClear || Trial::FireTrial.IsSkipped()) && - (WaterTrialClear || Trial::WaterTrial.IsSkipped()) && - (ShadowTrialClear || Trial::ShadowTrial.IsSkipped()) && - (SpiritTrialClear || Trial::SpiritTrial.IsSkipped()) && - (LightTrialClear || Trial::LightTrial.IsSkipped());}}), - Entrance(GANONS_CASTLE_MQ_DEKU_SCRUBS, {[]{return LogicLensCastleMQ || CanUse(LENS_OF_TRUTH);}}), + Entrance(RR_GANONS_CASTLE_ENTRYWAY, {[]{return (logic->CanUse(RG_MASTER_SWORD) || (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD)))));}}), + Entrance(RR_GANONS_CASTLE_MQ_FOREST_TRIAL, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_MQ_FIRE_TRIAL, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_MQ_WATER_TRIAL, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL, {[]{return true;}}), + Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}), + Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && + (logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && + (logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && + (logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && + (logic->SpiritTrialClear || ctx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) && + (logic->LightTrialClear || ctx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}}), + Entrance(RR_GANONS_CASTLE_MQ_DEKU_SCRUBS, {[]{return ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}), }); - areaTable[GANONS_CASTLE_MQ_DEKU_SCRUBS] = Area("Ganon's Castle MQ Deku Scrubs", "Ganon's Castle", 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(&FreeFairies, {[]{return true;}}), + EventAccess(&logic->FreeFairies, {[]{return true;}}), }, { //Locations - LocationAccess(GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, {[]{return CanStunDeku;}}), - LocationAccess(GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, {[]{return CanStunDeku;}}), - LocationAccess(GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, {[]{return CanStunDeku;}}), - LocationAccess(GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, {[]{return CanStunDeku;}}), - LocationAccess(GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, {[]{return CanStunDeku;}}), + LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, logic->CanStunDeku()), }, {}); - areaTable[GANONS_CASTLE_MQ_FOREST_TRIAL] = Area("Ganon's Castle MQ Forest Trial", "Ganons Castle", 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(&ForestTrialClear, {[]{return IsAdult && CanUse(LIGHT_ARROWS) && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && CanPlay(SongOfTime);}}), + EventAccess(&logic->ForestTrialClear, {[]{return logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->CanUse(RG_SONG_OF_TIME);}}), }, { //Locations - LocationAccess(GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && (CanUse(BOW) || CanUse(SLINGSHOT));}}), - LocationAccess(GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && HasFireSource;}}), - LocationAccess(GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && HookshotOrBoomerang;}}), + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FROZEN_EYE_SWITCH_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HasFireSource()), + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HookshotOrBoomerang()), }, {}); - areaTable[GANONS_CASTLE_MQ_FIRE_TRIAL] = Area("Ganon's Castle MQ Fire Trial", "Ganons Castle", 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(&FireTrialClear, {[]{return CanUse(GORON_TUNIC) && CanUse(GOLDEN_GAUNTLETS) && CanUse(LIGHT_ARROWS) && (CanUse(LONGSHOT) || HoverBoots || (LogicFireTrialMQ && CanUse(HOOKSHOT)));}}), - //Trick: CanUse(GORON_TUNIC) && CanUse(GOLDEN_GAUNTLETS) && CanUse(LIGHT_ARROWS) && (CanUse(LONGSHOT) || HoverBoots || (LogicFireTrialMQ && CanUse(HOOKSHOT))) + EventAccess(&logic->FireTrialClear, {[]{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_GANON_MQ_FIRE_TRIAL) && logic->CanUse(RG_HOOKSHOT)));}}), + //Trick: logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (LogicFireTrialMQ && logic->CanUse(RG_HOOKSHOT))) }, {}, {}); - areaTable[GANONS_CASTLE_MQ_WATER_TRIAL] = Area("Ganon's Castle MQ Water Trial", "Ganons Castle", 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(&WaterTrialClear, {[]{return BlueFire && IsAdult && CanUse(LIGHT_ARROWS) && SmallKeys(GANONS_CASTLE, 3);}}), - EventAccess(&BlueFireAccess, {[]{return BlueFireAccess || (HasBottle && CanJumpslash);}}), + EventAccess(&logic->WaterTrialClear, {[]{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->SmallKeys(RR_GANONS_CASTLE, 3);}}), + EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || (logic->HasBottle() && logic->CanJumpslash());}}), }, { //Locations - LocationAccess(GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, {[]{return BlueFire;}}), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire()), }, {}); - areaTable[GANONS_CASTLE_MQ_SHADOW_TRIAL] = Area("Ganon's Castle MQ Shadow Trial", "Ganons Castle", 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(&ShadowTrialClear, {[]{return IsAdult && CanUse(LIGHT_ARROWS) && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH)) && (HoverBoots || (Hookshot && (HasFireSource || LogicShadowTrialMQ)));}}), - //Trick: IsAdult && CanUse(LIGHT_ARROWS) && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH)) && (HoverBoots || (Hookshot && (HasFireSource || LogicShadowTrialMQ))) + EventAccess(&logic->ShadowTrialClear, {[]{return logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && (logic->HasFireSource() || ctx->GetTrickOption(RT_GANON_MQ_SHADOW_TRIAL))));}}), + //Trick: logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && (LogicLensCastleMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && (logic->HasFireSource() || LogicShadowTrialMQ))) }, { //Locations - LocationAccess(GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, {[]{return IsAdult && ((Bow && (CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS))) || (CanUse(HOVER_BOOTS) && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH)) && (HasExplosives || GoronBracelet || CanUse(DINS_FIRE))));}}), - LocationAccess(GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, {[]{return IsAdult && Bow && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH)) && (HoverBoots || (Hookshot && (HasFireSource || LogicShadowTrialMQ)));}}), - //Trick: IsAdult && Bow && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH)) && (HoverBoots || (Hookshot && (HasFireSource || LogicShadowTrialMQ))) + LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_BOMB_FLOWER_CHEST, logic->IsAdult && ((logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE))))), + LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_EYE_SWITCH_CHEST, logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && (logic->HasFireSource() || ctx->GetTrickOption(RT_GANON_MQ_SHADOW_TRIAL))))), + //Trick: logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && (LogicLensCastleMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && (logic->HasFireSource() || LogicShadowTrialMQ))) }, {}); - areaTable[GANONS_CASTLE_MQ_SPIRIT_TRIAL] = Area("Ganon's Castle MQ Spirit Castle", "Ganons Castle", 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(&SpiritTrialClear, {[]{return IsAdult && CanUse(LIGHT_ARROWS) && Hammer && HasBombchus && ((FireArrows && MirrorShield) || SunlightArrows);}}), - EventAccess(&NutPot, {[]{return NutPot || (Hammer && HasBombchus && IsAdult && ((CanUse(FIRE_ARROWS) && MirrorShield) || (SunlightArrows && CanUse(LIGHT_ARROWS))));}}), + EventAccess(&logic->SpiritTrialClear, {[]{return logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || ctx->GetOption(RSK_SUNLIGHT_ARROWS));}}), + EventAccess(&logic->NutPot, {[]{return logic->NutPot || (logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}}), }, { //Locations - LocationAccess(GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, {[]{return IsAdult && (Bow || LogicRustedSwitches) && Hammer;}}), - LocationAccess(GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, {[]{return IsAdult && (Bow || LogicRustedSwitches) && Hammer && HasBombchus && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH));}}), - LocationAccess(GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, {[]{return IsAdult && Hammer && HasBombchus && ((CanUse(FIRE_ARROWS) && CanUse(MIRROR_SHIELD)) || (SunlightArrows && CanUse(LIGHT_ARROWS)));}}), - LocationAccess(GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, {[]{return IsAdult && Hammer && HasBombchus && ((CanUse(FIRE_ARROWS) && CanUse(MIRROR_SHIELD)) || (SunlightArrows && CanUse(LIGHT_ARROWS)));}}), - LocationAccess(GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, {[]{return IsAdult && Hammer && HasBombchus && ((CanUse(FIRE_ARROWS) && CanUse(MIRROR_SHIELD)) || (SunlightArrows && CanUse(LIGHT_ARROWS)));}}), - LocationAccess(GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, {[]{return IsAdult && Hammer && HasBombchus && ((CanUse(FIRE_ARROWS) && CanUse(MIRROR_SHIELD)) || (SunlightArrows && CanUse(LIGHT_ARROWS)));}}), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_RUSTED_SWITCHES)) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_FRONT_LEFT_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_LEFT_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_SUN_BACK_RIGHT_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_BOMBCHU_5) && ((logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_MIRROR_SHIELD)) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), }, {}); - areaTable[GANONS_CASTLE_MQ_LIGHT_TRIAL] = Area("Ganon's Castle MQ Light Trial", "Ganons Castle", 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(&LightTrialClear, {[]{return IsAdult && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD)) && CanUse(LIGHT_ARROWS) && SmallKeys(GANONS_CASTLE, 3) && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH)) && (Hookshot || LogicLightTrialMQ);}}), - //Trick: IsAdult && CanUse(LIGHT_ARROWS) && SmallKeys(GANONS_CASTLE, 3) && (LogicLensCastleMQ || CanUse(LENS_OF_TRUTH)) && (Hookshot || LogicLightTrialMQ) + EventAccess(&logic->LightTrialClear, {[]{return logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->CanUse(RG_LIGHT_ARROWS) && logic->SmallKeys(RR_GANONS_CASTLE, 3) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL));}}), + //Trick: logic->IsAdult && logic->CanUse(RG_LIGHT_ARROWS) && logic->SmallKeys(RR_GANONS_CASTLE, 3) && (LogicLensCastleMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || LogicLightTrialMQ) }, { //Locations - LocationAccess(GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, {[]{return (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD)) && CanPlay(ZeldasLullaby);}}), + LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LULLABY_CHEST, (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->CanUse(RG_ZELDAS_LULLABY)), }, {}); } } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp index 15a9e4e64da..e6498181bf0 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 @@ -1,193 +1,191 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_GerudoTrainingGrounds() { +void RegionTable_Init_GerudoTrainingGrounds() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[GERUDO_TRAINING_GROUNDS_ENTRYWAY] = Area("Gerudo Training Grounds Entryway", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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(GERUDO_TRAINING_GROUNDS_LOBBY, {[]{return Dungeon::GerudoTrainingGrounds.IsVanilla();}}), - Entrance(GERUDO_TRAINING_GROUNDS_MQ_LOBBY, {[]{return Dungeon::GerudoTrainingGrounds.IsMQ();}}), - Entrance(GERUDO_FORTRESS, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_LOBBY, {[]{return ctx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsVanilla();}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY, {[]{return ctx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsMQ();}}), + Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::GerudoTrainingGrounds.IsVanilla()) { - areaTable[GERUDO_TRAINING_GROUNDS_LOBBY] = Area("Gerudo Training Grounds Lobby", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsVanilla()) { + areaTable[RR_GERUDO_TRAINING_GROUNDS_LOBBY] = Region("Gerudo Training Grounds Lobby", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_LOBBY_LEFT_CHEST, {[]{return CanUse(BOW) || CanUse(SLINGSHOT);}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_LOBBY_RIGHT_CHEST, {[]{return CanUse(BOW) || CanUse(SLINGSHOT);}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_STALFOS_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_BEAMOS_CHEST, {[]{return HasExplosives && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD));}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return true;}}), - Entrance(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && (CanUse(HOOKSHOT) || LogicGtgWithoutHookshot);}}), - Entrance(GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return Here(GERUDO_TRAINING_GROUNDS_LOBBY, []{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && HasExplosives;});}}), - Entrance(GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM, {[]{return (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GTG_WITHOUT_HOOKSHOT));}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_LOBBY, []{return (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HasExplosives();});}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE, {[]{return true;}}), }); - areaTable[GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE] = Area("Gerudo Training Grounds Central Maze", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_HIDDEN_CEILING_CHEST, {[]{return SmallKeys(GERUDO_TRAINING_GROUNDS, 3) && (LogicLensGtg || CanUse(LENS_OF_TRUTH));}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MAZE_PATH_FIRST_CHEST, {[]{return SmallKeys(GERUDO_TRAINING_GROUNDS, 4);}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MAZE_PATH_SECOND_CHEST, {[]{return SmallKeys(GERUDO_TRAINING_GROUNDS, 6);}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MAZE_PATH_THIRD_CHEST, {[]{return SmallKeys(GERUDO_TRAINING_GROUNDS, 7);}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MAZE_PATH_FINAL_CHEST, {[]{return SmallKeys(GERUDO_TRAINING_GROUNDS, 9);}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 4)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 6)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 7)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 9)), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT, {[]{return SmallKeys(GERUDO_TRAINING_GROUNDS, 9);}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT, {[]{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 9);}}), }); - areaTable[GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT] = Area("Gerudo Training Grounds Central Maze Right", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_CENTRAL_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MAZE_RIGHT_SIDE_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_FREESTANDING_KEY, {[]{return true;}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, true), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return CanUse(HOOKSHOT);}}), - Entrance(GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return true;}}), }); - areaTable[GERUDO_TRAINING_GROUNDS_LAVA_ROOM] = Area("Gerudo Training Grounds Lava Room", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_UNDERWATER_SILVER_RUPEE_CHEST, {[]{return CanUse(HOOKSHOT) && CanPlay(SongOfTime) && IronBoots && WaterTimer >= 24;}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT, {[]{return CanPlay(SongOfTime) || IsChild;}}), - Entrance(GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return CanUse(LONGSHOT) || (CanUse(HOVER_BOOTS) && CanUse(HOOKSHOT));}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT, {[]{return logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_HOOKSHOT));}}), }); - areaTable[GERUDO_TRAINING_GROUNDS_HAMMER_ROOM] = Area("Gerudo Training Grounds Hammer Room", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_CLEAR_CHEST, {[]{return CanAdultAttack || CanChildAttack;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_HAMMER_ROOM_SWITCH_CHEST, {[]{return CanUse(MEGATON_HAMMER) || (CanTakeDamage && LogicFlamingChests);}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, logic->CanAttack()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || (logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS))), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, {[]{return CanUse(MEGATON_HAMMER) && CanUse(BOW);}}), - Entrance(GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, {[]{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_FAIRY_BOW);}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return true;}}), }); - areaTable[GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER] = Area("Gerudo Training Grounds Eye Statue Lower", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_EYE_STATUE_CHEST, {[]{return CanUse(BOW);}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return true;}}), }); - areaTable[GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER] = Area("Gerudo Training Grounds Eye Statue Upper", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_NEAR_SCARECROW_CHEST, {[]{return CanUse(BOW);}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, {[]{return true;}}), }); - areaTable[GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM] = Area("Gerudo Training Grounds Heavy Block Room", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_BEFORE_HEAVY_BLOCK_CHEST, {[]{return CanJumpslash;}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanJumpslash()), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER, {[]{return (LogicLensGtg || CanUse(LENS_OF_TRUTH)) && (CanUse(HOOKSHOT) || (LogicGtgFakeWall && CanUse(HOVER_BOOTS)));}}), - Entrance(GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM, {[]{return (LogicLensGtg || CanUse(LENS_OF_TRUTH)) && (CanUse(HOOKSHOT) || (LogicGtgFakeWall && CanUse(HOVER_BOOTS))) && CanUse(SILVER_GAUNTLETS);}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER, {[]{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)));}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM, {[]{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanUse(RG_SILVER_GAUNTLETS);}}), }); - areaTable[GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM] = Area("Gerudo Training Grounds Like Like Room", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FIRST_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_SECOND_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_THIRD_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_FOURTH_CHEST, {[]{return CanJumpslash;}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanJumpslash()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanJumpslash()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, logic->CanJumpslash()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->CanJumpslash()), }, {}); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::GerudoTrainingGrounds.IsMQ()) { - areaTable[GERUDO_TRAINING_GROUNDS_MQ_LOBBY] = Area("Gerudo Training Grounds MQ Lobby", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_LOBBY_LEFT_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_LOBBY_RIGHT_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_HIDDEN_CEILING_CHEST, {[]{return LogicLensGtgMQ || CanUse(LENS_OF_TRUTH);}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_FIRST_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_SECOND_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_MAZE_PATH_THIRD_CHEST, {[]{return SmallKeys(GERUDO_TRAINING_GROUNDS, 1);}}), + if (ctx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsMQ()) { + areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY] = Region("Gerudo Training Grounds MQ Lobby", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 1)), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return true;}}), - Entrance(GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE, {[]{return Here(GERUDO_TRAINING_GROUNDS_MQ_LOBBY, []{return HasFireSource;});}}), - Entrance(GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, {[]{return Here(GERUDO_TRAINING_GROUNDS_MQ_LOBBY, []{return (IsAdult && CanUse(BOW)) || (IsChild && CanUse(SLINGSHOT));});}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY, []{return logic->HasFireSource();});}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_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[GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE] = Area("Gerudo Training Grounds MQ Right Side", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 || (IsAdult && CanUse(BOW));}}), + //EventAccess(&WallFairy, {[]{return WallFairy || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}}), }, { //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_DINOLFOS_CHEST, {[]{return IsAdult && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD));}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return (Bow || (CanUse(LONGSHOT) && HasFireSource)) && CanUse(HOVER_BOOTS) && IsAdult && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD));}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return (logic->CanUse(RG_FAIRY_BOW) || (logic->CanUse(RG_LONGSHOT) && logic->HasFireSource())) && logic->CanUse(RG_HOVER_BOOTS) && logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD));}}), }); - areaTable[GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER] = Area("Gerudo Training Grounds MQ Underwater", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER_SILVER_RUPEE_CHEST, {[]{return HasFireSource && IsAdult && CanUse(IRON_BOOTS) && WaterTimer >= 24 && CanTakeDamage;}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, logic->HasFireSource() && logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->TakeDamage()), }, {}); - areaTable[GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE] = Area("Gerudo Training Grounds MQ Left Side", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_FIRST_IRON_KNUCKLE_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || HasExplosives;}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->HasExplosives()), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM, {[]{return (IsAdult && CanUse(LONGSHOT)) || LogicGtgMQWithoutHookshot || (LogicGtgMQWithHookshot && IsAdult && CanUse(HOOKSHOT));}}), - //Trick: (IsAdult && CanUse(LONGSHOT)) || LogicGtgMQWithoutHookshot || (LogicGtgMQWithHookshot && IsAdult && CanUse(HOOKSHOT)) + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM, {[]{return (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || ctx->GetTrickOption(RT_GTG_MQ_WIHTOUT_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT));}}), + //Trick: (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || LogicGtgMQWithoutHookshot || (LogicGtgMQWithHookshot && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) }); - areaTable[GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM] = Area("Gerudo Training Grounds MQ Stalfos Room", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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(&BlueFireAccess, {[]{return BlueFireAccess || HasBottle;}}), + EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || logic->HasBottle();}}), }, { //Locations - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_BEFORE_HEAVY_BLOCK_CHEST, {[]{return IsAdult && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD));}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_HEAVY_BLOCK_CHEST, {[]{return CanUse(SILVER_GAUNTLETS) && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD));}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS, {[]{return IsAdult && (LogicLensGtgMQ || CanUse(LENS_OF_TRUTH)) && BlueFire && (CanPlay(SongOfTime) || (LogicGtgFakeWall && IsAdult && CanUse(HOVER_BOOTS)));}}), - //Trick: IsAdult && (LogicLensGtgMQ || CanUse(LENS_OF_TRUTH)) && BlueFire && (CanPlay(SongOfTime) || (LogicGtgFakeWall && IsAdult && CanUse(HOVER_BOOTS))) + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS, {[]{return logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));}}), + //Trick: logic->IsAdult && (LogicLensGtgMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire && (logic->CanUse(RG_SONG_OF_TIME) || (LogicGtgFakeWall && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS))) }); - areaTable[GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS] = Area("Gerudo Training Grounds MQ Back Areas", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_EYE_STATUE_CHEST, {[]{return CanUse(BOW);}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_SECOND_IRON_KNUCKLE_CHEST, {[]{return (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD));}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_FLAME_CIRCLE_CHEST, {[]{return CanUse(HOOKSHOT) || CanUse(BOW) || HasExplosives;}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->HasExplosives()), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT, {[]{return CanUse(MEGATON_HAMMER);}}), - Entrance(GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, {[]{return CanUse(LONGSHOT);}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, {[]{return logic->CanUse(RG_LONGSHOT);}}), }); - areaTable[GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT] = Area("Gerudo Training Grounds MQ Central Maze Right", "Gerudo Training Grounds", GERUDO_TRAINING_GROUNDS, 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 - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_CENTRAL_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_MAZE_RIGHT_SIDE_CHEST, {[]{return true;}}), - LocationAccess(GERUDO_TRAINING_GROUNDS_MQ_ICE_ARROWS_CHEST, {[]{return SmallKeys(GERUDO_TRAINING_GROUNDS, 3);}}), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 3)), }, { //Exits - Entrance(GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return IsAdult && (CanUse(LONGSHOT) || (CanUse(HOOKSHOT) && Bow));}}), - Entrance(GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, {[]{return IsAdult && CanUse(HOOKSHOT);}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)));}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, {[]{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}}), }); } } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_valley.cpp index f11a74f3cf8..636fe60eda8 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 @@ -1,209 +1,207 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" +#include "../../entrance.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_GerudoValley() { - areaTable[GERUDO_VALLEY] = Area("Gerudo Valley", "Gerudo Valley", 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(&BugRock, {[]{return BugRock || IsChild;}}), + EventAccess(&logic->BugRock, {[]{return logic->BugRock || logic->IsChild;}}), }, { //Locations - LocationAccess(GV_GS_SMALL_BRIDGE, {[]{return IsChild && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), + LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), - Entrance(GV_UPPER_STREAM, {[]{return true;}}), - Entrance(GV_CRATE_LEDGE, {[]{return IsChild || CanUse(LONGSHOT);}}), - Entrance(GV_GROTTO_LEDGE, {[]{return true;}}), - Entrance(GV_FORTRESS_SIDE, {[]{return (IsAdult && (CanRideEpona || CanUse(LONGSHOT) || GerudoFortress.Is(GERUDOFORTRESS_OPEN) || CarpenterRescue)) || (IsChild && CanUse(HOOKSHOT));}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_GV_UPPER_STREAM, {[]{return true;}}), + Entrance(RR_GV_CRATE_LEDGE, {[]{return logic->IsChild || logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_GV_GROTTO_LEDGE, {[]{return true;}}), + Entrance(RR_GV_FORTRESS_SIDE, {[]{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}}), }); - areaTable[GV_UPPER_STREAM] = Area("GV Upper Stream", "Gerudo Valley", GERUDO_VALLEY, DAY_NIGHT_CYCLE, { + areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, { //Events - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairy;}}), - EventAccess(&BeanPlantFairy, {[]{return BeanPlantFairy || (CanPlantBean(GV_UPPER_STREAM) && CanPlay(SongOfStorms));}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_GV_UPPER_STREAM) && logic->CanUse(RG_SONG_OF_STORMS));}}), }, { //Locations - LocationAccess(GV_WATERFALL_FREESTANDING_POH, {[]{return true;}}), - LocationAccess(GV_GS_BEAN_PATCH, {[]{return CanPlantBugs && CanChildAttack;}}), - LocationAccess(GV_COW, {[]{return IsChild && CanPlay(EponasSong);}}), - LocationAccess(GV_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE)),//can use cucco as child + LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_GV_COW, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_GV_GOSSIP_STONE, true), }, { //Exits - Entrance(GV_LOWER_STREAM, {[]{return true;}}), + Entrance(RR_GV_LOWER_STREAM, {[]{return true;}}), }); - areaTable[GV_LOWER_STREAM] = Area("GV Lower Stream", "Gerudo Valley", GERUDO_VALLEY, DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GV_LOWER_STREAM] = Region("GV Lower Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(LAKE_HYLIA, {[]{return true;}}), + Entrance(RR_LAKE_HYLIA, {[]{return logic->IsChild || logic->HasItem(RG_BRONZE_SCALE);}}),//can use cucco as child }); - areaTable[GV_GROTTO_LEDGE] = Area("GV Grotto Ledge", "Gerudo Valley", GERUDO_VALLEY, DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(GV_LOWER_STREAM, {[]{return true;}}), - Entrance(GV_OCTOROK_GROTTO, {[]{return CanUse(SILVER_GAUNTLETS);}}), - Entrance(GV_CRATE_LEDGE, {[]{return CanUse(LONGSHOT);}}), + 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[GV_CRATE_LEDGE] = Area("GV Crate Ledge", "Gerudo Valley", GERUDO_VALLEY, DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GV_CRATE_LEDGE] = Region("GV Crate Ledge", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GV_CRATE_FREESTANDING_POH, {[]{return true;}}), + LOCATION(RC_GV_CRATE_FREESTANDING_POH, true), }, { //Exits - Entrance(GV_LOWER_STREAM, {[]{return true;}}), + Entrance(RR_GV_LOWER_STREAM, {[]{return true;}}), }); - areaTable[GV_FORTRESS_SIDE] = Area("GV Fortress Side", "Gerudo Valley", GERUDO_VALLEY, DAY_NIGHT_CYCLE, { - //Events - EventAccess(&BrokenSwordAccess, {[]{return IsAdult && (PoachersSawAccess || PoachersSaw);}}), - }, { + areaTable[RR_GV_FORTRESS_SIDE] = Region("GV Fortress Side", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GV_CHEST, {[]{return IsAdult && CanUse(MEGATON_HAMMER);}}), - LocationAccess(GV_TRADE_SAW, {[]{return IsAdult && PoachersSaw;}}), - LocationAccess(GV_GS_BEHIND_TENT, {[]{return IsAdult && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), - LocationAccess(GV_GS_PILLAR, {[]{return IsAdult && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), + LOCATION(RC_GV_CHEST, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_TRADE_SAW, logic->IsAdult && logic->CanUse(RG_POACHERS_SAW)), + LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), }, { //Exits - Entrance(GERUDO_FORTRESS, {[]{return true;}}), - Entrance(GV_UPPER_STREAM, {[]{return true;}}), - Entrance(GERUDO_VALLEY, {[]{return IsChild || CanRideEpona || CanUse(LONGSHOT) || GerudoFortress.Is(GERUDOFORTRESS_OPEN) || CarpenterRescue;}}), - Entrance(GV_CARPENTER_TENT, {[]{return IsAdult;}}), - Entrance(GV_STORMS_GROTTO, {[]{return IsAdult && CanOpenStormGrotto;}}), - Entrance(GV_CRATE_LEDGE, {[]{return false;}}), + Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}), + Entrance(RR_GV_UPPER_STREAM, {[]{return true;}}), + Entrance(RR_GERUDO_VALLEY, {[]{return logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) || logic->CarpenterRescue;}}), + Entrance(RR_GV_CARPENTER_TENT, {[]{return logic->IsAdult;}}), + Entrance(RR_GV_STORMS_GROTTO, {[]{return logic->IsAdult && logic->CanOpenStormsGrotto();}}), + Entrance(RR_GV_CRATE_LEDGE, {[]{return false;}}), }); - areaTable[GV_CARPENTER_TENT] = Area("GV Carpenter Tent", "GV Carpenter Tent", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GV_CARPENTER_TENT] = Region("GV Carpenter Tent", "GV Carpenter Tent", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(GV_FORTRESS_SIDE, {[]{return true;}}), + Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), }); - areaTable[GV_OCTOROK_GROTTO] = Area("GV Octorok Grotto", "GV Octorok Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GV_OCTOROK_GROTTO] = Region("GV Octorok Grotto", "GV Octorok Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(GV_GROTTO_LEDGE, {[]{return true;}}), + Entrance(RR_GV_GROTTO_LEDGE, {[]{return true;}}), }); - areaTable[GV_STORMS_GROTTO] = Area("GV Storms Grotto", "GV Storms Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GV_STORMS_GROTTO] = Region("GV Storms Grotto", "GV Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GV_DEKU_SCRUB_GROTTO_REAR, {[]{return CanStunDeku;}}), - LocationAccess(GV_DEKU_SCRUB_GROTTO_FRONT, {[]{return CanStunDeku;}}), + LOCATION(RC_GV_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()), + LOCATION(RC_GV_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()), + LOCATION(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(GV_FORTRESS_SIDE, {[]{return true;}}), + Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), }); - areaTable[GERUDO_FORTRESS] = Area("Gerudo Fortress", "Gerudo Fortress", GERUDO_FORTRESS, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GERUDO_FORTRESS] = Region("Gerudo Fortress", "Gerudo Fortress", {RA_GERUDO_FORTRESS}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&CarpenterRescue, {[]{return CanFinishGerudoFortress;}}), - EventAccess(&GF_GateOpen, {[]{return IsAdult && GerudoToken;}}), - EventAccess(&GtG_GateOpen, {[]{return GtG_GateOpen || (IsAdult && GerudoToken);}}), + EventAccess(&logic->CarpenterRescue, {[]{return logic->CanFinishGerudoFortress();}}), + EventAccess(&logic->GF_GateOpen, {[]{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}}), + EventAccess(&logic->GtG_GateOpen, {[]{return logic->GtG_GateOpen || (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}}), }, { //Locations - LocationAccess(GF_CHEST, {[]{return CanUse(HOVER_BOOTS) || (IsAdult && CanUse(SCARECROW)) || CanUse(LONGSHOT);}}), - LocationAccess(GF_HBA_1000_POINTS, {[]{return GerudoToken && CanRideEpona && Bow && AtDay;}}), - LocationAccess(GF_HBA_1500_POINTS, {[]{return GerudoToken && CanRideEpona && Bow && AtDay;}}), - LocationAccess(GF_NORTH_F1_CARPENTER, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), - LocationAccess(GF_NORTH_F2_CARPENTER, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && (GerudoToken || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || LogicGerudoKitchen);}}), - LocationAccess(GF_SOUTH_F1_CARPENTER, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), - LocationAccess(GF_SOUTH_F2_CARPENTER, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), - LocationAccess(GF_GERUDO_MEMBERSHIP_CARD, {[]{return CanFinishGerudoFortress;}}), - LocationAccess(GF_GS_ARCHERY_RANGE, {[]{return IsAdult && HookshotOrBoomerang && GerudoToken && AtNight && CanGetNightTimeGS;}}), - LocationAccess(GF_GS_TOP_FLOOR, {[]{return IsAdult && AtNight && (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOOMERANG) || HasExplosives || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(DINS_FIRE)) && (GerudoToken || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || LogicGerudoKitchen || LogicGFJump) && CanGetNightTimeGS;}}), + LOCATION(RC_GF_CHEST, logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_GF_HBA_1000_POINTS, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), + LOCATION(RC_GF_HBA_1500_POINTS, logic->HasItem(RG_CHILD_WALLET) && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_EPONA) && logic->CanUse(RG_FAIRY_BOW) && logic->AtDay), + LOCATION(RC_GF_NORTH_F1_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), + LOCATION(RC_GF_NORTH_F2_CARPENTER, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))), + LOCATION(RC_GF_SOUTH_F1_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), + LOCATION(RC_GF_SOUTH_F2_CARPENTER, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), + LOCATION(RC_GF_GERUDO_MEMBERSHIP_CARD, logic->CanFinishGerudoFortress()), + LOCATION(RC_GF_GS_ARCHERY_RANGE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && logic->AtNight && (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)) && (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN) || ctx->GetTrickOption(RT_GF_JUMP)) && logic->CanGetNightTimeGS()), }, { //Exits - Entrance(GV_FORTRESS_SIDE, {[]{return true;}}), - Entrance(GF_OUTSIDE_GATE, {[]{return GF_GateOpen;}}), - Entrance(GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return GtG_GateOpen && (IsAdult || ShuffleDungeonEntrances);}}), - Entrance(GF_STORMS_GROTTO, {[]{return IsAdult && CanOpenStormGrotto;}}), + Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), + Entrance(RR_GF_OUTSIDE_GATE, {[]{return logic->GF_GateOpen;}}), + Entrance(RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return logic->GtG_GateOpen && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}}), + Entrance(RR_GF_STORMS_GROTTO, {[]{return logic->IsAdult && logic->CanOpenStormsGrotto();}}), }); - areaTable[GF_OUTSIDE_GATE] = Area("GF Outside Gate", "Gerudo Fortress", 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(&GF_GateOpen, {[]{return IsAdult && GerudoToken && (ShuffleGerudoToken || ShuffleOverworldEntrances /*|| ShuffleSpecialIndoorEntrances*/);}}), + EventAccess(&logic->GF_GateOpen, {[]{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) /*|| ShuffleSpecialIndoorEntrances*/);}}), }, {}, { //Exits - Entrance(GERUDO_FORTRESS, {[]{return (IsAdult && (Hookshot || !ShuffleOverworldEntrances)) || GF_GateOpen;}}), - Entrance(WASTELAND_NEAR_FORTRESS, {[]{return true;}}), + Entrance(RR_GERUDO_FORTRESS, {[]{return (logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || !ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES))) || logic->GF_GateOpen;}}), + Entrance(RR_WASTELAND_NEAR_FORTRESS, {[]{return true;}}), }); - areaTable[GF_STORMS_GROTTO] = Area("GF Storms Grotto", "GF Storms Grotto", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GF_STORMS_GROTTO] = Region("GF Storms Grotto", "GF Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&FreeFairies, {[]{return true;}}), + EventAccess(&logic->FreeFairies, {[]{return true;}}), }, {}, { //Exits - Entrance(GERUDO_FORTRESS, {[]{return true;}}), + Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}), }); - areaTable[WASTELAND_NEAR_FORTRESS] = Area("Wasteland Near Fortress", "Haunted Wasteland", 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(GF_OUTSIDE_GATE, {[]{return true;}}), - Entrance(HAUNTED_WASTELAND, {[]{return CanUse(HOVER_BOOTS) || CanUse(LONGSHOT) || LogicWastelandCrossing;}}), + Entrance(RR_GF_OUTSIDE_GATE, {[]{return true;}}), + Entrance(RR_HAUNTED_WASTELAND, {[]{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_HW_CROSSING);}}), }); - areaTable[HAUNTED_WASTELAND] = Area("Haunted Wasteland", "Haunted Wasteland", HAUNTED_WASTELAND, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_HAUNTED_WASTELAND] = Region("Haunted Wasteland", "Haunted Wasteland", {RA_HAUNTED_WASTELAND}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&FairyPot, {[]{return true;}}), - EventAccess(&NutPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), + EventAccess(&logic->NutPot, {[]{return true;}}), + EventAccess(&logic->CarpetMerchant, {[]{return logic->HasItem(RG_ADULT_WALLET) && CanBuyAnother(RC_WASTELAND_BOMBCHU_SALESMAN) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}}), }, { //Locations - LocationAccess(WASTELAND_CHEST, {[]{return HasFireSource;}}), - LocationAccess(WASTELAND_BOMBCHU_SALESMAN, {[]{return AdultsWallet && (CanJumpslash || CanUse(HOVER_BOOTS)) ;}}), - LocationAccess(WASTELAND_GS, {[]{return HookshotOrBoomerang;}}), + LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()), + LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang()), }, { //Exits - Entrance(WASTELAND_NEAR_COLOSSUS, {[]{return LogicLensWasteland || CanUse(LENS_OF_TRUTH);}}), - Entrance(WASTELAND_NEAR_FORTRESS, {[]{return CanUse(HOVER_BOOTS) || CanUse(LONGSHOT) || LogicWastelandCrossing;}}), + Entrance(RR_WASTELAND_NEAR_COLOSSUS, {[]{return ctx->GetTrickOption(RT_LENS_HW) || logic->CanUse(RG_LENS_OF_TRUTH);}}), + Entrance(RR_WASTELAND_NEAR_FORTRESS, {[]{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_HW_CROSSING);}}), }); - areaTable[WASTELAND_NEAR_COLOSSUS] = Area("Wasteland Near Colossus", "Haunted Wasteland", 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(DESERT_COLOSSUS, {[]{return true;}}), - Entrance(HAUNTED_WASTELAND, {[]{return LogicReverseWasteland || false;}}), + Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), + Entrance(RR_HAUNTED_WASTELAND, {[]{return ctx->GetTrickOption(RT_HW_REVERSE) || false;}}), }); - areaTable[DESERT_COLOSSUS] = Area("Desert Colossus", "Desert Colossus", DESERT_COLOSSUS, DAY_NIGHT_CYCLE, { + areaTable[RR_DESERT_COLOSSUS] = Region("Desert Colossus", "Desert Colossus", {RA_DESERT_COLOSSUS}, DAY_NIGHT_CYCLE, { //Events - EventAccess(&FairyPond, {[]{return FairyPond || CanPlay(SongOfStorms);}}), - EventAccess(&BugRock, {[]{return true;}}), + EventAccess(&logic->FairyPond, {[]{return logic->FairyPond || logic->CanUse(RG_SONG_OF_STORMS);}}), + EventAccess(&logic->BugRock, {[]{return true;}}), }, { //Locations - LocationAccess(COLOSSUS_FREESTANDING_POH, {[]{return IsAdult && CanPlantBean(DESERT_COLOSSUS);}}), - LocationAccess(COLOSSUS_GS_BEAN_PATCH, {[]{return CanPlantBugs && CanChildAttack;}}), - LocationAccess(COLOSSUS_GS_TREE, {[]{return IsAdult && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), - LocationAccess(COLOSSUS_GS_HILL, {[]{return IsAdult && AtNight && ((CanPlantBean(DESERT_COLOSSUS) && CanAdultAttack) || CanUse(LONGSHOT) || (LogicColossusGS && CanUse(HOOKSHOT))) && CanGetNightTimeGS;}}), - LocationAccess(COLOSSUS_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_COLOSSUS_FREESTANDING_POH, logic->IsAdult && CanPlantBean(RR_DESERT_COLOSSUS)), + LOCATION(RC_COLOSSUS_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_COLOSSUS_GS_TREE, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && logic->AtNight && ((CanPlantBean(RR_DESERT_COLOSSUS) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()), + LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), }, { //Exits - Entrance(COLOSSUS_GREAT_FAIRY_FOUNTAIN, {[]{return HasExplosives;}}), - Entrance(SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(WASTELAND_NEAR_COLOSSUS, {[]{return true;}}), - Entrance(COLOSSUS_GROTTO, {[]{return CanUse(SILVER_GAUNTLETS);}}), + Entrance(RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives();}}), + Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_WASTELAND_NEAR_COLOSSUS, {[]{return true;}}), + Entrance(RR_COLOSSUS_GROTTO, {[]{return logic->CanUse(RG_SILVER_GAUNTLETS);}}), }); - areaTable[DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY] = Area("Desert Colossus From Spirit Entryway", "Desert Colossus", 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 - LocationAccess(SHEIK_AT_COLOSSUS, {[]{return true;}}), + LOCATION(RC_SHEIK_AT_COLOSSUS, true), }, { //Exist - Entrance(DESERT_COLOSSUS, {[]{return true;}}), + Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), }); - areaTable[COLOSSUS_GREAT_FAIRY_FOUNTAIN] = Area("Colossus Great Fairy Fountain", "Colossus Great Fairy Fountain", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN] = Region("Colossus Great Fairy Fountain", "Colossus Great Fairy Fountain", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(COLOSSUS_GREAT_FAIRY_REWARD, {[]{return CanPlay(ZeldasLullaby);}}), + LOCATION(RC_COLOSSUS_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits - Entrance(DESERT_COLOSSUS, {[]{return true;}}), + Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), }); - areaTable[COLOSSUS_GROTTO] = Area("Colossus Grotto", "Colossus Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_COLOSSUS_GROTTO] = Region("Colossus Grotto", "Colossus Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(COLOSSUS_DEKU_SCRUB_GROTTO_REAR, {[]{return CanStunDeku;}}), - LocationAccess(COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, {[]{return CanStunDeku;}}), + LOCATION(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()), + LOCATION(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()), + LOCATION(RC_COLOSSUS_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(DESERT_COLOSSUS, {[]{return true;}}), + Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_hyrule_field.cpp index 5b3e34a4bda..9332decd44a 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 @@ -1,234 +1,277 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" +#include "../../entrance.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_HyruleField() { - areaTable[HYRULE_FIELD] = Area("Hyrule Field", "Hyrule Field", 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(&BigPoeKill, {[]{return CanUse(BOW) && CanRideEpona && HasBottle;}}), + EventAccess(&logic->BigPoeKill, {[]{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_EPONA) && logic->HasBottle();}}), }, { //Locations - LocationAccess(HF_OCARINA_OF_TIME_ITEM, {[]{return IsChild && HasAllStones;}}), - LocationAccess(SONG_FROM_OCARINA_OF_TIME, {[]{return IsChild && HasAllStones;}}), + LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3), + LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3), }, { //Exits - Entrance(LW_BRIDGE, {[]{return true;}}), - Entrance(LAKE_HYLIA, {[]{return true;}}), - Entrance(GERUDO_VALLEY, {[]{return true;}}), - Entrance(MARKET_ENTRANCE, {[]{return true;}}), - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), - Entrance(ZR_FRONT, {[]{return true;}}), - Entrance(LON_LON_RANCH, {[]{return true;}}), - Entrance(HF_SOUTHEAST_GROTTO, {[]{return Here(HYRULE_FIELD, []{return CanBlastOrSmash;});}}), - Entrance(HF_OPEN_GROTTO, {[]{return true;}}), - Entrance(HF_INSIDE_FENCE_GROTTO, {[]{return CanOpenBombGrotto;}}), - Entrance(HF_COW_GROTTO, {[]{return (CanUse(MEGATON_HAMMER) || IsChild) && CanOpenBombGrotto;}}), - Entrance(HF_NEAR_MARKET_GROTTO, {[]{return Here(HYRULE_FIELD, []{return CanBlastOrSmash;});}}), - Entrance(HF_FAIRY_GROTTO, {[]{return Here(HYRULE_FIELD, []{return CanBlastOrSmash;});}}), - Entrance(HF_NEAR_KAK_GROTTO, {[]{return CanOpenBombGrotto;}}), - Entrance(HF_TEKTITE_GROTTO, {[]{return CanOpenBombGrotto;}}), + Entrance(RR_LW_BRIDGE, {[]{return true;}}), + Entrance(RR_LAKE_HYLIA, {[]{return true;}}), + Entrance(RR_GERUDO_VALLEY, {[]{return true;}}), + Entrance(RR_MARKET_ENTRANCE, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_ZR_FRONT, {[]{return true;}}), + Entrance(RR_LON_LON_RANCH, {[]{return true;}}), + Entrance(RR_HF_SOUTHEAST_GROTTO, {[]{return Here(RR_HYRULE_FIELD, []{return logic->BlastOrSmash();});}}), + Entrance(RR_HF_OPEN_GROTTO, {[]{return true;}}), + Entrance(RR_HF_INSIDE_FENCE_GROTTO, {[]{return logic->CanOpenBombGrotto();}}), + Entrance(RR_HF_COW_GROTTO, {[]{return (logic->CanUse(RG_MEGATON_HAMMER) || logic->IsChild) && logic->CanOpenBombGrotto();}}), + Entrance(RR_HF_NEAR_MARKET_GROTTO, {[]{return Here(RR_HYRULE_FIELD, []{return logic->BlastOrSmash();});}}), + Entrance(RR_HF_FAIRY_GROTTO, {[]{return Here(RR_HYRULE_FIELD, []{return logic->BlastOrSmash();});}}), + Entrance(RR_HF_NEAR_KAK_GROTTO, {[]{return logic->CanOpenBombGrotto();}}), + Entrance(RR_HF_TEKTITE_GROTTO, {[]{return logic->CanOpenBombGrotto();}}), }); - areaTable[HF_SOUTHEAST_GROTTO] = Area("HF Southeast Grotto", "HF Southeast Grotto", NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_HF_SOUTHEAST_GROTTO] = Region("HF Southeast Grotto", "HF Southeast Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(HF_SOUTHEAST_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(HF_SOUTHEAST_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, true), + LOCATION(RC_HF_SOUTHEAST_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[HF_OPEN_GROTTO] = Area("HF Open Grotto", "HF Open Grotto", NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_HF_OPEN_GROTTO] = Region("HF Open Grotto", "HF Open Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(HF_OPEN_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(HF_OPEN_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_HF_OPEN_GROTTO_CHEST, true), + LOCATION(RC_HF_OPEN_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[HF_INSIDE_FENCE_GROTTO] = Area("HF Inside Fence Grotto", "HF Inside Fence Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_HF_INSIDE_FENCE_GROTTO] = Region("HF Inside Fence Grotto", "HF Inside Fence Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(HF_DEKU_SCRUB_GROTTO, {[]{return CanStunDeku;}}), + LOCATION(RC_HF_DEKU_SCRUB_GROTTO, logic->CanStunDeku()), + LOCATION(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[HF_COW_GROTTO] = Area("HF Cow Grotto", "HF Cow Grotto", NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_HF_COW_GROTTO] = Region("HF Cow Grotto", "HF Cow Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(HF_GS_COW_GROTTO, {[]{return HasFireSource && HookshotOrBoomerang;}}), - LocationAccess(HF_COW_GROTTO_COW, {[]{return HasFireSource && CanPlay(EponasSong);}}), - LocationAccess(HF_COW_GROTTO_GOSSIP_STONE, {[]{return HasFireSource;}}), + LOCATION(RC_HF_GS_COW_GROTTO, logic->HasFireSource() && logic->HookshotOrBoomerang()), + LOCATION(RC_HF_COW_GROTTO_COW, logic->HasFireSource() && logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE, logic->HasFireSource()), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[HF_NEAR_MARKET_GROTTO] = Area("HF Near Market Grotto", "HF Near Market Grotto", NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_HF_NEAR_MARKET_GROTTO] = Region("HF Near Market Grotto", "HF Near Market Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(HF_NEAR_MARKET_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_CHEST, true), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[HF_FAIRY_GROTTO] = Area("HF Fairy Grotto", "HF Fairy Grotto", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_HF_FAIRY_GROTTO] = Region("HF Fairy Grotto", "HF Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&FreeFairies, {[]{return true;}}), + EventAccess(&logic->FreeFairies, {[]{return true;}}), }, {}, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[HF_NEAR_KAK_GROTTO] = Area("HF Near Kak Grotto", "HF Near Kak Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_HF_NEAR_KAK_GROTTO] = Region("HF Near Kak Grotto", "HF Near Kak Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(HF_GS_NEAR_KAK_GROTTO, {[]{return HookshotOrBoomerang;}}), + LOCATION(RC_HF_GS_NEAR_KAK_GROTTO, logic->HookshotOrBoomerang()), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[HF_TEKTITE_GROTTO] = Area("HF Tektite Grotto", "HF Tektite Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_HF_TEKTITE_GROTTO] = Region("HF Tektite Grotto", "HF Tektite Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(HF_TEKTITE_GROTTO_FREESTANDING_POH, {[]{return ProgressiveScale >= 2 || CanUse(IRON_BOOTS);}}), + LOCATION(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS)), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[LAKE_HYLIA] = Area("Lake Hylia", "Lake Hylia", LAKE_HYLIA, DAY_NIGHT_CYCLE, { + areaTable[RR_LAKE_HYLIA] = Region("Lake Hylia", "Lake Hylia", {RA_LAKE_HYLIA}, DAY_NIGHT_CYCLE, { //Events - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairy;}}), - EventAccess(&BeanPlantFairy, {[]{return BeanPlantFairy || (CanPlantBean(LAKE_HYLIA) && CanPlay(SongOfStorms));}}), - EventAccess(&ButterflyFairy, {[]{return ButterflyFairy || CanUse(STICKS);}}), - EventAccess(&BugShrub, {[]{return BugShrub || (IsChild && CanCutShrubs);}}), - EventAccess(&ChildScarecrow, {[]{return ChildScarecrow || (IsChild && Ocarina);}}), - EventAccess(&AdultScarecrow, {[]{return AdultScarecrow || (IsAdult && Ocarina);}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_LAKE_HYLIA) && logic->CanUse(RG_SONG_OF_STORMS));}}), + EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), + EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || (logic->IsChild && logic->CanCutShrubs());}}), + EventAccess(&logic->ChildScarecrow, {[]{return logic->ChildScarecrow || (logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}}), + EventAccess(&logic->AdultScarecrow, {[]{return logic->AdultScarecrow || (logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}}), }, { //Locations - LocationAccess(LH_UNDERWATER_ITEM, {[]{return IsChild && CanDive;}}), - LocationAccess(LH_SUN, {[]{return IsAdult && WaterTempleClear && CanUse(BOW);}}), - LocationAccess(LH_FREESTANDING_POH, {[]{return IsAdult && (CanUse(SCARECROW) || CanPlantBean(LAKE_HYLIA));}}), - LocationAccess(LH_GS_BEAN_PATCH, {[]{return CanPlantBugs && CanChildAttack;}}), - LocationAccess(LH_GS_LAB_WALL, {[]{return IsChild && (HookshotOrBoomerang || (LogicLabWallGS && CanJumpslash)) && AtNight && CanGetNightTimeGS;}}), - LocationAccess(LH_GS_SMALL_ISLAND, {[]{return IsChild && CanChildAttack && AtNight && CanGetNightTimeGS;}}), - LocationAccess(LH_GS_TREE, {[]{return IsAdult && CanUse(LONGSHOT) && AtNight && CanGetNightTimeGS;}}), - LocationAccess(LH_LAB_GOSSIP_STONE, {[]{return true;}}), - LocationAccess(LH_GOSSIP_STONE_SOUTHEAST, {[]{return true;}}), - LocationAccess(LH_GOSSIP_STONE_SOUTHWEST, {[]{return true;}}), + LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)), + LOCATION(RC_LH_SUN, logic->IsAdult && logic->WaterTempleClear && logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA))), + LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslash())) && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanAttack() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LH_LAB_GOSSIP_STONE, true), + LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE, true), + LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE, true), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), - Entrance(ZORAS_DOMAIN, {[]{return IsChild && (CanDive || CanUse(IRON_BOOTS));}}), - Entrance(LH_OWL_FLIGHT, {[]{return IsChild;}}), - Entrance(LH_FISHING_ISLAND, {[]{return IsChild || CanUse(SCARECROW) || CanPlantBean(LAKE_HYLIA) || WaterTempleClear;}}), - Entrance(LH_LAB, {[]{return true;}}), - Entrance(WATER_TEMPLE_ENTRYWAY, {[]{return CanUse(HOOKSHOT) && ((CanUse(IRON_BOOTS) || (LogicWaterHookshotEntry && ProgressiveScale >= 2)) || (IsAdult && CanUse(LONGSHOT) && ProgressiveScale >= 2));}}), - Entrance(LH_GROTTO, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_ZORAS_DOMAIN, {[]{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_LH_OWL_FLIGHT, {[]{return logic->IsChild;}}), + Entrance(RR_LH_FISHING_ISLAND, {[]{return logic->IsChild || logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA) || logic->WaterTempleClear;}}), + Entrance(RR_LH_LAB, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)));}}), + Entrance(RR_LH_GROTTO, {[]{return true;}}), }); - areaTable[LH_FISHING_ISLAND] = Area("LH Fishing Island", "Lake Hylia", LAKE_HYLIA, DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", "Lake Hylia", {RA_LAKE_HYLIA}, DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(LAKE_HYLIA, {[]{return true;}}), - Entrance(LH_FISHING_HOLE, {[]{return true;}}), + Entrance(RR_LAKE_HYLIA, {[]{return true;}}), + Entrance(RR_LH_FISHING_HOLE, {[]{return true;}}), }); - areaTable[LH_OWL_FLIGHT] = Area("LH Owl Flight", "Lake Hylia", 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(HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}, false), }); - areaTable[LH_LAB] = Area("LH Lab", "LH Lab", NONE, NO_DAY_NIGHT_CYCLE, { - //Events - EventAccess(&EyedropsAccess, {[]{return EyedropsAccess || (IsAdult && (EyeballFrogAccess || (EyeballFrog && DisableTradeRevert)));}}), - }, { + areaTable[RR_LH_LAB] = Region("LH Lab", "LH Lab", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(LH_LAB_DIVE, {[]{return ProgressiveScale >= 2 || (LogicLabDiving && CanUse(IRON_BOOTS) && CanUse(HOOKSHOT));}}), - LocationAccess(LH_TRADE_FROG, {[]{return IsAdult && EyeballFrog;}}), - LocationAccess(LH_GS_LAB_CRATE, {[]{return CanUse(IRON_BOOTS) && CanUse(HOOKSHOT);}}), + LOCATION(RC_LH_LAB_DIVE, logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->CanUse(RG_EYEBALL_FROG)), + LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)), }, { //Exits - Entrance(LAKE_HYLIA, {[]{return true;}}), + Entrance(RR_LAKE_HYLIA, {[]{return true;}}), }); - areaTable[LH_FISHING_HOLE] = Area("LH Fishing Hole", "LH Fishing Hole", NONE, DAY_NIGHT_CYCLE, {}, { + // TODO: should some of these helpers be done via events instead? + areaTable[RR_LH_FISHING_HOLE] = Region("LH Fishing Hole", "LH Fishing Hole", {}, DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(LH_CHILD_FISHING, {[]{return IsChild;}}), - LocationAccess(LH_ADULT_FISHING, {[]{return IsAdult;}}), + LOCATION(RC_LH_CHILD_FISHING, logic->CanUse(RG_FISHING_POLE) && logic->IsChild), + LOCATION(RC_LH_CHILD_FISH_1, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_2, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_3, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_4, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_5, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_6, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_7, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_8, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_9, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_10, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_11, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_12, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_13, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_14, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_FISH_15, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_LOACH_1, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_CHILD_LOACH_2, logic->CanUse(RG_FISHING_POLE) && (logic->IsChild || ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT))), + LOCATION(RC_LH_ADULT_FISHING, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult), + LOCATION(RC_LH_ADULT_FISH_1, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_2, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_3, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_4, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_5, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_6, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_7, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_8, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_9, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_10, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_11, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_12, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_13, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_14, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_FISH_15, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_ADULT_LOACH, logic->CanUse(RG_FISHING_POLE) && logic->IsAdult && ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)), + LOCATION(RC_LH_HYRULE_LOACH, logic->CanUse(RG_FISHING_POLE)), + LOCATION(RC_FISHING_POLE_HINT, true), }, { //Exits - Entrance(LH_FISHING_ISLAND, {[]{return true;}}), + Entrance(RR_LH_FISHING_ISLAND, {[]{return true;}}), }); - areaTable[LH_GROTTO] = Area("LH Grotto", "LH Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LH_GROTTO] = Region("LH Grotto", "LH Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(LH_DEKU_SCRUB_GROTTO_LEFT, {[]{return CanStunDeku;}}), - LocationAccess(LH_DEKU_SCRUB_GROTTO_RIGHT, {[]{return CanStunDeku;}}), - LocationAccess(LH_DEKU_SCRUB_GROTTO_CENTER, {[]{return CanStunDeku;}}), + LOCATION(RC_LH_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku()), + LOCATION(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku()), + LOCATION(RC_LH_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku()), + LOCATION(RC_LH_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(LAKE_HYLIA, {[]{return true;}}), + Entrance(RR_LAKE_HYLIA, {[]{return true;}}), }); - areaTable[LON_LON_RANCH] = Area("Lon Lon Ranch", "Lon Lon Ranch", 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(&Epona, {[]{return Epona || (CanPlay(EponasSong) && IsAdult && AtDay);}}), - EventAccess(&LinksCow, {[]{return LinksCow || (CanPlay(EponasSong) && IsAdult && AtDay);}}), + EventAccess(&logic->FreedEpona, {[]{return logic->FreedEpona || ((logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}}), + EventAccess(&logic->LinksCow, {[]{return logic->LinksCow || (logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}}), }, { //Locations - LocationAccess(SONG_FROM_MALON, {[]{return IsChild && ZeldasLetter && Ocarina && AtDay;}}), - LocationAccess(LLR_GS_TREE, {[]{return IsChild;}}), - LocationAccess(LLR_GS_RAIN_SHED, {[]{return IsChild && AtNight && CanGetNightTimeGS;}}), - LocationAccess(LLR_GS_HOUSE_WINDOW, {[]{return IsChild && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), - LocationAccess(LLR_GS_BACK_WALL, {[]{return IsChild && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), + LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), + LOCATION(RC_LLR_GS_TREE, logic->IsChild), + LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), - Entrance(LLR_TALONS_HOUSE, {[]{return true;}}), - Entrance(LLR_STABLES, {[]{return true;}}), - Entrance(LLR_TOWER, {[]{return true;}}), - Entrance(LLR_GROTTO, {[]{return IsChild;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_LLR_TALONS_HOUSE, {[]{return true;}}), + Entrance(RR_LLR_STABLES, {[]{return true;}}), + Entrance(RR_LLR_TOWER, {[]{return true;}}), + Entrance(RR_LLR_GROTTO, {[]{return logic->IsChild;}}), }); - areaTable[LLR_TALONS_HOUSE] = Area("LLR Talons House", "LLR Talons House", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LLR_TALONS_HOUSE] = Region("LLR Talons House", "LLR Talons House", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(LLR_TALONS_CHICKENS, {[]{return IsChild && AtDay && ZeldasLetter;}}), + LOCATION(RC_LLR_TALONS_CHICKENS, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtDay && logic->HasItem(RG_ZELDAS_LETTER)), }, { //Exits - Entrance(LON_LON_RANCH, {[]{return true;}}), + Entrance(RR_LON_LON_RANCH, {[]{return true;}}), }); - areaTable[LLR_STABLES] = Area("LLR Stables", "LLR Stables", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LLR_STABLES] = Region("LLR Stables", "LLR Stables", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(LLR_STABLES_LEFT_COW, {[]{return CanPlay(EponasSong);}}), - LocationAccess(LLR_STABLES_RIGHT_COW, {[]{return CanPlay(EponasSong);}}), + LOCATION(RC_LLR_STABLES_LEFT_COW, logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_LLR_STABLES_RIGHT_COW, logic->CanUse(RG_EPONAS_SONG)), }, { //Exits - Entrance(LON_LON_RANCH, {[]{return true;}}), + Entrance(RR_LON_LON_RANCH, {[]{return true;}}), }); - areaTable[LLR_TOWER] = Area("LLR Tower", "LLR Tower", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LLR_TOWER] = Region("LLR Tower", "LLR Tower", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(LLR_FREESTANDING_POH, {[]{return IsChild;}}), - LocationAccess(LLR_TOWER_LEFT_COW, {[]{return CanPlay(EponasSong);}}), - LocationAccess(LLR_TOWER_RIGHT_COW, {[]{return CanPlay(EponasSong);}}), + LOCATION(RC_LLR_FREESTANDING_POH, logic->IsChild), + LOCATION(RC_LLR_TOWER_LEFT_COW, logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_LLR_TOWER_RIGHT_COW, logic->CanUse(RG_EPONAS_SONG)), }, { //Exits - Entrance(LON_LON_RANCH, {[]{return true;}}), + Entrance(RR_LON_LON_RANCH, {[]{return true;}}), }); - areaTable[LLR_GROTTO] = Area("LLR Grotto", "LLR Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LLR_GROTTO] = Region("LLR Grotto", "LLR Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(LLR_DEKU_SCRUB_GROTTO_LEFT, {[]{return CanStunDeku;}}), - LocationAccess(LLR_DEKU_SCRUB_GROTTO_RIGHT, {[]{return CanStunDeku;}}), - LocationAccess(LLR_DEKU_SCRUB_GROTTO_CENTER, {[]{return CanStunDeku;}}), + LOCATION(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, logic->CanStunDeku()), + LOCATION(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, logic->CanStunDeku()), + LOCATION(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, logic->CanStunDeku()), + LOCATION(RC_LLR_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(LON_LON_RANCH, {[]{return true;}}), + Entrance(RR_LON_LON_RANCH, {[]{return true;}}), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp index a7f74f83c9b..79057397169 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 @@ -1,86 +1,84 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_IceCavern() { +void RegionTable_Init_IceCavern() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[ICE_CAVERN_ENTRYWAY] = Area("Ice Cavern Entryway", "Ice Cavern", 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(ICE_CAVERN_BEGINNING, {[]{return Dungeon::IceCavern.IsVanilla();}}), - Entrance(ICE_CAVERN_MQ_BEGINNING, {[]{return Dungeon::IceCavern.IsMQ();}}), - Entrance(ZORAS_FOUNTAIN, {[]{return true;}}), + Entrance(RR_ICE_CAVERN_BEGINNING, {[]{return ctx->GetDungeon(ICE_CAVERN)->IsVanilla();}}), + Entrance(RR_ICE_CAVERN_MQ_BEGINNING, {[]{return ctx->GetDungeon(ICE_CAVERN)->IsMQ() && logic->CanUseProjectile();}}), + Entrance(RR_ZORAS_FOUNTAIN, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::IceCavern.IsVanilla()) { - areaTable[ICE_CAVERN_BEGINNING] = Area("Ice Cavern Beginning", "Ice Cavern", ICE_CAVERN, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(ICE_CAVERN)->IsVanilla()) { + areaTable[RR_ICE_CAVERN_BEGINNING] = Region("Ice Cavern Beginning", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(ICE_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(ICE_CAVERN_MAIN, {[]{return Here(ICE_CAVERN_BEGINNING, []{return (CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) || CanUse(RG_MEGATON_HAMMER) || HasExplosives || CanUse(HOOKSHOT) || CanUse(DINS_FIRE);});}}), + 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[ICE_CAVERN_MAIN] = Area("Ice Cavern", "Ice Cavern", 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(&BlueFireAccess, {[]{return BlueFireAccess || (IsAdult && HasBottle);}}), + EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || (logic->IsAdult && logic->HasBottle());}}), }, { //Locations - LocationAccess(ICE_CAVERN_MAP_CHEST, {[]{return BlueFire && IsAdult;}}), - LocationAccess(ICE_CAVERN_COMPASS_CHEST, {[]{return BlueFire;}}), - LocationAccess(ICE_CAVERN_IRON_BOOTS_CHEST, {[]{return BlueFire && (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || CanUse(DINS_FIRE));}}), - LocationAccess(SHEIK_IN_ICE_CAVERN, {[]{return BlueFire && (CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(MEGATON_HAMMER) || CanUse(DINS_FIRE)) && IsAdult;}}), - LocationAccess(ICE_CAVERN_FREESTANDING_POH, {[]{return BlueFire;}}), - LocationAccess(ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, {[]{return HookshotOrBoomerang;}}), - LocationAccess(ICE_CAVERN_GS_HEART_PIECE_ROOM, {[]{return BlueFire && HookshotOrBoomerang;}}), - LocationAccess(ICE_CAVERN_GS_PUSH_BLOCK_ROOM, {[]{return BlueFire && (HookshotOrBoomerang || (LogicIceBlockGS && IsAdult && CanUse(HOVER_BOOTS)));}}), + LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->IsAdult), + LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->BlueFire() && (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire() && (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_DINS_FIRE)) && logic->IsAdult), + LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang()), + LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->BlueFire() && logic->HookshotOrBoomerang()), + LOCATION(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, logic->BlueFire() && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_ICE_BLOCK_GS) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), }, {}); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::IceCavern.IsMQ()) { - areaTable[ICE_CAVERN_MQ_BEGINNING] = Area("Ice Cavern MQ Beginning", "Ice Cavern", ICE_CAVERN, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(ICE_CAVERN)->IsMQ()) { + areaTable[RR_ICE_CAVERN_MQ_BEGINNING] = Region("Ice Cavern MQ Beginning", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&FairyPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), }, {}, { //Exits - Entrance(ICE_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(ICE_CAVERN_MQ_MAP_ROOM, {[]{return CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || CanUse(DINS_FIRE) || (HasExplosives && (CanUse(KOKIRI_SWORD) || CanUse(STICKS) || CanUse(SLINGSHOT) || CanUse(BOW)));}}), - Entrance(ICE_CAVERN_MQ_COMPASS_ROOM, {[]{return IsAdult && BlueFire;}}), - Entrance(ICE_CAVERN_MQ_IRON_BOOTS_REGION, {[]{return BlueFire;}}), + Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return true;}}), + Entrance(RR_ICE_CAVERN_MQ_MAP_ROOM, {[]{return logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_DINS_FIRE) || (logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)));}}), + Entrance(RR_ICE_CAVERN_MQ_COMPASS_ROOM, {[]{return logic->IsAdult && logic->BlueFire();}}), + Entrance(RR_ICE_CAVERN_MQ_IRON_BOOTS_REGION, {[]{return logic->BlueFire();}}), }); - areaTable[ICE_CAVERN_MQ_MAP_ROOM] = Area("Ice Cavern MQ Map Room", "Ice Cavern", 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(&BlueFireAccess, {[]{return BlueFireAccess || (HasBottle && CanJumpslash);}}), + EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || (logic->HasBottle() && logic->CanJumpslash());}}), }, { //Locations - LocationAccess(ICE_CAVERN_MQ_MAP_CHEST, {[]{return BlueFire && (CanJumpslash || HasExplosives || CanUseProjectile);}}), + LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && (logic->CanJumpslash() || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUseProjectile())), }, {}); - areaTable[ICE_CAVERN_MQ_IRON_BOOTS_REGION] = Area("Ice Cavern MQ Iron Boots Region", "Ice Cavern", 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 - LocationAccess(ICE_CAVERN_MQ_IRON_BOOTS_CHEST, {[]{return IsAdult && (CanJumpslash || CanUse(RG_MEGATON_HAMMER));}}), - LocationAccess(SHEIK_IN_ICE_CAVERN, {[]{return IsAdult && (CanJumpslash || CanUse(RG_MEGATON_HAMMER));}}), - LocationAccess(ICE_CAVERN_MQ_GS_ICE_BLOCK, {[]{return CanAdultAttack || CanChildAttack;}}), - LocationAccess(ICE_CAVERN_MQ_GS_SCARECROW, {[]{return CanUse(SCARECROW) || (HoverBoots && CanUse(LONGSHOT)) || (LogicIceMQScarecrow && IsAdult);}}), - //Tricks: (CanUse(SCARECROW) || (HoverBoots && CanUse(LONGSHOT)) || LogicIceMQScarecrow) && IsAdult + LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->IsAdult && (logic->CanJumpslash() || logic->CanUse(RG_MEGATON_HAMMER))), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->IsAdult && (logic->CanJumpslash() || logic->CanUse(RG_MEGATON_HAMMER))), + LOCATION(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, logic->CanAttack()), + LOCATION(RC_ICE_CAVERN_MQ_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_ICE_MQ_SCARECROW) && logic->IsAdult)), + //Tricks: (logic->CanUse(RG_SCARECROW) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_LONGSHOT)) || LogicIceMQScarecrow) && logic->IsAdult }, {}); - areaTable[ICE_CAVERN_MQ_COMPASS_ROOM] = Area("Ice Cavern MQ Compass Room", "Ice Cavern", 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 - LocationAccess(ICE_CAVERN_MQ_COMPASS_CHEST, {[]{return true;}}), - LocationAccess(ICE_CAVERN_MQ_FREESTANDING_POH, {[]{return HasExplosives;}}), - LocationAccess(ICE_CAVERN_MQ_GS_RED_ICE, {[]{return CanPlay(SongOfTime) || LogicIceMQRedIceGS;}}), - //Trick: CanPlay(SongOfTime) || LogicIceMQRedIceGS + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, true), + LOCATION(RC_ICE_CAVERN_MQ_FREESTANDING_POH, logic->HasExplosives()), + LOCATION(RC_ICE_CAVERN_MQ_GS_RED_ICE, logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_ICE_MQ_RED_ICE_GS)), + //Trick: logic->CanUse(RG_SONG_OF_TIME) || LogicIceMQRedIceGS }, {}); } } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_jabujabus_belly.cpp index c8e38bb61ba..26930b84d2c 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 @@ -1,250 +1,249 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_JabuJabusBelly() { +void RegionTable_Init_JabuJabusBelly() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[JABU_JABUS_BELLY_ENTRYWAY] = Area("Jabu Jabus Belly Entryway", "Jabu Jabus Belly", 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(JABU_JABUS_BELLY_BEGINNING, {[]{return Dungeon::JabuJabusBelly.IsVanilla();}}), - Entrance(JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return Dungeon::JabuJabusBelly.IsMQ();}}), - Entrance(ZORAS_FOUNTAIN, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_BEGINNING, {[]{return ctx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla();}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return ctx->GetDungeon(JABU_JABUS_BELLY)->IsMQ();}}), + Entrance(RR_ZORAS_FOUNTAIN, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::JabuJabusBelly.IsVanilla()) { - areaTable[JABU_JABUS_BELLY_BEGINNING] = Area("Jabu Jabus Belly Beginning", "Jabu Jabus Belly", JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla()) { + areaTable[RR_JABU_JABUS_BELLY_BEGINNING] = Region("Jabu Jabus Belly Beginning", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(JABU_JABUS_BELLY_ENTRYWAY, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return CanUseProjectile;}}), + Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return logic->CanUseProjectile();}}), }); - areaTable[JABU_JABUS_BELLY_LIFT_MIDDLE] = Area("Jabu Jabus Belly Lift Middle", "Jabu Jabus Belly", 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(JABU_JABUS_BELLY_BEGINNING, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_LIFT_LOWER, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_NEAR_BOSS_ROOM, {[]{return HasAccessTo(JABU_JABUS_BELLY_LIFT_UPPER) || (LogicJabuBossHover && IsAdult && CanUse(HOVER_BOOTS));}}), + Entrance(RR_JABU_JABUS_BELLY_BEGINNING, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_LOWER, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, {[]{return HasAccessTo(RR_JABU_JABUS_BELLY_LIFT_UPPER) || (ctx->GetTrickOption(RT_JABU_BOSS_HOVER) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}}), }); - areaTable[JABU_JABUS_BELLY_MAIN_UPPER] = Area("Jabu Jabus Belly Main Upper", "Jabu Jabus Belly", 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(JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_BIGOCTO_ROOM, {[]{return Here(JABU_JABUS_BELLY_GREEN_TENTACLE, []{return CanUse(BOOMERANG);});}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_BIGOCTO_ROOM, {[]{return Here(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, []{return logic->CanUse(RG_BOOMERANG);});}}), }); - areaTable[JABU_JABUS_BELLY_MAIN_LOWER] = Area("Jabu Jabus Belly Main Lower", "Jabu Jabus Belly", 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 - LocationAccess(JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, {[]{return HookshotOrBoomerang;}}), - LocationAccess(JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, {[]{return HookshotOrBoomerang;}}), + LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, logic->HookshotOrBoomerang()), + LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, logic->HookshotOrBoomerang()), }, { //Exits - Entrance(JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_SHABOMB_CORRIDOR, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_LOWER_SIDE_ROOM, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_SHABOMB_CORRIDOR, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_LOWER_SIDE_ROOM, {[]{return true;}}), }); - areaTable[JABU_JABUS_BELLY_SHABOMB_CORRIDOR] = Area("Jabu Jabus Belly Shabomb Corridor", "Jabu Jabus Belly", 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(&FairyPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations - LocationAccess(JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, {[]{return true;}}), + LOCATION(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, true), }, { //Exits - Entrance(JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_LIFT_LOWER, {[]{return CanUseProjectile;}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return logic->HasItem(RG_BRONZE_SCALE);}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_LOWER, {[]{return logic->HasItem(RG_BRONZE_SCALE) && logic->CanUseProjectile();}}), }); - areaTable[JABU_JABUS_BELLY_LOWER_SIDE_ROOM] = Area("Jabu Jabus Belly Lower Side Room", "Jabu Jabus Belly", 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(&FairyPot, {[]{return FairyPot || (CanUse(BOOMERANG) || CanUse(HOVER_BOOTS));}}), + EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_HOVER_BOOTS));}}), }, {}, { //Exits - Entrance(JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), }); - areaTable[JABU_JABUS_BELLY_LIFT_LOWER] = Area("Jabu Jabus Belly Lift Lower", "Jabu Jabus Belly", 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 - LocationAccess(JABU_JABUS_BELLY_DEKU_SCRUB, {[]{return (IsChild || CanDive || LogicJabuAlcoveJumpDive || CanUse(IRON_BOOTS)) && CanStunDeku;}}), + LOCATION(RC_JABU_JABUS_BELLY_DEKU_SCRUB, logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || ctx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE) || logic->CanUse(RG_IRON_BOOTS)) && logic->CanStunDeku()), }, { //Exits - Entrance(JABU_JABUS_BELLY_SHABOMB_CORRIDOR, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_SHABOMB_CORRIDOR, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), }); - areaTable[JABU_JABUS_BELLY_FORKED_CORRIDOR] = Area("Jabu Jabus Belly Forked Corridor", "Jabu Jabus Belly", 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(JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_BOOMERANG_ROOM, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_MAP_ROOM, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_COMPASS_ROOM, {[]{return Here(JABU_JABUS_BELLY_MAP_ROOM, []{return CanUse(BOOMERANG);});}}), - Entrance(JABU_JABUS_BELLY_BLUE_TENTACLE, {[]{return Here(JABU_JABUS_BELLY_MAP_ROOM, []{return CanUse(BOOMERANG);});}}), - Entrance(JABU_JABUS_BELLY_GREEN_TENTACLE, {[]{return Here(JABU_JABUS_BELLY_BLUE_TENTACLE, []{return CanUse(BOOMERANG);});}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_BOOMERANG_ROOM, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MAP_ROOM, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_COMPASS_ROOM, {[]{return Here(RR_JABU_JABUS_BELLY_MAP_ROOM, []{return logic->CanUse(RG_BOOMERANG);});}}), + Entrance(RR_JABU_JABUS_BELLY_BLUE_TENTACLE, {[]{return Here(RR_JABU_JABUS_BELLY_MAP_ROOM, []{return logic->CanUse(RG_BOOMERANG);});}}), + Entrance(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, {[]{return Here(RR_JABU_JABUS_BELLY_BLUE_TENTACLE, []{return logic->CanUse(RG_BOOMERANG);});}}), }); - areaTable[JABU_JABUS_BELLY_BOOMERANG_ROOM] = Area("Jabu Jabus Belly Boomerang Room", "Jabu Jabus Belly", 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 - LocationAccess(JABU_JABUS_BELLY_BOOMERANG_CHEST, {[]{return true;}}), + LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, true), }, { //Exits - Entrance(JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), }); - areaTable[JABU_JABUS_BELLY_MAP_ROOM] = Area("Jabu Jabus Belly Map Room", "Jabu Jabus Belly", 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 - LocationAccess(JABU_JABUS_BELLY_MAP_CHEST, {[]{return CanUse(BOOMERANG);}}), + LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->CanUse(RG_BOOMERANG)), }, { //Exits - Entrance(JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), }); - areaTable[JABU_JABUS_BELLY_COMPASS_ROOM] = Area("Jabu Jabus Belly Compass Room", "Jabu Jabus Belly", 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 - LocationAccess(JABU_JABUS_BELLY_COMPASS_CHEST, {[]{return CanAdultAttack || CanChildAttack;}}), + LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanAttack()), }, { //Exits - Entrance(JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), }); - areaTable[JABU_JABUS_BELLY_BLUE_TENTACLE] = Area("Jabu Jabus Belly Blue Tentacle", "Jabu Jabus Belly", 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(JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return Here(JABU_JABUS_BELLY_BLUE_TENTACLE, []{return CanUse(BOOMERANG);});}}), + Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return Here(RR_JABU_JABUS_BELLY_BLUE_TENTACLE, []{return logic->CanUse(RG_BOOMERANG);});}}), }); - areaTable[JABU_JABUS_BELLY_GREEN_TENTACLE] = Area("Jabu Jabus Belly Green Tentacle", "Jabu Jabus Belly", 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(JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return Here(JABU_JABUS_BELLY_GREEN_TENTACLE, []{return CanUse(BOOMERANG);});}}), + Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return Here(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, []{return logic->CanUse(RG_BOOMERANG);});}}), }); - areaTable[JABU_JABUS_BELLY_BIGOCTO_ROOM] = Area("Jabu Jabus Belly Bigocto Room", "Jabu Jabus Belly", 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(JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_ABOVE_BIGOCTO, {[]{return Here(JABU_JABUS_BELLY_BIGOCTO_ROOM, []{return (CanUse(BOOMERANG) || Nuts) && (CanUse(KOKIRI_SWORD) || CanUse(STICKS));});}}), + 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[JABU_JABUS_BELLY_ABOVE_BIGOCTO] = Area("Jabu Jabus Belly Above Bigocto", "Jabu Jabus Belly", 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(&FairyPot, {[]{return true;}}), - EventAccess(&NutPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), + EventAccess(&logic->NutPot, {[]{return true;}}), }, {}, { //Exits - Entrance(JABU_JABUS_BELLY_LIFT_UPPER, {[]{return CanUse(BOOMERANG);}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_UPPER, {[]{return logic->CanUse(RG_BOOMERANG);}}), }); - areaTable[JABU_JABUS_BELLY_LIFT_UPPER] = Area("Jabu Jabus Belly Lift Upper", "Jabu Jabus Belly", 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(JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_LIFT_LOWER, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_LOWER, {[]{return true;}}), }); - areaTable[JABU_JABUS_BELLY_NEAR_BOSS_ROOM] = Area("Jabu Jabus Belly Near Boss Room", "Jabu Jabus Belly", 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 - LocationAccess(JABU_JABUS_BELLY_GS_NEAR_BOSS, {[]{return CanAdultAttack || CanChildAttack;}}), + LOCATION(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, logic->CanAttack()), }, { //Exits - Entrance(JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return CanUse(BOOMERANG) || (LogicJabuNearBossRanged && ((IsAdult && (CanUse(HOOKSHOT) || CanUse(BOW))) || (IsChild && CanUse(SLINGSHOT)))) || (LogicJabuNearBossExplosives && (HasBombchus || (IsAdult && CanUse(HOVER_BOOTS) && Bombs)));}}), + Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && ((logic->IsAdult && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW))) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)))) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_EXPLOSIVES) && (logic->CanUse(RG_BOMBCHU_5) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_BOMB_BAG))));}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::JabuJabusBelly.IsMQ()) { - areaTable[JABU_JABUS_BELLY_MQ_BEGINNING] = Area("Jabu Jabus Belly MQ Beginning", "Jabu Jabus Belly", JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(JABU_JABUS_BELLY)->IsMQ()) { + areaTable[RR_JABU_JABUS_BELLY_MQ_BEGINNING] = Region("Jabu Jabus Belly MQ Beginning", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&NutPot, {[]{return true;}}), + EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LocationAccess(JABU_JABUS_BELLY_MQ_MAP_CHEST, {[]{return CanBlastOrSmash;}}), - LocationAccess(JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, {[]{return IsChild && CanUse(SLINGSHOT);}}), + LOCATION(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)), }, { //Exits - Entrance(JABU_JABUS_BELLY_ENTRYWAY, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_MQ_MAIN, {[]{return Here(JABU_JABUS_BELLY_MQ_BEGINNING, []{return IsChild && CanUse(SLINGSHOT);});}}), + Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_MAIN, {[]{return Here(RR_JABU_JABUS_BELLY_MQ_BEGINNING, []{return logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT);});}}), }); - areaTable[JABU_JABUS_BELLY_MQ_MAIN] = Area("Jabu Jabus Belly MQ Main", "Jabu Jabus Belly", 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 - LocationAccess(JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, {[]{return true;}}), - LocationAccess(JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, {[]{return (IsAdult && (CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT))) || ChildCanAccess(JABU_JABUS_BELLY_MQ_BOSS_AREA);}}), - LocationAccess(JABU_JABUS_BELLY_MQ_COMPASS_CHEST, {[]{return (IsChild || CanDive || CanUse(IRON_BOOTS) || LogicJabuAlcoveJumpDive) && (CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(HOOKSHOT) || HasBombchus || (LogicJabuMQRangJump && CanUse(BOOMERANG)));}}), - LocationAccess(JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, {[]{return CanUse(SLINGSHOT);}}), - LocationAccess(JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, {[]{return CanUse(SLINGSHOT);}}), - LocationAccess(JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, {[]{return true;}}), - LocationAccess(JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MEGATON_HAMMER) || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(STICKS) || Bombs;}}), - LocationAccess(JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, {[]{return CanPlay(SongOfTime) || (LogicJabuMQSoTGS && IsChild && CanUse(BOOMERANG));}}), - //Trick: CanPlay(SongOfTime) || (LogicJabuMQSoTGS && IsChild && CanUse(BOOMERANG)) + LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))) || ChildCanAccess(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || + ctx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE)) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG)))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_VINES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_NEAR_SWITCHES_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_BOMB_BAG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_JABU_MQ_SOT_GS) && logic->IsChild && logic->CanUse(RG_BOOMERANG))), + //Trick: logic->CanUse(RG_SONG_OF_TIME) || (LogicJabuMQSoTGS && logic->IsChild && logic->CanUse(RG_BOOMERANG)) }, { //Exits - Entrance(JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_MQ_DEPTHS, {[]{return HasExplosives && CanUse(SLINGSHOT) && CanUse(BOOMERANG);}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_DEPTHS, {[]{return logic->HasExplosives() && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanUse(RG_BOOMERANG);}}), }); - areaTable[JABU_JABUS_BELLY_MQ_DEPTHS] = Area("Jabu Jabus Belly MQ Depths", "Jabu Jabus Belly", 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 - LocationAccess(JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, {[]{return true;}}), - LocationAccess(JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, {[]{return Sticks || CanUse(DINS_FIRE);}}), - LocationAccess(JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, {[]{return (LogicLensJabuMQ || CanUse(LENS_OF_TRUTH)) || Here(JABU_JABUS_BELLY_MQ_MAIN, []{return IsAdult && CanUse(HOVER_BOOTS) && CanUse(HOOKSHOT);});}}), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, logic->HasItem(RG_BRONZE_SCALE) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, (ctx->GetTrickOption(RT_LENS_JABU_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) || Here(RR_JABU_JABUS_BELLY_MQ_MAIN, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_HOOKSHOT);})), }, { //Exits - Entrance(JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_MQ_BOSS_AREA, {[]{return Sticks || (CanUse(DINS_FIRE) && KokiriSword);}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, {[]{return logic->CanUse(RG_STICKS) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_KOKIRI_SWORD));}}), }); - areaTable[JABU_JABUS_BELLY_MQ_BOSS_AREA] = Area("Jabu Jabus Belly MQ Boss Area", "Jabu Jabus Belly", 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(&FairyPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations - LocationAccess(JABU_JABUS_BELLY_MQ_COW, {[]{return CanPlay(EponasSong);}}), - LocationAccess(JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, {[]{return CanUse(SLINGSHOT);}}), - LocationAccess(JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, {[]{return CanUse(BOOMERANG) || (LogicJabuNearBossRanged && CanUse(HOOKSHOT));}}), + LOCATION(RC_JABU_JABUS_BELLY_MQ_COW, logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT))), }, { //Exits - Entrance(JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return CanUse(SLINGSHOT);}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT);}}), }); } /*--------------------------- | BOSS ROOM | ---------------------------*/ - areaTable[JABU_JABUS_BELLY_BOSS_ENTRYWAY] = - Area("Jabu Jabus Belly Boss Entryway", "Jabu Jabus Belly", JABU_JABUS_BELLY, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY] = + Region("Jabu Jabus Belly Boss Entryway", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(JABU_JABUS_BELLY_NEAR_BOSS_ROOM, { [] { return Dungeon::JabuJabusBelly.IsVanilla(); } }), - Entrance(JABU_JABUS_BELLY_MQ_BOSS_AREA, { [] { return Dungeon::JabuJabusBelly.IsMQ(); } }), - Entrance(JABU_JABUS_BELLY_BOSS_ROOM, { [] { return true; } }), + Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, { [] { return ctx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla(); } }), + Entrance(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, { [] { return ctx->GetDungeon(JABU_JABUS_BELLY)->IsMQ(); } }), + Entrance(RR_JABU_JABUS_BELLY_BOSS_ROOM, { [] { return true; } }), }); - areaTable[JABU_JABUS_BELLY_BOSS_ROOM] = - Area("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", NONE, NO_DAY_NIGHT_CYCLE, + areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = + Region("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", {}, NO_DAY_NIGHT_CYCLE, { // Events //todo: add pot kill trick - EventAccess(&JabuJabusBellyClear, - { [] { return JabuJabusBellyClear || (CanUse(BOOMERANG) && CanJumpslash); } }), + EventAccess(&logic->JabuJabusBellyClear, + { [] { return logic->JabuJabusBellyClear || (logic->HasBossSoul(RG_BARINADE_SOUL) && (logic->CanUse(RG_BOOMERANG) && logic->CanJumpslash())); } }), }, { // Locations - LocationAccess(JABU_JABUS_BELLY_BARINADE_HEART, { [] { return JabuJabusBellyClear; } }), - LocationAccess(BARINADE, { [] { return JabuJabusBellyClear; } }), + LOCATION(RC_JABU_JABUS_BELLY_BARINADE_HEART, logic->JabuJabusBellyClear), + LOCATION(RC_BARINADE, logic->JabuJabusBellyClear), }, { // Exits - Entrance(JABU_JABUS_BELLY_BOSS_ENTRYWAY, { [] { return false; } }), - Entrance(ZORAS_FOUNTAIN, { [] { return JabuJabusBellyClear; } }), + Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(RR_ZORAS_FOUNTAIN, { [] { return logic->JabuJabusBellyClear; } }, false), }); } 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 5660104f7b6..d5be78c6b40 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp @@ -1,286 +1,287 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" +#include "../../entrance.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_Kakariko() { - areaTable[KAKARIKO_VILLAGE] = Area("Kakariko Village", "Kakariko Village", 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(&CojiroAccess, {[]{return CojiroAccess || (IsAdult && WakeUpAdultTalon);}}), - EventAccess(&BugRock, {[]{return true;}}), - EventAccess(&KakarikoVillageGateOpen, {[]{return KakarikoVillageGateOpen || (IsChild && (ZeldasLetter || OpenKakariko.Is(OPENKAKARIKO_OPEN)));}}), + EventAccess(&logic->BugRock, {[]{return true;}}), + EventAccess(&logic->KakarikoVillageGateOpen, {[]{return logic->KakarikoVillageGateOpen || (logic->IsChild && (logic->HasItem(RG_ZELDAS_LETTER) || ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN)));}}), }, { //Locations - LocationAccess(SHEIK_IN_KAKARIKO, {[]{return IsAdult && ForestMedallion && FireMedallion && WaterMedallion;}}), - LocationAccess(KAK_ANJU_AS_CHILD, {[]{return IsChild && AtDay;}}), - LocationAccess(KAK_ANJU_AS_ADULT, {[]{return IsAdult && AtDay;}}), - LocationAccess(KAK_TRADE_POCKET_CUCCO, {[]{return IsAdult && AtDay && PocketEgg && WakeUpAdultTalon;}}), - LocationAccess(KAK_GS_HOUSE_UNDER_CONSTRUCTION, {[]{return IsChild && AtNight && CanGetNightTimeGS;}}), - LocationAccess(KAK_GS_SKULLTULA_HOUSE, {[]{return IsChild && AtNight && CanGetNightTimeGS;}}), - LocationAccess(KAK_GS_GUARDS_HOUSE, {[]{return IsChild && AtNight && CanGetNightTimeGS;}}), - LocationAccess(KAK_GS_TREE, {[]{return IsChild && AtNight && CanGetNightTimeGS;}}), - LocationAccess(KAK_GS_WATCHTOWER, {[]{return IsChild && (Slingshot || HasBombchus || CanUse(BOW) || CanUse(LONGSHOT) || (LogicKakarikoTowerGS && CanJumpslash)) && AtNight && CanGetNightTimeGS;}}), + LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION)), + LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay), + LOCATION(RC_KAK_ANJU_AS_ADULT, logic->IsAdult && logic->AtDay), + LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && (logic->CanUse(RG_POCKET_EGG) && logic->WakeUpAdultTalon)), + LOCATION(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslash())) && logic->AtNight && logic->CanGetNightTimeGS()), }, { //Exits - Entrance(HYRULE_FIELD, {[]{return true;}}), - Entrance(KAK_CARPENTER_BOSS_HOUSE, {[]{return true;}}), - Entrance(KAK_HOUSE_OF_SKULLTULA, {[]{return true;}}), - Entrance(KAK_IMPAS_HOUSE, {[]{return true;}}), - Entrance(KAK_WINDMILL, {[]{return true;}}), - Entrance(KAK_BAZAAR, {[]{return IsAdult && AtDay;}}), - Entrance(KAK_SHOOTING_GALLERY, {[]{return IsAdult && AtDay;}}), - Entrance(BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return DrainWell && (IsChild || ShuffleDungeonEntrances.IsNot(SHUFFLEDUNGEONS_OFF));}}), - Entrance(KAK_POTION_SHOP_FRONT, {[]{return AtDay || IsChild;}}), - Entrance(KAK_REDEAD_GROTTO, {[]{return CanOpenBombGrotto;}}), - Entrance(KAK_IMPAS_LEDGE, {[]{return (IsChild && AtDay) || CanUse(HOOKSHOT) || (IsAdult && LogicVisibleCollision);}}), - Entrance(KAK_ROOFTOP, {[]{return CanUse(HOOKSHOT) || (LogicManOnRoof && (IsAdult || AtDay || Slingshot || HasBombchus || CanUse(BOW) || CanUse(LONGSHOT)));}}), - Entrance(KAK_IMPAS_ROOFTOP, {[]{return CanUse(HOOKSHOT) || (LogicKakarikoRooftopGS && CanUse(HOVER_BOOTS));}}), - Entrance(THE_GRAVEYARD, {[]{return true;}}), - Entrance(KAK_BEHIND_GATE, {[]{return IsAdult || (KakarikoVillageGateOpen);}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_KAK_CARPENTER_BOSS_HOUSE, {[]{return true;}}), + Entrance(RR_KAK_HOUSE_OF_SKULLTULA, {[]{return true;}}), + Entrance(RR_KAK_IMPAS_HOUSE, {[]{return true;}}), + Entrance(RR_KAK_WINDMILL, {[]{return true;}}), + Entrance(RR_KAK_BAZAAR, {[]{return logic->IsAdult && logic->AtDay;}}), + Entrance(RR_KAK_SHOOTING_GALLERY, {[]{return logic->IsAdult && logic->AtDay;}}), + Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return logic->DrainWell && (logic->IsChild || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF));}}), + Entrance(RR_KAK_POTION_SHOP_FRONT, {[]{return logic->AtDay || logic->IsChild;}}), + Entrance(RR_KAK_REDEAD_GROTTO, {[]{return logic->CanOpenBombGrotto();}}), + Entrance(RR_KAK_IMPAS_LEDGE, {[]{return (logic->IsChild && logic->AtDay) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && ctx->GetTrickOption(RT_VISIBLE_COLLISION));}}), + Entrance(RR_KAK_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && (logic->IsAdult || logic->AtDay || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT)));}}), + Entrance(RR_KAK_IMPAS_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_ROOFTOP_GS) && logic->CanUse(RG_HOVER_BOOTS));}}), + Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), + Entrance(RR_KAK_BEHIND_GATE, {[]{return logic->IsAdult || (logic->KakarikoVillageGateOpen);}}), }); - areaTable[KAK_IMPAS_LEDGE] = Area("Kak Impas Ledge", "Kakariko Village", 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(KAK_IMPAS_HOUSE_BACK, {[]{return true;}}), - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAK_IMPAS_HOUSE_BACK, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[KAK_IMPAS_ROOFTOP] = Area("Kak Impas Rooftop", "Kakariko Village", 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 - LocationAccess(KAK_GS_ABOVE_IMPAS_HOUSE, {[]{return IsAdult && AtNight && CanGetNightTimeGS && (CanJumpslash || CanUseProjectile);}}), + LOCATION(RC_KAK_GS_ABOVE_IMPAS_HOUSE, logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS() && (logic->CanJumpslash() || logic->CanUseProjectile())), }, { //Exits - Entrance(KAK_IMPAS_LEDGE, {[]{return true;}}), - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAK_IMPAS_LEDGE, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[KAK_ROOFTOP] = Area("Kak Rooftop", "Kakariko Village", KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_ROOFTOP] = Region("Kak Rooftop", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KAK_MAN_ON_ROOF, {[]{return true;}}), + LOCATION(RC_KAK_MAN_ON_ROOF, true), }, { //Exits - Entrance(KAK_BACKYARD, {[]{return true;}}), + Entrance(RR_KAK_BACKYARD, {[]{return true;}}), }); - areaTable[KAK_BACKYARD] = Area("Kak Backyard", "Kakariko Village", KAKARIKO_VILLAGE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KAK_BACKYARD] = Region("Kak Backyard", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), - Entrance(KAK_OPEN_GROTTO, {[]{return true;}}), - Entrance(KAK_ODD_POTION_BUILDING, {[]{return IsAdult;}}), - Entrance(KAK_POTION_SHOP_BACK, {[]{return IsAdult && AtDay;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAK_OPEN_GROTTO, {[]{return true;}}), + Entrance(RR_KAK_ODD_POTION_BUILDING, {[]{return logic->IsAdult;}}), + Entrance(RR_KAK_POTION_SHOP_BACK, {[]{return logic->IsAdult && logic->AtDay;}}), }); - areaTable[KAK_CARPENTER_BOSS_HOUSE] = Area("Kak Carpenter Boss House", "Kak Carpenter Boss House", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_KAK_CARPENTER_BOSS_HOUSE] = Region("Kak Carpenter Boss House", "Kak Carpenter Boss House", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&WakeUpAdultTalon, {[]{return WakeUpAdultTalon || (IsAdult && PocketEgg);}}), + EventAccess(&logic->WakeUpAdultTalon, {[]{return logic->IsAdult && logic->CanUse(RG_POCKET_EGG);}}), }, {}, { //Exits - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[KAK_HOUSE_OF_SKULLTULA] = Area("Kak House of Skulltula", "Kak House of Skulltula", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_HOUSE_OF_SKULLTULA] = Region("Kak House of Skulltula", "Kak House of Skulltula", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KAK_10_GOLD_SKULLTULA_REWARD, {[]{return GoldSkulltulaTokens >= 10;}}), - LocationAccess(KAK_20_GOLD_SKULLTULA_REWARD, {[]{return GoldSkulltulaTokens >= 20;}}), - LocationAccess(KAK_30_GOLD_SKULLTULA_REWARD, {[]{return GoldSkulltulaTokens >= 30;}}), - LocationAccess(KAK_40_GOLD_SKULLTULA_REWARD, {[]{return GoldSkulltulaTokens >= 40;}}), - LocationAccess(KAK_50_GOLD_SKULLTULA_REWARD, {[]{return GoldSkulltulaTokens >= 50;}}), - LocationAccess(KAK_100_GOLD_SKULLTULA_REWARD, {[]{return GoldSkulltulaTokens >= 100;}}) + LOCATION(RC_KAK_10_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 10), + LOCATION(RC_KAK_20_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 20), + LOCATION(RC_KAK_30_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 30), + LOCATION(RC_KAK_40_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 40), + LOCATION(RC_KAK_50_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 50), + LOCATION(RC_KAK_100_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 100) }, { //Exits - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[KAK_IMPAS_HOUSE] = Area("Kak Impas House", "Kak Impas House", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KAK_IMPAS_HOUSE] = Region("Kak Impas House", "Kak Impas House", {}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_KAK_IMPAS_HOUSE_COW, logic->CanUse(RG_EPONAS_SONG)) + }, { //Exits - Entrance(KAK_IMPAS_HOUSE_NEAR_COW, {[]{return true;}}), - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[KAK_IMPAS_HOUSE_BACK] = Area("Kak Impas House Back", "Kak Impas House", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_IMPAS_HOUSE_BACK] = Region("Kak Impas House Back", "Kak Impas House", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KAK_IMPAS_HOUSE_FREESTANDING_POH, {[]{return true;}}), + LOCATION(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, true), + LOCATION(RC_KAK_IMPAS_HOUSE_COW, logic->CanUse(RG_EPONAS_SONG)) }, { //Exits - Entrance(KAK_IMPAS_LEDGE, {[]{return true;}}), - Entrance(KAK_IMPAS_HOUSE_NEAR_COW, {[]{return true;}}), + Entrance(RR_KAK_IMPAS_LEDGE, {[]{return true;}}), }); - areaTable[KAK_IMPAS_HOUSE_NEAR_COW] = Area("Kak Impas House Near Cow", "Kak Impas House", NONE, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LocationAccess(KAK_IMPAS_HOUSE_COW, {[]{return CanPlay(EponasSong);}}), - }, {}); - - areaTable[KAK_WINDMILL] = Area("Kak Windmill", "Windmill and Dampes Grave", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_KAK_WINDMILL] = Region("Kak Windmill", "Windmill and Dampes Grave", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DrainWell, {[]{return DrainWell || (IsChild && CanPlay(SongOfStorms));}}), + EventAccess(&logic->DrainWell, {[]{return logic->DrainWell || (logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS));}}), }, { //Locations - LocationAccess(KAK_WINDMILL_FREESTANDING_POH, {[]{return CanUse(BOOMERANG) || DampesWindmillAccess || (IsAdult && LogicAdultWindmillPoH) || (IsChild && CanJumpslash && LogicChildWindmillPoH);}}), + LOCATION(RC_KAK_WINDMILL_FREESTANDING_POH, logic->CanUse(RG_BOOMERANG) || logic->DampesWindmillAccess || (logic->IsAdult && ctx->GetTrickOption(RT_KAK_ADULT_WINDMILL_POH)) || (logic->IsChild && logic->CanJumpslash() && ctx->GetTrickOption(RT_KAK_CHILD_WINDMILL_POH))), //PoH as child not added to trick options yet (needs uncommenting in randomizer_tricks.cpp) - LocationAccess(SONG_FROM_WINDMILL, {[]{return IsAdult && Ocarina;}}), + LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA)), }, { //Exits - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[KAK_BAZAAR] = Area("Kak Bazaar", "Kak Bazaar", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_BAZAAR] = Region("Kak Bazaar", "Kak Bazaar", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KAK_BAZAAR_ITEM_1, {[]{return true;}}), - LocationAccess(KAK_BAZAAR_ITEM_2, {[]{return true;}}), - LocationAccess(KAK_BAZAAR_ITEM_3, {[]{return true;}}), - LocationAccess(KAK_BAZAAR_ITEM_4, {[]{return true;}}), - LocationAccess(KAK_BAZAAR_ITEM_5, {[]{return true;}}), - LocationAccess(KAK_BAZAAR_ITEM_6, {[]{return true;}}), - LocationAccess(KAK_BAZAAR_ITEM_7, {[]{return true;}}), - LocationAccess(KAK_BAZAAR_ITEM_8, {[]{return true;}}), + LOCATION(RC_KAK_BAZAAR_ITEM_1, true), + LOCATION(RC_KAK_BAZAAR_ITEM_2, true), + LOCATION(RC_KAK_BAZAAR_ITEM_3, true), + LOCATION(RC_KAK_BAZAAR_ITEM_4, true), + LOCATION(RC_KAK_BAZAAR_ITEM_5, true), + LOCATION(RC_KAK_BAZAAR_ITEM_6, true), + LOCATION(RC_KAK_BAZAAR_ITEM_7, true), + LOCATION(RC_KAK_BAZAAR_ITEM_8, true), }, { //Exits - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[KAK_SHOOTING_GALLERY] = Area("Kak Shooting Gallery", "Kak Shooting Gallery", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_SHOOTING_GALLERY] = Region("Kak Shooting Gallery", "Kak Shooting Gallery", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KAK_SHOOTING_GALLERY_REWARD, {[]{return IsAdult && Bow;}}), + LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), }, { //Exits - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[KAK_POTION_SHOP_FRONT] = Area("Kak Potion Shop Front", "Kak Potion Shop", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_POTION_SHOP_FRONT] = Region("Kak Potion Shop Front", "Kak Potion Shop", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KAK_POTION_SHOP_ITEM_1, {[]{return IsAdult;}}), - LocationAccess(KAK_POTION_SHOP_ITEM_2, {[]{return IsAdult;}}), - LocationAccess(KAK_POTION_SHOP_ITEM_3, {[]{return IsAdult;}}), - LocationAccess(KAK_POTION_SHOP_ITEM_4, {[]{return IsAdult;}}), - LocationAccess(KAK_POTION_SHOP_ITEM_5, {[]{return IsAdult;}}), - LocationAccess(KAK_POTION_SHOP_ITEM_6, {[]{return IsAdult;}}), - LocationAccess(KAK_POTION_SHOP_ITEM_7, {[]{return IsAdult;}}), - LocationAccess(KAK_POTION_SHOP_ITEM_8, {[]{return IsAdult;}}), + LOCATION(RC_KAK_POTION_SHOP_ITEM_1, logic->IsAdult), + LOCATION(RC_KAK_POTION_SHOP_ITEM_2, logic->IsAdult), + LOCATION(RC_KAK_POTION_SHOP_ITEM_3, logic->IsAdult), + LOCATION(RC_KAK_POTION_SHOP_ITEM_4, logic->IsAdult), + LOCATION(RC_KAK_POTION_SHOP_ITEM_5, logic->IsAdult), + LOCATION(RC_KAK_POTION_SHOP_ITEM_6, logic->IsAdult), + LOCATION(RC_KAK_POTION_SHOP_ITEM_7, logic->IsAdult), + LOCATION(RC_KAK_POTION_SHOP_ITEM_8, logic->IsAdult), }, { //Exits - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), - Entrance(KAK_POTION_SHOP_BACK, {[]{return IsAdult;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAK_POTION_SHOP_BACK, {[]{return logic->IsAdult;}}), }); - areaTable[KAK_POTION_SHOP_BACK] = Area("Kak Potion Shop Back", "Kak Potion Shop", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KAK_POTION_SHOP_BACK] = Region("Kak Potion Shop Back", "Kak Potion Shop", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(KAK_BACKYARD, {[]{return IsAdult;}}), - Entrance(KAK_POTION_SHOP_FRONT, {[]{return true;}}), + Entrance(RR_KAK_BACKYARD, {[]{return logic->IsAdult;}}), + Entrance(RR_KAK_POTION_SHOP_FRONT, {[]{return true;}}), }); - areaTable[KAK_ODD_POTION_BUILDING] = Area("Kak Granny's Potion Shop", "Kak Granny's Potion Shop", NONE, NO_DAY_NIGHT_CYCLE, { - //Events - EventAccess(&OddPoulticeAccess, {[]{return OddPoulticeAccess || (IsAdult && (OddMushroomAccess || (OddMushroom && DisableTradeRevert)));}}), - }, { - LocationAccess(KAK_TRADE_ODD_MUSHROOM, {[]{return IsAdult && OddMushroom;}}), - LocationAccess(KAK_GRANNYS_SHOP, {[]{return IsAdult && OddMushroom && AdultsWallet;}}), - }, { - //Exits - Entrance(KAK_BACKYARD, {[]{return true;}}), - }); + areaTable[RR_KAK_ODD_POTION_BUILDING] = + Region("Kak Granny's Potion Shop", "Kak Granny's Potion Shop", {}, NO_DAY_NIGHT_CYCLE, {}, + // RANDOTODO blue pot access + { + LOCATION(RC_KAK_TRADE_ODD_MUSHROOM, logic->IsAdult && logic->CanUse(RG_ODD_MUSHROOM)), + LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && (logic->CanUse(RG_ODD_MUSHROOM) || logic->TradeQuestStep(RG_ODD_MUSHROOM))), + }, + { + // Exits + Entrance(RR_KAK_BACKYARD, { [] { return true; } }), + }); - areaTable[KAK_REDEAD_GROTTO] = Area("Kak Redead Grotto", "Kak Redead Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KAK_REDEAD_GROTTO] = Region("Kak Redead Grotto", "Kak Redead Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KAK_REDEAD_GROTTO_CHEST, {[]{return CanUse(STICKS) || CanUse(KOKIRI_SWORD) || CanUse(DINS_FIRE) || CanUse(MEGATON_HAMMER) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), + 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)), }, { //Exits - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[KAK_OPEN_GROTTO] = Area("Kak Open Grotto", "Kak Open Grotto", NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_KAK_OPEN_GROTTO] = Region("Kak Open Grotto", "Kak Open Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(KAK_OPEN_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(KAK_OPEN_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_KAK_OPEN_GROTTO_CHEST, true), + LOCATION(RC_KAK_OPEN_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(KAK_BACKYARD, {[]{return true;}}), + Entrance(RR_KAK_BACKYARD, {[]{return true;}}), }); - areaTable[THE_GRAVEYARD] = Area("The Graveyard", "The Graveyard", THE_GRAVEYARD, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_THE_GRAVEYARD] = Region("The Graveyard", "The Graveyard", {RA_THE_GRAVEYARD}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&ButterflyFairy, {[]{return ButterflyFairy || (CanUse(STICKS) && AtDay);}}), - EventAccess(&BeanPlantFairy, {[]{return BeanPlantFairy || (CanPlantBean(THE_GRAVEYARD) && CanPlay(SongOfStorms));}}), - EventAccess(&BugRock, {[]{return true;}}), + EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_THE_GRAVEYARD) && logic->CanUse(RG_SONG_OF_STORMS));}}), + EventAccess(&logic->BugRock, {[]{return true;}}), }, { //Locations - LocationAccess(GRAVEYARD_FREESTANDING_POH, {[]{return (IsAdult && CanPlantBean(THE_GRAVEYARD)) || CanUse(LONGSHOT) || (LogicGraveyardPoH && CanUse(BOOMERANG));}}), - LocationAccess(GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, {[]{return IsChild && AtNight;}}), //TODO: This needs to change - LocationAccess(GRAVEYARD_GS_WALL, {[]{return IsChild && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), - LocationAccess(GRAVEYARD_GS_BEAN_PATCH, {[]{return CanPlantBugs && CanChildAttack;}}), + LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtNight), //TODO: This needs to change + LOCATION(RC_GRAVEYARD_GS_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), }, { //Exits - Entrance(GRAVEYARD_SHIELD_GRAVE, {[]{return IsAdult || AtNight;}}), - Entrance(GRAVEYARD_COMPOSERS_GRAVE, {[]{return CanPlay(ZeldasLullaby);}}), - Entrance(GRAVEYARD_HEART_PIECE_GRAVE, {[]{return IsAdult || AtNight;}}), - Entrance(GRAVEYARD_DAMPES_GRAVE, {[]{return IsAdult;}}), - Entrance(GRAVEYARD_DAMPES_HOUSE, {[]{return IsAdult || AtDampeTime;}}), //TODO: This needs to be handled - Entrance(KAKARIKO_VILLAGE, {[]{return true;}}), - Entrance(GRAVEYARD_WARP_PAD_REGION, {[]{return false;}}), + Entrance(RR_GRAVEYARD_SHIELD_GRAVE, {[]{return logic->IsAdult || logic->AtNight;}}), + Entrance(RR_GRAVEYARD_COMPOSERS_GRAVE, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}), + Entrance(RR_GRAVEYARD_HEART_PIECE_GRAVE, {[]{return logic->IsAdult || logic->AtNight;}}), + Entrance(RR_GRAVEYARD_DAMPES_GRAVE, {[]{return logic->IsAdult;}}), + Entrance(RR_GRAVEYARD_DAMPES_HOUSE, {[]{return logic->IsAdult /*|| logic->AtDampeTime*/;}}), //TODO: This needs to be handled in ToD rework + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_GRAVEYARD_WARP_PAD_REGION, {[]{return false;}}), }); - areaTable[GRAVEYARD_SHIELD_GRAVE] = Area("Graveyard Shield Grave", "Graveyard Shield Grave", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GRAVEYARD_SHIELD_GRAVE] = Region("Graveyard Shield Grave", "Graveyard Shield Grave", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GRAVEYARD_SHIELD_GRAVE_CHEST, {[]{return true;}}), + LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, true), //Free Fairies }, { //Exits - Entrance(THE_GRAVEYARD, {[]{return true;}}), + Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), }); - areaTable[GRAVEYARD_HEART_PIECE_GRAVE] = Area("Graveyard Heart Piece Grave", "Graveyard Heart Piece Grave", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GRAVEYARD_HEART_PIECE_GRAVE] = Region("Graveyard Heart Piece Grave", "Graveyard Heart Piece Grave", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GRAVEYARD_HEART_PIECE_GRAVE_CHEST, {[]{return CanPlay(SunsSong);}}), + LOCATION(RC_GRAVEYARD_HEART_PIECE_GRAVE_CHEST, logic->CanUse(RG_SUNS_SONG)), }, { //Exits - Entrance(THE_GRAVEYARD, {[]{return true;}}), + Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), }); - areaTable[GRAVEYARD_COMPOSERS_GRAVE] = Area("Graveyard Composers Grave", "Graveyard Composers Grave", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_GRAVEYARD_COMPOSERS_GRAVE] = Region("Graveyard Composers Grave", "Graveyard Composers Grave", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(GRAVEYARD_COMPOSERS_GRAVE_CHEST, {[]{return HasFireSource;}}), - LocationAccess(SONG_FROM_COMPOSERS_GRAVE, {[]{return CanUseProjectile || CanJumpslash || CanUse(MEGATON_HAMMER);}}), + LOCATION(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, logic->HasFireSource()), + LOCATION(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, logic->CanUseProjectile() || logic->CanJumpslash() || logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits - Entrance(THE_GRAVEYARD, {[]{return true;}}), + Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), }); - areaTable[GRAVEYARD_DAMPES_GRAVE] = Area("Graveyard Dampes Grave", "Windmill and Dampes Grave", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_GRAVEYARD_DAMPES_GRAVE] = Region("Graveyard Dampes Grave", "Windmill and Dampes Grave", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&NutPot, {[]{return true;}}), - EventAccess(&DampesWindmillAccess, {[]{return DampesWindmillAccess || (IsAdult && CanPlay(SongOfTime));}}), + EventAccess(&logic->NutPot, {[]{return true;}}), + EventAccess(&logic->DampesWindmillAccess, {[]{return logic->DampesWindmillAccess || (logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME));}}), }, { //Locations - LocationAccess(GRAVEYARD_HOOKSHOT_CHEST, {[]{return true;}}), - LocationAccess(GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, {[]{return IsAdult || LogicChildDampeRacePoH;}}), + LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, true), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, logic->IsAdult || ctx->GetTrickOption(RT_GY_CHILD_DAMPE_RACE_POH)), }, { //Exits - Entrance(THE_GRAVEYARD, {[]{return true;}}), - Entrance(KAK_WINDMILL, {[]{return IsAdult && CanPlay(SongOfTime);}}), + Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), + Entrance(RR_KAK_WINDMILL, {[]{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}}, false), }); - areaTable[GRAVEYARD_DAMPES_HOUSE] = Area("Graveyard Dampes House", "Graveyard Dampes House", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GRAVEYARD_DAMPES_HOUSE] = Region("Graveyard Dampes House", "Graveyard Dampes House", {}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DAMPE_HINT, logic->IsAdult), + }, { //Exits - Entrance(THE_GRAVEYARD, {[]{return true;}}), + Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), }); - areaTable[GRAVEYARD_WARP_PAD_REGION] = Area("Graveyard Warp Pad Region", "Graveyard", 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(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), }, { //Locations - LocationAccess(GRAVEYARD_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_GRAVEYARD_GOSSIP_STONE, true), }, { //Exits - Entrance(THE_GRAVEYARD, {[]{return true;}}), - Entrance(SHADOW_TEMPLE_ENTRYWAY, {[]{return CanUse(DINS_FIRE) || (LogicShadowFireArrowEntry && IsAdult && CanUse(FIRE_ARROWS));}}), + Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_GY_SHADOW_FIRE_ARROWS) && logic->IsAdult && logic->CanUse(RG_FIRE_ARROWS));}}), }); - areaTable[KAK_BEHIND_GATE] = Area("Kak Behind Gate", "Kakariko Village", 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(KAKARIKO_VILLAGE, {[]{return IsAdult || LogicVisibleCollision || KakarikoVillageGateOpen || OpenKakariko.Is(OPENKAKARIKO_OPEN);}}), - Entrance(DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return logic->IsAdult || ctx->GetTrickOption(RT_VISIBLE_COLLISION) || logic->KakarikoVillageGateOpen || ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}}), + Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_lost_woods.cpp index 27d3cecbe02..34b16a50639 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 @@ -1,250 +1,263 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" +#include "../../entrance.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_LostWoods() { - areaTable[KOKIRI_FOREST] = Area("Kokiri Forest", "Kokiri Forest", 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(&BeanPlantFairy, {[]{return BeanPlantFairy || (CanPlantBean(KOKIRI_FOREST) && CanPlay(SongOfStorms));}}), - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairyWithoutSuns;}}), - EventAccess(&ShowedMidoSwordAndShield, {[]{return ShowedMidoSwordAndShield || (IsChild && KokiriSword && DekuShield);}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_KOKIRI_FOREST) && logic->CanUse(RG_SONG_OF_STORMS));}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), + EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}), }, { //Locations - LocationAccess(KF_KOKIRI_SWORD_CHEST, {[]{return IsChild;}}), - LocationAccess(KF_GS_KNOW_IT_ALL_HOUSE, {[]{return IsChild && CanChildAttack && AtNight && (HasNightStart || CanLeaveForest || CanPlay(SunsSong)) && CanGetNightTimeGS;}}), - LocationAccess(KF_GS_BEAN_PATCH, {[]{return CanPlantBugs && CanChildAttack;}}), - LocationAccess(KF_GS_HOUSE_OF_TWINS, {[]{return IsAdult && AtNight && (HookshotOrBoomerang || (LogicAdultKokiriGS && CanUse(HOVER_BOOTS))) && CanGetNightTimeGS;}}), - LocationAccess(KF_GOSSIP_STONE, {[]{return true;}}), - }, { - //Exits - Entrance(KF_LINKS_HOUSE, {[]{return true;}}), - Entrance(KF_MIDOS_HOUSE, {[]{return true;}}), - Entrance(KF_SARIAS_HOUSE, {[]{return true;}}), - Entrance(KF_HOUSE_OF_TWINS, {[]{return true;}}), - Entrance(KF_KNOW_IT_ALL_HOUSE, {[]{return true;}}), - Entrance(KF_KOKIRI_SHOP, {[]{return true;}}), - Entrance(KF_OUTSIDE_DEKU_TREE, {[]{return IsAdult || OpenForest.Is(OPENFOREST_OPEN) || ShowedMidoSwordAndShield;}}), - Entrance(THE_LOST_WOODS, {[]{return true;}}), - Entrance(LW_BRIDGE_FROM_FOREST, {[]{return IsAdult || OpenForest.IsNot(OPENFOREST_CLOSED) || DekuTreeClear;}}), - Entrance(KF_STORMS_GROTTO, {[]{return CanOpenStormGrotto;}}), - }); - - areaTable[KF_OUTSIDE_DEKU_TREE] = Area("KF Outside Deku Tree", "Kokiri Forest", KOKIRI_FOREST, NO_DAY_NIGHT_CYCLE, { + LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild), + LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && logic->AtNight && (/*TODO: HasNightStart ||*/ logic->CanLeaveForest() || logic->CanUse(RG_SUNS_SONG)) && logic->CanGetNightTimeGS()), + LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && logic->AtNight && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()), + LOCATION(RC_KF_GOSSIP_STONE, true), + }, { + //Exits + Entrance(RR_KF_LINKS_HOUSE, {[]{return true;}}), + Entrance(RR_KF_MIDOS_HOUSE, {[]{return true;}}), + Entrance(RR_KF_SARIAS_HOUSE, {[]{return true;}}), + Entrance(RR_KF_HOUSE_OF_TWINS, {[]{return true;}}), + Entrance(RR_KF_KNOW_IT_ALL_HOUSE, {[]{return true;}}), + Entrance(RR_KF_KOKIRI_SHOP, {[]{return true;}}), + Entrance(RR_KF_OUTSIDE_DEKU_TREE, {[]{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield;}}), + Entrance(RR_THE_LOST_WOODS, {[]{return true;}}), + Entrance(RR_LW_BRIDGE_FROM_FOREST, {[]{return logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_FOREST_CLOSED) || logic->DekuTreeClear;}}), + Entrance(RR_KF_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), + }); + + areaTable[RR_KF_OUTSIDE_DEKU_TREE] = Region("KF Outside Deku Tree", "Kokiri Forest", {RA_KOKIRI_FOREST}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&DekuBabaSticks, {[]{return DekuBabaSticks || ((IsAdult && (CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(KOKIRI_SWORD)) && !ShuffleEntrances) || (IsChild && (CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(MASTER_SWORD) || CanUse(BOOMERANG))));}}), - EventAccess(&DekuBabaNuts, {[]{return DekuBabaNuts || ((IsAdult && (CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(KOKIRI_SWORD)) && !ShuffleEntrances) || (IsChild && (CanJumpslash || CanUse(SLINGSHOT) || HasExplosives || CanUse(DINS_FIRE))));}}), - EventAccess(&ShowedMidoSwordAndShield, {[]{return ShowedMidoSwordAndShield || (IsChild && KokiriSword && DekuShield);}}), + EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || ((logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_KOKIRI_SWORD)) && !ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES)) || (logic->IsChild && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BOOMERANG))));}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || ((logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_KOKIRI_SWORD)) && !ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES)) || (logic->IsChild && (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE))));}}), + EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}), }, { //Locations - LocationAccess(KF_DEKU_TREE_GOSSIP_STONE_LEFT, {[]{return true;}}), - LocationAccess(KF_DEKU_TREE_GOSSIP_STONE_RIGHT, {[]{return true;}}), + LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, true), + LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, true), }, { //Exits - Entrance(DEKU_TREE_ENTRYWAY, {[]{return IsChild || (ShuffleDungeonEntrances.IsNot(SHUFFLEDUNGEONS_OFF) && (OpenForest.Is(OPENFOREST_OPEN) || ShowedMidoSwordAndShield));}}), - Entrance(KOKIRI_FOREST, {[]{return IsAdult || OpenForest.Is(OPENFOREST_OPEN) || ShowedMidoSwordAndShield;}}), + Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return logic->IsChild || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && (ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield));}}), + Entrance(RR_KOKIRI_FOREST, {[]{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield;}}), }); - areaTable[KF_LINKS_HOUSE] = Area("KF Link's House", "KF Link's House", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KF_LINKS_HOUSE] = Region("KF Link's House", "KF Link's House", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KF_LINKS_HOUSE_COW, {[]{return IsAdult && CanPlay(EponasSong) && LinksCow;}}), + LOCATION(RC_KF_LINKS_HOUSE_COW, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && logic->LinksCow), }, { //Exits - Entrance(KOKIRI_FOREST, {[]{return true;}}) + Entrance(RR_KOKIRI_FOREST, {[]{return true;}}) }); - areaTable[KF_MIDOS_HOUSE] = Area("KF Mido's House", "KF Mido's House", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KF_MIDOS_HOUSE] = Region("KF Mido's House", "KF Mido's House", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KF_MIDOS_TOP_LEFT_CHEST, {[]{return true;}}), - LocationAccess(KF_MIDOS_TOP_RIGHT_CHEST, {[]{return true;}}), - LocationAccess(KF_MIDOS_BOTTOM_LEFT_CHEST, {[]{return true;}}), - LocationAccess(KF_MIDOS_BOTTOM_RIGHT_CHEST, {[]{return true;}}), + LOCATION(RC_KF_MIDOS_TOP_LEFT_CHEST, true), + LOCATION(RC_KF_MIDOS_TOP_RIGHT_CHEST, true), + LOCATION(RC_KF_MIDOS_BOTTOM_LEFT_CHEST, true), + LOCATION(RC_KF_MIDOS_BOTTOM_RIGHT_CHEST, true), }, { //Exits - Entrance(KOKIRI_FOREST, {[]{return true;}}), + Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[KF_SARIAS_HOUSE] = Area("KF Saria's House", "KF Saria's House", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KF_SARIAS_HOUSE] = Region("KF Saria's House", "KF Saria's House", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(KOKIRI_FOREST, {[]{return true;}}), + Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[KF_HOUSE_OF_TWINS] = Area("KF House of Twins", "KF House of Twins", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KF_HOUSE_OF_TWINS] = Region("KF House of Twins", "KF House of Twins", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(KOKIRI_FOREST, {[]{return true;}}), + Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[KF_KNOW_IT_ALL_HOUSE] = Area("KF Know It All House", "KF Know It All House", NONE, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KF_KNOW_IT_ALL_HOUSE] = Region("KF Know It All House", "KF Know It All House", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(KOKIRI_FOREST, {[]{return true;}}), + Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[KF_KOKIRI_SHOP] = Area("KF Kokiri Shop", "KF Kokiri Shop", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_KF_KOKIRI_SHOP] = Region("KF Kokiri Shop", "KF Kokiri Shop", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(KF_SHOP_ITEM_1, {[]{return true;}}), - LocationAccess(KF_SHOP_ITEM_2, {[]{return true;}}), - LocationAccess(KF_SHOP_ITEM_3, {[]{return true;}}), - LocationAccess(KF_SHOP_ITEM_4, {[]{return true;}}), - LocationAccess(KF_SHOP_ITEM_5, {[]{return true;}}), - LocationAccess(KF_SHOP_ITEM_6, {[]{return true;}}), - LocationAccess(KF_SHOP_ITEM_7, {[]{return true;}}), - LocationAccess(KF_SHOP_ITEM_8, {[]{return true;}}), + LOCATION(RC_KF_SHOP_ITEM_1, true), + LOCATION(RC_KF_SHOP_ITEM_2, true), + LOCATION(RC_KF_SHOP_ITEM_3, true), + LOCATION(RC_KF_SHOP_ITEM_4, true), + LOCATION(RC_KF_SHOP_ITEM_5, true), + LOCATION(RC_KF_SHOP_ITEM_6, true), + LOCATION(RC_KF_SHOP_ITEM_7, true), + LOCATION(RC_KF_SHOP_ITEM_8, true), }, { //Exits - Entrance(KOKIRI_FOREST, {[]{return true;}}), + Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[KF_STORMS_GROTTO] = Area("KF Storms Grotto", "KF Storms Grotto", NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_KF_STORMS_GROTTO] = Region("KF Storms Grotto", "KF Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(KF_STORMS_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(KF_STORMS_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_KF_STORMS_GROTTO_CHEST, true), + LOCATION(RC_KF_STORMS_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_KF_STORMS_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(KOKIRI_FOREST, {[]{return true;}}) + Entrance(RR_KOKIRI_FOREST, {[]{return true;}}) }); - areaTable[LW_FOREST_EXIT] = Area("LW Forest Exit", "Lost Woods", 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(KOKIRI_FOREST, {[]{return true;}}) + Entrance(RR_KOKIRI_FOREST, {[]{return true;}}) }); - areaTable[THE_LOST_WOODS] = Area("Lost Woods", "Lost Woods", 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(&OddMushroomAccess, {[]{return OddMushroomAccess || (IsAdult && (CojiroAccess || Cojiro));}}), - EventAccess(&PoachersSawAccess, {[]{return PoachersSawAccess || (IsAdult && OddPoulticeAccess);}}), - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairyWithoutSuns;}}), - EventAccess(&BeanPlantFairy, {[]{return BeanPlantFairy || CanPlay(SongOfStorms);}}), - EventAccess(&BugShrub, {[]{return IsChild && CanCutShrubs;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || logic->CanUse(RG_SONG_OF_STORMS);}}), + EventAccess(&logic->BugShrub, {[]{return logic->IsChild && logic->CanCutShrubs();}}), }, { //Locations - LocationAccess(LW_SKULL_KID, {[]{return IsChild && CanPlay(SariasSong);}}), - LocationAccess(LW_TRADE_COJIRO, {[]{return IsAdult && Cojiro;}}), - LocationAccess(LW_TRADE_ODD_POTION, {[]{return IsAdult && OddPoultice && Cojiro;}}), - LocationAccess(LW_OCARINA_MEMORY_GAME, {[]{return IsChild && Ocarina;}}), - LocationAccess(LW_TARGET_IN_WOODS, {[]{return IsChild && CanUse(SLINGSHOT);}}), - LocationAccess(LW_DEKU_SCRUB_NEAR_BRIDGE, {[]{return IsChild && CanStunDeku;}}), - LocationAccess(LW_GS_BEAN_PATCH_NEAR_BRIDGE, {[]{return CanPlantBugs && CanChildAttack;}}), - LocationAccess(LW_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), + LOCATION(RC_LW_TRADE_COJIRO, logic->IsAdult && logic->CanUse(RG_COJIRO)), + //I cannot think of a case where you can use Odd pot but not Cojiro to reset the quadrant should you have both. If one exists, add it to logic + LOCATION(RC_LW_TRADE_ODD_POTION, logic->IsAdult && logic->CanUse(RG_ODD_POTION)), + //all 5 buttons are logically required for memory game + //because the chances of being able to beat it + //every time you attempt it are as follows: + //0 or 1 button(s) => 0% + //2 buttons => 0.15625% + //3 buttons => 3.75% + //4 buttons => 25.3125% + //5 buttons => 100% + LOCATION(RC_LW_OCARINA_MEMORY_GAME, logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 5), + LOCATION(RC_LW_TARGET_IN_WOODS, logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, logic->IsChild && logic->CanStunDeku()), + LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_LW_GOSSIP_STONE, true), }, { //Exits - Entrance(LW_FOREST_EXIT, {[]{return true;}}), - Entrance(GC_WOODS_WARP, {[]{return true;}}), - Entrance(LW_BRIDGE, {[]{return CanLeaveForest && ((IsAdult && (CanPlantBean(THE_LOST_WOODS) || LogicLostWoodsBridge)) || CanUse(HOVER_BOOTS) || CanUse(LONGSHOT));}}), - Entrance(ZORAS_RIVER, {[]{return CanLeaveForest && (CanDive || CanUse(IRON_BOOTS));}}), - Entrance(LW_BEYOND_MIDO, {[]{return IsChild || CanPlay(SariasSong) || LogicMidoBackflip;}}), - Entrance(LW_NEAR_SHORTCUTS_GROTTO, {[]{return Here(THE_LOST_WOODS, []{return CanBlastOrSmash;});}}), + Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}), + Entrance(RR_GC_WOODS_WARP, {[]{return true;}}), + Entrance(RR_LW_BRIDGE, {[]{return logic->CanLeaveForest() && ((logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}}), + Entrance(RR_ZORAS_RIVER, {[]{return logic->CanLeaveForest() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_LW_BEYOND_MIDO, {[]{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || ctx->GetTrickOption(RT_LW_MIDO_BACKFLIP);}}), + Entrance(RR_LW_NEAR_SHORTCUTS_GROTTO, {[]{return Here(RR_THE_LOST_WOODS, []{return logic->BlastOrSmash();});}}), }); - areaTable[LW_BEYOND_MIDO] = Area("LW Beyond Mido", "Lost Woods", 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(&ButterflyFairy, {[]{return ButterflyFairy || CanUse(STICKS);}}), + EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), }, { //Locations - LocationAccess(LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, {[]{return IsChild && CanStunDeku;}}), - LocationAccess(LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, {[]{return IsChild && CanStunDeku;}}), - LocationAccess(LW_GS_ABOVE_THEATER, {[]{return IsAdult && AtNight && ((CanPlantBean(LW_BEYOND_MIDO) && CanAdultAttack) || (LogicLostWoodsGSBean && CanUse(HOOKSHOT) && (CanUse(LONGSHOT) || CanUse(BOW) || CanUse(SLINGSHOT) || HasBombchus || CanUse(DINS_FIRE)))) && CanGetNightTimeGS;}}), - LocationAccess(LW_GS_BEAN_PATCH_NEAR_THEATER, {[]{return CanPlantBugs && (CanChildAttack || (Scrubsanity.Is(SCRUBSANITY_OFF) && DekuShield));}}), + LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku()), + LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku()), + LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && logic->AtNight && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->CanAttack()) || (ctx->GetTrickOption(RT_LW_GS_BEAN) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOMBCHU_5) || logic->CanUse(RG_DINS_FIRE)))) && logic->CanGetNightTimeGS()), + LOCATION(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, logic->CanSpawnSoilSkull() && (logic->CanAttack() || (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF) && logic->CanReflectNuts()))), }, { //Exits - Entrance(LW_FOREST_EXIT, {[]{return true;}}), - Entrance(THE_LOST_WOODS, {[]{return IsChild || CanPlay(SariasSong);}}), - Entrance(SFM_ENTRYWAY, {[]{return true;}}), - Entrance(DEKU_THEATER, {[]{return true;}}), - Entrance(LW_SCRUBS_GROTTO, {[]{return Here(LW_BEYOND_MIDO, []{return CanBlastOrSmash;});}}), + Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}), + Entrance(RR_THE_LOST_WOODS, {[]{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG);}}), + Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}), + Entrance(RR_DEKU_THEATER, {[]{return true;}}), + Entrance(RR_LW_SCRUBS_GROTTO, {[]{return Here(RR_LW_BEYOND_MIDO, []{return logic->BlastOrSmash();});}}), }); - areaTable[LW_NEAR_SHORTCUTS_GROTTO] = Area("LW Near Shortcuts Grotto", "LW Near Shortcuts Grotto", NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_LW_NEAR_SHORTCUTS_GROTTO] = Region("LW Near Shortcuts Grotto", "LW Near Shortcuts Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(LW_NEAR_SHORTCUTS_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, true), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(THE_LOST_WOODS, {[]{return true;}}), + Entrance(RR_THE_LOST_WOODS, {[]{return true;}}), }); - areaTable[DEKU_THEATER] = Area("Deku Theater", "Deku Theater", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_DEKU_THEATER] = Region("Deku Theater", "Deku Theater", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(DEKU_THEATER_SKULL_MASK, {[]{return IsChild && SkullMask;}}), - LocationAccess(DEKU_THEATER_MASK_OF_TRUTH, {[]{return IsChild && MaskOfTruth;}}), + LOCATION(RC_DEKU_THEATER_SKULL_MASK, logic->IsChild && logic->SkullMask), + LOCATION(RC_DEKU_THEATER_MASK_OF_TRUTH, logic->IsChild && logic->MaskOfTruth), }, { //Exits - Entrance(LW_BEYOND_MIDO, {[]{return true;}}), + Entrance(RR_LW_BEYOND_MIDO, {[]{return true;}}), }); - areaTable[LW_SCRUBS_GROTTO] = Area("LW Scrubs Grotto", "LW Scrubs Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_LW_SCRUBS_GROTTO] = Region("LW Scrubs Grotto", "LW Scrubs Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(LW_DEKU_SCRUB_GROTTO_REAR, {[]{return CanStunDeku;}}), - LocationAccess(LW_DEKU_SCRUB_GROTTO_FRONT, {[]{return CanStunDeku;}}), + LOCATION(RC_LW_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()), + LOCATION(RC_LW_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()), + LOCATION(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(LW_BEYOND_MIDO, {[]{return true;}}), + Entrance(RR_LW_BEYOND_MIDO, {[]{return true;}}), }); - areaTable[SFM_ENTRYWAY] = Area("SFM Entryway", "Sacred Forest Meadow", 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(LW_BEYOND_MIDO, {[]{return true;}}), - Entrance(SACRED_FOREST_MEADOW, {[]{return IsAdult || CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(DINS_FIRE) || CanUse(MEGATON_HAMMER);}}), - Entrance(SFM_WOLFOS_GROTTO, {[]{return CanOpenBombGrotto;}}), + 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[SACRED_FOREST_MEADOW] = Area("Sacred Forest Meadow", "Sacred Forest Meadow", 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(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairyWithoutSuns;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), }, { //Locations - LocationAccess(SONG_FROM_SARIA, {[]{return IsChild && ZeldasLetter;}}), - LocationAccess(SHEIK_IN_FOREST, {[]{return IsAdult;}}), - LocationAccess(SFM_GS, {[]{return IsAdult && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), - LocationAccess(SFM_MAZE_GOSSIP_STONE_LOWER, {[]{return true;}}), - LocationAccess(SFM_MAZE_GOSSIP_STONE_UPPER, {[]{return true;}}), - LocationAccess(SFM_SARIA_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_SONG_FROM_SARIA, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER)), + LOCATION(RC_SHEIK_IN_FOREST, logic->IsAdult), + LOCATION(RC_SFM_GS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE, true), + LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE, true), + LOCATION(RC_SFM_SARIA_GOSSIP_STONE, true), }, { //Exits - Entrance(SFM_ENTRYWAY, {[]{return true;}}), - Entrance(FOREST_TEMPLE_ENTRYWAY, {[]{return CanUse(HOOKSHOT);}}), - Entrance(SFM_FAIRY_GROTTO, {[]{return true;}}), - Entrance(SFM_STORMS_GROTTO, {[]{return CanOpenStormGrotto;}}), + Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}), + Entrance(RR_FOREST_TEMPLE_ENTRYWAY, {[]{return logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_SFM_FAIRY_GROTTO, {[]{return true;}}), + Entrance(RR_SFM_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); - areaTable[SFM_FAIRY_GROTTO] = Area("SFM Fairy Grotto", "SFM Fairy Grotto", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_SFM_FAIRY_GROTTO] = Region("SFM Fairy Grotto", "SFM Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&FreeFairies, {[]{return true;}}), + EventAccess(&logic->FreeFairies, {[]{return true;}}), }, {}, { //Exits - Entrance(SACRED_FOREST_MEADOW, {[]{return true;}}), + Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), }); - areaTable[SFM_WOLFOS_GROTTO] = Area("SFM Wolfos Grotto", "SFM Wolfos Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SFM_WOLFOS_GROTTO] = Region("SFM Wolfos Grotto", "SFM Wolfos Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(SFM_WOLFOS_GROTTO_CHEST, {[]{return CanJumpslash || CanUse(SLINGSHOT) || CanUse(BOW) || CanUse(DINS_FIRE) || CanUse(MEGATON_HAMMER);}}), + LOCATION(RC_SFM_WOLFOS_GROTTO_CHEST, logic->IsAdult || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), //RANDOTODO is this meant to auto-pass as adult? }, { //Exits - Entrance(SFM_ENTRYWAY, {[]{return true;}}), + Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}), }); - areaTable[SFM_STORMS_GROTTO] = Area("SFM Storms Grotto", "SFM Storms Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SFM_STORMS_GROTTO] = Region("SFM Storms Grotto", "SFM Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(SFM_DEKU_SCRUB_GROTTO_REAR, {[]{return CanStunDeku;}}), - LocationAccess(SFM_DEKU_SCRUB_GROTTO_FRONT, {[]{return CanStunDeku;}}), + LOCATION(RC_SFM_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()), + LOCATION(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()), + LOCATION(RC_SFM_STORMS_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(SACRED_FOREST_MEADOW, {[]{return true;}}), + Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), }); - areaTable[LW_BRIDGE_FROM_FOREST] = Area("LW Bridge From Forest", "Lost Woods", 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 - LocationAccess(LW_GIFT_FROM_SARIA, {[]{return true;}}), + LOCATION(RC_LW_GIFT_FROM_SARIA, true), }, { //Exits - Entrance(LW_BRIDGE, {[]{return true;}}), + Entrance(RR_LW_BRIDGE, {[]{return true;}}), }); - areaTable[LW_BRIDGE] = Area("LW Bridge", "Lost Woods", 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(KOKIRI_FOREST, {[]{return true;}}), - Entrance(HYRULE_FIELD, {[]{return true;}}), - Entrance(THE_LOST_WOODS, {[]{return CanUse(LONGSHOT);}}), + Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_THE_LOST_WOODS, {[]{return logic->CanUse(RG_LONGSHOT);}}), }); } 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 61778d56300..fe61c0d8097 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 @@ -1,214 +1,214 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_ShadowTemple() { +void RegionTable_Init_ShadowTemple() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[SHADOW_TEMPLE_ENTRYWAY] = Area("Shadow Temple Entryway", "Shadow Temple", 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(SHADOW_TEMPLE_BEGINNING, {[]{return Dungeon::ShadowTemple.IsVanilla() && (LogicLensShadow || CanUse(LENS_OF_TRUTH)) && (CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT));}}), - Entrance(SHADOW_TEMPLE_MQ_BEGINNING, {[]{return Dungeon::ShadowTemple.IsMQ() && (LogicLensShadowMQ || CanUse(LENS_OF_TRUTH)) && (CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT));}}), - Entrance(GRAVEYARD_WARP_PAD_REGION, {[]{return true;}}), + Entrance(RR_SHADOW_TEMPLE_BEGINNING, {[]{return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_SHADOW_TEMPLE_MQ_BEGINNING, {[]{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_GRAVEYARD_WARP_PAD_REGION, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::ShadowTemple.IsVanilla()) { - areaTable[SHADOW_TEMPLE_BEGINNING] = Area("Shadow Temple Beginning", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, { + if (ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla()) { + areaTable[RR_SHADOW_TEMPLE_BEGINNING] = Region("Shadow Temple Beginning", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&NutPot, {[]{return true;}}), + EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LocationAccess(SHADOW_TEMPLE_MAP_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(SHADOW_TEMPLE_HOVER_BOOTS_CHEST, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD));}}), + LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), }, { //Exits - Entrance(SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(SHADOW_TEMPLE_FIRST_BEAMOS, {[]{return CanUse(HOVER_BOOTS);}}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_SHADOW_TEMPLE_FIRST_BEAMOS, {[]{return logic->CanUse(RG_HOVER_BOOTS);}}), }); - areaTable[SHADOW_TEMPLE_FIRST_BEAMOS] = Area("Shadow Temple First Beamos", "Shadow Temple", 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(&FairyPot, {[]{return true;}}), //This fairy pot is only on 3DS + EventAccess(&logic->FairyPot, {[]{return true;}}), //This fairy pot is only on 3DS }, { //Locations - LocationAccess(SHADOW_TEMPLE_COMPASS_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, {[]{return CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT);}}), - LocationAccess(SHADOW_TEMPLE_GS_NEAR_SHIP, {[]{return false;}}), + LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_EARLY_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, false), }, { //Exits - Entrance(SHADOW_TEMPLE_HUGE_PIT, {[]{return HasExplosives && IsAdult && SmallKeys(SHADOW_TEMPLE, 1, 2);}}), - Entrance(SHADOW_TEMPLE_BEYOND_BOAT, {[]{return false;}}), + Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, {[]{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1, 2);}}), + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, {[]{return false;}}), }); - areaTable[SHADOW_TEMPLE_HUGE_PIT] = Area("Shadow Temple Huge Pit", "Shadow Temple", 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 - LocationAccess(SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, {[]{return (LogicShadowUmbrella && HoverBoots) || GoronBracelet;}}), - LocationAccess(SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, {[]{return (LogicShadowUmbrella && HoverBoots) || GoronBracelet;}}), - LocationAccess(SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, {[]{return SmallKeys(SHADOW_TEMPLE, 2, 3) && ((LogicLensShadowPlatform && LogicLensShadow) || CanUse(LENS_OF_TRUTH));}}), - LocationAccess(SHADOW_TEMPLE_FREESTANDING_KEY, {[]{return SmallKeys(SHADOW_TEMPLE, 2, 3) && ((LogicLensShadowPlatform && LogicLensShadow) || CanUse(LENS_OF_TRUTH)) && Hookshot && (Bombs || GoronBracelet || (LogicShadowFreestandingKey && HasBombchus));}}), - LocationAccess(SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, {[]{return CanJumpslash;}}), - LocationAccess(SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, {[]{return Hookshot || (LogicShadowUmbrellaGS && HoverBoots);}}), - LocationAccess(SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, {[]{return SmallKeys(SHADOW_TEMPLE, 2, 3) && ((LogicLensShadowPlatform && LogicLensShadow) || CanUse(LENS_OF_TRUTH)) && Hookshot;}}), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_LOWER_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_SWITCH_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_SPIKES_CHEST, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_FREESTANDING_KEY, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_BOMB_BAG) || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_FREESTANDING_KEY) && logic->CanUse(RG_BOMBCHU_5)))), + LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT)), }, { //Exits - Entrance(SHADOW_TEMPLE_WIND_TUNNEL, {[]{return ((LogicLensShadowPlatform && LogicLensShadow) || CanUse(LENS_OF_TRUTH)) && Hookshot && SmallKeys(SHADOW_TEMPLE, 3, 4);}}), + Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, {[]{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3, 4);}}), }); - areaTable[SHADOW_TEMPLE_WIND_TUNNEL] = Area("Shadow Temple Wind Tunnel", "Shadow Temple", 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 - LocationAccess(SHADOW_TEMPLE_WIND_HINT_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_GS_NEAR_SHIP, {[]{return CanUse(LONGSHOT) && SmallKeys(SHADOW_TEMPLE, 4, 5);}}), + LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), }, { //Exits - Entrance(SHADOW_TEMPLE_BEYOND_BOAT, {[]{return CanJumpslash && CanPlay(ZeldasLullaby) && SmallKeys(SHADOW_TEMPLE, 4, 5);}}), + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, {[]{return logic->CanJumpslash() && logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5);}}), }); - areaTable[SHADOW_TEMPLE_BEYOND_BOAT] = Area("Shadow Temple Beyond Boat", "Shadow Temple", 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 - LocationAccess(SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, {[]{return CanUse(DINS_FIRE);}}), - LocationAccess(SHADOW_TEMPLE_BOSS_KEY_CHEST, {[]{return CanUse(DINS_FIRE);}}), - LocationAccess(SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, {[]{return CanAdultAttack;}}), + LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanJumpslash()), + //RANDOTODO check if child can reach the token + LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->IsAdult && logic->CanAttack()), }, { //Exits - Entrance(SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (CanUse(BOW) || CanUse(DISTANT_SCARECROW) || (LogicShadowStatue && HasBombchus)) && SmallKeys(SHADOW_TEMPLE, 5) && CanUse(HOVER_BOOTS) && BossKeyShadowTemple;}}) + Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}) }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::ShadowTemple.IsMQ()) { - areaTable[SHADOW_TEMPLE_MQ_BEGINNING] = Area("Shadow Temple MQ Beginning", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ()) { + //RANDOTODO doublecheck CanAttack when rewriting, as I assumed it only checked adult due to the entrance + areaTable[RR_SHADOW_TEMPLE_MQ_BEGINNING] = Region("Shadow Temple MQ Beginning", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return IsAdult && (CanUse(FIRE_ARROWS) || HoverBoots || (LogicShadowMQGap && CanUse(LONGSHOT)));}}), - //Trick: IsAdult && (CanUse(FIRE_ARROWS) || HoverBoots || (LogicShadowMQGap && CanUse(LONGSHOT))) - Entrance(SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, {[]{return HasExplosives && SmallKeys(SHADOW_TEMPLE, 6);}}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT)));}}), + //Trick: logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOVER_BOOTS) || (LogicShadowMQGap && logic->CanUse(RG_LONGSHOT))) + Entrance(RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 6);}}), }); - areaTable[SHADOW_TEMPLE_MQ_DEAD_HAND_AREA] = Area("Shadow Temple MQ Dead Hand Area", "Shadow Temple", 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 - LocationAccess(SHADOW_TEMPLE_MQ_COMPASS_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, {[]{return CanJumpslash && CanPlay(SongOfTime) && IsAdult && CanUse(BOW);}}), + LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanJumpslash() && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), }, {}); - areaTable[SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Area("Shadow Temple MQ First Beamos", "Shadow Temple", 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 - LocationAccess(SHADOW_TEMPLE_MQ_MAP_CHEST, {[]{return CanAdultAttack || Nuts;}}), - LocationAccess(SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, {[]{return CanAdultAttack || Nuts;}}), + LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanAttack() || logic->CanUse(RG_NUTS)), + LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, logic->CanAttack() || logic->CanUse(RG_NUTS)), }, { //Exits - Entrance(SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return HasExplosives && SmallKeys(SHADOW_TEMPLE, 2);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}), }); - areaTable[SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT] = Area("Shadow Temple MQ Upper Huge Pit", "Shadow Temple", 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 - LocationAccess(SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, {[]{return CanPlay(SongOfTime) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO));}}), - //Trick: CanPlay(SongOfTime) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO)) - LocationAccess(SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, {[]{return CanPlay(SongOfTime) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO));}}), - //Trick: CanPlay(SongOfTime) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO)) + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO))), + //Trick: logic->CanUse(RG_SONG_OF_TIME) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO)) + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO))), + //Trick: logic->CanUse(RG_SONG_OF_TIME) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO)) }, { //Exits - Entrance(SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return HasFireSource || LogicShadowMQHugePit;}}), - //Trick: HasFireSource || LogicShadowMQHugePit + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return logic->HasFireSource() || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}}), + //Trick: logic->HasFireSource() || LogicShadowMQHugePit }); - areaTable[SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT] = Area("Shadow Temple MQ Lower Huge Pit", "Shadow Temple", 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 - LocationAccess(SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, {[]{return IsAdult && CanUse(LONGSHOT);}}), - LocationAccess(SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, {[]{return (LogicShadowUmbrella && HoverBoots) || GoronBracelet;}}), - LocationAccess(SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, {[]{return (LogicShadowUmbrella && HoverBoots) || GoronBracelet;}}), - LocationAccess(SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, {[]{return CanJumpslash && HoverBoots && SmallKeys(SHADOW_TEMPLE, 3) && ((LogicLensShadowMQ && LogicLensShadowMQPlatform) || CanUse(LENS_OF_TRUTH));}}), - LocationAccess(SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, {[]{return (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && HoverBoots && SmallKeys(SHADOW_TEMPLE, 3) && Hookshot && ((LogicLensShadowMQ && - LogicLensShadowMQInvisibleBlades && LogicLensShadowMQPlatform) || CanUse(LENS_OF_TRUTH));}}), - LocationAccess(SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, {[]{return Hookshot || (LogicShadowUmbrellaGS && HoverBoots);}}), + LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->IsAdult && logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanJumpslash() && logic->CanUse(RG_HOVER_BOOTS) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->CanUse(RG_HOVER_BOOTS) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3) && logic->CanUse(RG_HOOKSHOT) && ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && + ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) && ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS))), }, { //Exits - Entrance(SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return HoverBoots && ((LogicLensShadowMQ && LogicLensShadowMQPlatform) || CanUse(LENS_OF_TRUTH)) && Hookshot && SmallKeys(SHADOW_TEMPLE, 4);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return logic->CanUse(RG_HOVER_BOOTS) && ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}}), }); - areaTable[SHADOW_TEMPLE_MQ_WIND_TUNNEL] = Area("Shadow Temple MQ Wind Tunnel", "Shadow Temple", 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(&NutPot, {[]{return true;}}), + EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LocationAccess(SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, {[]{return CanJumpslash;}}), - LocationAccess(SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_MQ_GS_AFTER_WIND, {[]{return true;}}), + LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslash()), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, true), }, { //Exits - Entrance(SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return CanPlay(ZeldasLullaby) && SmallKeys(SHADOW_TEMPLE, 5);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}}), }); - areaTable[SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Area("Shadow Temple MQ Beyond Boat", "Shadow Temple", 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 - LocationAccess(SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, {[]{return true;}}), - LocationAccess(SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, {[]{return Bow || (LogicShadowStatue && HasBombchus);}}), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))), }, { //Exits - Entrance(SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return Bow && CanPlay(SongOfTime) && IsAdult && CanUse(LONGSHOT);}}), - Entrance(SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (CanUse(BOW) || (LogicShadowStatue && HasBombchus)) && CanUse(HOVER_BOOTS) && BossKeyShadowTemple;}}), + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}), }); - areaTable[SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Area("Shadow Temple MQ Invisible Maze", "Shadow Temple", 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 - LocationAccess(SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, {[]{return CanUse(DINS_FIRE) && SmallKeys(SHADOW_TEMPLE, 6);}}), - LocationAccess(SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, {[]{return CanUse(DINS_FIRE) && SmallKeys(SHADOW_TEMPLE, 6);}}), + LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6)), + LOCATION(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6)), //below previously returned true - LocationAccess(SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, {[]{return CanUse(LENS_OF_TRUTH) || LogicLensShadowMQDeadHand;}}), - LocationAccess(SHADOW_TEMPLE_MQ_FREESTANDING_KEY, {[]{return true;}}), + LOCATION(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_SHADOW_MQ_DEADHAND)), + LOCATION(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, true), }, {}); } /*--------------------------- | BOSS ROOM | ---------------------------*/ - areaTable[SHADOW_TEMPLE_BOSS_ENTRYWAY] = - Area("Shadow Temple Boss Entryway", "Shadow Temple", SHADOW_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_SHADOW_TEMPLE_BOSS_ENTRYWAY] = + Region("Shadow Temple Boss Entryway", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(SHADOW_TEMPLE_BEYOND_BOAT, { [] { return Dungeon::ShadowTemple.IsVanilla() && false; } }), - Entrance(SHADOW_TEMPLE_MQ_BEYOND_BOAT, { [] { return Dungeon::ShadowTemple.IsMQ() && false; } }), - Entrance(SHADOW_TEMPLE_BOSS_ROOM, { [] { return true; } }), + Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, { [] { return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && false; } }), + Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, { [] { return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && false; } }), + Entrance(RR_SHADOW_TEMPLE_BOSS_ROOM, { [] { return true; } }), }); - areaTable[SHADOW_TEMPLE_BOSS_ROOM] = - Area("Shadow Temple Boss Room", "Shadow Temple", NONE, NO_DAY_NIGHT_CYCLE, + areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = + Region("Shadow Temple Boss Room", "Shadow Temple", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&ShadowTempleClear, { [] { - return ShadowTempleClear || - ((CanUse(LENS_OF_TRUTH) || LogicLensBongo) && - (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && - (CanUse(HOOKSHOT) || CanUse(BOW) || CanUse(SLINGSHOT) || LogicShadowBongo)); + EventAccess(&logic->ShadowTempleClear, { [] { + return logic->ShadowTempleClear || (logic->HasBossSoul(RG_BONGO_BONGO_SOUL) && + ((logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) && + (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && + (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || ctx->GetTrickOption(RT_SHADOW_BONGO)))); } }), }, { // Locations - LocationAccess(SHADOW_TEMPLE_BONGO_BONGO_HEART, { [] { return ShadowTempleClear; } }), - LocationAccess(BONGO_BONGO, { [] { return ShadowTempleClear; } }), + LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleClear), + LOCATION(RC_BONGO_BONGO, logic->ShadowTempleClear), }, { // Exits - Entrance(SHADOW_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), - Entrance(GRAVEYARD_WARP_PAD_REGION, { [] { return ShadowTempleClear; } }), + Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(RR_GRAVEYARD_WARP_PAD_REGION, { [] { return logic->ShadowTempleClear; } }, false), }); } 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 f676c3c91d3..f91e4dfec2f 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 @@ -1,276 +1,268 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_SpiritTemple() { +void RegionTable_Init_SpiritTemple() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[SPIRIT_TEMPLE_ENTRYWAY] = Area("Spirit Temple Entryway", "Spirit Temple", 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(SPIRIT_TEMPLE_LOBBY, {[]{return Dungeon::SpiritTemple.IsVanilla();}}), - Entrance(SPIRIT_TEMPLE_MQ_LOBBY, {[]{return Dungeon::SpiritTemple.IsMQ();}}), - Entrance(DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_LOBBY, {[]{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla();}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ();}}), + Entrance(RR_DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::SpiritTemple.IsVanilla()) { - areaTable[SPIRIT_TEMPLE_LOBBY] = Area("Spirit Temple Lobby", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla()) { + areaTable[RR_SPIRIT_TEMPLE_LOBBY] = Region("Spirit Temple Lobby", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(SPIRIT_TEMPLE_CHILD, {[]{return IsChild;}}), - Entrance(SPIRIT_TEMPLE_EARLY_ADULT, {[]{return CanUse(SILVER_GAUNTLETS);}}), + 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[SPIRIT_TEMPLE_CHILD] = Area("Child Spirit Temple", "Spirit Temple", 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(&NutCrate, {[]{return true;}}), + EventAccess(&logic->NutCrate, {[]{return true;}}), }, { //Locations - LocationAccess(SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, {[]{return (Boomerang || Slingshot || (HasBombchus && LogicSpiritChildBombchu)) && (HasExplosives || ((Nuts || Boomerang) && (Sticks || KokiriSword || Slingshot)));}}), - LocationAccess(SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, {[]{return (Boomerang || Slingshot || (HasBombchus && LogicSpiritChildBombchu)) && (HasExplosives || ((Nuts || Boomerang) && (Sticks || KokiriSword || Slingshot))) && (Sticks || CanUse(DINS_FIRE));}}), - LocationAccess(SPIRIT_TEMPLE_GS_METAL_FENCE, {[]{return (Boomerang || Slingshot || (HasBombchus && LogicSpiritChildBombchu)) && (HasExplosives || ((Nuts || Boomerang) && (Sticks || KokiriSword || Slingshot)));}}), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_BRIDGE_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_EARLY_TORCHES_CHEST, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), }, { //Exits - Entrance(SPIRIT_TEMPLE_CHILD_CLIMB, {[]{return SmallKeys(SPIRIT_TEMPLE, 1);}}), + Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}), }); - areaTable[SPIRIT_TEMPLE_CHILD_CLIMB] = Area("Child Spirit Temple Climb", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, {[]{return HasProjectile(HasProjectileAge::Both) || ((SmallKeys(SPIRIT_TEMPLE, 3) || (SmallKeys(SPIRIT_TEMPLE, 2) && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))) && CanUse(SILVER_GAUNTLETS) && HasProjectile(HasProjectileAge::Adult)) || (SmallKeys(SPIRIT_TEMPLE, 5) && IsChild && HasProjectile(HasProjectileAge::Child));}}), - LocationAccess(SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, {[]{return HasProjectile(HasProjectileAge::Both) || ((SmallKeys(SPIRIT_TEMPLE, 3) || (SmallKeys(SPIRIT_TEMPLE, 2) && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))) && CanUse(SILVER_GAUNTLETS) && HasProjectile(HasProjectileAge::Adult)) || (SmallKeys(SPIRIT_TEMPLE, 5) && IsChild && HasProjectile(HasProjectileAge::Child));}}), - LocationAccess(SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, {[]{return HasProjectile(HasProjectileAge::Both) || CanUse(DINS_FIRE) || - (CanTakeDamage && (CanJumpslash || HasProjectile(HasProjectileAge::Child))) || - (IsChild && SmallKeys(SPIRIT_TEMPLE, 5) && HasProjectile(HasProjectileAge::Child)) || - ((SmallKeys(SPIRIT_TEMPLE, 3) || (SmallKeys(SPIRIT_TEMPLE, 2) && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))) && CanUse(SILVER_GAUNTLETS) && (HasProjectile(HasProjectileAge::Adult) || (CanTakeDamage && CanJumpslash)));}}), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, logic->HasProjectile(HasProjectileAge::Both) || ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, logic->HasProjectile(HasProjectileAge::Both) || ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))), + LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, logic->HasProjectile(HasProjectileAge::Both) || logic->CanUse(RG_DINS_FIRE) || + (logic->TakeDamage() && (logic->CanJumpslash() || logic->HasProjectile(HasProjectileAge::Child))) || + (logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasProjectile(HasProjectileAge::Child)) || + ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->HasProjectile(HasProjectileAge::Adult) || (logic->TakeDamage() && logic->CanJumpslash())))), }, { //Exits - Entrance(SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return HasExplosives || (SunlightArrows && CanUse(LIGHT_ARROWS));}}), + Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}}), }); - areaTable[SPIRIT_TEMPLE_EARLY_ADULT] = Area("Early Adult Spirit Temple", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_COMPASS_CHEST, {[]{return CanUse(HOOKSHOT) && CanPlay(ZeldasLullaby);}}), - LocationAccess(SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, {[]{return (CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(SLINGSHOT) || CanUse(BOOMERANG) || HasBombchus || (Bombs && IsAdult && LogicSpiritLowerAdultSwitch)) && (CanUse(HOVER_BOOTS) || CanJumpslash);}}), - LocationAccess(SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 3);}}), - LocationAccess(SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 3);}}), - LocationAccess(SPIRIT_TEMPLE_GS_BOULDER_ROOM, {[]{return CanPlay(SongOfTime) && (Bow || Hookshot || HasBombchus || (Bombs && LogicSpiritLowerAdultSwitch));}}), + LOCATION(RC_SPIRIT_TEMPLE_COMPASS_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_SPIRIT_TEMPLE_EARLY_ADULT_RIGHT_CHEST, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())), + LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_LEFT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)), + LOCATION(RC_SPIRIT_TEMPLE_FIRST_MIRROR_RIGHT_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3)), + LOCATION(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH)))), }, { //Exits - Entrance(SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return SmallKeys(SPIRIT_TEMPLE, 1);}}), + Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}), }); - areaTable[SPIRIT_TEMPLE_CENTRAL_CHAMBER] = Area("Spirit Temple Central Chamber", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_MAP_CHEST, {[]{return ((HasExplosives || SmallKeys(SPIRIT_TEMPLE, 3) || (SmallKeys(SPIRIT_TEMPLE, 2) && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))) && + LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST)) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS) ))) || + (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) || + (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))), + + LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + (logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST)) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS) ))) || + (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) || + (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))), - (CanUse(DINS_FIRE) || - (((MagicMeter && FireArrows) || LogicSpiritMapChest) && Bow && Sticks))) || - (SmallKeys(SPIRIT_TEMPLE, 5) && HasExplosives && - CanUse(STICKS)) || - (SmallKeys(SPIRIT_TEMPLE, 3) && - (CanUse(FIRE_ARROWS) || (LogicSpiritMapChest && Bow)) && - CanUse(SILVER_GAUNTLETS));}}), - LocationAccess(SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, {[]{return ((HasExplosives || SmallKeys(SPIRIT_TEMPLE, 3) || (SmallKeys(SPIRIT_TEMPLE, 2) && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))) && - (CanUse(DINS_FIRE) || - (((MagicMeter && FireArrows) || LogicSpiritSunChest) && Bow && Sticks))) || - (SmallKeys(SPIRIT_TEMPLE, 5) && HasExplosives && - CanUse(STICKS)) || - (SmallKeys(SPIRIT_TEMPLE, 3) && - (CanUse(FIRE_ARROWS) || (LogicSpiritSunChest && Bow)) && - CanUse(SILVER_GAUNTLETS));}}), - LocationAccess(SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 3) && CanUse(SILVER_GAUNTLETS) && CanPlay(ZeldasLullaby);}}), - LocationAccess(SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 3) && CanUse(SILVER_GAUNTLETS) && CanPlay(ZeldasLullaby) && (Hookshot || HoverBoots || LogicSpiritLobbyJump);}}), - LocationAccess(SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, {[]{return (HasExplosives && Boomerang && Hookshot) || - (CanUse(BOOMERANG) && SmallKeys(SPIRIT_TEMPLE, 5) && HasExplosives) || - (Hookshot && CanUse(SILVER_GAUNTLETS) && - (SmallKeys(SPIRIT_TEMPLE, 3) || - (SmallKeys(SPIRIT_TEMPLE, 2) && Boomerang && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))));}}), - LocationAccess(SPIRIT_TEMPLE_GS_LOBBY, {[]{return ((HasExplosives || SmallKeys(SPIRIT_TEMPLE, 3) || (SmallKeys(SPIRIT_TEMPLE, 2) && BombchusInLogic && ShuffleDungeonEntrances.Is(SHUFFLEDUNGEONS_OFF))) && - LogicSpiritLobbyGS && Boomerang && (Hookshot || HoverBoots || LogicSpiritLobbyJump)) || - (LogicSpiritLobbyGS && SmallKeys(SPIRIT_TEMPLE, 5) && HasExplosives && CanUse(BOOMERANG)) || - (SmallKeys(SPIRIT_TEMPLE, 3) && CanUse(SILVER_GAUNTLETS) && (Hookshot || HoverBoots || LogicSpiritLobbyJump));}}), + LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_HAND_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))), + LOCATION(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, (logic->HasExplosives() && logic->CanUse(RG_BOOMERANG) && logic->CanUse(RG_HOOKSHOT)) || + (logic->CanUse(RG_BOOMERANG) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives()) || + (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && + logic->CanUse(RG_BOOMERANG) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))))), + + LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHUS_IN_LOGIC) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && + ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) || + (ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_BOOMERANG)) || + (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)))), }, { //Exits - Entrance(SPIRIT_TEMPLE_OUTDOOR_HANDS, {[]{return CanJumpslash || HasExplosives;}}), - Entrance(SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR, {[]{return SmallKeys(SPIRIT_TEMPLE, 4) && CanUse(SILVER_GAUNTLETS);}}), - Entrance(SPIRIT_TEMPLE_CHILD_CLIMB, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_OUTDOOR_HANDS, {[]{return logic->CanJumpslash() || logic->HasExplosives();}}), + Entrance(RR_SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SILVER_GAUNTLETS);}}), + Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, {[]{return true;}}), }); - areaTable[SPIRIT_TEMPLE_OUTDOOR_HANDS] = Area("Spirit Temple Outdoor Hands", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, {[]{return (SmallKeys(SPIRIT_TEMPLE, 3) && Longshot && HasExplosives) || SmallKeys(SPIRIT_TEMPLE, 5);}}), - LocationAccess(SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 4) && CanUse(SILVER_GAUNTLETS) && HasExplosives;}}), + LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_LONGSHOT) && logic->HasExplosives()) || logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)), + LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasExplosives()), }, { //Exits - Entrance(DESERT_COLOSSUS, {[]{return (IsChild && SmallKeys(SPIRIT_TEMPLE, 5)) || (CanUse(SILVER_GAUNTLETS) && ((SmallKeys(SPIRIT_TEMPLE, 3) && HasExplosives) || SmallKeys(SPIRIT_TEMPLE, 5)));}}), + Entrance(RR_DESERT_COLOSSUS, {[]{return (logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)) || (logic->CanUse(RG_SILVER_GAUNTLETS) && ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->HasExplosives()) || logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)));}}), }); - areaTable[SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR] = Area("Spirit Temple Beyond Central Locked Door", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, {[]{return (MirrorShield || (SunlightArrows && CanUse(LIGHT_ARROWS))) && HasExplosives;}}), - LocationAccess(SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, {[]{return (LogicLensSpirit || CanUse(LENS_OF_TRUTH)) && HasExplosives;}}), - LocationAccess(SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, {[]{return (LogicLensSpirit || CanUse(LENS_OF_TRUTH)) && HasExplosives;}}), + LOCATION(RC_SPIRIT_TEMPLE_NEAR_FOUR_ARMOS_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))) && logic->HasExplosives()), + LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_LEFT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), + LOCATION(RC_SPIRIT_TEMPLE_HALLWAY_RIGHT_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->HasExplosives()), }, { //Exits - Entrance(SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, {[]{return SmallKeys(SPIRIT_TEMPLE, 5) && (LogicSpiritWall || CanUse(LONGSHOT) || HasBombchus || ((Bombs || Nuts || CanUse(DINS_FIRE)) && (Bow || CanUse(HOOKSHOT) || Hammer)));}}), + Entrance(RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && (ctx->GetTrickOption(RT_SPIRIT_WALL) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5) || ((logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_NUTS) || logic->CanUse(RG_DINS_FIRE)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_MEGATON_HAMMER))));}}), }); - areaTable[SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Area("Spirit Temple Beyond Final Locked Door", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_BOSS_KEY_CHEST, {[]{return CanPlay(ZeldasLullaby) && ((CanTakeDamage && LogicFlamingChests) || (Bow && Hookshot));}}), - LocationAccess(SPIRIT_TEMPLE_TOPMOST_CHEST, {[]{return (MirrorShield && CanAdultAttack) || (SunlightArrows && CanUse(LIGHT_ARROWS));}}), + LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && ((logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS)) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT)))), + LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanAttack()) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), }, { //Exits - Entrance(SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, {[]{return MirrorShield && HasExplosives && Hookshot;}}), + Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[SPIRIT_TEMPLE_INSIDE_STATUE_HEAD] = - Area("Spirit Temple Inside Statue Head", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD] = + Region("Spirit Temple Inside Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(SPIRIT_TEMPLE_CENTRAL_CHAMBER, { [] { return true; } }), - Entrance(SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return BossKeySpiritTemple; } }), + Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, { [] { return true; } }), + Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY); } }), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::SpiritTemple.IsMQ()) { - areaTable[SPIRIT_TEMPLE_MQ_LOBBY] = Area("Spirit Temple MQ Lobby", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, { + if (ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ()) { + areaTable[RR_SPIRIT_TEMPLE_MQ_LOBBY] = Region("Spirit Temple MQ Lobby", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, {[]{return true;}}), - LocationAccess(SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, {[]{return Here(SPIRIT_TEMPLE_MQ_LOBBY, []{return CanBlastOrSmash;}) && ((IsChild && CanUse(SLINGSHOT)) || (IsAdult && CanUse(BOW)));}}), - LocationAccess(SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, {[]{return HasBombchus || (IsAdult && (CanUse(BOW) || CanUse(HOOKSHOT))) || (IsChild && (CanUse(SLINGSHOT) || CanUse(BOOMERANG)));}}), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && ((logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanUse(RG_BOMBCHU_5) || (logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))) || (logic->IsChild && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)))), }, { //Exits - Entrance(SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(SPIRIT_TEMPLE_MQ_CHILD, {[]{return IsChild;}}), - Entrance(SPIRIT_TEMPLE_MQ_ADULT, {[]{return HasBombchus && IsAdult && CanUse(LONGSHOT) && CanUse(SILVER_GAUNTLETS);}}), + Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_CHILD, {[]{return logic->IsChild;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_ADULT, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS);}}), }); - areaTable[SPIRIT_TEMPLE_MQ_CHILD] = Area("Spirit Temple MQ Child", "Spirit Temple", 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(&FairyPot, {[]{return FairyPot || (KokiriSword && HasBombchus && Slingshot);}}), + EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_SLINGSHOT));}}), }, { //Locations - LocationAccess(SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, {[]{return Here(SPIRIT_TEMPLE_MQ_ADULT, []{return SmallKeys(SPIRIT_TEMPLE, 7) && Hammer;});}}), - LocationAccess(SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, {[]{return KokiriSword && HasBombchus && Slingshot && CanUse(DINS_FIRE);}}), - LocationAccess(SPIRIT_TEMPLE_MQ_MAP_CHEST, {[]{return KokiriSword || Bombs;}}), - LocationAccess(SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, {[]{return HasBombchus && SmallKeys(SPIRIT_TEMPLE, 7) && Slingshot && (CanUse(DINS_FIRE) || (Here(SPIRIT_TEMPLE_MQ_ADULT, []{return IsAdult && (CanUse(FIRE_ARROWS) || (LogicSpiritMQFrozenEye && CanUse(BOW) && CanPlay(SongOfTime)));})));}}), - //Trick: HasBombchus && SmallKeys(SPIRIT_TEMPLE, 7) && Slingshot && (CanUse(DINS_FIRE) || (SPIRIT_TEMPLE_MQ_ADULT.Adult() && IsAdult && (CanUse(FIRE_ARROWS) || (LogicSpiritMQFrozenEye && CanUse(BOW) && CanPlay(SongOfTime))))) + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_MEGATON_HAMMER);})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BOMB_BAG)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->CanUse(RG_DINS_FIRE) || (Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME)));})))), + //Trick: logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->CanUse(RG_DINS_FIRE) || (SPIRIT_TEMPLE_MQ_ADULT.Adult() && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQFrozenEye && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME))))) }, { //Exits - Entrance(SPIRIT_TEMPLE_MQ_SHARED, {[]{return HasBombchus && SmallKeys(SPIRIT_TEMPLE, 2);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}}), }); - areaTable[SPIRIT_TEMPLE_MQ_ADULT] = Area("Spirit Temple MQ Adult", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 7);}}), - LocationAccess(SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, {[]{return CanPlay(ZeldasLullaby) && (CanJumpslash || CanUse(HOVER_BOOTS));}}), - LocationAccess(SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, {[]{return (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH));}}), - LocationAccess(SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 5);}}), - LocationAccess(SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 5) && CanPlay(SongOfTime);}}), - LocationAccess(SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 5) && CanPlay(SongOfTime) && (MirrorShield || (SunlightArrows && CanUse(LIGHT_ARROWS)));}}), - LocationAccess(SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 7);}}), - LocationAccess(SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, {[]{return SmallKeys(SPIRIT_TEMPLE, 7);}}), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)), }, { //Exits - Entrance(SPIRIT_TEMPLE_MQ_LOWER_ADULT, {[]{return MirrorShield && IsAdult && (CanUse(FIRE_ARROWS) || (LogicSpiritMQLowerAdult && CanUse(DINS_FIRE) && Bow));}}), - //Trick: MirrorShield && IsAdult && (CanUse(FIRE_ARROWS) || (LogicSpiritMQLowerAdult && CanUse(DINS_FIRE) && Bow)) - Entrance(SPIRIT_TEMPLE_MQ_SHARED, {[]{return true;}}), - Entrance(SPIRIT_TEMPLE_MQ_BOSS_AREA, {[]{return SmallKeys(SPIRIT_TEMPLE, 6) && CanPlay(ZeldasLullaby) && Hammer;}}), - Entrance(SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return SmallKeys(SPIRIT_TEMPLE, 5) && CanPlay(SongOfTime) && CanJumpslash && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH));}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)));}}), + //Trick: logic->CanUse(RG_MIRROR_SHIELD) && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQLowerAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW))) + Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BOSS_AREA, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanUse(RG_MEGATON_HAMMER);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslash() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}), }); - areaTable[SPIRIT_TEMPLE_MQ_SHARED] = Area("Spirit Temple MQ Shared", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 6);}}), - LocationAccess(SPIRIT_TEMPLE_MQ_COMPASS_CHEST, {[]{return (IsChild && CanUse(SLINGSHOT) && SmallKeys(SPIRIT_TEMPLE, 7)) || (IsAdult && CanUse(BOW)) || (Bow && Slingshot);}}), - LocationAccess(SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, {[]{return CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult;}}), - //Trick: CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult - LocationAccess(SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, {[]{return (LogicSpiritMQSunBlockGS && Boomerang && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT)) || IsAdult;}}), - //Trick: (LogicSpiritMQSunBlockGS && Boomerang && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT)) || IsAdult + 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->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_FAIRY_SLINGSHOT))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult), + //Trick: logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT))) || logic->IsAdult), + //Trick: (LogicSpiritMQSunBlockGS && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT)) || logic->IsAdult }, { //Exits - Entrance(SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return (SmallKeys(SPIRIT_TEMPLE, 7) && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult)) || (SmallKeys(SPIRIT_TEMPLE, 4) && CanPlay(SongOfTime) && CanJumpslash && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH)));}}), - //Trick: (SmallKeys(SPIRIT_TEMPLE, 7) && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult)) || (SmallKeys(SPIRIT_TEMPLE, 4) && CanPlay(SongOfTime) && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH))) - Entrance(DESERT_COLOSSUS, {[]{return (SmallKeys(SPIRIT_TEMPLE, 7) && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult)) || (SmallKeys(SPIRIT_TEMPLE, 4) && CanPlay(SongOfTime) && CanJumpslash && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH)) && IsAdult);}}), - //Trick: (SmallKeys(SPIRIT_TEMPLE, 7) && (CanPlay(SongOfTime) || LogicSpiritMQSunBlockSoT || IsAdult)) || (SmallKeys(SPIRIT_TEMPLE, 4) && CanPlay(SongOfTime) && (LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH)) && IsAdult) + Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslash() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)));}}), + //Trick: (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && (LogicLensSpiritMQ || logic->CanUse(RG_LENS_OF_TRUTH))) + Entrance(RR_DESERT_COLOSSUS, {[]{return (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslash() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult);}}), + //Trick: (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && (LogicLensSpiritMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult) }); - areaTable[SPIRIT_TEMPLE_MQ_LOWER_ADULT] = Area("Spirit Temple MQ Lower Adult", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, {[]{return true;}}), - LocationAccess(SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, {[]{return SmallKeys(SPIRIT_TEMPLE, 7) && Hammer && Ocarina && SongOfTime && EponasSong && SunsSong && SongOfStorms && ZeldasLullaby;}}), - LocationAccess(SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, {[]{return Hammer;}}), - LocationAccess(SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, {[]{return true;}}), - LocationAccess(SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, {[]{return SmallKeys(SPIRIT_TEMPLE, 7) && Hammer && Ocarina && SongOfTime && EponasSong && SunsSong && SongOfStorms && ZeldasLullaby;}}), + LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG) + && logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, true), + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG) + && logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY)), }, {}); - areaTable[SPIRIT_TEMPLE_MQ_BOSS_AREA] = Area("Spirit Temple MQ Boss Area", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, {[]{return LogicLensSpiritMQ || CanUse(LENS_OF_TRUTH);}}), + LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), }, { //Exits - Entrance(SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return MirrorShield && Hookshot;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD] = - Area("Spirit Temple MQ Inside Statue Head", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD] = + Region("Spirit Temple MQ Inside Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(SPIRIT_TEMPLE_MQ_SHARED, { [] { return true; } }), - Entrance(SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return BossKeySpiritTemple; } }), + Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, { [] { return true; } }), + Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY); } }), }); - areaTable[SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Area("Spirit Temple MQ Mirror Shield Hand", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, {[]{return true;}}), + LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true), }, {}); - areaTable[SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND] = Area("Spirit Temple MQ Silver Gauntlets Hand", "Spirit Temple", 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 - LocationAccess(SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, {[]{return true;}}), + LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, true), }, {}); } /*--------------------------- | BOSS ROOM | ---------------------------*/ - areaTable[SPIRIT_TEMPLE_BOSS_ENTRYWAY] = Area( - "Spirit Temple Boss Entryway", "Spirit Temple", SPIRIT_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY] = Region( + "Spirit Temple Boss Entryway", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, { [] { return Dungeon::SpiritTemple.IsVanilla() && false; } }), - Entrance(SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, { [] { return Dungeon::SpiritTemple.IsMQ() && false; } }), - Entrance(SPIRIT_TEMPLE_BOSS_ROOM, { [] { return true; } }), + Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, { [] { return ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla() && false; } }), + Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, { [] { return ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ() && false; } }), + Entrance(RR_SPIRIT_TEMPLE_BOSS_ROOM, { [] { return true; } }), }); - areaTable[SPIRIT_TEMPLE_BOSS_ROOM] = Area( - "Spirit Temple Boss Room", "Spirit Temple", NONE, NO_DAY_NIGHT_CYCLE, + areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", "Spirit Temple", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&SpiritTempleClear, { [] { - return SpiritTempleClear || (CanUse(MIRROR_SHIELD) && - (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD))); + EventAccess(&logic->SpiritTempleClear, { [] { + return logic->SpiritTempleClear || (logic->HasBossSoul(RG_TWINROVA_SOUL) && (logic->CanUse(RG_MIRROR_SHIELD) && + (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)))); } }), }, { // Locations - LocationAccess(SPIRIT_TEMPLE_TWINROVA_HEART, { [] { return SpiritTempleClear; } }), - LocationAccess(TWINROVA, { [] { return SpiritTempleClear; } }), + LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleClear), + LOCATION(RC_TWINROVA, logic->SpiritTempleClear), }, { // Exits - Entrance(SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), - Entrance(DESERT_COLOSSUS, { [] { return SpiritTempleClear; } }), + Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(RR_DESERT_COLOSSUS, { [] { return logic->SpiritTempleClear; } }, false), }); } 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 f1c86abb0bf..5f6d80a2e1b 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 @@ -1,336 +1,333 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" -#include "../dungeon.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_WaterTemple() { +void RegionTable_Init_WaterTemple() { /*-------------------------- | VANILLA/MQ DECIDER | ---------------------------*/ - areaTable[WATER_TEMPLE_ENTRYWAY] = Area("Water Temple Entryway", "Water Temple", 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(WATER_TEMPLE_LOBBY, {[]{return Dungeon::WaterTemple.IsVanilla();}}), - Entrance(WATER_TEMPLE_MQ_LOBBY, {[]{return Dungeon::WaterTemple.IsMQ();}}), - Entrance(LAKE_HYLIA, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->HasItem(RG_BRONZE_SCALE) && ctx->GetDungeon(WATER_TEMPLE)->IsVanilla();}}), + Entrance(RR_WATER_TEMPLE_MQ_LOBBY, {[]{return logic->HasItem(RG_BRONZE_SCALE) && ctx->GetDungeon(WATER_TEMPLE)->IsMQ();}}), + Entrance(RR_LAKE_HYLIA, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ - if (Dungeon::WaterTemple.IsVanilla()) { + if (ctx->GetDungeon(WATER_TEMPLE)->IsVanilla()) { //Water Temple logic currently assumes that the locked door leading to the upper water raising location is unlocked from the start - areaTable[WATER_TEMPLE_LOBBY] = Area("Water Temple Lobby", "Water Temple", 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(WATER_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(WATER_TEMPLE_EAST_LOWER, {[]{return WaterTempleLow || ((LogicFewerTunicRequirements || CanUse(ZORA_TUNIC)) && (CanUse(IRON_BOOTS) || (CanUse(LONGSHOT) && LogicWaterTempleTorchLongshot)));}}), - Entrance(WATER_TEMPLE_NORTH_LOWER, {[]{return WaterTempleLow || ((LogicFewerTunicRequirements || CanUse(ZORA_TUNIC)) && CanUse(IRON_BOOTS));}}), - Entrance(WATER_TEMPLE_SOUTH_LOWER, {[]{return WaterTempleLow && HasExplosives && (CanDive || CanUse(IRON_BOOTS)) && (LogicFewerTunicRequirements || CanUse(ZORA_TUNIC));}}), - Entrance(WATER_TEMPLE_WEST_LOWER, {[]{return WaterTempleLow && GoronBracelet && (IsChild || CanDive || CanUse(IRON_BOOTS)) && (LogicFewerTunicRequirements || CanUse(ZORA_TUNIC));}}), - Entrance(WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return WaterTempleLow && SmallKeys(WATER_TEMPLE, 5);}}), - Entrance(WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return (WaterTempleLow || WaterTempleMiddle) && (HasFireSourceWithTorch || CanUse(BOW));}}), - Entrance(WATER_TEMPLE_EAST_MIDDLE, {[]{return (WaterTempleLow || WaterTempleMiddle || (CanUse(IRON_BOOTS) && WaterTimer >= 16)) && CanUse(HOOKSHOT);}}), - Entrance(WATER_TEMPLE_WEST_MIDDLE, {[]{return WaterTempleMiddle;}}), - Entrance(WATER_TEMPLE_HIGH_WATER, {[]{return IsAdult && (CanUse(HOVER_BOOTS) || (LogicDamageBoost && Bombs && CanTakeDamage));}}), - Entrance(WATER_TEMPLE_BLOCK_CORRIDOR, {[]{return (WaterTempleLow || WaterTempleMiddle) && (CanUse(SLINGSHOT) || CanUse(BOW)) && (CanUse(LONGSHOT) || CanUse(HOVER_BOOTS) || (LogicWaterCentralBow && (IsAdult || WaterTempleMiddle)));}}), - Entrance(WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return WaterTempleHigh && SmallKeys(WATER_TEMPLE, 4);}}), - Entrance(WATER_TEMPLE_PRE_BOSS_ROOM, {[]{return WaterTempleHigh && CanUse(LONGSHOT);}}), + Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return logic->WaterTempleLow || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && (logic->CanUse(RG_IRON_BOOTS) || (logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_WATER_LONGSHOT_TORCH))));}}), + Entrance(RR_WATER_TEMPLE_NORTH_LOWER, {[]{return logic->WaterTempleLow || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_WATER_TEMPLE_SOUTH_LOWER, {[]{return logic->WaterTempleLow && logic->HasExplosives() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}}), + Entrance(RR_WATER_TEMPLE_WEST_LOWER, {[]{return logic->WaterTempleLow && logic->HasItem(RG_GORONS_BRACELET) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return logic->WaterTempleLow && logic->SmallKeys(RR_WATER_TEMPLE, 5);}}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle) && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}}), + Entrance(RR_WATER_TEMPLE_EAST_MIDDLE, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_WEST_MIDDLE, {[]{return logic->WaterTempleMiddle;}}), + Entrance(RR_WATER_TEMPLE_HIGH_WATER, {[]{return logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DAMAGE_BOOST) && logic->CanUse(RG_BOMB_BAG) && logic->TakeDamage()));}}), + Entrance(RR_WATER_TEMPLE_BLOCK_CORRIDOR, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_WATER_CENTRAL_BOW) && (logic->IsAdult || logic->WaterTempleMiddle)));}}), + Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return logic->WaterTempleHigh && logic->SmallKeys(RR_WATER_TEMPLE, 4);}}), + Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, {[]{return logic->WaterTempleHigh && logic->CanUse(RG_LONGSHOT);}}), }); - areaTable[WATER_TEMPLE_EAST_LOWER] = Area("Water Temple East Lower", "Water Temple", 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(&WaterTempleLow, {[]{return WaterTempleLow || CanPlay(ZeldasLullaby);}}), + EventAccess(&logic->WaterTempleLow, {[]{return logic->WaterTempleLow || logic->CanUse(RG_ZELDAS_LULLABY);}}), }, {}, { //Exits - Entrance(WATER_TEMPLE_LOBBY, {[]{return WaterTempleLow || ((LogicFewerTunicRequirements || CanUse(ZORA_TUNIC)) && CanUse(IRON_BOOTS));}}), - Entrance(WATER_TEMPLE_MAP_ROOM, {[]{return WaterTempleHigh;}}), - Entrance(WATER_TEMPLE_CRACKED_WALL, {[]{return WaterTempleMiddle || (WaterTempleHigh && WaterTempleLow && ((CanUse(HOVER_BOOTS) && LogicWaterCrackedWallHovers) || LogicWaterCrackedWallNothing));}}), - Entrance(WATER_TEMPLE_TORCH_ROOM, {[]{return WaterTempleLow && (HasFireSourceWithTorch || CanUse(BOW));}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->WaterTempleLow || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_WATER_TEMPLE_MAP_ROOM, {[]{return logic->WaterTempleHigh;}}), + Entrance(RR_WATER_TEMPLE_CRACKED_WALL, {[]{return logic->WaterTempleMiddle || (logic->WaterTempleHigh && logic->WaterTempleLow && ((logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_WATER_CRACKED_WALL_HOVERS)) || ctx->GetTrickOption(RT_WATER_CRACKED_WALL)));}}), + Entrance(RR_WATER_TEMPLE_TORCH_ROOM, {[]{return logic->WaterTempleLow && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}}), }); - areaTable[WATER_TEMPLE_MAP_ROOM] = Area("Water Temple Map Room", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_MAP_CHEST, {[]{return (MagicMeter && CanUse(KOKIRI_SWORD)) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(HOOKSHOT);}}), + LOCATION(RC_WATER_TEMPLE_MAP_CHEST, (logic->CanUse(RG_MAGIC_SINGLE) && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT)), }, { //Exits - Entrance(WATER_TEMPLE_EAST_LOWER, {[]{return (MagicMeter && CanUse(KOKIRI_SWORD)) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return (logic->CanUse(RG_MAGIC_SINGLE) && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[WATER_TEMPLE_CRACKED_WALL] = Area("Water Temple Cracked Wall", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_CRACKED_WALL_CHEST, {[]{return HasExplosives;}}), + LOCATION(RC_WATER_TEMPLE_CRACKED_WALL_CHEST, logic->HasExplosives()), }, { //Exits - Entrance(WATER_TEMPLE_EAST_LOWER, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return true;}}), }); - areaTable[WATER_TEMPLE_TORCH_ROOM] = Area("Water Temple Torch Room", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_TORCHES_CHEST, {[]{return (MagicMeter && CanUse(KOKIRI_SWORD)) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(HOOKSHOT);}}), + LOCATION(RC_WATER_TEMPLE_TORCHES_CHEST, (logic->CanUse(RG_MAGIC_SINGLE) && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT)), }, { //Exits - Entrance(WATER_TEMPLE_EAST_LOWER, {[]{return (MagicMeter && CanUse(KOKIRI_SWORD)) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD) || CanUse(HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return (logic->CanUse(RG_MAGIC_SINGLE) && logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[WATER_TEMPLE_NORTH_LOWER] = Area("Water Temple North Lower", "Water Temple", 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(WATER_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(WATER_TEMPLE_BOULDERS_LOWER, {[]{return (CanUse(LONGSHOT) || (LogicWaterBossKeyRegion && CanUse(HOVER_BOOTS))) && SmallKeys(WATER_TEMPLE, 4);}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_BOULDERS_LOWER, {[]{return (logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_WATER_BK_REGION) && logic->CanUse(RG_HOVER_BOOTS))) && logic->SmallKeys(RR_WATER_TEMPLE, 4);}}), }); - areaTable[WATER_TEMPLE_BOULDERS_LOWER] = Area("Water Temple Boulders Lower", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, {[]{return CanUse(LONGSHOT) || Here(WATER_TEMPLE_BOULDERS_UPPER, []{return (IsAdult && HookshotOrBoomerang) || (CanUse(IRON_BOOTS) && CanUse(HOOKSHOT));});}}), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_LONGSHOT) || Here(RR_WATER_TEMPLE_BOULDERS_UPPER, []{return (logic->IsAdult && logic->HookshotOrBoomerang()) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT));})), }, { //Exits - Entrance(WATER_TEMPLE_NORTH_LOWER, {[]{return SmallKeys(WATER_TEMPLE, 4);}}), - Entrance(WATER_TEMPLE_BLOCK_ROOM, {[]{return true;}}), - Entrance(WATER_TEMPLE_BOULDERS_UPPER, {[]{return (IsAdult && (CanUse(HOVER_BOOTS) || LogicWaterNorthBasementLedgeJump)) || (CanUse(HOVER_BOOTS) && CanUse(IRON_BOOTS));}}), + Entrance(RR_WATER_TEMPLE_NORTH_LOWER, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 4);}}), + Entrance(RR_WATER_TEMPLE_BLOCK_ROOM, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, {[]{return (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP))) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_IRON_BOOTS));}}), }); - areaTable[WATER_TEMPLE_BLOCK_ROOM] = Area("Water Temple Block Room", "Water Temple", 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(WATER_TEMPLE_BOULDERS_LOWER, {[]{return (GoronBracelet && HasExplosives) || CanUse(HOOKSHOT);}}), - Entrance(WATER_TEMPLE_JETS_ROOM, {[]{return (GoronBracelet && HasExplosives) || (CanUse(HOOKSHOT) && CanUse(HOVER_BOOTS));}}), + Entrance(RR_WATER_TEMPLE_BOULDERS_LOWER, {[]{return (logic->HasItem(RG_GORONS_BRACELET) && logic->HasExplosives()) || logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_JETS_ROOM, {[]{return (logic->HasItem(RG_GORONS_BRACELET) && logic->HasExplosives()) || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_HOVER_BOOTS));}}), }); - areaTable[WATER_TEMPLE_JETS_ROOM] = Area("Water Temple Jets Room", "Water Temple", 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(WATER_TEMPLE_BLOCK_ROOM, {[]{return CanUse(HOOKSHOT);}}), - Entrance(WATER_TEMPLE_BOULDERS_UPPER, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_BLOCK_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, {[]{return true;}}), }); - areaTable[WATER_TEMPLE_BOULDERS_UPPER] = Area("Water Temple Boulders Upper", "Water Temple", 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(WATER_TEMPLE_BOULDERS_LOWER, {[]{return true;}}), - Entrance(WATER_TEMPLE_JETS_ROOM, {[]{return IsAdult;}}), - Entrance(WATER_TEMPLE_BOSS_KEY_ROOM, {[]{return (CanUse(IRON_BOOTS) || (IsAdult && LogicWaterBKJumpDive)) && SmallKeys(WATER_TEMPLE, 5);}}), + Entrance(RR_WATER_TEMPLE_BOULDERS_LOWER, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_JETS_ROOM, {[]{return logic->IsAdult;}}), + Entrance(RR_WATER_TEMPLE_BOSS_KEY_ROOM, {[]{return (logic->CanUse(RG_IRON_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_WATER_BK_JUMP_DIVE))) && logic->SmallKeys(RR_WATER_TEMPLE, 5);}}), }); - areaTable[WATER_TEMPLE_BOSS_KEY_ROOM] = Area("Water Temple Boss Key Room", "Water Temple", 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(&FairyPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations - LocationAccess(WATER_TEMPLE_BOSS_KEY_CHEST, {[]{return true;}}), + LOCATION(RC_WATER_TEMPLE_BOSS_KEY_CHEST, true), }, { //Exits - Entrance(WATER_TEMPLE_BOULDERS_UPPER, {[]{return (CanUse(IRON_BOOTS) || (IsAdult && LogicWaterBKJumpDive) || IsChild || CanDive) && SmallKeys(WATER_TEMPLE, 5);}}), + Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, {[]{return (logic->CanUse(RG_IRON_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_WATER_BK_JUMP_DIVE)) || logic->IsChild || logic->HasItem(RG_SILVER_SCALE)) && logic->SmallKeys(RR_WATER_TEMPLE, 5);}}), }); - areaTable[WATER_TEMPLE_SOUTH_LOWER] = Area("Water Temple South Lower", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_GS_BEHIND_GATE, {[]{return (CanJumpslash || CanUse(MEGATON_HAMMER)) && (CanUse(HOOKSHOT) || (IsAdult && CanUse(HOVER_BOOTS)));}}), + LOCATION(RC_WATER_TEMPLE_GS_BEHIND_GATE, (logic->CanJumpslash() || logic->CanUse(RG_MEGATON_HAMMER)) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), }, { //Exits - Entrance(WATER_TEMPLE_LOBBY, {[]{return CanUse(IRON_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_IRON_BOOTS);}}), }); - areaTable[WATER_TEMPLE_WEST_LOWER] = Area("Water Temple West Lower", "Water Temple", 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(WATER_TEMPLE_LOBBY, {[]{return CanUse(HOOKSHOT) && CanUse(IRON_BOOTS) && GoronBracelet;}}), - Entrance(WATER_TEMPLE_DRAGON_ROOM, {[]{return CanJumpslash || CanUseProjectile;}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_GORONS_BRACELET);}}), + Entrance(RR_WATER_TEMPLE_DRAGON_ROOM, {[]{return logic->CanJumpslash() || logic->CanUseProjectile();}}), }); - areaTable[WATER_TEMPLE_DRAGON_ROOM] = Area("Water Temple Dragon Room", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_DRAGON_CHEST, {[]{return (CanUse(HOOKSHOT) && CanUse(IRON_BOOTS)) || (((IsAdult && LogicWaterDragonAdult && (CanUse(HOOKSHOT) || CanUse(BOW) || HasBombchus)) || (IsChild && LogicWaterDragonChild && (CanUse(SLINGSHOT) || CanUse(BOOMERANG) || HasBombchus))) && (CanDive || CanUse(IRON_BOOTS))) || - Here(WATER_TEMPLE_RIVER, []{return IsAdult && CanUse(BOW) && ((LogicWaterDragonAdult && (CanDive || CanUse(IRON_BOOTS))) || LogicWaterDragonJumpDive);});}}), + LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOMBCHU_5))) || (logic->IsChild && ctx->GetTrickOption(RT_WATER_CHILD_DRAGON) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5)))) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))) || + Here(RR_WATER_TEMPLE_RIVER, []{return logic->IsAdult && logic->CanUse(RG_FAIRY_BOW) && ((ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))) || ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE));})), }, { //Exits - Entrance(WATER_TEMPLE_WEST_LOWER, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_WEST_LOWER, {[]{return true;}}), }); - areaTable[WATER_TEMPLE_CENTRAL_PILLAR_LOWER] = Area("Water Temple Central Pillar Lower", "Water Temple", 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(WATER_TEMPLE_LOBBY, {[]{return SmallKeys(WATER_TEMPLE, 5);}}), - Entrance(WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return CanUse(HOOKSHOT);}}), - Entrance(WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, {[]{return WaterTempleMiddle && CanUse(IRON_BOOTS) && WaterTimer >= 40;}}), + 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[WATER_TEMPLE_CENTRAL_PILLAR_UPPER] = Area("Water Temple Central Pillar Upper", "Water Temple", 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(&WaterTempleMiddle, {[]{return WaterTempleMiddle || CanPlay(ZeldasLullaby);}}), + EventAccess(&logic->WaterTempleMiddle, {[]{return logic->WaterTempleMiddle || logic->CanUse(RG_ZELDAS_LULLABY);}}), }, { //Locations - LocationAccess(WATER_TEMPLE_GS_CENTRAL_PILLAR, {[]{return CanUse(LONGSHOT) || (((LogicWaterCentralGSFW && CanUse(FARORES_WIND) && (CanUse(BOW) || CanUse(DINS_FIRE) || SmallKeys(WATER_TEMPLE, 5))) || (LogicWaterCentralGSIrons && CanUse(IRON_BOOTS) && ((CanUse(HOOKSHOT) && CanUse(BOW)) || (CanUse(DINS_FIRE))))) && WaterTempleHigh && HookshotOrBoomerang);}}), + LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(RR_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->WaterTempleHigh && logic->HookshotOrBoomerang())), }, { //Exits - Entrance(WATER_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return true;}}), }); - areaTable[WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT] = Area("Water Temple Central Pillar Basement", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_CENTRAL_PILLAR_CHEST, {[]{return CanUse(HOOKSHOT) && CanUse(IRON_BOOTS) && WaterTimer >= 40;}}), + LOCATION(RC_WATER_TEMPLE_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40), }, { //Exits - Entrance(WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return CanUse(IRON_BOOTS) && WaterTimer >= 16;}}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16;}}), }); - areaTable[WATER_TEMPLE_EAST_MIDDLE] = Area("Water Temple East Middle", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_COMPASS_CHEST, {[]{return CanUseProjectile;}}), + LOCATION(RC_WATER_TEMPLE_COMPASS_CHEST, logic->CanUseProjectile()), }, { //Exits - Entrance(WATER_TEMPLE_LOBBY, {[]{return CanUse(IRON_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_IRON_BOOTS);}}), }); - areaTable[WATER_TEMPLE_WEST_MIDDLE] = Area("Water Temple West Middle", "Water Temple", 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(WATER_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(WATER_TEMPLE_HIGH_WATER, {[]{return CanUseProjectile;}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_HIGH_WATER, {[]{return logic->CanUseProjectile();}}), }); - areaTable[WATER_TEMPLE_HIGH_WATER] = Area("Water Temple High Water", "Water Temple", 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(&WaterTempleHigh, {[]{return WaterTempleHigh || CanPlay(ZeldasLullaby);}}), + EventAccess(&logic->WaterTempleHigh, {[]{return logic->WaterTempleHigh || logic->CanUse(RG_ZELDAS_LULLABY);}}), }, {}, { //Exits - Entrance(WATER_TEMPLE_LOBBY, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), }); - areaTable[WATER_TEMPLE_BLOCK_CORRIDOR] = Area("Water Temple Block Corridor", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, {[]{return GoronBracelet && (WaterTempleLow || WaterTempleMiddle);}}), + LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->WaterTempleLow || logic->WaterTempleMiddle)), }, { //Exits - Entrance(WATER_TEMPLE_LOBBY, {[]{return CanUse(HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[WATER_TEMPLE_FALLING_PLATFORM_ROOM] = Area("Water Temple Falling Platform Room", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, {[]{return CanUse(LONGSHOT) || (LogicWaterFallingPlatformGSBoomerang && IsChild && CanUse(BOOMERANG)) || (LogicWaterFallingPlatformGSHookshot && IsAdult && CanUse(HOOKSHOT));}}), + LOCATION(RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_WATER_RANG_FALLING_PLATFORM_GS) && logic->IsChild && logic->CanUse(RG_BOOMERANG)) || (ctx->GetTrickOption(RT_WATER_HOOKSHOT_FALLING_PLATFORM_GS) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT))), }, { //Exits - Entrance(WATER_TEMPLE_LOBBY, {[]{return CanUse(HOOKSHOT) && SmallKeys(WATER_TEMPLE, 4);}}), - Entrance(WATER_TEMPLE_DRAGON_PILLARS_ROOM, {[]{return CanUse(HOOKSHOT) && SmallKeys(WATER_TEMPLE, 5);}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_WATER_TEMPLE, 4);}}), + Entrance(RR_WATER_TEMPLE_DRAGON_PILLARS_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_WATER_TEMPLE, 5);}}), }); - areaTable[WATER_TEMPLE_DRAGON_PILLARS_ROOM] = Area("Water Temple Dragon Pillars Room", "Water Temple", 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(WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return CanUseProjectile;}}), - Entrance(WATER_TEMPLE_DARK_LINK_ROOM, {[]{return CanUse(HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return logic->CanUseProjectile();}}), + Entrance(RR_WATER_TEMPLE_DARK_LINK_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[WATER_TEMPLE_DARK_LINK_ROOM] = Area("Water Temple Dark Link Room", "Water Temple", 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(WATER_TEMPLE_DRAGON_PILLARS_ROOM, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), - Entrance(WATER_TEMPLE_LONGSHOT_ROOM, {[]{return CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD);}}), + 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[WATER_TEMPLE_LONGSHOT_ROOM] = Area("Water Temple Longshot Room", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_LONGSHOT_CHEST, {[]{return true;}}), + LOCATION(RC_WATER_TEMPLE_LONGSHOT_CHEST, true), }, { //Exits - Entrance(WATER_TEMPLE_DARK_LINK_ROOM, {[]{return true;}}), - Entrance(WATER_TEMPLE_RIVER, {[]{return IsChild || CanPlay(SongOfTime);}}), + Entrance(RR_WATER_TEMPLE_DARK_LINK_ROOM, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_RIVER, {[]{return logic->IsChild || logic->CanUse(RG_SONG_OF_TIME);}}), }); - areaTable[WATER_TEMPLE_RIVER] = Area("Water Temple River", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_RIVER_CHEST, {[]{return (CanUse(SLINGSHOT) || CanUse(BOW)) && (IsAdult || CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT));}}), - LocationAccess(WATER_TEMPLE_GS_RIVER, {[]{return (CanUse(IRON_BOOTS) && CanUse(HOOKSHOT)) || (LogicWaterRiverGS && CanUse(LONGSHOT));}}), + 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)) || (ctx->GetTrickOption(RT_WATER_RIVER_GS) && logic->CanUse(RG_LONGSHOT))), }, { //Exits - Entrance(WATER_TEMPLE_DRAGON_ROOM, {[]{return (CanUse(SLINGSHOT) || CanUse(BOW)) && (IsAdult || CanUse(HOVER_BOOTS) || CanUse(HOOKSHOT));}}), + 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[WATER_TEMPLE_PRE_BOSS_ROOM] = Area("Water Temple Pre Boss Room", "Water Temple", 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(&FairyPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), }, {}, { //Exits - Entrance(WATER_TEMPLE_LOBBY, {[]{return true;}}), - Entrance(WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyWaterTemple;}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY);}}), }); } /*--------------------------- | MASTER QUEST DUNGEON | ---------------------------*/ - if (Dungeon::WaterTemple.IsMQ()) { - areaTable[WATER_TEMPLE_MQ_LOBBY] = Area("Water Temple MQ Lobby", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, { + if (ctx->GetDungeon(WATER_TEMPLE)->IsMQ()) { + areaTable[RR_WATER_TEMPLE_MQ_LOBBY] = Region("Water Temple MQ Lobby", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(WATER_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(WATER_TEMPLE_MQ_DIVE, {[]{return IsAdult && WaterTimer >= 24 && CanUse(IRON_BOOTS);}}), - Entrance(WATER_TEMPLE_MQ_DARK_LINK_REGION, {[]{return SmallKeys(WATER_TEMPLE, 1) && IsAdult && CanUse(LONGSHOT) && CanJumpslash && Hearts > 0;}}), - Entrance(WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return BossKeyWaterTemple && IsAdult && CanJumpslash && CanUse(LONGSHOT);}}), + Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_DIVE, {[]{return logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_IRON_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_MQ_DARK_LINK_REGION, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslash();}}), + Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY) && logic->IsAdult && logic->CanJumpslash() && logic->CanUse(RG_LONGSHOT);}}), }); - areaTable[WATER_TEMPLE_MQ_DIVE] = Area("Water Temple MQ Dive", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_MQ_MAP_CHEST, {[]{return HasFireSource && IsAdult && CanUse(HOOKSHOT);}}), - LocationAccess(WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, {[]{return IsAdult && CanUse(ZORA_TUNIC) && CanUse(HOOKSHOT) && ((LogicWaterMQCentralPillar && CanUse(FIRE_ARROWS)) || (CanUse(DINS_FIRE) && CanPlay(SongOfTime)));}}), - //Trick: IsAdult && CanUse(ZORA_TUNIC) && CanUse(HOOKSHOT) && ((LogicWaterMQCentralPillar && CanUse(FIRE_ARROWS)) || (CanUse(DINS_FIRE) && CanPlay(SongOfTime))) + LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->HasFireSource() && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->IsAdult && logic->CanUse(RG_ZORA_TUNIC) && logic->CanUse(RG_HOOKSHOT) && ((ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS)) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_SONG_OF_TIME)))), + //Trick: logic->IsAdult && logic->CanUse(RG_ZORA_TUNIC) && logic->CanUse(RG_HOOKSHOT) && ((LogicWaterMQCentralPillar && logic->CanUse(RG_FIRE_ARROWS)) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_SONG_OF_TIME))) }, { //Exits - Entrance(WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS, {[]{return CanPlay(ZeldasLullaby);}}), + Entrance(RR_WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}), }); - areaTable[WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS] = Area("Water Temple MQ Lowered Water Levels", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_MQ_COMPASS_CHEST, {[]{return ((IsAdult && CanUse(BOW)) || CanUse(DINS_FIRE) || Here(WATER_TEMPLE_MQ_LOBBY, []{return IsChild && CanUse(STICKS) && HasExplosives;})) && - (CanJumpslash || CanUseProjectile);}}), - LocationAccess(WATER_TEMPLE_MQ_LONGSHOT_CHEST, {[]{return IsAdult && CanUse(HOOKSHOT);}}), - LocationAccess(WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, {[]{return CanUse(DINS_FIRE);}}), - LocationAccess(WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, {[]{return IsAdult && CanUse(LONGSHOT);}}), + LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, ((logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || logic->CanUse(RG_DINS_FIRE) || Here(RR_WATER_TEMPLE_MQ_LOBBY, []{return logic->IsChild && logic->CanUse(RG_STICKS) && logic->HasExplosives();})) && + (logic->CanJumpslash() || logic->CanUseProjectile())), + LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, logic->IsAdult && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, logic->IsAdult && logic->CanUse(RG_LONGSHOT)), }, {}); - areaTable[WATER_TEMPLE_MQ_DARK_LINK_REGION] = Area("Water Temple MQ Dark Link Region", "Water Temple", 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(&FairyPot, {[]{return true;}}), - EventAccess(&NutPot, {[]{return true;}}), + EventAccess(&logic->FairyPot, {[]{return true;}}), + EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LocationAccess(WATER_TEMPLE_MQ_BOSS_KEY_CHEST, {[]{return IsAdult && WaterTimer >= 24 && CanUse(DINS_FIRE) && (LogicWaterDragonJumpDive || CanDive || CanUse(IRON_BOOTS));}}), - LocationAccess(WATER_TEMPLE_MQ_GS_RIVER, {[]{return true;}}), + LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE) || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_WATER_TEMPLE_MQ_GS_RIVER, true), }, { //Exits - Entrance(WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS, {[]{return IsAdult && WaterTimer >= 24 && CanUse(DINS_FIRE) && CanUse(IRON_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS, {[]{return logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_IRON_BOOTS);}}), }); - areaTable[WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS] = Area("Water Temple MQ Basement Gated Areas", "Water Temple", 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 - LocationAccess(WATER_TEMPLE_MQ_FREESTANDING_KEY, {[]{return HoverBoots || CanUse(SCARECROW) || LogicWaterNorthBasementLedgeJump;}}), - LocationAccess(WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, {[]{return CanUse(FIRE_ARROWS) && (HoverBoots || CanUse(SCARECROW));}}), - LocationAccess(WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, {[]{return LogicWaterMQLockedGS || (SmallKeys(WATER_TEMPLE, 2) && (HoverBoots || CanUse(SCARECROW) || LogicWaterNorthBasementLedgeJump) && CanJumpslash);}}), - //Trick: LogicWaterMQLockedGS || (SmallKeys(WATER_TEMPLE, 2) && (HoverBoots || CanUse(SCARECROW) || LogicWaterNorthBasementLedgeJump)) + LOCATION(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP)), + LOCATION(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, logic->CanUse(RG_FIRE_ARROWS) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW))), + LOCATION(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, ctx->GetTrickOption(RT_WATER_MQ_LOCKED_GS) || (logic->SmallKeys(RR_WATER_TEMPLE, 2) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP)) && logic->CanJumpslash())), + //Trick: LogicWaterMQLockedGS || (logic->SmallKeys(RR_WATER_TEMPLE, 2) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW) || LogicWaterNorthBasementLedgeJump)) }, {}); } /*--------------------------- | BOSS ROOM | ---------------------------*/ - areaTable[WATER_TEMPLE_BOSS_ENTRYWAY] = - Area("Water Temple Boss Entryway", "Water Temple", WATER_TEMPLE, NO_DAY_NIGHT_CYCLE, {}, {}, + areaTable[RR_WATER_TEMPLE_BOSS_ENTRYWAY] = + Region("Water Temple Boss Entryway", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - Entrance(WATER_TEMPLE_PRE_BOSS_ROOM, { [] { return Dungeon::WaterTemple.IsVanilla() && false; } }), - Entrance(WATER_TEMPLE_MQ_LOBBY, { [] { return Dungeon::WaterTemple.IsMQ() && false; } }), - Entrance(WATER_TEMPLE_BOSS_ROOM, { [] { return true; } }), + Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, { [] { return ctx->GetDungeon(WATER_TEMPLE)->IsVanilla() && false; } }), + Entrance(RR_WATER_TEMPLE_MQ_LOBBY, { [] { return ctx->GetDungeon(WATER_TEMPLE)->IsMQ() && false; } }), + Entrance(RR_WATER_TEMPLE_BOSS_ROOM, { [] { return true; } }), }); - areaTable[WATER_TEMPLE_BOSS_ROOM] = Area( - "Water Temple Boss Room", "Water Temple", NONE, NO_DAY_NIGHT_CYCLE, + areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", "Water Temple", {}, NO_DAY_NIGHT_CYCLE, { // Events - EventAccess(&WaterTempleClear, { [] { - return WaterTempleClear || - (CanUse(HOOKSHOT) && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD))); + EventAccess(&logic->WaterTempleClear, { [] { + return logic->WaterTempleClear || (logic->HasBossSoul(RG_MORPHA_SOUL) && + (logic->CanUse(RG_HOOKSHOT) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)))); } }), }, { // Locations - LocationAccess(WATER_TEMPLE_MORPHA_HEART, { [] { return WaterTempleClear; } }), - LocationAccess(MORPHA, { [] { return WaterTempleClear; } }), + LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleClear), + LOCATION(RC_MORPHA, logic->WaterTempleClear), }, { // Exits - Entrance(WATER_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), - Entrance(LAKE_HYLIA, { [] { return WaterTempleClear; } }), + Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, { [] { return false; } }), + Entrance(RR_LAKE_HYLIA, { [] { return logic->WaterTempleClear; } }, false), }); } 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 434095145f0..658cc29f667 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 @@ -1,166 +1,177 @@ #include "../location_access.hpp" -#include "../logic.hpp" -#include "../entrance.hpp" +#include "../../entrance.h" -using namespace Logic; -using namespace Settings; +using namespace Rando; -void AreaTable_Init_ZorasDomain() { - areaTable[ZR_FRONT] = Area("ZR Front", "Zora River", 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 - LocationAccess(ZR_GS_TREE, {[]{return IsChild && CanChildAttack;}}), + LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanAttack()), }, { //Exits - Entrance(ZORAS_RIVER, {[]{return IsAdult || CanBlastOrSmash;}}), - Entrance(HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_ZORAS_RIVER, {[]{return logic->IsAdult || logic->BlastOrSmash();}}), + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[ZORAS_RIVER] = Area("Zora River", "Zora River", ZORAS_RIVER, DAY_NIGHT_CYCLE, { + areaTable[RR_ZORAS_RIVER] = Region("Zora River", "Zora River", {RA_ZORAS_RIVER}, DAY_NIGHT_CYCLE, { //Events - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairy;}}), - EventAccess(&BeanPlantFairy, {[]{return BeanPlantFairy || (CanPlantBean(ZORAS_RIVER) && CanPlay(SongOfStorms));}}), - EventAccess(&ButterflyFairy, {[]{return ButterflyFairy || CanUse(STICKS);}}), - EventAccess(&BugShrub, {[]{return BugShrub || CanCutShrubs;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_ZORAS_RIVER) && logic->CanUse(RG_SONG_OF_STORMS));}}), + EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}}), + EventAccess(&logic->BugShrub, {[]{return logic->BugShrub || logic->CanCutShrubs();}}), }, { //Locations - LocationAccess(ZR_MAGIC_BEAN_SALESMAN, {[]{return IsChild;}}), - LocationAccess(ZR_FROGS_OCARINA_GAME, {[]{return IsChild && CanPlay(ZeldasLullaby) && CanPlay(SariasSong) && CanPlay(SunsSong) && CanPlay(EponasSong) && CanPlay(SongOfTime) && CanPlay(SongOfStorms);}}), - LocationAccess(ZR_FROGS_IN_THE_RAIN, {[]{return IsChild && CanPlay(SongOfStorms);}}), - LocationAccess(ZR_FROGS_ZELDAS_LULLABY, {[]{return IsChild && CanPlay(ZeldasLullaby);}}), - LocationAccess(ZR_FROGS_EPONAS_SONG, {[]{return IsChild && CanPlay(EponasSong);}}), - LocationAccess(ZR_FROGS_SARIAS_SONG, {[]{return IsChild && CanPlay(SariasSong);}}), - LocationAccess(ZR_FROGS_SUNS_SONG, {[]{return IsChild && CanPlay(SunsSong);}}), - LocationAccess(ZR_FROGS_SONG_OF_TIME, {[]{return IsChild && CanPlay(SongOfTime);}}), - LocationAccess(ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, {[]{return IsChild || CanUse(HOVER_BOOTS) || (IsAdult && LogicZoraRiverLower);}}), - LocationAccess(ZR_NEAR_DOMAIN_FREESTANDING_POH, {[]{return IsChild || CanUse(HOVER_BOOTS) || (IsAdult && LogicZoraRiverUpper);}}), - LocationAccess(ZR_GS_LADDER, {[]{return IsChild && AtNight && CanChildAttack && CanGetNightTimeGS;}}), - LocationAccess(ZR_GS_NEAR_RAISED_GROTTOS, {[]{return IsAdult && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), - LocationAccess(ZR_GS_ABOVE_BRIDGE, {[]{return IsAdult && CanUse(HOOKSHOT) && AtNight && CanGetNightTimeGS;}}), - LocationAccess(ZR_NEAR_GROTTOS_GOSSIP_STONE, {[]{return true;}}), - LocationAccess(ZR_NEAR_DOMAIN_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), + LOCATION(RC_ZR_FROGS_OCARINA_GAME, logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanUse(RG_SARIAS_SONG) && logic->CanUse(RG_SUNS_SONG) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_FROGS_IN_THE_RAIN, logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_FROGS_ZELDAS_LULLABY, logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY)), + LOCATION(RC_ZR_FROGS_EPONAS_SONG, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_ZR_FROGS_SARIAS_SONG, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), + LOCATION(RC_ZR_FROGS_SUNS_SONG, logic->IsChild && logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_ZR_FROGS_SONG_OF_TIME, logic->IsChild && logic->CanUse(RG_SONG_OF_TIME)), + LOCATION(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, logic->IsChild || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_ZR_LOWER))), + LOCATION(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, logic->IsChild || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_ZR_UPPER))), + LOCATION(RC_ZR_GS_LADDER, logic->IsChild && logic->AtNight && logic->CanAttack() && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, true), + LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), }, { //Exits - Entrance(ZR_FRONT, {[]{return true;}}), - Entrance(ZR_OPEN_GROTTO, {[]{return true;}}), - Entrance(ZR_FAIRY_GROTTO, {[]{return Here(ZORAS_RIVER, []{return CanBlastOrSmash;});}}), - Entrance(THE_LOST_WOODS, {[]{return CanDive || CanUse(IRON_BOOTS);}}), - Entrance(ZR_STORMS_GROTTO, {[]{return CanOpenStormGrotto;}}), - Entrance(ZR_BEHIND_WATERFALL, {[]{return CanPlay(ZeldasLullaby) || (IsChild && LogicZoraWithCucco) || (IsAdult && CanUse(HOVER_BOOTS) && LogicZoraWithHovers);}}), + Entrance(RR_ZR_FRONT, {[]{return true;}}), + Entrance(RR_ZR_OPEN_GROTTO, {[]{return true;}}), + Entrance(RR_ZR_FAIRY_GROTTO, {[]{return Here(RR_ZORAS_RIVER, []{return logic->BlastOrSmash();});}}), + Entrance(RR_THE_LOST_WOODS, {[]{return logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS);}}), + Entrance(RR_ZR_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), + Entrance(RR_ZR_BEHIND_WATERFALL, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) || (logic->IsChild && ctx->GetTrickOption(RT_ZR_CUCCO)) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_ZR_HOVERS));}}), }); - areaTable[ZR_BEHIND_WATERFALL] = Area("ZR Behind Waterfall", "Zora River", ZORAS_RIVER, DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_ZR_BEHIND_WATERFALL] = Region("ZR Behind Waterfall", "Zora River", {RA_ZORAS_RIVER}, DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(ZORAS_RIVER, {[]{return true;}}), - Entrance(ZORAS_DOMAIN, {[]{return true;}}), + Entrance(RR_ZORAS_RIVER, {[]{return true;}}), + Entrance(RR_ZORAS_DOMAIN, {[]{return true;}}), }); - areaTable[ZR_OPEN_GROTTO] = Area("ZR Open Grotto", "ZR Open Grotto", NONE, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_ZR_OPEN_GROTTO] = Region("ZR Open Grotto", "ZR Open Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LocationAccess(ZR_OPEN_GROTTO_CHEST, {[]{return true;}}), - LocationAccess(ZR_OPEN_GROTTO_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_ZR_OPEN_GROTTO_CHEST, true), + LOCATION(RC_ZR_OPEN_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), + LOCATION(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), }, { //Exits - Entrance(ZORAS_RIVER, {[]{return true;}}), + Entrance(RR_ZORAS_RIVER, {[]{return true;}}), }); - areaTable[ZR_FAIRY_GROTTO] = Area("ZR Fairy Grotto", "ZR Fairy Grotto", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_ZR_FAIRY_GROTTO] = Region("ZR Fairy Grotto", "ZR Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Event - EventAccess(&FreeFairies, {[]{return true;}}), + EventAccess(&logic->FreeFairies, {[]{return true;}}), }, {}, { //Exits - Entrance(ZORAS_RIVER, {[]{return true;}}), + Entrance(RR_ZORAS_RIVER, {[]{return true;}}), }); - areaTable[ZR_STORMS_GROTTO] = Area("ZR Storms Grotto", "ZR Storms Grotto", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ZR_STORMS_GROTTO] = Region("ZR Storms Grotto", "ZR Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(ZR_DEKU_SCRUB_GROTTO_REAR, {[]{return CanStunDeku;}}), - LocationAccess(ZR_DEKU_SCRUB_GROTTO_FRONT, {[]{return CanStunDeku;}}), + LOCATION(RC_ZR_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()), + LOCATION(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()), + LOCATION(RC_ZR_STORMS_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(ZORAS_RIVER, {[]{return true;}}), + Entrance(RR_ZORAS_RIVER, {[]{return true;}}), }); - areaTable[ZORAS_DOMAIN] = Area("Zoras Domain", "Zoras Domain", ZORAS_DOMAIN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_ZORAS_DOMAIN] = Region("Zoras Domain", "Zoras Domain", {RA_ZORAS_DOMAIN}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&EyeballFrogAccess, {[]{return EyeballFrogAccess || (IsAdult && KingZoraThawed && (Eyedrops || EyeballFrog || Prescription || PrescriptionAccess));}}), - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairyWithoutSuns;}}), - EventAccess(&NutPot, {[]{return true;}}), - EventAccess(&StickPot, {[]{return StickPot || IsChild;}}), - EventAccess(&FishGroup, {[]{return FishGroup || IsChild;}}), - EventAccess(&KingZoraThawed, {[]{return KingZoraThawed || (IsAdult && BlueFire);}}), - EventAccess(&DeliverLetter, {[]{return DeliverLetter || (RutosLetter && IsChild && ZorasFountain.IsNot(ZORASFOUNTAIN_OPEN));}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), + EventAccess(&logic->NutPot, {[]{return true;}}), + EventAccess(&logic->StickPot, {[]{return logic->StickPot || logic->IsChild;}}), + EventAccess(&logic->FishGroup, {[]{return logic->FishGroup || logic->IsChild;}}), + EventAccess(&logic->KingZoraThawed, {[]{return logic->KingZoraThawed || (logic->IsAdult && logic->BlueFire());}}), + EventAccess(&logic->DeliverLetter, {[]{return logic->DeliverLetter || (logic->CanUse(RG_RUTOS_LETTER) && logic->IsChild && ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN));}}), }, { //Locations - LocationAccess(ZD_DIVING_MINIGAME, {[]{return IsChild;}}), - LocationAccess(ZD_CHEST, {[]{return IsChild && CanUse(STICKS);}}), - LocationAccess(ZD_KING_ZORA_THAWED, {[]{return KingZoraThawed;}}), - LocationAccess(ZD_TRADE_PRESCRIPTION, {[]{return KingZoraThawed && Prescription;}}), - LocationAccess(ZD_GS_FROZEN_WATERFALL, {[]{return IsAdult && AtNight && (HookshotOrBoomerang || CanUse(SLINGSHOT) || Bow || (MagicMeter && (CanUse(MASTER_SWORD) || CanUse(KOKIRI_SWORD) || CanUse(BIGGORON_SWORD))) || (LogicDomainGS && CanJumpslash)) && CanGetNightTimeGS;}}), - LocationAccess(ZD_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_ZD_DIVING_MINIGAME, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET) && logic->IsChild), + LOCATION(RC_ZD_CHEST, logic->IsChild && logic->CanUse(RG_STICKS)), + LOCATION(RC_ZD_KING_ZORA_THAWED, logic->KingZoraThawed), + LOCATION(RC_ZD_TRADE_PRESCRIPTION, logic->KingZoraThawed && logic->CanUse(RG_PRESCRIPTION)), + LOCATION(RC_ZD_GS_FROZEN_WATERFALL, logic->IsAdult && logic->AtNight && (logic->HookshotOrBoomerang() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || (logic->CanUse(RG_MAGIC_SINGLE) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))) || (ctx->GetTrickOption(RT_ZD_GS) && logic->CanJumpslash())) && logic->CanGetNightTimeGS()), + LOCATION(RC_ZD_FISH_1, logic->IsChild && logic->HasBottle()), + LOCATION(RC_ZD_FISH_2, logic->IsChild && logic->HasBottle()), + LOCATION(RC_ZD_FISH_3, logic->IsChild && logic->HasBottle()), + LOCATION(RC_ZD_FISH_4, logic->IsChild && logic->HasBottle()), + LOCATION(RC_ZD_FISH_5, logic->IsChild && logic->HasBottle()), + LOCATION(RC_ZD_GOSSIP_STONE, true), + LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, logic->CanBreakUpperBeehives()), + LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, logic->CanBreakUpperBeehives()), }, { //Exits - Entrance(ZR_BEHIND_WATERFALL, {[]{return true;}}), - Entrance(LAKE_HYLIA, {[]{return IsChild && (CanDive || CanUse(IRON_BOOTS));}}), - Entrance(ZD_BEHIND_KING_ZORA, {[]{return DeliverLetter || ZorasFountain.Is(ZORASFOUNTAIN_OPEN) || (ZorasFountain.Is(ZORASFOUNTAIN_ADULT) && IsAdult) || (LogicKingZoraSkip && IsAdult);}}), - Entrance(ZD_SHOP, {[]{return IsChild || BlueFire;}}), - Entrance(ZD_STORMS_GROTTO, {[]{return CanOpenStormGrotto;}}), + Entrance(RR_ZR_BEHIND_WATERFALL, {[]{return true;}}), + Entrance(RR_LAKE_HYLIA, {[]{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult) || (ctx->GetTrickOption(RT_ZD_KING_ZORA_SKIP) && logic->IsAdult);}}), + Entrance(RR_ZD_SHOP, {[]{return logic->IsChild || logic->BlueFire();}}), + Entrance(RR_ZD_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); - areaTable[ZD_BEHIND_KING_ZORA] = Area("ZD Behind King Zora", "Zoras Domain", 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()), + }, { //Exits - Entrance(ZORAS_DOMAIN, {[]{return DeliverLetter || ZorasFountain.Is(ZORASFOUNTAIN_OPEN) || (ZorasFountain.Is(ZORASFOUNTAIN_ADULT) && IsAdult);}}), - Entrance(ZORAS_FOUNTAIN, {[]{return true;}}), + Entrance(RR_ZORAS_DOMAIN, {[]{return logic->DeliverLetter || ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN) || (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_CLOSED_CHILD) && logic->IsAdult);}}), + Entrance(RR_ZORAS_FOUNTAIN, {[]{return true;}}), }); - areaTable[ZD_SHOP] = Area("ZD Shop", "ZD Shop", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ZD_SHOP] = Region("ZD Shop", "ZD Shop", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(ZD_SHOP_ITEM_1, {[]{return true;}}), - LocationAccess(ZD_SHOP_ITEM_2, {[]{return true;}}), - LocationAccess(ZD_SHOP_ITEM_3, {[]{return true;}}), - LocationAccess(ZD_SHOP_ITEM_4, {[]{return true;}}), - LocationAccess(ZD_SHOP_ITEM_5, {[]{return true;}}), - LocationAccess(ZD_SHOP_ITEM_6, {[]{return true;}}), - LocationAccess(ZD_SHOP_ITEM_7, {[]{return true;}}), - LocationAccess(ZD_SHOP_ITEM_8, {[]{return true;}}), + LOCATION(RC_ZD_SHOP_ITEM_1, true), + LOCATION(RC_ZD_SHOP_ITEM_2, true), + LOCATION(RC_ZD_SHOP_ITEM_3, true), + LOCATION(RC_ZD_SHOP_ITEM_4, true), + LOCATION(RC_ZD_SHOP_ITEM_5, true), + LOCATION(RC_ZD_SHOP_ITEM_6, true), + LOCATION(RC_ZD_SHOP_ITEM_7, true), + LOCATION(RC_ZD_SHOP_ITEM_8, true), }, { //Exits - Entrance(ZORAS_DOMAIN, {[]{return true;}}), + Entrance(RR_ZORAS_DOMAIN, {[]{return true;}}), }); - areaTable[ZD_STORMS_GROTTO] = Area("ZD Storms Grotto", "ZD Storms Grotto", NONE, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_ZD_STORMS_GROTTO] = Region("ZD Storms Grotto", "ZD Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&FreeFairies, {[]{return true;}}), + EventAccess(&logic->FreeFairies, {[]{return true;}}), }, {}, { //Exits - Entrance(ZORAS_DOMAIN, {[]{return true;}}), + Entrance(RR_ZORAS_DOMAIN, {[]{return true;}}), }); - areaTable[ZORAS_FOUNTAIN] = Area("Zoras Fountain", "Zoras Fountain", ZORAS_FOUNTAIN, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_ZORAS_FOUNTAIN] = Region("Zoras Fountain", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&GossipStoneFairy, {[]{return GossipStoneFairy || CanSummonGossipFairyWithoutSuns;}}), - EventAccess(&ButterflyFairy, {[]{return ButterflyFairy || (CanUse(STICKS) && AtDay);}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), + EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}), }, { //Locations - LocationAccess(ZF_ICEBERG_FREESTANDING_POH, {[]{return IsAdult;}}), - LocationAccess(ZF_BOTTOM_FREESTANDING_POH, {[]{return IsAdult && IronBoots && WaterTimer >= 24;}}), - LocationAccess(ZF_GS_TREE, {[]{return IsChild;}}), - LocationAccess(ZF_GS_ABOVE_THE_LOG, {[]{return IsChild && HookshotOrBoomerang && AtNight && CanGetNightTimeGS;}}), - LocationAccess(ZF_GS_HIDDEN_CAVE, {[]{return CanUse(SILVER_GAUNTLETS) && CanBlastOrSmash && HookshotOrBoomerang && IsAdult && AtNight && CanGetNightTimeGS;}}), - LocationAccess(ZF_FAIRY_GOSSIP_STONE, {[]{return true;}}), - LocationAccess(ZF_JABU_GOSSIP_STONE, {[]{return true;}}), + LOCATION(RC_ZF_ICEBERC_FREESTANDING_POH, logic->IsAdult), + LOCATION(RC_ZF_BOTTOM_FREESTANDING_POH, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24), + LOCATION(RC_ZF_GS_TREE, logic->IsChild), + LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_ZF_GS_HIDDEN_CAVE, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash() && logic->HookshotOrBoomerang() && logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE, true), + LOCATION(RC_ZF_JABU_GOSSIP_STONE, true), }, { //Exits - Entrance(ZD_BEHIND_KING_ZORA, {[]{return true;}}), - Entrance(JABU_JABUS_BELLY_ENTRYWAY, {[]{return (IsChild && Fish);}}), - Entrance(ICE_CAVERN_ENTRYWAY, {[]{return IsAdult;}}), - Entrance(ZF_GREAT_FAIRY_FOUNTAIN, {[]{return HasExplosives;}}), + Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, {[]{return (logic->IsChild && logic->CanUse(RG_BOTTLE_WITH_FISH));}}), + Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return logic->IsAdult;}}), + Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives();}}), }); - areaTable[ZF_GREAT_FAIRY_FOUNTAIN] = Area("ZF Great Fairy Fountain", "ZF Great Fairy Fountain", NONE, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ZF_GREAT_FAIRY_FOUNTAIN] = Region("ZF Great Fairy Fountain", "ZF Great Fairy Fountain", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LocationAccess(ZF_GREAT_FAIRY_REWARD, {[]{return CanPlay(ZeldasLullaby);}}), + LOCATION(RC_ZF_GREAT_FAIRY_REWARD, logic->CanUse(RG_ZELDAS_LULLABY)), }, { //Exits - Entrance(ZORAS_FOUNTAIN, {[]{return true;}}), + Entrance(RR_ZORAS_FOUNTAIN, {[]{return true;}}), }); } diff --git a/soh/soh/Enhancements/randomizer/3drando/logic.cpp b/soh/soh/Enhancements/randomizer/3drando/logic.cpp deleted file mode 100644 index df127e69931..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/logic.cpp +++ /dev/null @@ -1,1067 +0,0 @@ -#include "logic.hpp" - -#include -#include -#include -#include -#include - -#include "settings.hpp" -#include "dungeon.hpp" - -using namespace Settings; - -namespace Logic { - - bool noVariable = false; - - //Child item logic - bool KokiriSword = false; - bool ZeldasLetter = false; - bool WeirdEgg = false; - bool HasBottle = false; - bool Bombchus = false; - bool Bombchus5 = false; - bool Bombchus10 = false; - bool Bombchus20 = false; - bool MagicBean = false; - bool MagicBeanPack = false; - bool RutosLetter = false; - bool Boomerang = false; - bool DinsFire = false; - bool FaroresWind = false; - bool NayrusLove = false; - bool LensOfTruth = false; - bool ShardOfAgony = false; - bool SkullMask = false; - bool MaskOfTruth = false; - - //Adult logic - bool Hammer = false; - bool IronBoots = false; - bool HoverBoots = false; - bool MirrorShield = false; - bool GoronTunic = false; - bool ZoraTunic = false; - bool Epona = false; - bool BigPoe = false; - bool GerudoToken = false; - bool FireArrows = false; - bool IceArrows = false; - bool LightArrows = false; - bool MasterSword = false; - bool BiggoronSword = false; - - //Trade Quest - bool PocketEgg = false; - bool Cojiro = false; - bool OddMushroom = false; - bool OddPoultice = false; - bool PoachersSaw = false; - bool BrokenSword = false; - bool Prescription = false; - bool EyeballFrog = false; - bool Eyedrops = false; - bool ClaimCheck = false; - - //Trade Quest Events - bool WakeUpAdultTalon = false; - bool CojiroAccess = false; - bool OddMushroomAccess = false; - bool OddPoulticeAccess = false; - bool PoachersSawAccess = false; - bool BrokenSwordAccess = false; - bool PrescriptionAccess = false; - bool EyeballFrogAccess = false; - bool EyedropsAccess = false; - bool DisableTradeRevert = false; - - //Songs - bool ZeldasLullaby = false; - bool SariasSong = false; - bool SunsSong = false; - bool SongOfStorms = false; - bool EponasSong = false; - bool SongOfTime = false; - bool MinuetOfForest = false; - bool BoleroOfFire = false; - bool SerenadeOfWater = false; - bool RequiemOfSpirit = false; - bool NocturneOfShadow = false; - bool PreludeOfLight = false; - - //Stones and Meddallions - bool ForestMedallion = false; - bool FireMedallion = false; - bool WaterMedallion = false; - bool SpiritMedallion = false; - bool ShadowMedallion = false; - bool LightMedallion = false; - bool KokiriEmerald = false; - bool GoronRuby = false; - bool ZoraSapphire = false; - - //Dungeon Clears - bool DekuTreeClear = false; - bool DodongosCavernClear = false; - bool JabuJabusBellyClear = false; - bool ForestTempleClear = false; - bool FireTempleClear = false; - bool WaterTempleClear = false; - bool SpiritTempleClear = false; - bool ShadowTempleClear = false; - - //Trial Clears - bool ForestTrialClear = false; - bool FireTrialClear = false; - bool WaterTrialClear = false; - bool SpiritTrialClear = false; - bool ShadowTrialClear = false; - bool LightTrialClear = false; - - //Greg - bool Greg = false; - bool GregInBridgeLogic = false; - bool GregInLacsLogic = false; - - //Progressive Items - uint8_t ProgressiveBulletBag = 0; - uint8_t ProgressiveBombBag = 0; - uint8_t ProgressiveMagic = 0; - uint8_t ProgressiveScale = 0; - uint8_t ProgressiveHookshot = 0; - uint8_t ProgressiveBow = 0; - uint8_t ProgressiveWallet = 0; - uint8_t ProgressiveStrength = 0; - uint8_t ProgressiveOcarina = 0; - uint8_t ProgressiveGiantKnife = 0; - - //Logical keysanity - bool IsKeysanity = false; - - //Keys - uint8_t ForestTempleKeys = 0; - uint8_t FireTempleKeys = 0; - uint8_t WaterTempleKeys = 0; - uint8_t SpiritTempleKeys = 0; - uint8_t ShadowTempleKeys = 0; - uint8_t GanonsCastleKeys = 0; - uint8_t GerudoFortressKeys = 0; - uint8_t GerudoTrainingGroundsKeys = 0; - uint8_t BottomOfTheWellKeys = 0; - uint8_t TreasureGameKeys = 0; - - //Triforce Pieces - uint8_t TriforcePieces = 0; - - //Boss Keys - bool BossKeyForestTemple = false; - bool BossKeyFireTemple = false; - bool BossKeyWaterTemple = false; - bool BossKeySpiritTemple = false; - bool BossKeyShadowTemple = false; - bool BossKeyGanonsCastle = false; - - //Gold Skulltula Count - uint8_t GoldSkulltulaTokens = 0; - - //Bottle Count - uint8_t Bottles = 0; - uint8_t NumBottles = 0; - bool NoBottles = false; - - //Drops and Bottle Contents Access - bool DekuNutDrop = false; - bool NutPot = false; - bool NutCrate = false; - bool DekuBabaNuts = false; - bool DekuStickDrop = false; - bool StickPot = false; - bool DekuBabaSticks = false; - bool BugsAccess = false; - bool BugShrub = false; - bool WanderingBugs = false; - bool BugRock = false; - bool BlueFireAccess = false; - bool FishAccess = false; - bool FishGroup = false; - bool LoneFish = false; - bool FairyAccess = false; - bool GossipStoneFairy = false; - bool BeanPlantFairy = false; - bool ButterflyFairy = false; - bool FairyPot = false; - bool FreeFairies = false; - bool FairyPond = false; - bool BombchuDrop = false; - bool AmmoCanDrop = false; - - bool BuyBombchus10 = false; - bool BuyBombchus20 = false; - bool BuySeed = false; - bool BuyArrow = false; - bool BuyBomb = false; - bool BuyGPotion = false; - bool BuyBPotion = false; - bool MagicRefill = false; - - uint8_t PieceOfHeart = 0; - uint8_t HeartContainer = 0; - bool DoubleDefense = false; - - /* --- HELPERS, EVENTS, AND LOCATION ACCESS --- */ - /* These are used to simplify reading the logic, but need to be updated - / every time a base value is updated. */ - - bool Slingshot = false; - bool Ocarina = false; - bool OcarinaOfTime = false; - bool BombBag = false; - bool MagicMeter = false; - bool Hookshot = false; - bool Longshot = false; - bool Bow = false; - bool GoronBracelet = false; - bool SilverGauntlets = false; - bool GoldenGauntlets = false; - bool SilverScale = false; - bool GoldScale = false; - bool AdultsWallet = false; - - bool ChildScarecrow = false; - bool AdultScarecrow = false; - bool ScarecrowSong = false; - bool Scarecrow = false; - bool DistantScarecrow = false; - - bool Bombs = false; - bool DekuShield = false; - bool HylianShield = false; - bool Nuts = false; - bool Sticks = false; - bool Bugs = false; - bool BlueFire = false; - bool Fish = false; - bool Fairy = false; - bool BottleWithBigPoe = false; - - bool FoundBombchus = false; - bool CanPlayBowling = false; - bool HasBombchus = false; - bool HasExplosives = false; - bool HasBoots = false; - bool IsChild = false; - bool IsAdult = false; - bool IsGlitched = false; - bool CanBlastOrSmash = false; - bool CanChildAttack = false; - bool CanChildDamage = false; - bool CanAdultAttack = false; - bool CanAdultDamage = false; - bool CanCutShrubs = false; - bool CanDive = false; - bool CanLeaveForest = false; - bool CanPlantBugs = false; - bool CanRideEpona = false; - bool CanStunDeku = false; - bool CanSummonGossipFairy = false; - bool CanSummonGossipFairyWithoutSuns = false; - bool NeedNayrusLove = false; - bool CanSurviveDamage = false; - bool CanTakeDamage = false; - bool CanTakeDamageTwice = false; - //bool CanPlantBean = false; - bool CanOpenBombGrotto = false; - bool CanOpenStormGrotto = false; - bool BigPoeKill = false; - bool HookshotOrBoomerang = false; - bool CanGetNightTimeGS = false; - - uint8_t BaseHearts = 0; - uint8_t Hearts = 0; - uint8_t Multiplier = 0; - uint8_t EffectiveHealth = 0; - uint8_t FireTimer = 0; - uint8_t WaterTimer = 0; - - bool GuaranteeTradePath = false; - bool GuaranteeHint = false; - bool HasFireSource = false; - bool HasFireSourceWithTorch = false; - - bool CanFinishGerudoFortress = false; - - bool HasShield = false; - bool CanShield = false; - bool ChildShield = false; - bool AdultReflectShield = false; - bool AdultShield = false; - bool CanShieldFlick = false; - bool CanJumpslash = false; - bool CanUseProjectile = false; - bool CanUseMagicArrow = false; - - //Bridge and LACS Requirements - uint8_t StoneCount = 0; - uint8_t MedallionCount = 0; - uint8_t DungeonCount = 0; - bool HasAllStones = false; - bool HasAllMedallions = false; - bool CanBuildRainbowBridge = false; - bool BuiltRainbowBridge = false; - bool CanTriggerLACS = false; - - //Other - bool AtDay = false; - bool AtNight = false; - uint8_t Age = 0; - bool CanCompleteTriforce = false; - - //Events - bool ShowedMidoSwordAndShield = false; - bool CarpenterRescue = false; - bool GF_GateOpen = false; - bool GtG_GateOpen = false; - bool DampesWindmillAccess = false; - bool DrainWell = false; - bool GoronCityChildFire = false; - bool GCWoodsWarpOpen = false; - bool GCDaruniasDoorOpenChild = false; - bool StopGCRollingGoronAsAdult = false; - bool WaterTempleLow = false; - bool WaterTempleMiddle = false; - bool WaterTempleHigh = false; - bool KakarikoVillageGateOpen = false; - bool KingZoraThawed = false; - bool ForestTempleJoelle = false; - bool ForestTempleBeth = false; - bool ForestTempleJoAndBeth = false; - bool ForestTempleAmy = false; - bool ForestTempleMeg = false; - bool ForestTempleAmyAndMeg = false; - bool FireLoopSwitch = false; - bool LinksCow = false; - bool AtDampeTime = false; - bool DeliverLetter = false; - bool TimeTravel = false; - - /* --- END OF HELPERS AND LOCATION ACCESS --- */ - - //Placement Tracking - uint8_t AddedProgressiveBulletBags = 0; - uint8_t AddedProgressiveBombBags = 0; - uint8_t AddedProgressiveMagics = 0; - uint8_t AddedProgressiveScales = 0; - uint8_t AddedProgressiveHookshots = 0; - uint8_t AddedProgressiveBows = 0; - uint8_t AddedProgressiveWallets = 0; - uint8_t AddedProgressiveStrengths = 0; - uint8_t AddedProgressiveOcarinas = 0; - uint8_t TokensInPool = 0; - - //Event checking past - bool DrainWellPast = false; - bool DampesWindmillAccessPast = false; - bool DekuTreeClearPast = false; - bool GoronRubyPast = false; - bool ZoraSapphirePast = false; - bool ForestTrialClearPast = false; - bool FireTrialClearPast = false; - bool WaterTrialClearPast = false; - bool SpiritTrialClearPast = false; - bool ShadowTrialClearPast = false; - bool LightTrialClearPast = false; - bool BuyDekuShieldPast = false; - bool TimeTravelPast = false; - - bool CanPlay(bool song) { - return Ocarina && song; - } - - static bool IsMagicItem(uint32_t item) { - return item == DINS_FIRE || - item == FARORES_WIND || - item == NAYRUS_LOVE || - item == LENS_OF_TRUTH; - } - - static bool IsMagicArrow(uint32_t item) { - return item == FIRE_ARROWS || - item == ICE_ARROWS || - item == LIGHT_ARROWS; - } - - bool HasItem(uint32_t itemName) { - return (itemName == DINS_FIRE && DinsFire) || - (itemName == FARORES_WIND && FaroresWind) || - (itemName == NAYRUS_LOVE && NayrusLove) || - (itemName == LENS_OF_TRUTH && LensOfTruth) || - (itemName == BOW && Bow) || - (itemName == MEGATON_HAMMER && Hammer) || - (itemName == IRON_BOOTS && IronBoots) || - (itemName == HOVER_BOOTS && HoverBoots) || - (itemName == HOOKSHOT && Hookshot) || - (itemName == LONGSHOT && Longshot) || - (itemName == SILVER_GAUNTLETS && SilverGauntlets) || - (itemName == GOLDEN_GAUNTLETS && GoldenGauntlets) || - (itemName == GORON_TUNIC && GoronTunic) || - (itemName == ZORA_TUNIC && ZoraTunic) || - (itemName == SCARECROW && Scarecrow) || - (itemName == DISTANT_SCARECROW && DistantScarecrow)|| - (itemName == HYLIAN_SHIELD && HylianShield) || - (itemName == MIRROR_SHIELD && MirrorShield) || - (itemName == MASTER_SWORD && MasterSword) || - (itemName == BIGGORON_SWORD && BiggoronSword) || - (itemName == SLINGSHOT && Slingshot) || - (itemName == BOOMERANG && Boomerang) || - (itemName == KOKIRI_SWORD && KokiriSword) || - (itemName == STICKS && Sticks) || - (itemName == DEKU_SHIELD && DekuShield) || - (itemName == FIRE_ARROWS && FireArrows) || - (itemName == ICE_ARROWS && IceArrows) || - (itemName == LIGHT_ARROWS && LightArrows); - - } - - //Can the passed in item be used? - bool CanUse(uint32_t itemName) { - if (!HasItem(itemName)) - return false; - - switch (itemName) { - // Adult items - case BOW: return IsAdult || BowAsChild; - case MEGATON_HAMMER: return IsAdult || HammerAsChild; - case IRON_BOOTS: return IsAdult || IronBootsAsChild; - case HOVER_BOOTS: return IsAdult || HoverBootsAsChild; - case HOOKSHOT: return IsAdult || HookshotAsChild; - case LONGSHOT: return IsAdult || HookshotAsChild; - case SILVER_GAUNTLETS: return IsAdult; - case GOLDEN_GAUNTLETS: return IsAdult; - case GORON_TUNIC: return IsAdult || GoronTunicAsChild; - case ZORA_TUNIC: return IsAdult || ZoraTunicAsChild; - case SCARECROW: return IsAdult || HookshotAsChild; - case DISTANT_SCARECROW: return IsAdult || HookshotAsChild; - case HYLIAN_SHIELD: return IsAdult; - case MIRROR_SHIELD: return IsAdult || MirrorShieldAsChild; - case MASTER_SWORD: return IsAdult || MasterSwordAsChild; - case BIGGORON_SWORD: return IsAdult || BiggoronSwordAsChild; - - // Child items - case SLINGSHOT: return IsChild || SlingshotAsAdult; - case BOOMERANG: return IsChild || BoomerangAsAdult; - case KOKIRI_SWORD: return IsChild || KokiriSwordAsAdult; - case STICKS: return IsChild || StickAsAdult; - case DEKU_SHIELD: return IsChild || DekuShieldAsAdult; - - // Magic items - default: return MagicMeter && (IsMagicItem(itemName) || (IsMagicArrow(itemName) && CanUse(BOW))); - } - } - - bool HasProjectile(HasProjectileAge age) { - return HasExplosives || - (age == HasProjectileAge::Child && (Slingshot || Boomerang)) || - (age == HasProjectileAge::Adult && (Hookshot || Bow )) || - (age == HasProjectileAge::Both && (Slingshot || Boomerang) && (Hookshot || Bow)) || - (age == HasProjectileAge::Either && (Slingshot || Boomerang || Hookshot || Bow)); - } - - uint8_t GetDifficultyValueFromString(Option& glitchOption) { - return 0; - } - -//todo rewrite glitch section - - bool CanEquipSwap(uint32_t itemName) { - if (!HasItem(itemName)) - return false; - - if (CanDoGlitch(GlitchType::EquipSwapDins) || CanDoGlitch(GlitchType::EquipSwap)) - return true; - - return false; - } - - bool CanDoGlitch(GlitchType glitch) { - switch(glitch) { - case GlitchType::EquipSwapDins: - return ((IsAdult && HasItem(DINS_FIRE)) || (IsChild && (HasItem(STICKS) || HasItem(DINS_FIRE)))) && GlitchEquipSwapDins; - case GlitchType::EquipSwap: // todo: add bunny hood to adult item equippable list and child trade item to child item equippable list - return ((IsAdult && (HasItem(DINS_FIRE) || HasItem(FARORES_WIND) || HasItem(NAYRUS_LOVE))) || (IsChild && (HasItem(STICKS) || HasItem(SLINGSHOT) || HasItem(BOOMERANG) || HasBottle || Nuts || Ocarina || HasItem(LENS_OF_TRUTH) || HasExplosives || (MagicBean || MagicBeanPack) || HasItem(DINS_FIRE) || HasItem(FARORES_WIND) || HasItem(NAYRUS_LOVE)))) && GlitchEquipSwap; - } - - //Shouldn't be reached - return false; - } - - //Updates all logic helpers. Should be called whenever a non-helper is changed - void UpdateHelpers() { - NumBottles = ((NoBottles) ? 0 : (Bottles + ((DeliverLetter) ? 1 : 0))); - HasBottle = NumBottles >= 1; - Slingshot = (ProgressiveBulletBag >= 1) && (BuySeed || AmmoCanDrop); - Ocarina = ProgressiveOcarina >= 1; - OcarinaOfTime = ProgressiveOcarina >= 2; - MagicMeter = (ProgressiveMagic >= 1) && (AmmoCanDrop || (HasBottle && (BuyGPotion || BuyBPotion))); - BombBag = (ProgressiveBombBag >= 1) && (BuyBomb || AmmoCanDrop); - Hookshot = ProgressiveHookshot >= 1; - Longshot = ProgressiveHookshot >= 2; - Bow = (ProgressiveBow >= 1) && (BuyArrow || AmmoCanDrop); - GoronBracelet = ProgressiveStrength >= 1; - SilverGauntlets = ProgressiveStrength >= 2; - GoldenGauntlets = ProgressiveStrength >= 3; - SilverScale = ProgressiveScale >= 1; - GoldScale = ProgressiveScale >= 2; - AdultsWallet = ProgressiveWallet >= 1; - BiggoronSword = BiggoronSword || ProgressiveGiantKnife >= 2; - - ScarecrowSong = ScarecrowSong || FreeScarecrow || (ChildScarecrow && AdultScarecrow); - Scarecrow = Hookshot && CanPlay(ScarecrowSong); - DistantScarecrow = Longshot && CanPlay(ScarecrowSong); - - //Drop Access - DekuStickDrop = StickPot || DekuBabaSticks; - DekuNutDrop = (NutPot || NutCrate || DekuBabaNuts) && AmmoCanDrop; - BugsAccess = BugShrub || WanderingBugs || BugRock; - FishAccess = LoneFish || FishGroup; - FairyAccess = FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond; - - - //refills - Bombs = BombBag; - Nuts = DekuNutDrop || Nuts; - Sticks = DekuStickDrop || Sticks; - Bugs = HasBottle && BugsAccess; - BlueFire = (HasBottle && BlueFireAccess) || (BlueFireArrows && CanUse(ICE_ARROWS)); - Fish = HasBottle && FishAccess; - Fairy = HasBottle && FairyAccess; - - FoundBombchus = (BombchuDrop || Bombchus || Bombchus5 || Bombchus10 || Bombchus20) && (BombBag || BombchusInLogic); - CanPlayBowling = (BombchusInLogic && FoundBombchus) || (!BombchusInLogic && BombBag); - HasBombchus = (BuyBombchus10 || BuyBombchus20 || (AmmoDrops.Is(AMMODROPS_BOMBCHU) && FoundBombchus)); - - HasExplosives = Bombs || (BombchusInLogic && HasBombchus); - - HasBoots = IronBoots || HoverBoots; - - //Unshuffled adult trade quest - Eyedrops = Eyedrops || (!ShuffleAdultTradeQuest && ClaimCheck); - EyeballFrog = EyeballFrog || (!ShuffleAdultTradeQuest && Eyedrops); - Prescription = Prescription || (!ShuffleAdultTradeQuest && EyeballFrog); - BrokenSword = BrokenSword || (!ShuffleAdultTradeQuest && Prescription); - PoachersSaw = PoachersSaw || (!ShuffleAdultTradeQuest && BrokenSword); - OddPoultice = OddPoultice || (!ShuffleAdultTradeQuest && PoachersSaw); - OddMushroom = OddMushroom || (!ShuffleAdultTradeQuest && OddPoultice); - Cojiro = Cojiro || (!ShuffleAdultTradeQuest && OddMushroom); - PocketEgg = PocketEgg || (!ShuffleAdultTradeQuest && Cojiro); - - // IsChild = Age == AGE_CHILD; - // IsAdult = Age == AGE_ADULT; - - CanBlastOrSmash = HasExplosives || CanUse(MEGATON_HAMMER); - CanChildAttack = IsChild && (Slingshot || Boomerang || Sticks || KokiriSword || HasExplosives || CanUse(DINS_FIRE) || CanUse(MASTER_SWORD) || CanUse(MEGATON_HAMMER) || CanUse(BIGGORON_SWORD)); - CanChildDamage = IsChild && (Slingshot || Sticks || KokiriSword || HasExplosives || CanUse(DINS_FIRE) || CanUse(MASTER_SWORD) || CanUse(MEGATON_HAMMER) || CanUse(BIGGORON_SWORD)); - CanAdultAttack = IsAdult && (CanUse(BOW) || CanUse(BOOMERANG) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || HasExplosives || CanUse(DINS_FIRE) || MasterSword || Hammer || BiggoronSword || Hookshot); - CanAdultDamage = IsAdult && (CanUse(BOW) || CanUse(STICKS) || CanUse(KOKIRI_SWORD) || HasExplosives || CanUse(DINS_FIRE) || MasterSword || Hammer || BiggoronSword); - CanStunDeku = CanAdultAttack || CanChildAttack || Nuts || HasShield; - CanCutShrubs = CanUse(KOKIRI_SWORD) || CanUse(BOOMERANG) || HasExplosives || CanUse(MASTER_SWORD) || CanUse(MEGATON_HAMMER) || CanUse(BIGGORON_SWORD); - CanDive = ProgressiveScale >= 1; - CanLeaveForest = OpenForest.IsNot(OPENFOREST_CLOSED) || IsAdult || DekuTreeClear || ShuffleInteriorEntrances || ShuffleOverworldEntrances; - CanPlantBugs = IsChild && Bugs; - CanRideEpona = IsAdult && Epona && CanPlay(EponasSong); - CanSummonGossipFairy = Ocarina && (ZeldasLullaby || EponasSong || SongOfTime || SunsSong); - CanSummonGossipFairyWithoutSuns = Ocarina && (ZeldasLullaby || EponasSong || SongOfTime); - Hearts = BaseHearts + HeartContainer + (PieceOfHeart >> 2); - 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(GORON_TUNIC) ? 255 : (LogicFewerTunicRequirements) ? (Hearts * 8) : 0; - WaterTimer = CanUse( ZORA_TUNIC) ? 255 : (LogicFewerTunicRequirements) ? (Hearts * 8) : 0; - NeedNayrusLove = (EffectiveHealth == 1); - CanSurviveDamage = !NeedNayrusLove || CanUse(NAYRUS_LOVE); - CanTakeDamage = Fairy || CanSurviveDamage; - CanTakeDamageTwice = (Fairy && NumBottles >= 2) || ((EffectiveHealth == 2) && (CanUse(NAYRUS_LOVE) || Fairy)) || (EffectiveHealth > 2); - //CanPlantBean = IsChild && (MagicBean || MagicBeanPack); - CanOpenBombGrotto = CanBlastOrSmash && (ShardOfAgony || LogicGrottosWithoutAgony); - CanOpenStormGrotto = CanPlay(SongOfStorms) && (ShardOfAgony || LogicGrottosWithoutAgony); - HookshotOrBoomerang = CanUse(HOOKSHOT) || CanUse(BOOMERANG); - CanGetNightTimeGS = (CanPlay(SunsSong) || !NightGSExpectSuns); - - GuaranteeTradePath = ShuffleInteriorEntrances || ShuffleOverworldEntrances || LogicBiggoronBolero || CanBlastOrSmash || StopGCRollingGoronAsAdult; - //GuaranteeHint = (hints == "Mask" && MaskofTruth) || (hints == "Agony") || (hints != "Mask" && hints != "Agony"); - HasFireSource = CanUse(DINS_FIRE) || CanUse(FIRE_ARROWS); - HasFireSourceWithTorch = HasFireSource || CanUse(STICKS); - - //Gerudo Fortress - CanFinishGerudoFortress = (GerudoFortress.Is(GERUDOFORTRESS_NORMAL) && GerudoFortressKeys >= 4 && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD)) && (GerudoToken || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(HOVER_BOOTS) || LogicGerudoKitchen)) || - (GerudoFortress.Is(GERUDOFORTRESS_FAST) && GerudoFortressKeys >= 1 && (CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD))) || - (GerudoFortress.IsNot(GERUDOFORTRESS_NORMAL) && GerudoFortress.IsNot(GERUDOFORTRESS_FAST)); - - HasShield = CanUse(HYLIAN_SHIELD) || CanUse(DEKU_SHIELD); //Mirror shield can't reflect attacks - CanShield = CanUse(MIRROR_SHIELD) || HasShield; - ChildShield = IsChild && CanUse(DEKU_SHIELD); //hylian shield is not helpful for child - AdultReflectShield = IsAdult && CanUse(HYLIAN_SHIELD); //Mirror shield can't reflect attacks - AdultShield = IsAdult && (CanUse(HYLIAN_SHIELD) || CanUse(MIRROR_SHIELD)); - CanShieldFlick = ChildShield || AdultShield; - CanJumpslash = CanUse(STICKS) || CanUse(KOKIRI_SWORD) || CanUse(MASTER_SWORD) || CanUse(BIGGORON_SWORD); // Not including hammer as hammer jump attacks can be weird - CanUseProjectile = HasExplosives || CanUse(BOW) || CanUse(HOOKSHOT) || CanUse(SLINGSHOT) || CanUse(BOOMERANG); - CanUseMagicArrow = CanUse(FIRE_ARROWS) || CanUse(ICE_ARROWS) || CanUse(LIGHT_ARROWS); - - //Bridge and LACS Requirements - MedallionCount = (ForestMedallion ? 1:0) + (FireMedallion ? 1:0) + (WaterMedallion ? 1:0) + (SpiritMedallion ? 1:0) + (ShadowMedallion ? 1:0) + (LightMedallion ? 1:0); - StoneCount = (KokiriEmerald ? 1:0) + (GoronRuby ? 1:0) + (ZoraSapphire ? 1:0); - DungeonCount = (DekuTreeClear ? 1:0) + (DodongosCavernClear ? 1:0) + (JabuJabusBellyClear ? 1:0) + (ForestTempleClear ? 1:0) + (FireTempleClear ? 1:0) + (WaterTempleClear ? 1:0) + (SpiritTempleClear ? 1:0) + (ShadowTempleClear ? 1:0); - HasAllStones = StoneCount == 3; - HasAllMedallions = MedallionCount == 6; - GregInBridgeLogic = BridgeRewardOptions.Is(BRIDGE_OPTION_GREG); - GregInLacsLogic = LACSRewardOptions.Is(LACS_OPTION_GREG); - - CanBuildRainbowBridge = Bridge.Is(RAINBOWBRIDGE_OPEN) || - (Bridge.Is(RAINBOWBRIDGE_VANILLA) && ShadowMedallion && SpiritMedallion && LightArrows) || - (Bridge.Is(RAINBOWBRIDGE_STONES) && StoneCount + (Greg && GregInBridgeLogic ? 1 : 0) >= BridgeStoneCount.Value()) || - (Bridge.Is(RAINBOWBRIDGE_MEDALLIONS) && MedallionCount + (Greg && GregInBridgeLogic ? 1 : 0) >= BridgeMedallionCount.Value()) || - (Bridge.Is(RAINBOWBRIDGE_REWARDS) && StoneCount + MedallionCount + (Greg && GregInBridgeLogic ? 1 : 0) >= BridgeRewardCount.Value()) || - (Bridge.Is(RAINBOWBRIDGE_DUNGEONS) && DungeonCount + (Greg && GregInBridgeLogic ? 1 : 0) >= BridgeDungeonCount.Value()) || - (Bridge.Is(RAINBOWBRIDGE_TOKENS) && GoldSkulltulaTokens >= BridgeTokenCount.Value()) || - (Bridge.Is(RAINBOWBRIDGE_GREG) && Greg); - - CanTriggerLACS = (LACSCondition == LACSCONDITION_VANILLA && ShadowMedallion && SpiritMedallion) || - (LACSCondition == LACSCONDITION_STONES && StoneCount + (Greg && GregInLacsLogic ? 1 : 0) >= LACSStoneCount.Value()) || - (LACSCondition == LACSCONDITION_MEDALLIONS && MedallionCount + (Greg && GregInLacsLogic ? 1 : 0) >= LACSMedallionCount.Value()) || - (LACSCondition == LACSCONDITION_REWARDS && StoneCount + MedallionCount + (Greg && GregInLacsLogic ? 1 : 0) >= LACSRewardCount.Value()) || - (LACSCondition == LACSCONDITION_DUNGEONS && DungeonCount + (Greg && GregInLacsLogic ? 1 : 0) >= LACSDungeonCount.Value()) || - (LACSCondition == LACSCONDITION_TOKENS && GoldSkulltulaTokens >= LACSTokenCount.Value()); - CanCompleteTriforce = TriforcePieces >= TriforceHuntRequired.Value(); - } - - bool SmallKeys(Key dungeon, uint8_t requiredAmount) { - return SmallKeys(dungeon, requiredAmount, requiredAmount); - } - - bool SmallKeys(Key dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched) { - switch (dungeon) { - case FOREST_TEMPLE: - /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotJump_Boots) >= static_cast(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHoverBoost) >= static_cast(GlitchDifficulty::NOVICE) || - (GetDifficultyValueFromString(GlitchHover) >= static_cast(GlitchDifficulty::NOVICE) && GetDifficultyValueFromString(GlitchISG) >= static_cast(GlitchDifficulty::INTERMEDIATE)))) { - return ForestTempleKeys >= requiredAmountGlitched; - }*/ - return ForestTempleKeys >= requiredAmountGlitchless; - - case FIRE_TEMPLE: - /*if (IsGlitched && (GetDifficultyValueFromString(GlitchLedgeClip) >= static_cast(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHover) >= static_cast(GlitchDifficulty::INTERMEDIATE))) { - return FireTempleKeys >= requiredAmountGlitched; - }*/ - return FireTempleKeys >= requiredAmountGlitchless; - - case WATER_TEMPLE: - /*if (IsGlitched && (false)) { - return WaterTempleKeys >= requiredAmountGlitched; - }*/ - return WaterTempleKeys >= requiredAmountGlitchless; - - case SPIRIT_TEMPLE: - /*if (IsGlitched && (false)) { - return SpiritTempleKeys >= requiredAmountGlitched; - }*/ - return SpiritTempleKeys >= requiredAmountGlitchless; - - case SHADOW_TEMPLE: - /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotClip) >= static_cast(GlitchDifficulty::NOVICE))) { - return ShadowTempleKeys >= requiredAmountGlitched; - }*/ - return ShadowTempleKeys >= requiredAmountGlitchless; - - case BOTTOM_OF_THE_WELL: - /*if (IsGlitched && (false)) { - return BottomOfTheWellKeys >= requiredAmountGlitched; - }*/ - return BottomOfTheWellKeys >= requiredAmountGlitchless; - - case GERUDO_TRAINING_GROUNDS: - /*if (IsGlitched && (false)) { - return GerudoTrainingGroundsKeys >= requiredAmountGlitched; - }*/ - return GerudoTrainingGroundsKeys >= requiredAmountGlitchless; - - case GANONS_CASTLE: - /*if (IsGlitched && (false)) { - return GanonsCastleKeys >= requiredAmountGlitched; - }*/ - return GanonsCastleKeys >= requiredAmountGlitchless; - - case MARKET_TREASURE_CHEST_GAME: - /*if (IsGlitched && (false)) { - return TreasureGameKeys >= requiredAmountGlitched; - }*/ - return TreasureGameKeys >= requiredAmountGlitchless; - - default: - return false; - } - } - - bool EventsUpdated() { - - if (DekuTreeClearPast != DekuTreeClear || - GoronRubyPast != GoronRuby || - ZoraSapphirePast != ZoraSapphire || - ForestTrialClearPast != ForestTrialClear || - FireTrialClearPast != FireTrialClear || - WaterTrialClearPast != WaterTrialClear || - ShadowTrialClearPast != ShadowTrialClear || - SpiritTrialClearPast != SpiritTrialClear || - LightTrialClearPast != LightTrialClear || - DrainWellPast != DrainWell || - DampesWindmillAccessPast != DampesWindmillAccess || - TimeTravelPast != TimeTravel) { - DekuTreeClearPast = DekuTreeClear; - GoronRubyPast = GoronRuby; - ZoraSapphirePast = ZoraSapphire; - ForestTrialClearPast = ForestTrialClear; - FireTrialClearPast = FireTrialClear; - WaterTrialClearPast = WaterTrialClear; - ShadowTrialClearPast = ShadowTrialClear; - SpiritTrialClearPast = SpiritTrialClear; - LightTrialClearPast = LightTrialClear; - DrainWellPast = DrainWell; - DampesWindmillAccessPast = DampesWindmillAccess; - return true; - } - return false; - } - - //Reset All Logic to false - void LogicReset() { - //Settings-dependent variables - IsKeysanity = Keysanity.Is(KEYSANITY_ANYWHERE) || Keysanity.Is(KEYSANITY_OVERWORLD) || Keysanity.Is(KEYSANITY_ANY_DUNGEON); - AmmoCanDrop = AmmoDrops.IsNot(AMMODROPS_NONE); - - //Child item logic - KokiriSword = false; - ZeldasLetter = false; - WeirdEgg = false; - HasBottle = false; - Bombchus = false; - Bombchus5 = false; - Bombchus10 = false; - Bombchus20 = false; - MagicBean = false; - MagicBeanPack = false; - RutosLetter = false; - Boomerang = false; - DinsFire = false; - FaroresWind = false; - NayrusLove = false; - LensOfTruth = false; - ShardOfAgony = false; - SkullMask = false; - MaskOfTruth = false; - - //Adult logic - Hammer = false; - IronBoots = false; - HoverBoots = false; - MirrorShield = false; - GoronTunic = false; - ZoraTunic = false; - Epona = false; - BigPoe = false; - GerudoToken = false; - FireArrows = false; - IceArrows = false; - LightArrows = false; - MasterSword = false; - BiggoronSword = false; - - //Trade Quest - PocketEgg = false; - Cojiro = false; - OddMushroom = false; - OddPoultice = false; - PoachersSaw = false; - BrokenSword = false; - Prescription = false; - EyeballFrog = false; - Eyedrops = false; - ClaimCheck = false; - - //Trade Quest Events - WakeUpAdultTalon = false; - CojiroAccess = false; - OddMushroomAccess = false; - OddPoulticeAccess = false; - PoachersSawAccess = false; - BrokenSwordAccess = false; - PrescriptionAccess = false; - EyeballFrogAccess = false; - EyedropsAccess = false; - DisableTradeRevert = false; - - //Songs - ZeldasLullaby = false; - SariasSong = false; - SunsSong = false; - SongOfStorms = false; - EponasSong = false; - SongOfTime = false; - MinuetOfForest = false; - BoleroOfFire = false; - SerenadeOfWater = false; - RequiemOfSpirit = false; - NocturneOfShadow = false; - PreludeOfLight = false; - - //Stones and Meddallions - ForestMedallion = false; - FireMedallion = false; - WaterMedallion = false; - SpiritMedallion = false; - ShadowMedallion = false; - LightMedallion = false; - KokiriEmerald = false; - GoronRuby = false; - ZoraSapphire = false; - - //Dungeon Clears - DekuTreeClear = false; - DodongosCavernClear = false; - JabuJabusBellyClear = false; - ForestTempleClear = false; - FireTempleClear = false; - WaterTempleClear = false; - SpiritTempleClear = false; - ShadowTempleClear = false; - - //Trial Clears - ForestTrialClear = false; - FireTrialClear = false; - WaterTrialClear = false; - SpiritTrialClear = false; - ShadowTrialClear = false; - LightTrialClear = false; - - //Greg - Greg = false; - GregInBridgeLogic = false; - GregInLacsLogic = false; - - //Progressive Items - ProgressiveBulletBag = 0; - ProgressiveBombBag = 0; - ProgressiveMagic = 0; - ProgressiveScale = 0; - ProgressiveHookshot = 0; - ProgressiveBow = 0; - ProgressiveWallet = 0; - ProgressiveStrength = 0; - ProgressiveOcarina = 0; - ProgressiveGiantKnife = 0; - - //Keys - ForestTempleKeys = 0; - //If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in vanilla FiT - FireTempleKeys = IsKeysanity || Dungeon::FireTemple.IsMQ() ? 0 : 1; - WaterTempleKeys = 0; - SpiritTempleKeys = 0; - ShadowTempleKeys = 0; - GanonsCastleKeys = 0; - GerudoFortressKeys = 0; - GerudoTrainingGroundsKeys = 0; - BottomOfTheWellKeys = 0; - TreasureGameKeys = 0; - - //Boss Keys - BossKeyForestTemple = 0; - BossKeyFireTemple = 0; - BossKeyWaterTemple = 0; - BossKeySpiritTemple = 0; - BossKeyShadowTemple = 0; - BossKeyGanonsCastle = 0; - - //Gold Skulltula Count - GoldSkulltulaTokens = 0; - - //Bottle Count - Bottles = 0; - NumBottles = 0; - NoBottles = false; - - //Triforce Pieces - TriforcePieces = 0; - - //Drops and Bottle Contents Access - DekuNutDrop = false; - NutPot = false; - NutCrate = false; - DekuBabaNuts = false; - DekuStickDrop = false; - StickPot = false; - DekuBabaSticks = false; - BugsAccess = false; - BugShrub = false; - WanderingBugs = false; - BugRock = false; - BlueFireAccess = false; - FishAccess = false; - FishGroup = false; - LoneFish = false; - FairyAccess = false; - GossipStoneFairy = false; - BeanPlantFairy = false; - ButterflyFairy = false; - FairyPot = false; - FreeFairies = false; - FairyPond = false; - BombchuDrop = false; - - BuyBombchus10 = false; - BuyBombchus20 = false; - BuySeed = false; - BuyArrow = false; - BuyBomb = false; - BuyGPotion = false; - BuyBPotion = false; - MagicRefill = false; - - PieceOfHeart = 0; - HeartContainer = 0; - DoubleDefense = false; - - /* --- HELPERS, EVENTS, AND LOCATION ACCESS --- */ - /* These are used to simplify reading the logic, but need to be updated - / every time a base value is updated. */ - - Slingshot = false; - Ocarina = false; - OcarinaOfTime = false; - BombBag = false; - MagicMeter = false; - Hookshot = false; - Longshot = false; - Bow = false; - GoronBracelet = false; - SilverGauntlets = false; - GoldenGauntlets = false; - SilverScale = false; - GoldScale = false; - AdultsWallet = false; - - ChildScarecrow = false; - AdultScarecrow = false; - ScarecrowSong = false; - Scarecrow = false; - DistantScarecrow = false; - - Bombs = false; - DekuShield = false; - HylianShield = false; - Nuts = false; - Sticks = false; - Bugs = false; - BlueFire = false; - Fish = false; - Fairy = false; - BottleWithBigPoe = false; - - FoundBombchus = false; - CanPlayBowling = false; - HasBombchus = false; - HasExplosives = false; - HasBoots = false; - IsChild = false; - IsAdult = false; - IsGlitched = Settings::Logic.Is(LOGIC_GLITCHED); - CanBlastOrSmash = false; - CanChildAttack = false; - CanChildDamage = false; - CanCutShrubs = false; - CanDive = false; - CanLeaveForest = false; - CanPlantBugs = false; - CanRideEpona = false; - CanStunDeku = false; - CanSummonGossipFairy = false; - CanSummonGossipFairyWithoutSuns = false; - //CanPlantBean = false; - CanOpenBombGrotto = false; - CanOpenStormGrotto = false; - BigPoeKill = false; - HookshotOrBoomerang = false; - - BaseHearts = StartingHearts.Value() + 1; - Hearts = 0; - Multiplier = (DamageMultiplier.Value() < 6) ? DamageMultiplier.Value() : 10; - EffectiveHealth = 0; - FireTimer = 0; - WaterTimer = 0; - - GuaranteeTradePath = false; - GuaranteeHint = false; - HasFireSource = false; - HasFireSourceWithTorch = false; - - CanFinishGerudoFortress = false; - - HasShield = false; - CanShield = false; - ChildShield = false; - AdultReflectShield = false; - AdultShield = false; - CanShieldFlick = false; - CanJumpslash = false; - CanUseProjectile = false; - CanUseMagicArrow = false; - - //Bridge Requirements - HasAllStones = false; - HasAllMedallions = false; - CanBuildRainbowBridge = false; - BuiltRainbowBridge = false; - CanTriggerLACS = false; - - //Other - AtDay = false; - AtNight = false; - Age = Settings::ResolvedStartingAge; - - //Events - ShowedMidoSwordAndShield = false; - CarpenterRescue = false; - GF_GateOpen = false; - GtG_GateOpen = false; - DampesWindmillAccess = false; - DrainWell = false; - GoronCityChildFire = false; - GCWoodsWarpOpen = false; - GCDaruniasDoorOpenChild = false; - StopGCRollingGoronAsAdult = false; - WaterTempleLow = false; - WaterTempleMiddle = false; - WaterTempleHigh = false; - KakarikoVillageGateOpen = false; - KingZoraThawed = false; - ForestTempleJoelle = false; - ForestTempleBeth = false; - ForestTempleJoAndBeth = false; - ForestTempleAmy = false; - ForestTempleMeg = false; - ForestTempleAmyAndMeg = false; - FireLoopSwitch = false; - LinksCow = false; - AtDampeTime = false; - DeliverLetter = false; - TimeTravel = false; - - DrainWellPast = false; - DampesWindmillAccessPast = false; - DekuTreeClearPast = false; - GoronRubyPast = false; - ZoraSapphirePast = false; - ForestTrialClearPast = false; - FireTrialClearPast = false; - WaterTrialClearPast = false; - SpiritTrialClearPast = false; - ShadowTrialClearPast = false; - LightTrialClearPast = false; - BuyDekuShieldPast = false; - TimeTravelPast = false; - } -} diff --git a/soh/soh/Enhancements/randomizer/3drando/logic.hpp b/soh/soh/Enhancements/randomizer/3drando/logic.hpp deleted file mode 100644 index 2c5bca890de..00000000000 --- a/soh/soh/Enhancements/randomizer/3drando/logic.hpp +++ /dev/null @@ -1,379 +0,0 @@ -#pragma once - -#include "keys.hpp" -#include - -namespace Logic { -extern bool noVariable; - -// Child item logic -extern bool KokiriSword; -extern bool Slingshot; -extern bool ZeldasLetter; -extern bool WeirdEgg; -extern bool HasBottle; -extern bool BombBag; -extern bool Bombchus; -extern bool Bombchus5; -extern bool Bombchus10; -extern bool Bombchus20; -extern bool MagicBean; -extern bool MagicBeanPack; -extern bool RutosLetter; -extern bool Boomerang; -extern bool DinsFire; -extern bool FaroresWind; -extern bool NayrusLove; -extern bool LensOfTruth; -extern bool ShardOfAgony; -extern bool SkullMask; -extern bool MaskOfTruth; - -// Adult logic -extern bool Bow; -extern bool Hammer; -extern bool IronBoots; -extern bool HoverBoots; -extern bool MirrorShield; -extern bool GoronTunic; -extern bool ZoraTunic; -extern bool Epona; -extern bool BigPoe; -extern bool GerudoToken; -extern bool FireArrows; -extern bool IceArrows; -extern bool LightArrows; -extern bool MasterSword; -extern bool BiggoronSword; - -// Trade Quest -extern bool PocketEgg; -extern bool Cojiro; -extern bool OddMushroom; -extern bool OddPoultice; -extern bool PoachersSaw; -extern bool BrokenSword; -extern bool Prescription; -extern bool EyeballFrog; -extern bool Eyedrops; -extern bool ClaimCheck; - -// Trade Quest Events -extern bool WakeUpAdultTalon; -extern bool CojiroAccess; -extern bool OddMushroomAccess; -extern bool OddPoulticeAccess; -extern bool PoachersSawAccess; -extern bool BrokenSwordAccess; -extern bool PrescriptionAccess; -extern bool EyeballFrogAccess; -extern bool EyedropsAccess; -extern bool DisableTradeRevert; - -// Songs -extern bool ZeldasLullaby; -extern bool SariasSong; -extern bool SunsSong; -extern bool SongOfStorms; -extern bool EponasSong; -extern bool SongOfTime; -extern bool MinuetOfForest; -extern bool BoleroOfFire; -extern bool SerenadeOfWater; -extern bool RequiemOfSpirit; -extern bool NocturneOfShadow; -extern bool PreludeOfLight; - -// Stones and Meddallions -extern bool ForestMedallion; -extern bool FireMedallion; -extern bool WaterMedallion; -extern bool SpiritMedallion; -extern bool ShadowMedallion; -extern bool LightMedallion; -extern bool KokiriEmerald; -extern bool GoronRuby; -extern bool ZoraSapphire; - -// Dungeon Clears -extern bool DekuTreeClear; -extern bool DodongosCavernClear; -extern bool JabuJabusBellyClear; -extern bool ForestTempleClear; -extern bool FireTempleClear; -extern bool WaterTempleClear; -extern bool SpiritTempleClear; -extern bool ShadowTempleClear; - -// Trial Clears -extern bool ForestTrialClear; -extern bool FireTrialClear; -extern bool WaterTrialClear; -extern bool SpiritTrialClear; -extern bool ShadowTrialClear; -extern bool LightTrialClear; - -//Greg -extern bool Greg; -extern bool GregInBridgeLogic; -extern bool GregInLacsLogic; - -// Progression Items -extern uint8_t ProgressiveBulletBag; -extern uint8_t ProgressiveBombBag; -extern uint8_t ProgressiveScale; -extern uint8_t ProgressiveHookshot; -extern uint8_t ProgressiveBow; -extern uint8_t ProgressiveStrength; -extern uint8_t ProgressiveWallet; -extern uint8_t ProgressiveMagic; -extern uint8_t ProgressiveOcarina; -extern uint8_t ProgressiveGiantKnife; - -// Keysanity -extern bool IsKeysanity; - -// Keys -extern uint8_t ForestTempleKeys; -extern uint8_t FireTempleKeys; -extern uint8_t WaterTempleKeys; -extern uint8_t SpiritTempleKeys; -extern uint8_t ShadowTempleKeys; -extern uint8_t BottomOfTheWellKeys; -extern uint8_t GerudoTrainingGroundsKeys; -extern uint8_t GerudoFortressKeys; -extern uint8_t GanonsCastleKeys; -extern uint8_t TreasureGameKeys; - -// Triforce Pieces -extern uint8_t TriforcePieces; - -// Boss Keys -extern bool BossKeyForestTemple; -extern bool BossKeyFireTemple; -extern bool BossKeyWaterTemple; -extern bool BossKeySpiritTemple; -extern bool BossKeyShadowTemple; -extern bool BossKeyGanonsCastle; - -// Gold Skulltula Count -extern uint8_t GoldSkulltulaTokens; - -// Bottle Count, with and without Ruto's Letter -extern uint8_t Bottles; -extern uint8_t NumBottles; -extern bool NoBottles; - -// item and bottle drops -extern bool DekuNutDrop; -extern bool NutPot; -extern bool NutCrate; -extern bool DekuBabaNuts; -extern bool DekuStickDrop; -extern bool StickPot; -extern bool DekuBabaSticks; -extern bool BugsAccess; -extern bool BugShrub; -extern bool WanderingBugs; -extern bool BugRock; -extern bool BlueFireAccess; -extern bool FishAccess; -extern bool FishGroup; -extern bool LoneFish; -extern bool FairyAccess; -extern bool GossipStoneFairy; -extern bool BeanPlantFairy; -extern bool ButterflyFairy; -extern bool FairyPot; -extern bool FreeFairies; -extern bool FairyPond; -extern bool BombchuDrop; - -extern bool BuyBombchus10; -extern bool BuyBombchus20; -extern bool BuyArrow; -extern bool BuyBomb; -extern bool BuyGPotion; -extern bool BuyBPotion; -extern bool BuySeed; -extern bool MagicRefill; - -extern uint8_t PieceOfHeart; -extern uint8_t HeartContainer; -extern bool DoubleDefense; - -/* --- HELPERS --- */ -/* These are used to simplify reading the logic, but need to be updated -/ every time a base value is updated. */ - -extern bool Ocarina; -extern bool OcarinaOfTime; -extern bool MagicMeter; -extern bool Hookshot; -extern bool Longshot; -extern bool GoronBracelet; -extern bool SilverGauntlets; -extern bool GoldenGauntlets; -extern bool SilverScale; -extern bool GoldScale; -extern bool AdultsWallet; - -extern bool ChildScarecrow; -extern bool AdultScarecrow; -extern bool ScarecrowSong; -extern bool Scarecrow; -extern bool DistantScarecrow; - -extern bool Bombs; -extern bool DekuShield; -extern bool HylianShield; -extern bool Nuts; -extern bool Sticks; -extern bool Bugs; -extern bool BlueFire; -extern bool Fish; -extern bool Fairy; -extern bool BottleWithBigPoe; - -extern bool Bombs; -extern bool FoundBombchus; -extern bool CanPlayBowling; -extern bool HasBombchus; -extern bool HasExplosives; -extern bool HasBoots; -extern bool IsChild; -extern bool IsAdult; -extern bool IsGlitched; -extern bool CanBlastOrSmash; -extern bool CanChildAttack; -extern bool CanChildDamage; -extern bool CanAdultAttack; -extern bool CanAdultDamage; -extern bool CanCutShrubs; -extern bool CanDive; -extern bool CanLeaveForest; -extern bool CanPlantBugs; -extern bool CanRideEpona; -extern bool CanStunDeku; -extern bool CanSummonGossipFairy; -extern bool CanSummonGossipFairyWithoutSuns; -extern bool NeedNayrusLove; -extern bool CanSurviveDamage; -extern bool CanTakeDamage; -extern bool CanTakeDamageTwice; -// extern bool CanPlantBean; -extern bool CanOpenBombGrotto; -extern bool CanOpenStormGrotto; -extern bool HookshotOrBoomerang; -extern bool CanGetNightTimeGS; -extern bool BigPoeKill; - -extern uint8_t BaseHearts; -extern uint8_t Hearts; -extern uint8_t Multiplier; -extern uint8_t EffectiveHealth; -extern uint8_t FireTimer; -extern uint8_t WaterTimer; - -extern bool GuaranteeTradePath; -extern bool GuaranteeHint; -extern bool HasFireSource; -extern bool HasFireSourceWithTorch; - -// Gerudo Fortress -extern bool CanFinishGerudoFortress; - -extern bool HasShield; -extern bool CanShield; -extern bool ChildShield; -extern bool AdultReflectShield; -extern bool AdultShield; -extern bool CanShieldFlick; -extern bool CanJumpslash; -extern bool CanUseProjectile; -extern bool CanUseMagicArrow; - -// Bridge Requirements -extern bool HasAllStones; -extern bool HasAllMedallions; -extern bool CanBuildRainbowBridge; -extern bool BuiltRainbowBridge; -extern bool CanTriggerLACS; - -// Other -extern bool AtDay; -extern bool AtNight; -extern bool LinksCow; -extern uint8_t Age; -extern bool CanCompleteTriforce; - -// Events -extern bool ShowedMidoSwordAndShield; -extern bool CarpenterRescue; -extern bool DampesWindmillAccess; -extern bool GF_GateOpen; -extern bool GtG_GateOpen; -extern bool DrainWell; -extern bool GoronCityChildFire; -extern bool GCWoodsWarpOpen; -extern bool GCDaruniasDoorOpenChild; -extern bool StopGCRollingGoronAsAdult; -extern bool WaterTempleLow; -extern bool WaterTempleMiddle; -extern bool WaterTempleHigh; -extern bool KingZoraThawed; -extern bool AtDampeTime; -extern bool DeliverLetter; -extern bool KakarikoVillageGateOpen; -extern bool ForestTempleJoelle; -extern bool ForestTempleBeth; -extern bool ForestTempleJoAndBeth; -extern bool ForestTempleAmy; -extern bool ForestTempleMeg; -extern bool ForestTempleAmyAndMeg; -extern bool FireLoopSwitch; -extern bool TimeTravel; - -/* --- END OF HELPERS --- */ - -extern uint8_t AddedProgressiveBulletBags; -extern uint8_t AddedProgressiveBombBags; -extern uint8_t AddedProgressiveMagics; -extern uint8_t AddedProgressiveScales; -extern uint8_t AddedProgressiveHookshots; -extern uint8_t AddedProgressiveBows; -extern uint8_t AddedProgressiveWallets; -extern uint8_t AddedProgressiveStrengths; -extern uint8_t AddedProgressiveOcarinas; -extern uint8_t TokensInPool; - -enum class HasProjectileAge { - Adult, - Child, - Both, - Either, -}; - -enum class GlitchType { - EquipSwapDins, - EquipSwap, -}; - -enum class GlitchDifficulty { - NOVICE = 1, - INTERMEDIATE, - ADVANCED, - EXPERT, - HERO, -}; - -void UpdateHelpers(); -bool CanPlay(bool song); -bool CanUse(uint32_t itemName); -bool HasProjectile(HasProjectileAge age); -bool SmallKeys(Key dungeon, uint8_t requiredAmount); -bool SmallKeys(Key dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched); -bool CanDoGlitch(GlitchType glitch); -bool EventsUpdated(); -void LogicReset(); -} // namespace Logic \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index 9f6cc279601..ab064bfe00a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -8,9 +8,9 @@ #include "menu.hpp" #include "playthrough.hpp" #include "randomizer.hpp" -#include "settings.hpp" #include "spoiler_log.hpp" #include "location_access.hpp" +#include "soh/Enhancements/debugger/performanceTimer.h" #include #include "../../randomizer/randomizerTypes.h" #include @@ -19,68 +19,76 @@ namespace { bool seedChanged; uint16_t pastSeedLength; std::vector presetEntries; -Option* currentSetting; +Rando::Option* currentSetting; } // namespace -static void RestoreOverrides() { - if (Settings::Logic.Is(LOGIC_VANILLA)) { - for (auto overridePair : Settings::vanillaLogicOverrides) { - overridePair.first->RestoreDelayedOption(); - } - } -} - -std::string GenerateRandomizer(std::unordered_map cvarSettings, std::set excludedLocations, std::set enabledTricks, - std::string seedString) { +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 - if (seedString.empty()) { - seedString = std::to_string(rand() % 0xFFFFFFFF); - } else if (seedString.rfind("seed_testing_count", 0) == 0 && seedString.length() > 18) { + if (seedInput.empty()) { + seedInput = std::to_string(rand() % 0xFFFFFFFF); + } else if (seedInput.rfind("seed_testing_count", 0) == 0 && seedInput.length() > 18) { int count; try { - count = std::stoi(seedString.substr(18), nullptr); + count = std::stoi(seedInput.substr(18), nullptr); } catch (std::invalid_argument &e) { count = 1; } catch (std::out_of_range &e) { count = 1; } - Playthrough::Playthrough_Repeat(cvarSettings, excludedLocations, enabledTricks, count); - return ""; + Playthrough::Playthrough_Repeat(excludedLocations, enabledTricks, count); + return false; // TODO: Not sure if this is correct but I don't think we support this functionality yet anyway. } - Settings::seedString = seedString; - uint32_t seedHash = boost::hash_32{}(Settings::seedString); - Settings::seed = seedHash & 0xFFFFFFFF; + ctx->GetSettings()->SetSeedString(seedInput); + uint32_t seedHash = boost::hash_32{}(ctx->GetSettings()->GetSeedString()); + ctx->GetSettings()->SetSeed(seedHash & 0xFFFFFFFF); - int ret = Playthrough::Playthrough_Init(Settings::seed, cvarSettings, excludedLocations, enabledTricks); + ctx->ClearItemLocations(); + int ret = Playthrough::Playthrough_Init(ctx->GetSettings()->GetSeed(), excludedLocations, enabledTricks); if (ret < 0) { if (ret == -1) { // Failed to generate after 5 tries - printf("\n\nFailed to generate after 5 tries.\nPress B to go back to the menu.\nA different seed might be " - "successful."); - SPDLOG_DEBUG("\nRANDOMIZATION FAILED COMPLETELY. PLZ FIX\n"); - RestoreOverrides(); - return ""; + SPDLOG_ERROR("Failed to generate after 5 tries."); + return false; } else { - printf("\n\nError %d with fill.\nPress Select to exit or B to go back to the menu.\n", ret); - RestoreOverrides(); - return ""; + SPDLOG_ERROR("Error {} with fill.", ret); + return false; } } - RestoreOverrides(); - - std::ostringstream fileNameStream; - for (int i = 0; i < Settings::hashIconIndexes.size(); i++) { - if (i) { - fileNameStream << '-'; - } - if (Settings::hashIconIndexes[i] < 10) { - fileNameStream << '0'; + // Restore settings that were set to a specific value for vanilla logic + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) { + for (Rando::Option* setting : ctx->GetSettings()->VanillaLogicDefaults) { + setting->RestoreDelayedOption(); } - fileNameStream << std::to_string(Settings::hashIconIndexes[i]); + ctx->GetOption(RSK_KEYSANITY).RestoreDelayedOption(); } - std::string fileName = fileNameStream.str(); - return "./Randomizer/" + fileName + ".json"; + + StopPerformanceTimer(PT_WHOLE_SEED); + SPDLOG_DEBUG("Full Seed Genration Time: {}ms", GetPerformanceTimer(PT_WHOLE_SEED).count()); + SPDLOG_DEBUG("LogicReset time: {}ms", GetPerformanceTimer(PT_LOGIC_RESET).count()); + SPDLOG_DEBUG("Area->Reset time: {}ms", GetPerformanceTimer(PT_REGION_RESET).count()); + SPDLOG_DEBUG("Total Entrance Shuffle time: {}ms", GetPerformanceTimer(PT_ENTRANCE_SHUFFLE).count()); + SPDLOG_DEBUG("Total Shopsanity time: {}ms", GetPerformanceTimer(PT_SHOPSANITY).count()); + SPDLOG_DEBUG("Total Dungeon Specific Items time: {}ms", GetPerformanceTimer(PT_OWN_DUNGEON).count()); + SPDLOG_DEBUG("Total Misc Limited Checks time: {}ms", GetPerformanceTimer(PT_LIMITED_CHECKS).count()); + SPDLOG_DEBUG("Total Advancment Checks time: {}ms", GetPerformanceTimer(PT_ADVANCEMENT_ITEMS).count()); + SPDLOG_DEBUG("Total Other Checks time: {}ms", GetPerformanceTimer(PT_REMAINING_ITEMS).count()); + SPDLOG_DEBUG("Total Playthrough Generation time: {}ms", GetPerformanceTimer(PT_PLAYTHROUGH_GENERATION).count()); + SPDLOG_DEBUG("Total PareDownPlaythrough time: {}ms", GetPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH).count()); + SPDLOG_DEBUG("Total WotH generation time: {}ms", GetPerformanceTimer(PT_WOTH).count()); + SPDLOG_DEBUG("Total Foolish generation time: {}ms", GetPerformanceTimer(PT_FOOLISH).count()); + SPDLOG_DEBUG("Total Overrides time: {}ms", GetPerformanceTimer(PT_OVERRIDES).count()); + SPDLOG_DEBUG("Total Hint Generation time: {}ms", GetPerformanceTimer(PT_HINTS).count()); + SPDLOG_DEBUG("SpoilerLog writing time: {}ms", GetPerformanceTimer(PT_SPOILER_LOG).count()); + SPDLOG_DEBUG("Total Event Access Calculation time: {}ms", GetPerformanceTimer(PT_EVENT_ACCESS).count()); + SPDLOG_DEBUG("Total ToD Access Calculation: {}ms", GetPerformanceTimer(PT_TOD_ACCESS).count()); + SPDLOG_DEBUG("Total Entrance Logic Calculation time: {}ms", GetPerformanceTimer(PT_ENTRANCE_LOGIC).count()); + SPDLOG_DEBUG("Total Check Logic Calculation time: {}ms", GetPerformanceTimer(PT_LOCATION_LOGIC).count()); + return true; } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.hpp b/soh/soh/Enhancements/randomizer/3drando/menu.hpp index 333fcbb2ba5..f9393d90e5c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.hpp @@ -13,16 +13,16 @@ #define DELETE_PRESET 6 #define RESET_TO_DEFAULTS 8 -#define RESET "\x1b[0m" -#define DIM "\x1b[2m" +// #define RESET "\x1b[0m" +// #define DIM "\x1b[2m" -#define BLACK "\x1b[30m" -#define RED "\x1b[31m" -#define GREEN "\x1b[32m" -#define YELLOW "\x1b[33m" -#define BLUE "\x1b[34m" -#define MEGANTA "\x1b[35m" -#define CYAN "\x1b[36m" -#define WHITE "\x1b[37m" +// #define BLACK "\x1b[30m" +// #define RED "\x1b[31m" +// #define GREEN "\x1b[32m" +// #define YELLOW "\x1b[33m" +// #define BLUE "\x1b[34m" +// #define MEGANTA "\x1b[35m" +// #define CYAN "\x1b[36m" +// #define WHITE "\x1b[37m" -std::string GenerateRandomizer(std::unordered_map cvarSetting, std::set excludedLocations, std::set enabledTricks, std::string seedInput); \ No newline at end of file +bool GenerateRandomizer(std::set excludedLocations, std::set enabledTricks, std::string seedInput); \ 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 e1a5656eaea..0d4f39c5c3a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -5,39 +5,45 @@ #include "custom_messages.hpp" #include "fill.hpp" #include "location_access.hpp" -#include "logic.hpp" #include "random.hpp" #include "spoiler_log.hpp" #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "variables.h" #include "soh/OTRGlobals.h" +#include "../option.h" +#include "soh/Enhancements/debugger/performanceTimer.h" namespace Playthrough { -int Playthrough_Init(uint32_t seed, std::unordered_map cvarSettings, std::set excludedLocations, std::set enabledTricks) { +int Playthrough_Init(uint32_t seed, std::set excludedLocations, std::set enabledTricks) { // initialize the RNG with just the seed incase any settings need to be // resolved to something random Random_Init(seed); - overrides.clear(); + auto ctx = Rando::Context::GetInstance(); + ctx->overrides.clear(); CustomMessages::ClearMessages(); - ItemReset(); - HintReset(); - Areas::AccessReset(); - - Settings::UpdateSettings(cvarSettings, excludedLocations, enabledTricks); + ctx->ItemReset(); + ctx->HintReset(); + ctx->GetLogic()->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 std::string settingsStr; - for (Menu* menu : Settings::GetAllOptionMenus()) { + for (const Rando::OptionGroup& optionGroup : ctx->GetSettings()->GetOptionGroups()) { // don't go through non-menus - if (menu->mode != OPTION_SUB_MENU) { + if (optionGroup.GetContainsType() == Rando::OptionGroupType::SUBGROUP) { continue; } - for (size_t i = 0; i < menu->settingsList->size(); i++) { - Option* setting = menu->settingsList->at(i); - if (setting->IsCategory(OptionCategory::Setting)) { - settingsStr += setting->GetSelectedOptionText(); + for (Rando::Option* option : optionGroup.GetOptions()) { + if (option->IsCategory(Rando::OptionCategory::Setting)) { + if (option->GetOptionCount() > 0) { + settingsStr += option->GetSelectedOptionText(); + } } } } @@ -46,13 +52,12 @@ int Playthrough_Init(uint32_t seed, std::unordered_map{}(std::to_string(Settings::seed) + settingsStr); + uint32_t finalHash = boost::hash_32{}(std::to_string(ctx->GetSettings()->GetSeed()) + settingsStr); Random_Init(finalHash); - Settings::hash = std::to_string(finalHash); + ctx->GetSettings()->SetHash(std::to_string(finalHash)); - Logic::UpdateHelpers(); - if (Settings::Logic.Is(LOGIC_VANILLA)) { + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) { VanillaFill(); // Just place items in their vanilla locations } else { // Fill locations with logic int ret = Fill(); @@ -62,45 +67,47 @@ int Playthrough_Init(uint32_t seed, std::unordered_mapplaythroughLocations.clear(); + ctx->playthroughBeatable = false; return 1; } // used for generating a lot of seeds at once -int Playthrough_Repeat(std::unordered_map cvarSettings, std::set excludedLocations, std::set enabledTricks, int count /*= 1*/) { - printf("\x1b[0;0HGENERATING %d SEEDS", count); +int Playthrough_Repeat(std::set excludedLocations, std::set enabledTricks, int count /*= 1*/) { + SPDLOG_INFO("GENERATING {} SEEDS", count); + auto ctx = Rando::Context::GetInstance(); uint32_t repeatedSeed = 0; for (int i = 0; i < count; i++) { - Settings::seedString = std::to_string(rand() % 0xFFFFFFFF); - repeatedSeed = boost::hash_32{}(Settings::seedString); - Settings::seed = repeatedSeed % 0xFFFFFFFF; + ctx->GetSettings()->SetSeedString(std::to_string(rand() % 0xFFFFFFFF)); + repeatedSeed = boost::hash_32{}(ctx->GetSettings()->GetSeedString()); + ctx->GetSettings()->SetSeed(repeatedSeed % 0xFFFFFFFF); //CitraPrint("testing seed: " + std::to_string(Settings::seed)); ClearProgress(); - Playthrough_Init(Settings::seed, cvarSettings, excludedLocations, enabledTricks); - printf("\x1b[15;15HSeeds Generated: %d\n", i + 1); + Playthrough_Init(ctx->GetSettings()->GetSeed(), excludedLocations, enabledTricks); + SPDLOG_INFO("Seeds Generated: {}", i + 1); } return 1; diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.hpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.hpp index 90e5988b9ca..1dbbc784294 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.hpp @@ -1,9 +1,9 @@ #pragma once #include #include -#include "item_location.hpp" +#include "../context.h" namespace Playthrough { - int Playthrough_Init(uint32_t seed, std::unordered_map cvarSettings, std::set excludedLocations, std::set enabledTricks); - int Playthrough_Repeat(std::unordered_map cvarSettings, std::set excludedLocations, std::set enabledTricks, int count = 1); + int Playthrough_Init(uint32_t seed, std::set excludedLocations, std::set enabledTricks); + int Playthrough_Repeat(std::set excludedLocations, std::set enabledTricks, int count = 1); } diff --git a/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp b/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp index 1cb96c74622..5a83cda5bc6 100644 --- a/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp @@ -36,3 +36,7 @@ template bool ElementInContainer(T& element, const Container& container) { return std::find(container.begin(), container.end(), element) != container.end(); } + +template bool IsAnyOf(First&& first, T&&... t) { + return ((first == t) || ...); +} diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp index 9705d9a1430..d4d7ebdd7e5 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp @@ -1,33 +1,23 @@ #include "menu.hpp" -#include "hint_list.hpp" -#include "item_list.hpp" -#include "item_location.hpp" +#include "../static_data.h" +#include "../item_location.h" #include "location_access.hpp" #include "rando_main.hpp" +#include "../context.h" // #include #include #include #include #include "soh/OTRGlobals.h" -void RandoMain::GenerateRando(std::unordered_map cvarSettings, std::set excludedLocations, std::set enabledTricks, +void RandoMain::GenerateRando(std::set excludedLocations, std::set enabledTricks, std::string seedString) { - HintTable_Init(); - ItemTable_Init(); - LocationTable_Init(); // std::string settingsFileName = "./randomizer/latest_settings.json"; // CVarSetString(CVAR_RANDOMIZER_SETTING("LoadedPreset"), settingsFileName.c_str()); - std::string fileName = Ship::Context::GetPathRelativeToAppDirectory(GenerateRandomizer(cvarSettings, excludedLocations, enabledTricks, seedString).c_str()); - CVarSetString(CVAR_GENERAL("SpoilerLog"), fileName.c_str()); + Rando::Context::GetInstance()->SetSeedGenerated(GenerateRandomizer(excludedLocations, enabledTricks, seedString)); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - CVarSetInteger(CVAR_GENERAL("NewSeedGenerated"), 1); -} - -std::array* RandoMain::GetFullItemTable() { - ItemTable_Init(); - - return GetFullItemTable_(); + Rando::Context::GetInstance()->SetPlandoLoaded(false); } diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp index 159afb0cb0a..8ac22069bfa 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp @@ -1,8 +1,7 @@ #pragma once +#include "soh/Enhancements/randomizer/item.h" -#include "item.hpp" - +#include namespace RandoMain { -void GenerateRando(std::unordered_map cvarSettings, std::set excludedLocations, std::set enabledTricks, std::string seedInput); -std::array* GetFullItemTable(); +void GenerateRando(std::set excludedLocations, std::set enabledTricks, std::string seedInput); } diff --git a/soh/soh/Enhancements/randomizer/3drando/random.hpp b/soh/soh/Enhancements/randomizer/3drando/random.hpp index c8ccf0f50d3..2d2f11dbef9 100644 --- a/soh/soh/Enhancements/randomizer/3drando/random.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/random.hpp @@ -5,6 +5,7 @@ #include #include #include +#include void Random_Init(uint32_t seed); uint32_t Random(int min, int max); @@ -29,7 +30,21 @@ const auto& RandomElement(const Container& container) { return container[Random(0, std::size(container))]; } +template +const T RandomElementFromSet(const std::set& set) { + if (set.size() == 1) { + return *set.begin(); + } + uint32_t rand = Random(0, set.size()); + auto it = set.begin(); + for (uint32_t i = 0; i < rand; i++) { + it++; + } + return *it; +} + //Shuffle items within a vector or array +//RANDOTODO There's probably a more efficient way to do what this does. template void Shuffle(std::vector& vector) { for (std::size_t i = 0; i + 1 < vector.size(); i++) diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index 5dcd5a79274..e69de29bb2d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -1,2694 +0,0 @@ -#include "settings.hpp" - -#include "dungeon.hpp" -#include "fill.hpp" -#include "item_location.hpp" -#include "random.hpp" -#include "randomizer.hpp" -#include "trial.hpp" -#include "keys.hpp" - -using namespace Dungeon; -using namespace Trial; - -namespace Settings { - uint32_t seed; - std::string hash; - std::string version = RANDOMIZER_VERSION "-" COMMIT_NUMBER; - std::array hashIconIndexes; - std::string seedString; - - bool skipChildZelda = false; - - std::vector NumOpts(int min, int max, int step = 1, std::string textBefore = {}, std::string textAfter = {}) { - std::vector options; - options.reserve((max - min) / step + 1); - for (int i = min; i <= max; i += step) { - options.push_back(textBefore + std::to_string(i) + textAfter); - } - return options; - } - - std::vector MultiVecOpts(std::vector> optionsVector) { - uint32_t totalSize = 0; - for (auto vector : optionsVector) { - totalSize += vector.size(); - } - std::vector options; - options.reserve(totalSize); - for (auto vector : optionsVector) { - for (auto op : vector) { - options.push_back(op); - } - } - return options; - } - - // Setting name, Options, Category (default: Setting),Default index (default: 0), Default hidden (default: false) - //Open Settings - Option RandomizeOpen = Option::Bool("Randomize Settings", {"No","Yes"}, OptionCategory::Toggle); - Option OpenForest = Option::U8 ("Forest", {"Closed", "Closed Deku", "Open"}, OptionCategory::Setting, OPENFOREST_CLOSED); - Option OpenKakariko = Option::U8 ("Kakariko Gate", {"Closed", "Open"}); - Option OpenDoorOfTime = Option::U8 ("Door of Time", {"Closed", "Song only", "Open"}); - Option ZorasFountain = Option::U8 ("Zora's Fountain", {"Closed", "Closed as child", "Open"}); - Option GerudoFortress = Option::U8 ("Gerudo Fortress", {"Normal", "Fast", "Open"}); - Option Bridge = Option::U8 ("Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Greg"}, OptionCategory::Setting, RAINBOWBRIDGE_VANILLA); - Option BridgeStoneCount = Option::U8 ("Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, 1, true); - Option BridgeMedallionCount= Option::U8 ("Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, 1, true); - Option BridgeRewardCount = Option::U8 ("Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, 1, true); - Option BridgeDungeonCount = Option::U8 ("Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, 1, true); - Option BridgeTokenCount = Option::U8 ("Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, 1, true); - Option BridgeRewardOptions = Option::U8 ("Bridge Reward Options", {"Standard Rewards", "Greg as Reward", "Greg as Wildcard"}); - Option RandomGanonsTrials = Option::Bool("Random Ganon's Trials", {"Off", "On"}, OptionCategory::Setting, ON); - Option GanonsTrialsCount = Option::U8 ("Trial Count", {NumOpts(0, 6)}, OptionCategory::Setting, 1, true); - std::vector