diff --git a/.github/workflows/apt-deps.txt b/.github/workflows/apt-deps.txt index c06068ab4..51e9574f8 100644 --- a/.github/workflows/apt-deps.txt +++ b/.github/workflows/apt-deps.txt @@ -1 +1 @@ -libusb-dev libusb-1.0-0-dev libsdl2-dev libsdl2-net-dev libpng-dev libglew-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev ninja-build +libusb-dev libusb-1.0-0-dev libsdl2-dev libsdl2-net-dev libpng-dev libglew-dev nlohmann-json3-dev libtinyxml2-dev libspdlog-dev ninja-build diff --git a/.github/workflows/generate-builds.yml b/.github/workflows/generate-builds.yml index 29cd94c8a..64c908a37 100644 --- a/.github/workflows/generate-builds.yml +++ b/.github/workflows/generate-builds.yml @@ -22,7 +22,7 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install -y $(cat .github/workflows/apt-deps.txt) + sudo apt-get install -y $(cat .github/workflows/apt-deps.txt) libzip-dev zipcmp zipmerge ziptool - name: Cache build folders uses: actions/cache@v4 with: @@ -32,15 +32,16 @@ jobs: ${{ runner.os }}-otr-build- path: | build-cmake - SDL2-2.28.5 + SDL2-2.30.3 + tinyxml2-10.0.0 - name: Install latest SDL run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - if [ ! -d "SDL2-2.28.5" ]; then - wget https://www.libsdl.org/release/SDL2-2.28.5.tar.gz - tar -xzf SDL2-2.28.5.tar.gz + if [ ! -d "SDL2-2.30.3" ]; then + wget https://www.libsdl.org/release/SDL2-2.30.3.tar.gz + tar -xzf SDL2-2.30.3.tar.gz fi - cd SDL2-2.28.5 + cd SDL2-2.30.3 ./configure --enable-hidapi-libusb make -j 10 sudo make install @@ -54,7 +55,7 @@ jobs: tar -xzf 10.0.0.tar.gz fi cd tinyxml2-10.0.0 - mkdir build + mkdir -p build cd build cmake .. make @@ -157,34 +158,22 @@ jobs: linux-build-${{ github.ref }} linux-build- path: | - SDL2-2.28.5 + SDL2-2.30.3 SDL2_net-2.2.0 + tinyxml2-10.0.0 + libzip-1.10.1 - name: Install latest SDL run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - if [ ! -d "SDL2-2.28.5" ]; then - wget https://www.libsdl.org/release/SDL2-2.28.5.tar.gz - tar -xzf SDL2-2.28.5.tar.gz + if [ ! -d "SDL2-2.30.3" ]; then + wget https://www.libsdl.org/release/SDL2-2.30.3.tar.gz + tar -xzf SDL2-2.30.3.tar.gz fi - cd SDL2-2.28.5 + cd SDL2-2.30.3 ./configure --enable-hidapi-libusb make -j 10 sudo make install sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/ - - name: Install latest tinyxml2 - run: | - sudo apt-get remove libtinyxml2-dev - export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" - if [ ! -d "tinyxml2-10.0.0" ]; then - wget https://github.com/leethomason/tinyxml2/archive/refs/tags/10.0.0.tar.gz - tar -xzf 10.0.0.tar.gz - fi - cd tinyxml2-10.0.0 - mkdir build - cd build - cmake .. - make - sudo make install - name: Install latest SDL_net run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" @@ -197,6 +186,34 @@ jobs: make -j 10 sudo make install sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/ + - name: Install latest tinyxml2 + run: | + sudo apt-get remove libtinyxml2-dev + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + if [ ! -d "tinyxml2-10.0.0" ]; then + wget https://github.com/leethomason/tinyxml2/archive/refs/tags/10.0.0.tar.gz + tar -xzf 10.0.0.tar.gz + fi + cd tinyxml2-10.0.0 + mkdir -p build + cd build + cmake .. + make + sudo make install + - name: Install libzip without crypto + run: | + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + if [ ! -d "libzip-1.10.1" ]; then + wget https://github.com/nih-at/libzip/releases/download/v1.10.1/libzip-1.10.1.tar.gz + tar -xzf libzip-1.10.1.tar.gz + fi + cd libzip-1.10.1 + mkdir -p build + cd build + cmake .. -DENABLE_COMMONCRYPTO=OFF -DENABLE_GNUTLS=OFF -DENABLE_MBEDTLS=OFF -DENABLE_OPENSSL=OFF + make + sudo make install + sudo cp -av /usr/local/lib/libzip* /lib/x86_64-linux-gnu/ - name: Download soh.otr uses: actions/download-artifact@v4 with: @@ -244,7 +261,6 @@ jobs: - name: Cache build folder uses: actions/cache@v4 with: - save-always: true key: ${{ runner.os }}-build-${{ github.ref }}-${{ github.sha }} restore-keys: | ${{ runner.os }}-build-${{ github.ref }} diff --git a/.github/workflows/pr-artifacts.yml b/.github/workflows/pr-artifacts.yml index 43b985b5d..85db7de59 100644 --- a/.github/workflows/pr-artifacts.yml +++ b/.github/workflows/pr-artifacts.yml @@ -12,7 +12,7 @@ jobs: if: ${{ github.event.workflow_run.event == 'pull_request' }} steps: - id: 'pr-number' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: result-encoding: string script: | @@ -20,8 +20,9 @@ jobs: const pullHeadSHA = '${{github.event.workflow_run.head_sha}}'; const pullUserId = ${{github.event.sender.id}}; const prNumber = await (async () => { - const pulls = await github.rest.pulls.list({owner, repo}); - for await (const {data} of github.paginate.iterator(pulls)) { + for await (const { data } of github.paginate.iterator( + github.rest.pulls.list, { owner, repo } + )) { for (const pull of data) { if (pull.head.sha === pullHeadSHA && pull.user.id === pullUserId) { return pull.number; @@ -36,7 +37,7 @@ jobs: return prNumber; - id: 'artifacts-text' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: result-encoding: string script: | @@ -47,13 +48,13 @@ jobs: }); return allArtifacts.data.artifacts.reduce((acc, item) => { - if (item.name === "assets") return acc; + if (item.name === "soh.otr") return acc; acc += ` - [${item.name}.zip](https://nightly.link/${context.repo.owner}/${context.repo.repo}/actions/artifacts/${item.id}.zip)`; return acc; }, '### Build Artifacts'); - id: 'add-to-pr' - uses: garrettjoecox/pr-section@3.1.0 + uses: garrettjoecox/pr-section@4.0.0 with: repo-token: '${{ secrets.GITHUB_TOKEN }}' pr-number: ${{ steps.pr-number.outputs.result }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 606abeba7..2bdaf1de9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,18 @@ project(Ship VERSION 8.0.6 LANGUAGES C CXX) include(CMake/soh-cvars.cmake) include(CMake/lus-cvars.cmake) +option(SUPPRESS_WARNINGS "Suppress warnings in LUS and src (decomp)" ON) +if(SUPPRESS_WARNINGS) + MESSAGE("Suppressing warnings in LUS and src") + if(MSVC) + set(WARNING_OVERRIDE /w) + else() + set(WARNING_OVERRIDE -w) + endif() +else() + MESSAGE("Skipping warning suppression") +endif() + set(NATO_PHONETIC_ALPHABET "Alfa" "Bravo" "Charlie" "Delta" "Echo" "Foxtrot" "Golf" "Hotel" "India" "Juliett" "Kilo" "Lima" "Mike" "November" "Oscar" "Papa" @@ -148,6 +160,7 @@ add_compile_definitions(CONTROLLERBUTTONS_T=uint32_t) # Sub-projects ################################################################################ add_subdirectory(libultraship ${CMAKE_BINARY_DIR}/libultraship) +target_compile_options(libultraship PRIVATE "${WARNING_OVERRIDE}") add_subdirectory(ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD) add_subdirectory(OTRExporter) add_subdirectory(soh) diff --git a/OTRExporter b/OTRExporter index 467f36589..8f7167290 160000 --- a/OTRExporter +++ b/OTRExporter @@ -1 +1 @@ -Subproject commit 467f36589b0d6fe6c7f9d248945650a459bce768 +Subproject commit 8f71672901987bc3dbf6256e64e228db36a686f5 diff --git a/README.md b/README.md index c84059892..e7f929bad 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Official Website: https://www.shipofharkinian.com/ Official Discord: https://discord.com/invite/shipofharkinian -If you're having any trouble after reading through this `README`, feel free ask for help in the Support text channels. Please keep in mind that we do not condone piracy. +If you're having any trouble after reading through this `README`, feel free to ask for help in the Support text channels. Please keep in mind that we do not condone piracy. # Quick Start @@ -73,7 +73,7 @@ Congratulations, you are now sailing with the Ship of Harkinian! Have fun! # 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. +In order for the game to function, you will require a **legally acquired** ROM for Ocarina of Time. Click [here](https://ship.equipment/) to check the compatibility of your specific rom. Any copyrighted assets are extracted from the ROM and reformatted 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. @@ -99,13 +99,13 @@ If you want to playtest a continuous integration build, you can find them at the * [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). +More detailed documentation can be found in the 'docs' directory, including the aforementioned [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) +* [Credits](docs/CREDITS.md) +* [Custom Music](docs/CUSTOM_MUSIC.md) +* [Controller Mapping](docs/GAME_CONTROLLER_DB.md) +* [Modding](docs/MODDING.md) +* [Versioning](docs/VERSIONING.md) diff --git a/docs/BUILDING.md b/docs/BUILDING.md index aa44f3e44..963037465 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -3,7 +3,7 @@ ## Windows Requires: - * At least 8GB of RAM (machines with 4GB have seen complier failures) + * At least 8GB of RAM (machines with 4GB have seen compiler failures) * Visual Studio 2022 Community Edition with the C++ feature set * One of the Windows SDKs that comes with Visual Studio, for example the current Windows 10 version 10.0.19041.0 * The `MSVC v143 - VS 2022 C++ build tools` component of Visual Studio @@ -22,7 +22,7 @@ It is recommended that you install Python and Git standalone, the install proces _Note: Be sure to either clone with the ``--recursive`` flag or do ``git submodule update --init`` after cloning to pull in the libultraship submodule!_ -2. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice +2. After setup and initial build, use the built-in OTR extraction to make your oot.otr/oot-mq.otr files. _Note: Instructions assume using powershell_ ```powershell @@ -30,22 +30,18 @@ _Note: Instructions assume using powershell_ cd Shipwright # Setup cmake project -& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v143 -A x64 # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) -# Extract assets & generate OTR (run this anytime you need to regenerate OTR) -& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target ExtractAssets # --config Release (if you're packaging) -# Compile project -& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 # --config Release (if you're packaging) +# Add `-DCMAKE_BUILD_TYPE:STRING=Release` if you're packaging +# Add `-DSUPPRESS_WARNINGS=0` to prevent suppression of warnings from LUS and decomp (src) files. set to 1 to re-enable suppression +& 'C:\Program Files\CMake\bin\cmake' -S . -B "build/x64" -G "Visual Studio 17 2022" -T v143 -A x64 -# Now you can run the executable in .\build\x64 - -# If you need to clean the project you can run -& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target clean - -# If you need to regenerate the asset headers to check them into source -& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target ExtractAssetHeaders - -# If you need a newer soh.otr only +# Generate soh.otr & 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 --target GenerateSohOtr + +# Compile project +# Add `--config Release` if you're packaging +& 'C:\Program Files\CMake\bin\cmake.exe' --build .\build\x64 + +# Now you can run the executable in .\build\x64 or run in Visual Studio ``` ### Developing SoH @@ -76,6 +72,19 @@ cd "build/x64" & 'C:\Program Files\CMake\bin\cpack.exe' -G ZIP ``` +### Additional CMake Targets +#### Clean +```powershell +# If you need to clean the project you can run +C:\Program Files\CMake\bin\cmake.exe --build build-cmake --target clean +``` + +#### Regenerate Asset Headers +```powershell +# If you need to regenerate the asset headers to check them into source +C:\Program Files\CMake\bin\cmake.exe --build build-cmake --target ExtractAssetHeaders +``` + ## Linux ### Install dependencies #### Debian/Ubuntu @@ -124,13 +133,17 @@ cd Shipwright git submodule update --init # Generate Ninja project -cmake -H. -Bbuild-cmake -GNinja # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) -DPython3_EXECUTABLE=$(which python3) (if you are using non-standard Python installations such as PyEnv) +# Add `-DCMAKE_BUILD_TYPE:STRING=Release` if you're packaging +# Add `-DSUPPRESS_WARNINGS=0` to prevent suppression of warnings from LUS and decomp (src) files. set to 1 to re-enable suppression +# Add `-DPython3_EXECUTABLE=$(which python3)` if you are using non-standard Python installations such as PyEnv +cmake -H. -Bbuild-cmake -GNinja # Generate soh.otr cmake --build build-cmake --target GenerateSohOtr # Compile the project -cmake --build build-cmake # --config Release (if you're packaging) +# Add `--config Release` if you're packaging +cmake --build build-cmake # Now you can run the executable in ./build-cmake/soh/soh.elf # To develop the project open the repository in VSCode (or your preferred editor) @@ -153,16 +166,14 @@ cpack -G External (creates appimage) # If you need to clean the project you can run cmake --build build-cmake --target clean ``` - #### Regenerate Asset Headers ```bash # If you need to regenerate the asset headers to check them into source -cp OTRExporter cmake --build build-cmake --target ExtractAssetHeaders ``` ## macOS -Requires Xcode (or xcode-tools) && `sdl2, libpng, glew, ninja, cmake` (can be installed via homebrew, macports, etc) +Requires Xcode (or xcode-tools) && `sdl2, libpng, glew, ninja, cmake, tinyxml2, nlohmann-json, libzip` (can be installed via [homebrew](https://brew.sh/), macports, etc) **Important: For maximum performance make sure you have ninja build tools installed!** @@ -172,32 +183,28 @@ _Note: If you're using Visual Studio Code, the [cpack plugin](https://marketplac # Clone the repo git clone https://github.com/HarbourMasters/Shipwright.git cd ShipWright + # Clone the submodule libultraship git submodule update --init -# Copy the baserom to the OTRExporter folder -cp OTRExporter -# Generate Ninja project -cmake -H. -Bbuild-cmake -GNinja # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) -# Extract assets & generate OTR (run this anytime you need to regenerate OTR) -cmake --build build-cmake --target ExtractAssets -# Compile the project -cmake --build build-cmake # --config Release (if you're packaging) -# Copy oot.otr into the Application Support directory -cp build-cmake/soh/oot.otr ~/Library/Application\ Support/com.shipofharkinian.soh/ +# Install development dependencies (assuming homebrew) +brew install sdl2 libpng glew ninja cmake tinyxml2 nlohmann-json libzip + +# Generate Ninja project +# Add `-DCMAKE_BUILD_TYPE:STRING=Release` if you're packaging +# Add `-DSUPPRESS_WARNINGS=0` to prevent suppression of warnings from LUS and decomp (src) files. set to 1 to re-enable suppression +cmake -H. -Bbuild-cmake -GNinja + +# Generate soh.otr +cmake --build build-cmake --target GenerateSohOtr + +# Compile the project +# Add `--config Release` if you're packaging +cmake --build build-cmake # Now you can run the executable file: ./build-cmake/soh/soh-macos # To develop the project open the repository in VSCode (or your preferred editor) - -# If you need to clean the project you can run -cmake --build build-cmake --target clean - -# If you need to regenerate the asset headers to check them into source -cmake --build build-cmake --target ExtractAssetHeaders - -# If you need a newer soh.otr only -cmake --build build-cmake --target GenerateSohOtr ``` ### Generating a distributable @@ -209,6 +216,19 @@ cd build-cmake cpack ``` +### Additional CMake Targets +#### Clean +```bash +# If you need to clean the project you can run +cmake --build build-cmake --target clean +``` + +#### Regenerate Asset Headers +```bash +# If you need to regenerate the asset headers to check them into source +cmake --build build-cmake --target ExtractAssetHeaders +``` + ## Switch 1. Requires that your build machine is setup with the tools necessary for your platform above 2. Requires that you have the switch build tools installed diff --git a/docs/GAME_CONTROLLER_DB.md b/docs/GAME_CONTROLLER_DB.md index 4728c8981..3867f5a63 100644 --- a/docs/GAME_CONTROLLER_DB.md +++ b/docs/GAME_CONTROLLER_DB.md @@ -29,3 +29,10 @@ This file is pulled from https://github.com/gabomdq/SDL_GameControllerDB during | Spock Charlie 7.0.2 | [c5b4df0](https://github.com/gabomdq/SDL_GameControllerDB/tree/c5b4df0e1061175cb11e3ebbf8045178339864a5) | [+3](https://github.com/gabomdq/SDL_GameControllerDB/compare/228d980...c5b4df0) | | Sulu Alfa 7.1.0 | [a2cf171](https://github.com/gabomdq/SDL_GameControllerDB/tree/a2cf1711b4ebc646a3814705d2fb6aac5707bcae) | [+4/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/c5b4df0...a2cf171) | | Sulu Bravo 7.1.1 | [cc9f777](https://github.com/gabomdq/SDL_GameControllerDB/tree/cc9f777721f0cb30058d9eef52a295130b734a4a) | [+29/-9](https://github.com/gabomdq/SDL_GameControllerDB/compare/a2cf171...cc9f777) | +| MacReady Alfa 8.0.0 | [c56329f](https://github.com/gabomdq/SDL_GameControllerDB/tree/c56329f4df93fc7a780bdbeae47a9c91447b629c) | [+67/-23](https://github.com/gabomdq/SDL_GameControllerDB/compare/cc9f777...c56329f) | +| MacReady Bravo 8.0.1 | [721b575](https://github.com/gabomdq/SDL_GameControllerDB/tree/721b575d3053b21d6d30419bf74afb5b1d0fa7a4) | [+5/-5](https://github.com/gabomdq/SDL_GameControllerDB/compare/c56329f...721b575) | +| MacReady Charlie 8.0.2 | [721b575](https://github.com/gabomdq/SDL_GameControllerDB/tree/721b575d3053b21d6d30419bf74afb5b1d0fa7a4) | [+0/-0](https://github.com/gabomdq/SDL_GameControllerDB/compare/721b575...721b575) | +| MacReady Delta 8.0.3 | [d4ab609](https://github.com/gabomdq/SDL_GameControllerDB/tree/d4ab609121ee6e687bc3d3a7e80244b3b26d1164) | [+5/-3](https://github.com/gabomdq/SDL_GameControllerDB/compare/721b575...d4ab609) | +| MacReady Echo 8.0.4 | [6555d47](https://github.com/gabomdq/SDL_GameControllerDB/tree/6555d47ecb5d9eebac0e3d8cd19a545e9d946c40) | [+2/-0](https://github.com/gabomdq/SDL_GameControllerDB/compare/d4ab609...6555d47) | +| MacReady Foxtrot 8.0.5 | [037d6a1](https://github.com/gabomdq/SDL_GameControllerDB/tree/037d6a1533ed94fbc6a8c71e6f1f9aff1e46208a) | [+47/-14](https://github.com/gabomdq/SDL_GameControllerDB/compare/6555d47...037d6a1) | +| MacReady Golf 8.0.6 | [075c154](https://github.com/gabomdq/SDL_GameControllerDB/tree/075c1549075ef89a397fd7e0663d21e53a2485fd) | [+340/-301](https://github.com/gabomdq/SDL_GameControllerDB/compare/037d6a1...075c154) | diff --git a/docs/MODDING.md b/docs/MODDING.md index 75293b64a..1f4f4b607 100644 --- a/docs/MODDING.md +++ b/docs/MODDING.md @@ -59,7 +59,7 @@ if (IS_DAY || gTimeIncrement >= 0x190) { } ``` -We can make a quick change to this code to verify this is indeed what we are looking for, lets multiply the the gTimeIncrement by 10: +We can make a quick change to this code to verify this is indeed what we are looking for, lets multiply the gTimeIncrement by 10: ```diff if (IS_DAY || gTimeIncrement >= 0x190) { diff --git a/libultraship b/libultraship index 0302eab05..3e46fe77a 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit 0302eab051a7e0e5a8dc208aca5b00899a91808c +Subproject commit 3e46fe77a4581a84f9c0edfab9c3a69a5320fe01 diff --git a/soh/.gitignore b/soh/.gitignore index 3c7bcce33..60d09e672 100644 --- a/soh/.gitignore +++ b/soh/.gitignore @@ -7,7 +7,6 @@ __pycache__/ .vscode/ .vs/ .idea/ -CMakeLists.txt cmake-build-debug venv/ diff --git a/soh/CMakeLists.txt b/soh/CMakeLists.txt index 42d12991b..8218588e4 100644 --- a/soh/CMakeLists.txt +++ b/soh/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR) +cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR) set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE) @@ -173,6 +173,7 @@ endif() # src (decomp) {{{ file(GLOB_RECURSE src__ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.c" "src/*.h") +set_source_files_properties(${src__} PROPERTIES COMPILE_OPTIONS "${WARNING_OVERRIDE}") list(APPEND src__ ${CMAKE_CURRENT_SOURCE_DIR}/Resource.rc) list(FILTER src__ EXCLUDE REGEX "src/dmadata/*") @@ -606,18 +607,22 @@ endif() ################################################################################ # Pre build events ################################################################################ +if (CMAKE_GENERATOR MATCHES "Visual Studio") + set(VS_COPY_ASSETS_CMD ${CMAKE_COMMAND} -E copy_directory_if_different $/assets ${CMAKE_BINARY_DIR}/soh/assets) +endif() if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS") add_custom_command( TARGET ${PROJECT_NAME} POST_BUILD COMMENT "Copying asset xmls..." - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/soh/assets/extractor $/assets/extractor - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/soh/assets/xml $/assets/extractor/xmls - COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/filelists $/assets/extractor/filelists + COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_SOURCE_DIR}/soh/assets/extractor $/assets/extractor + COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_SOURCE_DIR}/soh/assets/xml $/assets/extractor/xmls + COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/filelists $/assets/extractor/filelists COMMAND ${CMAKE_COMMAND} -E make_directory $/assets/extractor/symbols - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ActorList_OoTMqDbg.txt $/assets/extractor/symbols - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ObjectList_OoTMqDbg.txt $/assets/extractor/symbols - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/SymbolMap_OoTMqDbg.txt $/assets/extractor/symbols + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ActorList_OoTMqDbg.txt $/assets/extractor/symbols + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/ObjectList_OoTMqDbg.txt $/assets/extractor/symbols + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/OTRExporter/CFG/SymbolMap_OoTMqDbg.txt $/assets/extractor/symbols + COMMAND ${VS_COPY_ASSETS_CMD} ) endif() ################################################################################ diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/PotBaseNoise_8 b/soh/assets/custom/objects/gameplay_dangeon_keep/PotBaseNoise_8 new file mode 100644 index 000000000..a278fcdff Binary files /dev/null and b/soh/assets/custom/objects/gameplay_dangeon_keep/PotBaseNoise_8 differ diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/PotFaceNoise_16 b/soh/assets/custom/objects/gameplay_dangeon_keep/PotFaceNoise_16 new file mode 100644 index 000000000..302172ec0 Binary files /dev/null and b/soh/assets/custom/objects/gameplay_dangeon_keep/PotFaceNoise_16 differ diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/PotFaceYellow_16 b/soh/assets/custom/objects/gameplay_dangeon_keep/PotFaceYellow_16 new file mode 100644 index 000000000..cb3e67e38 Binary files /dev/null and b/soh/assets/custom/objects/gameplay_dangeon_keep/PotFaceYellow_16 differ diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/PotFace_32 b/soh/assets/custom/objects/gameplay_dangeon_keep/PotFace_32 new file mode 100644 index 000000000..a34be6c81 Binary files /dev/null and b/soh/assets/custom/objects/gameplay_dangeon_keep/PotFace_32 differ diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL new file mode 100644 index 000000000..f1e794a96 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_0 b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_0 new file mode 100644 index 000000000..e3d576ab5 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_0 @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_1 b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_1 new file mode 100644 index 000000000..9e3577c30 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_1 @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_2 b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_2 new file mode 100644 index 000000000..957020e99 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_2 @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_3 b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_3 new file mode 100644 index 000000000..7b2e00037 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_3 @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_4 b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_4 new file mode 100644 index 000000000..554a34e4b --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_tri_4 @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_0 b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_0 new file mode 100644 index 000000000..88f1059c3 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_0 @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_1 b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_1 new file mode 100644 index 000000000..24da4e34f --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_1 @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_2 b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_2 new file mode 100644 index 000000000..6683ff1d2 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_2 @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_3 b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_3 new file mode 100644 index 000000000..4394fa228 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_3 @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_4 b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_4 new file mode 100644 index 000000000..2ef56105a --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/gRandoPotDL_vtx_4 @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potbase b/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potbase new file mode 100644 index 000000000..6c4a0fdee --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potbase @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potbottom b/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potbottom new file mode 100644 index 000000000..e69179046 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potbottom @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potface b/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potface new file mode 100644 index 000000000..0969a02d5 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potface @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potrim b/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potrim new file mode 100644 index 000000000..3c56bbc96 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potrim @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potvoid b/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potvoid new file mode 100644 index 000000000..d39d1af92 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_dangeon_keep/mat_gRandoPotDL_f3dlite_potvoid @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/soh/assets/custom/textures/parameter_static/gMoon.rgba32.png b/soh/assets/custom/textures/parameter_static/gMoon.rgba32.png new file mode 100644 index 000000000..9c1afa577 Binary files /dev/null and b/soh/assets/custom/textures/parameter_static/gMoon.rgba32.png differ diff --git a/soh/assets/custom/textures/parameter_static/gNavi.rgba32.png b/soh/assets/custom/textures/parameter_static/gNavi.rgba32.png new file mode 100644 index 000000000..aae12c339 Binary files /dev/null and b/soh/assets/custom/textures/parameter_static/gNavi.rgba32.png differ diff --git a/soh/assets/custom/textures/parameter_static/gSun.rgba32.png b/soh/assets/custom/textures/parameter_static/gSun.rgba32.png new file mode 100644 index 000000000..954726e05 Binary files /dev/null and b/soh/assets/custom/textures/parameter_static/gSun.rgba32.png differ diff --git a/soh/assets/objects/object_link_child/object_link_child.h b/soh/assets/objects/object_link_child/object_link_child.h index 8f49d115c..a6515cc56 100644 --- a/soh/assets/objects/object_link_child/object_link_child.h +++ b/soh/assets/objects/object_link_child/object_link_child.h @@ -220,7 +220,7 @@ static const ALIGN_ASSET(2) char gLinkChildDL_18580[] = dgLinkChildDL_18580; static const ALIGN_ASSET(2) char gLinkChildBottle2DL[] = dgLinkChildBottle2DL; #define dgLinkChildSlinghotStringDL "__OTR__objects/object_link_child/gLinkChildSlinghotStringDL" -static const ALIGN_ASSET(2) char gLinkChildSlinghotStringDL[] = dgLinkChildSlinghotStringDL; +static const ALIGN_ASSET(2) char gLinkChildSlingshotStringDL[] = dgLinkChildSlinghotStringDL; #define dgLinkChildDekuShieldDL "__OTR__objects/object_link_child/gLinkChildDekuShieldDL" static const ALIGN_ASSET(2) char gLinkChildDekuShieldDL[] = dgLinkChildDekuShieldDL; diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h index c0acacf21..894be4106 100644 --- a/soh/assets/soh_assets.h +++ b/soh/assets/soh_assets.h @@ -74,6 +74,9 @@ static const ALIGN_ASSET(2) char gTriforcePieceCompletedDL[] = dgTriforcePieceCo #define dgBossSoulSkullDL "__OTR__objects/object_boss_soul/gGIBossSoulSkullDL" static const ALIGN_ASSET(2) char gBossSoulSkullDL[] = dgBossSoulSkullDL; +#define dgRandoPotDL "__OTR__objects/gameplay_dangeon_keep/gRandoPotDL" +static const ALIGN_ASSET(2) char gRandoPotDL[] = dgRandoPotDL; + #define dgFishingPoleGiDL "__OTR__objects/object_gi_fishing_pole/gFishingPoleGiDL" static const ALIGN_ASSET(2) char gFishingPoleGiDL[] = dgFishingPoleGiDL; @@ -106,6 +109,15 @@ static const ALIGN_ASSET(2) char gSplitEntranceTex[] = dgSplitEntrance; #define dgBossSoul "__OTR__textures/parameter_static/gBossSoul" static const ALIGN_ASSET(2) char gBossSoulTex[] = dgBossSoul; +#define dgMoonIcon "__OTR__textures/parameter_static/gMoon" +static const ALIGN_ASSET(2) char gMoonIconTex[] = dgMoonIcon; + +#define dgSunIcon "__OTR__textures/parameter_static/gSun" +static const ALIGN_ASSET(2) char gSunIconTex[] = dgSunIcon; + +#define dgNaviIcon "__OTR__textures/parameter_static/gNavi" +static const ALIGN_ASSET(2) char gNaviIconTex[] = dgNaviIcon; + #define dgFileSelMQButtonTex "__OTR__textures/title_static/gFileSelMQButtonTex" static const ALIGN_ASSET(2) char gFileSelMQButtonTex[] = dgFileSelMQButtonTex; @@ -150,3 +162,22 @@ static const ALIGN_ASSET(2) char gFileSelLanguageGERTex[] = dgFileSelLanguageGER #define dgEmptyTexture "__OTR__textures/virtual/gEmptyTexture" static const ALIGN_ASSET(2) char gEmptyTexture[] = dgEmptyTexture; + +// Custom Tunic Models +#define dgLinkChildKokiriTunicSkel "__OTR__objects/object_link_child_kokiri/gLinkChildKokiriTunicSkel" +static const ALIGN_ASSET(2) char gLinkChildKokiriTunicSkel[] = dgLinkChildKokiriTunicSkel; + +#define dgLinkChildGoronTunicSkel "__OTR__objects/object_link_child_goron/gLinkChildGoronTunicSkel" +static const ALIGN_ASSET(2) char gLinkChildGoronTunicSkel[] = dgLinkChildGoronTunicSkel; + +#define dgLinkChildZoraTunicSkel "__OTR__objects/object_link_child_zora/gLinkChildZoraTunicSkel" +static const ALIGN_ASSET(2) char gLinkChildZoraTunicSkel[] = dgLinkChildZoraTunicSkel; + +#define dgLinkAdultKokiriTunicSkel "__OTR__objects/object_link_boy_kokiri/gLinkAdultKokiriTunicSkel" +static const ALIGN_ASSET(2) char gLinkAdultKokiriTunicSkel[] = dgLinkAdultKokiriTunicSkel; + +#define dgLinkAdultGoronTunicSkel "__OTR__objects/object_link_boy_goron/gLinkAdultGoronTunicSkel" +static const ALIGN_ASSET(2) char gLinkAdultGoronTunicSkel[] = dgLinkAdultGoronTunicSkel; + +#define dgLinkAdultZoraTunicSkel "__OTR__objects/object_link_boy_zora/gLinkAdultZoraTunicSkel" +static const ALIGN_ASSET(2) char gLinkAdultZoraTunicSkel[] = dgLinkAdultZoraTunicSkel; diff --git a/soh/assets/sources/potshuffle/MysteryPot.blend b/soh/assets/sources/potshuffle/MysteryPot.blend new file mode 100644 index 000000000..a3a8334cc Binary files /dev/null and b/soh/assets/sources/potshuffle/MysteryPot.blend differ diff --git a/soh/assets/sources/potshuffle/PotBaseNoise_8.png b/soh/assets/sources/potshuffle/PotBaseNoise_8.png new file mode 100644 index 000000000..db1d6e91e Binary files /dev/null and b/soh/assets/sources/potshuffle/PotBaseNoise_8.png differ diff --git a/soh/assets/sources/potshuffle/PotFace_32.png b/soh/assets/sources/potshuffle/PotFace_32.png new file mode 100644 index 000000000..12543fcd4 Binary files /dev/null and b/soh/assets/sources/potshuffle/PotFace_32.png differ diff --git a/soh/include/attributes.h b/soh/include/attributes.h new file mode 100644 index 000000000..f58cc8122 --- /dev/null +++ b/soh/include/attributes.h @@ -0,0 +1,12 @@ +#ifndef ATTRIBUTES_H +#define ATTRIBUTES_H + +#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif + +#define UNUSED __attribute__((unused)) +#define FALLTHROUGH __attribute__((fallthrough)) +#define NORETURN __attribute__((noreturn)) + +#endif diff --git a/soh/include/functions.h b/soh/include/functions.h index 41b325236..64d7026e1 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -398,12 +398,12 @@ void Actor_Kill(Actor* actor); void Actor_SetFocus(Actor* actor, f32 offset); void Actor_SetScale(Actor* actor, f32 scale); void Actor_SetObjectDependency(PlayState* play, Actor* actor); -void func_8002D7EC(Actor* actor); -void func_8002D868(Actor* actor); -void Actor_MoveForward(Actor* actor); -void func_8002D908(Actor* actor); -void func_8002D97C(Actor* actor); -void func_8002D9A4(Actor* actor, f32 arg1); +void Actor_UpdatePos(Actor* actor); +void Actor_UpdateVelocityXZGravity(Actor* actor); +void Actor_MoveXZGravity(Actor* actor); +void Actor_UpdateVelocityXYZ(Actor* actor); +void Actor_MoveXYZ(Actor* actor); +void Actor_SetProjectileSpeed(Actor* actor, f32 arg1); s16 Actor_WorldYawTowardActor(Actor* actorA, Actor* actorB); s16 Actor_WorldYawTowardPoint(Actor* actor, Vec3f* refPoint); f32 Actor_WorldDistXYZToActor(Actor* actorA, Actor* actorB); @@ -412,7 +412,7 @@ s16 Actor_WorldPitchTowardActor(Actor* actorA, Actor* actorB); s16 Actor_WorldPitchTowardPoint(Actor* actor, Vec3f* refPoint); f32 Actor_WorldDistXZToActor(Actor* actorA, Actor* actorB); f32 Actor_WorldDistXZToPoint(Actor* actor, Vec3f* refPoint); -void func_8002DBD0(Actor* actor, Vec3f* result, Vec3f* arg2); +void Actor_WorldToActorCoords(Actor* actor, Vec3f* result, Vec3f* arg2); f32 Actor_HeightDiff(Actor* actorA, Actor* actorB); f32 Player_GetHeight(Player* player); s32 Player_ActionHandler_2(Player* player, PlayState* play); @@ -455,13 +455,13 @@ 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 Actor_OfferGetItem and func_8002F554. +// TODO: Rename the follwing 3 functions using whatever scheme we use when we rename Actor_OfferGetItem and Actor_OfferGetItemNearby. s32 GiveItemEntryWithoutActor(PlayState* play, GetItemEntry getItemEntry); s32 GiveItemEntryFromActor(Actor* actor, PlayState* play, GetItemEntry getItemEntry, 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); +void Actor_OfferGetItemNearby(Actor* actor, PlayState* play, s32 getItemId); +void Actor_OfferCarry(Actor* actor, PlayState* play); u32 Actor_HasNoParent(Actor* actor, PlayState* play); void func_8002F5C4(Actor* actorA, Actor* actorB, PlayState* play); void func_8002F5F0(Actor* actor, PlayState* play); @@ -537,7 +537,7 @@ void func_80034BA0(PlayState* play, SkelAnime* skelAnime, OverrideLimbDraw overr PostLimbDraw postLimbDraw, Actor* actor, s16 alpha); void func_80034CC4(PlayState* play, SkelAnime* skelAnime, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, s16 alpha); -s16 func_80034DD4(Actor* actor, PlayState* play, s16 arg2, f32 arg3); +s16 Actor_UpdateAlphaByDistance(Actor* actor, PlayState* play, s16 arg2, f32 arg3); void Animation_ChangeByInfo(SkelAnime* skelAnime, AnimationInfo* animationInfo, s32 index); void func_80034F54(PlayState* play, s16* arg1, s16* arg2, s32 arg3); void Actor_Noop(Actor* actor, PlayState* play); @@ -717,15 +717,15 @@ void BgCheck_DrawStaticCollision(PlayState*, CollisionContext*); void func_80043334(CollisionContext* colCtx, Actor* actor, s32 bgId); s32 func_800433A4(CollisionContext* colCtx, s32 bgId, Actor* actor); void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 flags); -void func_800434A0(DynaPolyActor* dynaActor); -void func_800434A8(DynaPolyActor* dynaActor); -void func_800434C8(CollisionContext* colCtx, s32 floorBgId); -void func_80043508(CollisionContext* colCtx, s32 floorBgId); -void func_80043538(DynaPolyActor* dynaActor); -s32 func_80043548(DynaPolyActor* dynaActor); -s32 func_8004356C(DynaPolyActor* dynaActor); -s32 func_80043590(DynaPolyActor* dynaActor); -s32 func_800435B4(DynaPolyActor* dynaActor); +void DynaPolyActor_UnsetAllInteractFlags(DynaPolyActor* dynaActor); +void DynaPolyActor_SetActorOnTop(DynaPolyActor* dynaActor); +void DynaPoly_SetPlayerOnTop(CollisionContext* colCtx, s32 floorBgId); +void DynaPoly_SetPlayerAbove(CollisionContext* colCtx, s32 floorBgId); +void DynaPolyActor_SetSwitchPressed(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsActorOnTop(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsPlayerOnTop(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsPlayerAbove(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsSwitchPressed(DynaPolyActor* dynaActor); s32 func_800435D8(PlayState* play, DynaPolyActor* dynaActor, s16 arg2, s16 arg3, s16 arg4); void Camera_Init(Camera* camera, View* view, CollisionContext* colCtx, PlayState* play); void Camera_InitPlayerSettings(Camera* camera, Player* player); @@ -980,9 +980,9 @@ f32 Math_SmoothStepToDegF(f32* pValue, f32 target, f32 fraction, f32 step, f32 m s16 Math_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step, s16 minStep); void Math_ApproachS(s16* pValue, s16 target, s16 scale, s16 step); void Color_RGBA8_Copy(Color_RGBA8* dst, Color_RGBA8* src); -void func_80078884(u16 sfxId); -void func_800788CC(u16 sfxId); -void func_80078914(Vec3f* arg0, u16 sfxId); +void Sfx_PlaySfxCentered(u16 sfxId); +void Sfx_PlaySfxCentered2(u16 sfxId); +void Sfx_PlaySfxAtPos(Vec3f* arg0, u16 sfxId); s16 getHealthMeterXOffset(); s16 getHealthMeterYOffset(); void HealthMeter_Init(PlayState* play); @@ -1419,18 +1419,6 @@ void ViMode_Init(ViMode* viMode); void ViMode_Destroy(ViMode* viMode); void ViMode_ConfigureFeatures(ViMode* viMode, s32 viFeatures); void ViMode_Update(ViMode* viMode, Input* input); -void func_800ACE70(struct_801664F0* this); -void func_800ACE90(struct_801664F0* this); -void func_800ACE98(struct_801664F0* this, Gfx** gfxp); -void VisMono_Init(VisMono* this); -void VisMono_Destroy(VisMono* this); -void VisMono_UpdateTexture(VisMono* this, u16* tex); -Gfx* VisMono_DrawTexture(VisMono* this, Gfx* gfx); -void VisMono_Draw(VisMono* this, Gfx** gfxp); -void VisMono_DrawOld(VisMono* this); -void func_800AD920(struct_80166500* this); -void func_800AD950(struct_80166500* this); -void func_800AD958(struct_80166500* this, Gfx** gfxp); void Skybox_Init(GameState* state, SkyboxContext* skyboxCtx, s16 skyboxId); Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z); void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z); @@ -1536,9 +1524,9 @@ void KaleidoScopeCall_Init(PlayState* play); void KaleidoScopeCall_Destroy(PlayState* play); void KaleidoScopeCall_Update(PlayState* play); void KaleidoScopeCall_Draw(PlayState* play); -void func_800BC490(PlayState* play, s16 point); -s32 func_800BC56C(PlayState* play, s16 arg1); -void func_800BC590(PlayState* play); +void Play_SetViewpoint(PlayState* play, s16 viewpoint); +s32 Play_CheckViewpoint(PlayState* play, s16 viewpoint); +void Play_SetShopBrowsingViewpoint(PlayState* play); void Gameplay_SetupTransition(PlayState* play, s32 arg1); Gfx* Play_SetFog(PlayState* play, Gfx* gfx); void Play_Destroy(GameState* thisx); @@ -1552,7 +1540,7 @@ u8 CheckLACSRewardCount(); s32 Play_InCsMode(PlayState* play); f32 func_800BFCB8(PlayState* play, MtxF* mf, Vec3f* vec); void* Play_LoadFile(PlayState* play, RomFile* file); -void Play_SpawnScene(PlayState* play, s32 sceneNum, s32 spawn); +void Play_SpawnScene(PlayState* play, s32 sceneId, s32 spawn); void func_800C016C(PlayState* play, Vec3f* src, Vec3f* dest); s16 Play_CreateSubCamera(PlayState* play); s16 Play_GetActiveCamId(PlayState* play); @@ -2279,7 +2267,7 @@ void __osMallocInit(Arena* arena, void* start, size_t size); void __osMallocAddBlock(Arena* arena, void* start, ptrdiff_t size); void ArenaImpl_RemoveAllBlocks(Arena* arena); void __osMallocCleanup(Arena* arena); -u8 __osMallocIsInitalized(Arena* arena); +s32 __osMallocIsInitialized(Arena* arena); void __osMalloc_FreeBlockTest(Arena* arena, ArenaNode* node); void* __osMalloc_NoLockDebug(Arena* arena, size_t size, const char* file, s32 line); void* __osMallocDebug(Arena* arena, size_t size, const char* file, s32 line); @@ -2296,7 +2284,7 @@ void* __osReallocDebug(Arena* arena, void* ptr, size_t newSize, const char* file void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAlloc); void __osDisplayArena(Arena* arena); void ArenaImpl_FaultClient(Arena* arena); -u32 __osCheckArena(Arena* arena); +s32 __osCheckArena(Arena* arena); u8 func_800FF334(Arena* arena); s32 PrintUtils_VPrintf(PrintCallback* pfn, const char* fmt, va_list args); s32 PrintUtils_Printf(PrintCallback* pfn, const char* fmt, ...); @@ -2420,7 +2408,7 @@ OSThread* __osGetCurrFaultedThread(void); u32* osViGetCurrentFramebuffer(void); s32 __osSpSetPc(void* pc); f32 absf(f32); -void* func_801068B0(void* dst, void* src, size_t size); +void* oot_memmove(void* dest, const void* src, size_t len); void Message_UpdateOcarinaGame(PlayState* play); u8 Message_ShouldAdvance(PlayState* play); u8 Message_ShouldAdvanceSilent(PlayState* play); diff --git a/soh/include/gfx.h b/soh/include/gfx.h new file mode 100644 index 000000000..d8aa9945f --- /dev/null +++ b/soh/include/gfx.h @@ -0,0 +1,9 @@ +#ifndef GFX_H +#define GFX_H + +// Texture memory size, 4 KiB +#define TMEM_SIZE 0x1000 + +// Upstream TODO: Rest of this file + +#endif diff --git a/soh/include/global.h b/soh/include/global.h index 43f56ed0e..b453439fd 100644 --- a/soh/include/global.h +++ b/soh/include/global.h @@ -8,7 +8,7 @@ #include "functions.h" #include "variables.h" #include "macros.h" -#include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" #include "soh/Enhancements/gameconsole.h" #include "soh/Enhancements/gameplaystats.h" #include diff --git a/soh/include/libc/math.h b/soh/include/libc/math.h index cad323823..473ef112b 100644 --- a/soh/include/libc/math.h +++ b/soh/include/libc/math.h @@ -3,9 +3,15 @@ #include +#ifndef M_PI #define M_PI 3.14159265358979323846f +#endif +#ifndef M_SQRT2 #define M_SQRT2 1.41421356237309504880f +#endif +#ifndef FLT_MAX #define FLT_MAX 340282346638528859811704183484516925440.0f +#endif #define SHT_MAX 32767.0f #define SHT_MINV (1.0f / SHT_MAX) #define DEGTORAD(x) (x * M_PI / 180.0f) diff --git a/soh/include/macros.h b/soh/include/macros.h index e5c03ceca..5db738735 100644 --- a/soh/include/macros.h +++ b/soh/include/macros.h @@ -32,8 +32,12 @@ //#define SEGMENTED_TO_VIRTUAL(addr) PHYSICAL_TO_VIRTUAL(gSegments[SEGMENT_NUMBER(addr)] + SEGMENT_OFFSET(addr)) #define SEGMENTED_TO_VIRTUAL(addr) addr +#ifndef SQ #define SQ(x) ((x)*(x)) +#endif +#ifndef ABS #define ABS(x) ((x) >= 0 ? (x) : -(x)) +#endif #define DECR(x) ((x) == 0 ? 0 : --(x)) #define CLAMP(x, min, max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x)) #define CLAMP_MAX(x, max) ((x) > (max) ? (max) : (x)) @@ -295,6 +299,10 @@ extern GraphicsContext* __gfxCtx; #define BGCHECK_POS_ERROR_CHECK(vec3f) BgCheck_PosErrorCheck(vec3f, __FILE__, __LINE__) #define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1) + +// Upstream TODO: Bring back decomp file/line macro use in src (but ignore the args for our needs) +#define SYSTEM_ARENA_MALLOC(size, file, line) SystemArena_MallocDebug(size, __FILE__, __LINE__) +#define SYSTEM_ARENA_FREE(ptr, file, line) SystemArena_FreeDebug(ptr, __FILE__, __LINE__) // #endregion #define DPAD_ITEM(button) ((gSaveContext.buttonStatus[(button) + 5] != BTN_DISABLED) \ @@ -312,7 +320,7 @@ extern GraphicsContext* __gfxCtx; #define SPIRIT_TEMPLE_SMALL_KEY_MAX (ResourceMgr_IsSceneMasterQuest(SCENE_SPIRIT_TEMPLE) ? 7 : 5) #define SHADOW_TEMPLE_SMALL_KEY_MAX (ResourceMgr_IsSceneMasterQuest(SCENE_SHADOW_TEMPLE) ? 6 : 5) #define BOTTOM_OF_THE_WELL_SMALL_KEY_MAX (ResourceMgr_IsSceneMasterQuest(SCENE_BOTTOM_OF_THE_WELL) ? 2 : 3) -#define GERUDO_TRAINING_GROUNDS_SMALL_KEY_MAX (ResourceMgr_IsSceneMasterQuest(SCENE_GERUDO_TRAINING_GROUND) ? 3 : 9) +#define GERUDO_TRAINING_GROUND_SMALL_KEY_MAX (ResourceMgr_IsSceneMasterQuest(SCENE_GERUDO_TRAINING_GROUND) ? 3 : 9) #define GERUDO_FORTRESS_SMALL_KEY_MAX 4 #define GANONS_CASTLE_SMALL_KEY_MAX (ResourceMgr_IsSceneMasterQuest(SCENE_INSIDE_GANONS_CASTLE) ? 3 : 2) #define TREASURE_GAME_SMALL_KEY_MAX 6 diff --git a/soh/include/tables/entrance_table.h b/soh/include/tables/entrance_table.h index fc7cc00b2..fe62e632b 100644 --- a/soh/include/tables/entrance_table.h +++ b/soh/include/tables/entrance_table.h @@ -19,27 +19,27 @@ * Only the first entrance within a group of layers is expected to be referenced in code. * The entrance system will apply the offset on its own to access the correct entrance for a given layer. */ -/* 0x000 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_0, SCENE_DEKU_TREE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x000 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_ENTRANCE, SCENE_DEKU_TREE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x001 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_0_1, SCENE_DEKU_TREE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x002 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_0_2, SCENE_DEKU_TREE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x003 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_0_3, SCENE_DEKU_TREE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x004 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_0, SCENE_DODONGOS_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x004 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_ENTRANCE, SCENE_DODONGOS_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x005 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_0_1, SCENE_DODONGOS_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x006 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_0_2, SCENE_DODONGOS_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x007 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_0_3, SCENE_DODONGOS_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x008 */ DEFINE_ENTRANCE(ENTR_GERUDO_TRAINING_GROUND_0, SCENE_GERUDO_TRAINING_GROUND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x008 */ DEFINE_ENTRANCE(ENTR_GERUDO_TRAINING_GROUND_ENTRANCE, SCENE_GERUDO_TRAINING_GROUND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x009 */ DEFINE_ENTRANCE(ENTR_GERUDO_TRAINING_GROUND_0_1, SCENE_GERUDO_TRAINING_GROUND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x00A */ DEFINE_ENTRANCE(ENTR_GERUDO_TRAINING_GROUND_0_2, SCENE_GERUDO_TRAINING_GROUND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x00B */ DEFINE_ENTRANCE(ENTR_GERUDO_TRAINING_GROUND_0_3, SCENE_GERUDO_TRAINING_GROUND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x00C */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_BOSS_0, SCENE_FOREST_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x00C */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_BOSS_ENTRANCE, SCENE_FOREST_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x00D */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_BOSS_0_1, SCENE_FOREST_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x00E */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_BOSS_0_2, SCENE_FOREST_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x00F */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_BOSS_0_3, SCENE_FOREST_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x010 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_0, SCENE_WATER_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x010 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_ENTRANCE, SCENE_WATER_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x011 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_0_1, SCENE_WATER_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x012 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_0_2, SCENE_WATER_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x013 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_0_3, SCENE_WATER_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -69,7 +69,7 @@ /* 0x026 */ DEFINE_ENTRANCE(ENTR_TESTROOM_0_2, SCENE_TESTROOM, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x027 */ DEFINE_ENTRANCE(ENTR_TESTROOM_0_3, SCENE_TESTROOM, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x028 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_0, SCENE_JABU_JABU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x028 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_ENTRANCE, SCENE_JABU_JABU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x029 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_0_1, SCENE_JABU_JABU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x02A */ DEFINE_ENTRANCE(ENTR_JABU_JABU_0_2, SCENE_JABU_JABU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x02B */ DEFINE_ENTRANCE(ENTR_JABU_JABU_0_3, SCENE_JABU_JABU, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -82,12 +82,12 @@ /* 0x031 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_0_4, SCENE_ROYAL_FAMILYS_TOMB, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x032 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_0_5, SCENE_ROYAL_FAMILYS_TOMB, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x033 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_DAY_0, SCENE_MARKET_ENTRANCE_DAY, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x033 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_NORTH_EXIT, SCENE_MARKET_ENTRANCE_DAY, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x034 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_NIGHT_0_1, SCENE_MARKET_ENTRANCE_NIGHT, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x035 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_0_2, SCENE_MARKET_ENTRANCE_RUINS, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x036 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_0_3, SCENE_MARKET_ENTRANCE_RUINS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x037 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_0, SCENE_SHADOW_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x037 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_ENTRANCE, SCENE_SHADOW_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x038 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_0_1, SCENE_SHADOW_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x039 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_0_2, SCENE_SHADOW_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x03A */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_0_3, SCENE_SHADOW_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -117,12 +117,12 @@ /* 0x04D */ DEFINE_ENTRANCE(ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0_2, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) /* 0x04E */ DEFINE_ENTRANCE(ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0_3, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) -/* 0x04F */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_0, SCENE_LON_LON_BUILDINGS, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x04F */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_TALONS_HOUSE, SCENE_LON_LON_BUILDINGS, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x050 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_0_1, SCENE_LON_LON_BUILDINGS, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x051 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_0_2, SCENE_LON_LON_BUILDINGS, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x052 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_0_3, SCENE_LON_LON_BUILDINGS, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x053 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x053 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_ENTRANCE, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x054 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_1, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x055 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_2, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x056 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_0_3, SCENE_TEMPLE_OF_TIME, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -144,7 +144,7 @@ /* 0x065 */ DEFINE_ENTRANCE(ENTR_TREASURE_BOX_SHOP_0_2, SCENE_TREASURE_BOX_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x066 */ DEFINE_ENTRANCE(ENTR_TREASURE_BOX_SHOP_0_3, SCENE_TREASURE_BOX_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x067 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_3, SCENE_BACK_ALLEY_DAY, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x067 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_OUTSIDE_MAN_IN_GREEN_HOUSE, SCENE_BACK_ALLEY_DAY, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x068 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_3_1, SCENE_BACK_ALLEY_NIGHT, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x069 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_3_2, SCENE_BACK_ALLEY_DAY, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x06A */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_3_3, SCENE_BACK_ALLEY_NIGHT, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -177,20 +177,20 @@ /* 0x080 */ DEFINE_ENTRANCE(ENTR_MARKET_GUARD_HOUSE_0_2, SCENE_MARKET_GUARD_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x081 */ DEFINE_ENTRANCE(ENTR_MARKET_GUARD_HOUSE_0_3, SCENE_MARKET_GUARD_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x082 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x082 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_ENTRANCE, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x083 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0_1, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x084 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0_2, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x085 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0_3, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x086 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0_4, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x087 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_0_5, SCENE_SPIRIT_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x088 */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_0, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x088 */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_ENTRANCE, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x089 */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_0_1, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x08A */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_0_2, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x08B */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_0_3, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x08C */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_0_4, SCENE_ICE_CAVERN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x08D */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0, SCENE_SPIRIT_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x08D */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE, SCENE_SPIRIT_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x08E */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0_1, SCENE_SPIRIT_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x08F */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0_2, SCENE_SPIRIT_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x090 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_0_3, SCENE_SPIRIT_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -203,7 +203,7 @@ /* 0x096 */ DEFINE_ENTRANCE(ENTR_TEST01_0_2, SCENE_TEST01, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x097 */ DEFINE_ENTRANCE(ENTR_TEST01_0_3, SCENE_TEST01, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x098 */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_0, SCENE_BOTTOM_OF_THE_WELL, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x098 */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_ENTRANCE, SCENE_BOTTOM_OF_THE_WELL, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x099 */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_0_1, SCENE_BOTTOM_OF_THE_WELL, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x09A */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_0_2, SCENE_BOTTOM_OF_THE_WELL, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x09B */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_0_3, SCENE_BOTTOM_OF_THE_WELL, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) @@ -232,7 +232,7 @@ /* 0x0AF */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_0_2, SCENE_BACK_ALLEY_DAY, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0B0 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_0_3, SCENE_BACK_ALLEY_NIGHT, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x0B1 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_0, SCENE_MARKET_DAY, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0B1 */ DEFINE_ENTRANCE(ENTR_MARKET_SOUTH_EXIT, SCENE_MARKET_DAY, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x0B2 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_0_1, SCENE_MARKET_NIGHT, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0B3 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_0_2, SCENE_MARKET_RUINS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0B4 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_0_3, SCENE_MARKET_RUINS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -245,7 +245,7 @@ /* 0x0B9 */ DEFINE_ENTRANCE(ENTR_BAZAAR_0_2, SCENE_BAZAAR, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x0BA */ DEFINE_ENTRANCE(ENTR_BAZAAR_0_3, SCENE_BAZAAR, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x0BB */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_0, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x0BB */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_CHILD_SPAWN, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x0BC */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_0_1, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x0BD */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_0_2, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x0BE */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_0_3, SCENE_LINKS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) @@ -257,7 +257,7 @@ /* 0x0C3 */ DEFINE_ENTRANCE(ENTR_KOKIRI_SHOP_0_2, SCENE_KOKIRI_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x0C4 */ DEFINE_ENTRANCE(ENTR_KOKIRI_SHOP_0_3, SCENE_KOKIRI_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x0C5 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_1, SCENE_DODONGOS_CAVERN, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0C5 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_BOSS_DOOR, SCENE_DODONGOS_CAVERN, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0C6 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_1_1, SCENE_DODONGOS_CAVERN, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0C7 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_1_2, SCENE_DODONGOS_CAVERN, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0C8 */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_1_3, SCENE_DODONGOS_CAVERN, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -267,7 +267,7 @@ /* 0x0CB */ DEFINE_ENTRANCE(ENTR_KNOW_IT_ALL_BROS_HOUSE_0_2, SCENE_KNOW_IT_ALL_BROS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x0CC */ DEFINE_ENTRANCE(ENTR_KNOW_IT_ALL_BROS_HOUSE_0_3, SCENE_KNOW_IT_ALL_BROS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x0CD */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0CD */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x0CE */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_1, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0CF */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_2, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x0D0 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_3, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -282,7 +282,7 @@ /* 0x0D9 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_12, SCENE_HYRULE_FIELD, 0, false, true, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_WHITE, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_WHITE, TCS_SLOW)) /* 0x0DA */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_0_13, SCENE_HYRULE_FIELD, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x0DB */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0DB */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_FRONT_GATE, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x0DC */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_1, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0DD */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_2, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x0DE */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_3, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -292,14 +292,14 @@ /* 0x0E2 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_7, SCENE_KAKARIKO_VILLAGE, 0, false, true, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW), TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_SLOW)) /* 0x0E3 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_0_8, SCENE_KAKARIKO_VILLAGE, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x0E4 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0E4 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_ENTRANCE, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x0E5 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0_1, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0E6 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0_2, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x0E7 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0_3, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0E8 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0_4, SCENE_GRAVEYARD, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x0E9 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_0_5, SCENE_GRAVEYARD, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x0EA */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_0, SCENE_ZORAS_RIVER, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x0EA */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_WEST_EXIT, SCENE_ZORAS_RIVER, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x0EB */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_0_1, SCENE_ZORAS_RIVER, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0EC */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_0_2, SCENE_ZORAS_RIVER, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x0ED */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_0_3, SCENE_ZORAS_RIVER, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -319,28 +319,28 @@ /* 0x0FA */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_12, SCENE_KOKIRI_FOREST, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0FB */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_0_13, SCENE_KOKIRI_FOREST, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x0FC */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0, SCENE_SACRED_FOREST_MEADOW, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x0FC */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT, SCENE_SACRED_FOREST_MEADOW, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0FD */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0_1, SCENE_SACRED_FOREST_MEADOW, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0FE */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0_2, SCENE_SACRED_FOREST_MEADOW, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x0FF */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0_3, SCENE_SACRED_FOREST_MEADOW, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x100 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0_4, SCENE_SACRED_FOREST_MEADOW, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x101 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_0_5, SCENE_SACRED_FOREST_MEADOW, 0, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) -/* 0x102 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x102 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_NORTH_EXIT, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x103 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0_1, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x104 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0_2, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x105 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0_3, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x106 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0_4, SCENE_LAKE_HYLIA, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x107 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_0_5, SCENE_LAKE_HYLIA, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x108 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0, SCENE_ZORAS_DOMAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x108 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_ENTRANCE, SCENE_ZORAS_DOMAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x109 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0_1, SCENE_ZORAS_DOMAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x10A */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0_2, SCENE_ZORAS_DOMAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x10B */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0_3, SCENE_ZORAS_DOMAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x10C */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0_4, SCENE_ZORAS_DOMAIN, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x10D */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_0_5, SCENE_ZORAS_DOMAIN, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x10E */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x10E */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x10F */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_1, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x110 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_2, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x111 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_3, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -350,7 +350,7 @@ /* 0x115 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_7, SCENE_ZORAS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x116 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_0_8, SCENE_ZORAS_FOUNTAIN, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x117 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0, SCENE_GERUDO_VALLEY, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x117 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_EAST_EXIT, SCENE_GERUDO_VALLEY, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x118 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_1, SCENE_GERUDO_VALLEY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x119 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_2, SCENE_GERUDO_VALLEY, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x11A */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_3, SCENE_GERUDO_VALLEY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -358,20 +358,20 @@ /* 0x11C */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_5, SCENE_GERUDO_VALLEY, 0, true, true, TRANS_TYPE_FILL_WHITE, TRANS_TYPE_FILL_WHITE) /* 0x11D */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_0_6, SCENE_GERUDO_VALLEY, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x11E */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_0, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x11E */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_SOUTH_EXIT, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x11F */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_0_1, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x120 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_0_2, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x121 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_0_3, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x122 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_0_4, SCENE_LOST_WOODS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x123 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x123 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_EAST_EXIT, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) /* 0x124 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0_1, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) /* 0x125 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0_2, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) /* 0x126 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0_3, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) /* 0x127 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0_4, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x128 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_0_5, SCENE_DESERT_COLOSSUS, 0, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) -/* 0x129 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x129 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_EAST_EXIT, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x12A */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_1, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x12B */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_2, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x12C */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_3, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -379,7 +379,7 @@ /* 0x12E */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_5, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x12F */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_0_6, SCENE_GERUDOS_FORTRESS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x130 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_0, SCENE_HAUNTED_WASTELAND, 0, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x130 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_EAST_EXIT, SCENE_HAUNTED_WASTELAND, 0, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) /* 0x131 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_0_1, SCENE_HAUNTED_WASTELAND, 0, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) /* 0x132 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_0_2, SCENE_HAUNTED_WASTELAND, 0, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) /* 0x133 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_0_3, SCENE_HAUNTED_WASTELAND, 0, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) @@ -389,13 +389,13 @@ /* 0x136 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_1_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x137 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_1_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x138 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_0, SCENE_HYRULE_CASTLE, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x138 */ DEFINE_ENTRANCE(ENTR_CASTLE_GROUNDS_SOUTH_EXIT, SCENE_HYRULE_CASTLE, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x139 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_0_1, SCENE_HYRULE_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x13A */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_0_2, SCENE_OUTSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x13B */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_0_3, SCENE_OUTSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x13C */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_0_4, SCENE_OUTSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x13D */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x13D */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x13E */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_1, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x13F */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_2, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x140 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_3, SCENE_DEATH_MOUNTAIN_TRAIL, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -406,14 +406,14 @@ /* 0x145 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_8, SCENE_DEATH_MOUNTAIN_TRAIL, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x146 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_0_9, SCENE_DEATH_MOUNTAIN_TRAIL, 0, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x147 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x147 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x148 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0_1, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x149 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0_2, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x14A */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0_3, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x14B */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0_4, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x14C */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_0_5, SCENE_DEATH_MOUNTAIN_CRATER, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x14D */ DEFINE_ENTRANCE(ENTR_GORON_CITY_0, SCENE_GORON_CITY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x14D */ DEFINE_ENTRANCE(ENTR_GORON_CITY_UPPER_EXIT, SCENE_GORON_CITY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x14E */ DEFINE_ENTRANCE(ENTR_GORON_CITY_0_1, SCENE_GORON_CITY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x14F */ DEFINE_ENTRANCE(ENTR_GORON_CITY_0_2, SCENE_GORON_CITY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x150 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_0_3, SCENE_GORON_CITY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -425,7 +425,7 @@ /* 0x155 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_3_2, SCENE_ZORAS_DOMAIN, 3, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) /* 0x156 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_3_3, SCENE_ZORAS_DOMAIN, 3, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) -/* 0x157 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x157 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_ENTRANCE, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x158 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_1, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x159 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_2, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x15A */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_3, SCENE_LON_LON_RANCH, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -440,12 +440,12 @@ /* 0x163 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_12, SCENE_LON_LON_RANCH, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x164 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_0_13, SCENE_LON_LON_RANCH, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x165 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_0, SCENE_FIRE_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x165 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_ENTRANCE, SCENE_FIRE_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x166 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_0_1, SCENE_FIRE_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x167 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_0_2, SCENE_FIRE_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x168 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_0_3, SCENE_FIRE_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x169 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_0, SCENE_FOREST_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x169 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_ENTRANCE, SCENE_FOREST_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x16A */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_0_1, SCENE_FOREST_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x16B */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_0_2, SCENE_FOREST_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x16C */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_0_3, SCENE_FOREST_TEMPLE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -455,12 +455,12 @@ /* 0x16F */ DEFINE_ENTRANCE(ENTR_SHOOTING_GALLERY_1_2, SCENE_SHOOTING_GALLERY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x170 */ DEFINE_ENTRANCE(ENTR_SHOOTING_GALLERY_1_3, SCENE_SHOOTING_GALLERY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x171 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_0, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x171 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x172 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_NIGHT_0_1, SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x173 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_RUINS_0_2, SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x174 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_RUINS_0_3, SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x175 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_1, SCENE_FIRE_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x175 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_BOSS_DOOR, SCENE_FIRE_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x176 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_1_1, SCENE_FIRE_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x177 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_1_2, SCENE_FIRE_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x178 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_1_3, SCENE_FIRE_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -470,37 +470,37 @@ /* 0x17B */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_0_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x17C */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_0_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x17D */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_1, SCENE_HYRULE_FIELD, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x17D */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_STAIRS_EXIT, SCENE_HYRULE_FIELD, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x17E */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_1_1, SCENE_HYRULE_FIELD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x17F */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_1_2, SCENE_HYRULE_FIELD, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x180 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_1_3, SCENE_HYRULE_FIELD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x181 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_2, SCENE_HYRULE_FIELD, 2, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x181 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_RIVER_EXIT, SCENE_HYRULE_FIELD, 2, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x182 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_2_1, SCENE_HYRULE_FIELD, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x183 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_2_2, SCENE_HYRULE_FIELD, 2, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x184 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_2_3, SCENE_HYRULE_FIELD, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x185 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_3, SCENE_HYRULE_FIELD, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x185 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_WOODED_EXIT, SCENE_HYRULE_FIELD, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x186 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_3_1, SCENE_HYRULE_FIELD, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x187 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_3_2, SCENE_HYRULE_FIELD, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x188 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_3_3, SCENE_HYRULE_FIELD, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x189 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_4, SCENE_HYRULE_FIELD, 4, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x189 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_FENCE_EXIT, SCENE_HYRULE_FIELD, 4, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x18A */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_4_1, SCENE_HYRULE_FIELD, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x18B */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_4_2, SCENE_HYRULE_FIELD, 4, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x18C */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_4_3, SCENE_HYRULE_FIELD, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x18D */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_5, SCENE_HYRULE_FIELD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x18D */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_ROCKY_PATH, SCENE_HYRULE_FIELD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x18E */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_5_1, SCENE_HYRULE_FIELD, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x18F */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_5_2, SCENE_HYRULE_FIELD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x190 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_5_3, SCENE_HYRULE_FIELD, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x191 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_1, SCENE_KAKARIKO_VILLAGE, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x191 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_GUARD_GATE, SCENE_KAKARIKO_VILLAGE, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x192 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_1_1, SCENE_KAKARIKO_VILLAGE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x193 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_1_2, SCENE_KAKARIKO_VILLAGE, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x194 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_1_3, SCENE_KAKARIKO_VILLAGE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x195 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_2, SCENE_KAKARIKO_VILLAGE, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x195 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_SOUTHEAST_EXIT, SCENE_KAKARIKO_VILLAGE, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x196 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_2_1, SCENE_KAKARIKO_VILLAGE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x197 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_2_2, SCENE_KAKARIKO_VILLAGE, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x198 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_2_3, SCENE_KAKARIKO_VILLAGE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -510,12 +510,12 @@ /* 0x19B */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_1_2, SCENE_ZORAS_RIVER, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x19C */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_1_3, SCENE_ZORAS_RIVER, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x19D */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_2, SCENE_ZORAS_RIVER, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x19D */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_WATERFALL_EXIT, SCENE_ZORAS_RIVER, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x19E */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_2_1, SCENE_ZORAS_RIVER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x19F */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_2_2, SCENE_ZORAS_RIVER, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1A0 */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_2_3, SCENE_ZORAS_RIVER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x1A1 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_1, SCENE_ZORAS_DOMAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1A1 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_KING_ZORA_EXIT, SCENE_ZORAS_DOMAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1A2 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_1_1, SCENE_ZORAS_DOMAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1A3 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_1_2, SCENE_ZORAS_DOMAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1A4 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_1_3, SCENE_ZORAS_DOMAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -525,7 +525,7 @@ /* 0x1A7 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_1_2, SCENE_GERUDO_VALLEY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1A8 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_1_3, SCENE_GERUDO_VALLEY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x1A9 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_1, SCENE_LOST_WOODS, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1A9 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_NORTH_EXIT, SCENE_LOST_WOODS, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1AA */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_1_1, SCENE_LOST_WOODS, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1AB */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_1_2, SCENE_LOST_WOODS, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1AC */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_1_3, SCENE_LOST_WOODS, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -545,17 +545,17 @@ /* 0x1B7 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_2_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1B8 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_2_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x1B9 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_1, SCENE_DEATH_MOUNTAIN_TRAIL, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1B9 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT, SCENE_DEATH_MOUNTAIN_TRAIL, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1BA */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_1_1, SCENE_DEATH_MOUNTAIN_TRAIL, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1BB */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_1_2, SCENE_DEATH_MOUNTAIN_TRAIL, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1BC */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_1_3, SCENE_DEATH_MOUNTAIN_TRAIL, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x1BD */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_2, SCENE_DEATH_MOUNTAIN_TRAIL, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1BD */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT, SCENE_DEATH_MOUNTAIN_TRAIL, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1BE */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_2_1, SCENE_DEATH_MOUNTAIN_TRAIL, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1BF */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_2_2, SCENE_DEATH_MOUNTAIN_TRAIL, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1C0 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_2_3, SCENE_DEATH_MOUNTAIN_TRAIL, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x1C1 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_1, SCENE_GORON_CITY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x1C1 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_DARUNIA_ROOM_EXIT, SCENE_GORON_CITY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1C2 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_1_1, SCENE_GORON_CITY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1C3 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_1_2, SCENE_GORON_CITY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1C4 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_1_3, SCENE_GORON_CITY, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -570,17 +570,17 @@ /* 0x1CB */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_5_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 5, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1CC */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_5_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 5, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x1CD */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_8, SCENE_MARKET_DAY, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1CD */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_OUTSIDE_SHOOTING_GALLERY, SCENE_MARKET_DAY, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x1CE */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_8_1, SCENE_MARKET_NIGHT, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x1CF */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_8_2, SCENE_MARKET_RUINS, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x1D0 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_8_3, SCENE_MARKET_RUINS, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x1D1 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_9, SCENE_MARKET_DAY, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1D1 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_OUTSIDE_HAPPY_MASK_SHOP, SCENE_MARKET_DAY, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x1D2 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_9_1, SCENE_MARKET_NIGHT, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x1D3 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_9_2, SCENE_MARKET_RUINS, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x1D4 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_9_3, SCENE_MARKET_RUINS, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x1D5 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_10, SCENE_MARKET_DAY, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x1D5 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_OUTSIDE_TREASURE_BOX_SHOP, SCENE_MARKET_DAY, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x1D6 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_10_1, SCENE_MARKET_NIGHT, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x1D7 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_10_2, SCENE_MARKET_RUINS, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x1D8 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_10_3, SCENE_MARKET_RUINS, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -590,12 +590,12 @@ /* 0x1DB */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_3_2, SCENE_ZORAS_RIVER, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1DC */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_3_3, SCENE_ZORAS_RIVER, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x1DD */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_4, SCENE_ZORAS_RIVER, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x1DD */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT, SCENE_ZORAS_RIVER, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x1DE */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_4_1, SCENE_ZORAS_RIVER, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x1DF */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_4_2, SCENE_ZORAS_RIVER, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x1E0 */ DEFINE_ENTRANCE(ENTR_ZORAS_RIVER_4_3, SCENE_ZORAS_RIVER, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) -/* 0x1E1 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_1, SCENE_DESERT_COLOSSUS, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1E1 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, SCENE_DESERT_COLOSSUS, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1E2 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_1_1, SCENE_DESERT_COLOSSUS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1E3 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_1_2, SCENE_DESERT_COLOSSUS, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1E4 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_1_3, SCENE_DESERT_COLOSSUS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -615,7 +615,7 @@ /* 0x1EF */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_4_2, SCENE_DESERT_COLOSSUS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1F0 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_4_3, SCENE_DESERT_COLOSSUS, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x1F1 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_5, SCENE_DESERT_COLOSSUS, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1F1 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_WARP_PAD, SCENE_DESERT_COLOSSUS, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1F2 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_5_1, SCENE_DESERT_COLOSSUS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1F3 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_5_2, SCENE_DESERT_COLOSSUS, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1F4 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_5_3, SCENE_DESERT_COLOSSUS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -625,62 +625,62 @@ /* 0x1F7 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_6_2, SCENE_DESERT_COLOSSUS, 6, true, false, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) /* 0x1F8 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_6_3, SCENE_DESERT_COLOSSUS, 6, true, false, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) -/* 0x1F9 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_6, SCENE_HYRULE_FIELD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1F9 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_CENTER_EXIT, SCENE_HYRULE_FIELD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1FA */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_6_1, SCENE_HYRULE_FIELD, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1FB */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_6_2, SCENE_HYRULE_FIELD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1FC */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_6_3, SCENE_HYRULE_FIELD, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x1FD */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_7, SCENE_HYRULE_FIELD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x1FD */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN, SCENE_HYRULE_FIELD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x1FE */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_7_1, SCENE_HYRULE_FIELD, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x1FF */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_7_2, SCENE_HYRULE_FIELD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x200 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_7_3, SCENE_HYRULE_FIELD, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x201 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_3, SCENE_KAKARIKO_VILLAGE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x201 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_BAZAAR, SCENE_KAKARIKO_VILLAGE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x202 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_3_1, SCENE_KAKARIKO_VILLAGE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x203 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_3_2, SCENE_KAKARIKO_VILLAGE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x204 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_3_3, SCENE_KAKARIKO_VILLAGE, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x205 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_1, SCENE_GRAVEYARD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x205 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_OUTSIDE_TEMPLE, SCENE_GRAVEYARD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x206 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_1_1, SCENE_GRAVEYARD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x207 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_1_2, SCENE_GRAVEYARD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x208 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_1_3, SCENE_GRAVEYARD, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x209 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_1, SCENE_KOKIRI_FOREST, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x209 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_OUTSIDE_DEKU_TREE, SCENE_KOKIRI_FOREST, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x20A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_1_1, SCENE_KOKIRI_FOREST, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x20B */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_1_2, SCENE_KOKIRI_FOREST, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x20C */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_1_3, SCENE_KOKIRI_FOREST, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x20D */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_2, SCENE_KOKIRI_FOREST, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x20D */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_LOWER_EXIT, SCENE_KOKIRI_FOREST, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x20E */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_2_1, SCENE_KOKIRI_FOREST, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x20F */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_2_2, SCENE_KOKIRI_FOREST, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x210 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_2_3, SCENE_KOKIRI_FOREST, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x211 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_3, SCENE_KOKIRI_FOREST, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x211 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE, SCENE_KOKIRI_FOREST, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x212 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_3_1, SCENE_KOKIRI_FOREST, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x213 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_3_2, SCENE_KOKIRI_FOREST, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x214 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_3_3, SCENE_KOKIRI_FOREST, 3, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x215 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_1, SCENE_SACRED_FOREST_MEADOW, 1, false, true, TRANS_TYPE_FADE_GREEN, TRANS_TYPE_FADE_GREEN) +/* 0x215 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE, SCENE_SACRED_FOREST_MEADOW, 1, false, true, TRANS_TYPE_FADE_GREEN, TRANS_TYPE_FADE_GREEN) /* 0x216 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_1_1, SCENE_SACRED_FOREST_MEADOW, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x217 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_1_2, SCENE_SACRED_FOREST_MEADOW, 1, false, true, TRANS_TYPE_FADE_GREEN, TRANS_TYPE_FADE_GREEN) /* 0x218 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_1_3, SCENE_SACRED_FOREST_MEADOW, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x219 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_1, SCENE_LAKE_HYLIA, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x219 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_RIVER_EXIT, SCENE_LAKE_HYLIA, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x21A */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_1_1, SCENE_LAKE_HYLIA, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x21B */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_1_2, SCENE_LAKE_HYLIA, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x21C */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_1_3, SCENE_LAKE_HYLIA, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x21D */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_2, SCENE_LAKE_HYLIA, 2, false, true, TRANS_TYPE_FADE_BLUE, TRANS_TYPE_FADE_BLUE) +/* 0x21D */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE, SCENE_LAKE_HYLIA, 2, false, true, TRANS_TYPE_FADE_BLUE, TRANS_TYPE_FADE_BLUE) /* 0x21E */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_2_1, SCENE_LAKE_HYLIA, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x21F */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_2_2, SCENE_LAKE_HYLIA, 2, false, true, TRANS_TYPE_FADE_BLUE, TRANS_TYPE_FADE_BLUE) /* 0x220 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_2_3, SCENE_LAKE_HYLIA, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x221 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_1, SCENE_ZORAS_FOUNTAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x221 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU, SCENE_ZORAS_FOUNTAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x222 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_1_1, SCENE_ZORAS_FOUNTAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x223 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_1_2, SCENE_ZORAS_FOUNTAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x224 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_1_3, SCENE_ZORAS_FOUNTAIN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x225 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_2, SCENE_ZORAS_FOUNTAIN, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x225 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_TUNNEL_EXIT, SCENE_ZORAS_FOUNTAIN, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x226 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_2_1, SCENE_ZORAS_FOUNTAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x227 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_2_2, SCENE_ZORAS_FOUNTAIN, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x228 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_2_3, SCENE_ZORAS_FOUNTAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -690,7 +690,7 @@ /* 0x22B */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_2_2, SCENE_GERUDO_VALLEY, 2, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x22C */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_2_3, SCENE_GERUDO_VALLEY, 2, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x22D */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_3, SCENE_GERUDO_VALLEY, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x22D */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_WEST_EXIT, SCENE_GERUDO_VALLEY, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x22E */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_3_1, SCENE_GERUDO_VALLEY, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x22F */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_3_2, SCENE_GERUDO_VALLEY, 3, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x230 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_3_3, SCENE_GERUDO_VALLEY, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -710,33 +710,33 @@ /* 0x23B */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_3_2, SCENE_GERUDOS_FORTRESS, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x23C */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_3_3, SCENE_GERUDOS_FORTRESS, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x23D */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_1, SCENE_HYRULE_CASTLE, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x23D */ DEFINE_ENTRANCE(ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT, SCENE_HYRULE_CASTLE, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x23E */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_1_1, SCENE_HYRULE_CASTLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x23F */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_1_2, SCENE_OUTSIDE_GANONS_CASTLE, 1, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) /* 0x240 */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_1_3, SCENE_OUTSIDE_GANONS_CASTLE, 1, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) /* 0x241 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_1_4, SCENE_HYRULE_CASTLE, 1, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) -/* 0x242 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_3, SCENE_DEATH_MOUNTAIN_TRAIL, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x242 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN, SCENE_DEATH_MOUNTAIN_TRAIL, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x243 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_3_1, SCENE_DEATH_MOUNTAIN_TRAIL, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x244 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_3_2, SCENE_DEATH_MOUNTAIN_TRAIL, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x245 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_3_3, SCENE_DEATH_MOUNTAIN_TRAIL, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x246 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_1, SCENE_DEATH_MOUNTAIN_CRATER, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x246 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT, SCENE_DEATH_MOUNTAIN_CRATER, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x247 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_1_1, SCENE_DEATH_MOUNTAIN_CRATER, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x248 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_1_2, SCENE_DEATH_MOUNTAIN_CRATER, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x249 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_1_3, SCENE_DEATH_MOUNTAIN_CRATER, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x24A */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_2, SCENE_DEATH_MOUNTAIN_CRATER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x24A */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE, SCENE_DEATH_MOUNTAIN_CRATER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x24B */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_2_1, SCENE_DEATH_MOUNTAIN_CRATER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x24C */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_2_2, SCENE_DEATH_MOUNTAIN_CRATER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x24D */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_2_3, SCENE_DEATH_MOUNTAIN_CRATER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x24E */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_1, SCENE_FOREST_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x24E */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_BOSS_DOOR, SCENE_FOREST_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x24F */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_1_1, SCENE_FOREST_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x250 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_1_2, SCENE_FOREST_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x251 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_1_3, SCENE_FOREST_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x252 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_1, SCENE_DEKU_TREE, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x252 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_BOSS_DOOR, SCENE_DEKU_TREE, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x253 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_1_1, SCENE_DEKU_TREE, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x254 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_1_2, SCENE_DEKU_TREE, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x255 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_1_3, SCENE_DEKU_TREE, 1, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -746,12 +746,12 @@ /* 0x258 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_3_2, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x259 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_3_3, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x25A */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_1, SCENE_MARKET_DAY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x25A */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_CASTLE_EXIT, SCENE_MARKET_DAY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x25B */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_1_1, SCENE_MARKET_NIGHT, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x25C */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_1_2, SCENE_MARKET_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x25D */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_1_3, SCENE_MARKET_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x25E */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_2, SCENE_MARKET_DAY, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x25E */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_TEMPLE_EXIT, SCENE_MARKET_DAY, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x25F */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_2_1, SCENE_MARKET_NIGHT, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x260 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_2_2, SCENE_MARKET_RUINS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x261 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_2_3, SCENE_MARKET_RUINS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -761,17 +761,17 @@ /* 0x264 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_3_2, SCENE_MARKET_RUINS, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x265 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_3_3, SCENE_MARKET_RUINS, 3, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x266 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_4, SCENE_KOKIRI_FOREST, 4, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x266 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_OUTSIDE_SHOP, SCENE_KOKIRI_FOREST, 4, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x267 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_4_1, SCENE_KOKIRI_FOREST, 4, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x268 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_4_2, SCENE_KOKIRI_FOREST, 4, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x269 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_4_3, SCENE_KOKIRI_FOREST, 4, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x26A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_5, SCENE_KOKIRI_FOREST, 5, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x26A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_OUTSIDE_KNOW_IT_ALL_HOUSE, SCENE_KOKIRI_FOREST, 5, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x26B */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_5_1, SCENE_KOKIRI_FOREST, 5, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x26C */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_5_2, SCENE_KOKIRI_FOREST, 5, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x26D */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_5_3, SCENE_KOKIRI_FOREST, 5, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x26E */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_DAY_2, SCENE_MARKET_ENTRANCE_DAY, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x26E */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_OUTSIDE_GUARD_HOUSE, SCENE_MARKET_ENTRANCE_DAY, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x26F */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_NIGHT_2_1, SCENE_MARKET_ENTRANCE_NIGHT, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x270 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_2_2, SCENE_MARKET_ENTRANCE_RUINS, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x271 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_2_3, SCENE_MARKET_ENTRANCE_RUINS, 2, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -781,7 +781,7 @@ /* 0x274 */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_1_2, SCENE_LINKS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x275 */ DEFINE_ENTRANCE(ENTR_LINKS_HOUSE_1_3, SCENE_LINKS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x276 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_DAY_1, SCENE_MARKET_ENTRANCE_DAY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x276 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT, SCENE_MARKET_ENTRANCE_DAY, 1, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x277 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_NIGHT_1_1, SCENE_MARKET_ENTRANCE_NIGHT, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x278 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_1_2, SCENE_MARKET_ENTRANCE_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x279 */ DEFINE_ENTRANCE(ENTR_MARKET_ENTRANCE_RUINS_1_3, SCENE_MARKET_ENTRANCE_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -791,7 +791,7 @@ /* 0x27C */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_8_2, SCENE_HYRULE_FIELD, 8, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x27D */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_8_3, SCENE_HYRULE_FIELD, 8, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x27E */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_9, SCENE_HYRULE_FIELD, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x27E */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_OWL_DROP, SCENE_HYRULE_FIELD, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x27F */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_9_1, SCENE_HYRULE_FIELD, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x280 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_9_2, SCENE_HYRULE_FIELD, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x281 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_9_3, SCENE_HYRULE_FIELD, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) @@ -801,7 +801,7 @@ /* 0x284 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_10_2, SCENE_HYRULE_FIELD, 10, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x285 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_10_3, SCENE_HYRULE_FIELD, 10, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x286 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_6, SCENE_KOKIRI_FOREST, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x286 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_UPPER_EXIT, SCENE_KOKIRI_FOREST, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x287 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_6_1, SCENE_KOKIRI_FOREST, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x288 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_6_2, SCENE_KOKIRI_FOREST, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x289 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_6_3, SCENE_KOKIRI_FOREST, 6, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -836,12 +836,12 @@ /* 0x2A0 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_4_2, SCENE_MARKET_RUINS, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2A1 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_4_3, SCENE_MARKET_RUINS, 4, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x2A2 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_5, SCENE_MARKET_DAY, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x2A2 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP, SCENE_MARKET_DAY, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x2A3 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_5_1, SCENE_MARKET_NIGHT, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x2A4 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_5_2, SCENE_MARKET_RUINS, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x2A5 */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_5_3, SCENE_MARKET_RUINS, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x2A6 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_4, SCENE_KAKARIKO_VILLAGE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2A6 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL, SCENE_KAKARIKO_VILLAGE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2A7 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_4_1, SCENE_KAKARIKO_VILLAGE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2A8 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_4_2, SCENE_KAKARIKO_VILLAGE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2A9 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_4_3, SCENE_KAKARIKO_VILLAGE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -856,7 +856,7 @@ /* 0x2B0 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_1_2, SCENE_LON_LON_RANCH, 1, false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x2B1 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_1_3, SCENE_LON_LON_RANCH, 1, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x2B2 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_1, SCENE_SHADOW_TEMPLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2B2 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_BOSS_DOOR, SCENE_SHADOW_TEMPLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2B3 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_1_1, SCENE_SHADOW_TEMPLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2B4 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_1_2, SCENE_SHADOW_TEMPLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2B5 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_1_3, SCENE_SHADOW_TEMPLE, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -939,7 +939,7 @@ /* 0x2F3 */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0_9, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2F4 */ DEFINE_ENTRANCE(ENTR_TEST_SHOOTING_GALLERY_0_10, SCENE_SHOOTING_GALLERY, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x2F5 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_1, SCENE_SPIRIT_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x2F5 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_BOSS_DOOR, SCENE_SPIRIT_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2F6 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_1_1, SCENE_SPIRIT_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2F7 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_1_2, SCENE_SPIRIT_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x2F8 */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_1_3, SCENE_SPIRIT_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -954,17 +954,17 @@ /* 0x2FF */ DEFINE_ENTRANCE(ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0_2, SCENE_KAKARIKO_CENTER_GUEST_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x300 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0_3, SCENE_KAKARIKO_CENTER_GUEST_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x301 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_BOSS_0, SCENE_JABU_JABU_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x301 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_BOSS_ENTRANCE, SCENE_JABU_JABU_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x302 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_BOSS_0_1, SCENE_JABU_JABU_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x303 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_BOSS_0_2, SCENE_JABU_JABU_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x304 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_BOSS_0_3, SCENE_JABU_JABU_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x305 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_BOSS_0, SCENE_FIRE_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x305 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_BOSS_ENTRANCE, SCENE_FIRE_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x306 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_BOSS_0_1, SCENE_FIRE_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x307 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_BOSS_0_2, SCENE_FIRE_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x308 */ DEFINE_ENTRANCE(ENTR_FIRE_TEMPLE_BOSS_0_3, SCENE_FIRE_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x309 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_6, SCENE_LAKE_HYLIA, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x309 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND, SCENE_LAKE_HYLIA, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x30A */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_6_1, SCENE_LAKE_HYLIA, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x30B */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_6_2, SCENE_LAKE_HYLIA, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x30C */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_6_3, SCENE_LAKE_HYLIA, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -979,7 +979,7 @@ /* 0x313 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_14_2, SCENE_HYRULE_FIELD, 14, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x314 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_14_3, SCENE_HYRULE_FIELD, 14, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x315 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x315 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x316 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0_1, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x317 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0_2, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x318 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0_3, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1002,7 +1002,7 @@ /* 0x326 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_4_2, SCENE_TEMPLE_OF_TIME, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x327 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_4_3, SCENE_TEMPLE_OF_TIME, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x328 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_4, SCENE_ZORAS_DOMAIN, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x328 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT, SCENE_ZORAS_DOMAIN, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x329 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_4_1, SCENE_ZORAS_DOMAIN, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x32A */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_4_2, SCENE_ZORAS_DOMAIN, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x32B */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_4_3, SCENE_ZORAS_DOMAIN, 4, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) @@ -1027,58 +1027,58 @@ /* 0x33A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_7_2, SCENE_KOKIRI_FOREST, 7, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x33B */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_7_3, SCENE_KOKIRI_FOREST, 7, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x33C */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_8, SCENE_KOKIRI_FOREST, 8, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x33C */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_OUTSIDE_TWINS_HOUSE, SCENE_KOKIRI_FOREST, 8, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x33D */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_8_1, SCENE_KOKIRI_FOREST, 8, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x33E */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_8_2, SCENE_KOKIRI_FOREST, 8, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x33F */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_8_3, SCENE_KOKIRI_FOREST, 8, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x340 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_2, SCENE_HYRULE_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x340 */ DEFINE_ENTRANCE(ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, SCENE_HYRULE_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x341 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_2_1, SCENE_HYRULE_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x342 */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_2_2, SCENE_OUTSIDE_GANONS_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x343 */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_2_3, SCENE_OUTSIDE_GANONS_CASTLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x344 */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_2_4, SCENE_HYRULE_CASTLE, 2, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) -/* 0x345 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_5, SCENE_KAKARIKO_VILLAGE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x345 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_FRONT, SCENE_KAKARIKO_VILLAGE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x346 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_5_1, SCENE_KAKARIKO_VILLAGE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x347 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_5_2, SCENE_KAKARIKO_VILLAGE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x348 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_5_3, SCENE_KAKARIKO_VILLAGE, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x349 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_6, SCENE_KAKARIKO_VILLAGE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x349 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_CENTER_GUEST_HOUSE, SCENE_KAKARIKO_VILLAGE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x34A */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_6_1, SCENE_KAKARIKO_VILLAGE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x34B */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_6_2, SCENE_KAKARIKO_VILLAGE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x34C */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_6_3, SCENE_KAKARIKO_VILLAGE, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x34D */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_7, SCENE_KAKARIKO_VILLAGE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x34D */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOP_GRANNY, SCENE_KAKARIKO_VILLAGE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x34E */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_7_1, SCENE_KAKARIKO_VILLAGE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x34F */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_7_2, SCENE_KAKARIKO_VILLAGE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x350 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_7_3, SCENE_KAKARIKO_VILLAGE, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x351 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_8, SCENE_KAKARIKO_VILLAGE, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x351 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_WINDMILL, SCENE_KAKARIKO_VILLAGE, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x352 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_8_1, SCENE_KAKARIKO_VILLAGE, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x353 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_8_2, SCENE_KAKARIKO_VILLAGE, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x354 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_8_3, SCENE_KAKARIKO_VILLAGE, 8, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x355 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_2, SCENE_GRAVEYARD, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x355 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_OUTSIDE_DAMPES_HUT, SCENE_GRAVEYARD, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x356 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_2_1, SCENE_GRAVEYARD, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x357 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_2_2, SCENE_GRAVEYARD, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x358 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_2_3, SCENE_GRAVEYARD, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x359 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_3, SCENE_GRAVEYARD, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x359 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_DAMPES_GRAVE_EXIT, SCENE_GRAVEYARD, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x35A */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_3_1, SCENE_GRAVEYARD, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x35B */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_3_2, SCENE_GRAVEYARD, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x35C */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_3_3, SCENE_GRAVEYARD, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x35D */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_4, SCENE_GRAVEYARD, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x35D */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_SHIELD_GRAVE_EXIT, SCENE_GRAVEYARD, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x35E */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_4_1, SCENE_GRAVEYARD, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x35F */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_4_2, SCENE_GRAVEYARD, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x360 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_4_3, SCENE_GRAVEYARD, 4, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x361 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_5, SCENE_GRAVEYARD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x361 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_HEART_PIECE_GRAVE_EXIT, SCENE_GRAVEYARD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x362 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_5_1, SCENE_GRAVEYARD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x363 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_5_2, SCENE_GRAVEYARD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x364 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_5_3, SCENE_GRAVEYARD, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x365 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_1, SCENE_HAUNTED_WASTELAND, 1, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) +/* 0x365 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_WEST_EXIT, SCENE_HAUNTED_WASTELAND, 1, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) /* 0x366 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_1_1, SCENE_HAUNTED_WASTELAND, 1, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) /* 0x367 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_1_2, SCENE_HAUNTED_WASTELAND, 1, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) /* 0x368 */ DEFINE_ENTRANCE(ENTR_HAUNTED_WASTELAND_1_3, SCENE_HAUNTED_WASTELAND, 1, true, true, TRANS_TYPE_SANDSTORM_PERSIST, TRANS_TYPE_SANDSTORM_PERSIST) @@ -1093,7 +1093,7 @@ /* 0x36F */ DEFINE_ENTRANCE(ENTR_FAIRYS_FOUNTAIN_0_2, SCENE_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x370 */ DEFINE_ENTRANCE(ENTR_FAIRYS_FOUNTAIN_0_3, SCENE_FAIRYS_FOUNTAIN, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x371 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x371 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x372 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_1, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x373 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_2, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x374 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_3, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1101,7 +1101,7 @@ /* 0x376 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_5, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x377 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0_6, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x378 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_4, SCENE_LON_LON_RANCH, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x378 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE, SCENE_LON_LON_RANCH, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x379 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_4_1, SCENE_LON_LON_RANCH, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x37A */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_4_2, SCENE_LON_LON_RANCH, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x37B */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_4_3, SCENE_LON_LON_RANCH, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -1116,7 +1116,7 @@ /* 0x382 */ DEFINE_ENTRANCE(ENTR_ZORA_SHOP_0_2, SCENE_ZORA_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x383 */ DEFINE_ENTRANCE(ENTR_ZORA_SHOP_0_3, SCENE_ZORA_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x384 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_0, SCENE_POTION_SHOP_KAKARIKO, 0, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x384 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_FRONT, SCENE_POTION_SHOP_KAKARIKO, 0, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x385 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_0_1, SCENE_POTION_SHOP_KAKARIKO, 0, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x386 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_0_2, SCENE_POTION_SHOP_KAKARIKO, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x387 */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_0_3, SCENE_POTION_SHOP_KAKARIKO, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) @@ -1136,7 +1136,7 @@ /* 0x392 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_SHOP_0_2, SCENE_BOMBCHU_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x393 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_SHOP_0_3, SCENE_BOMBCHU_SHOP, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x394 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_5, SCENE_ZORAS_FOUNTAIN, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x394 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY, SCENE_ZORAS_FOUNTAIN, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x395 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_5_1, SCENE_ZORAS_FOUNTAIN, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x396 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_5_2, SCENE_ZORAS_FOUNTAIN, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x397 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_5_3, SCENE_ZORAS_FOUNTAIN, 5, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) @@ -1146,7 +1146,7 @@ /* 0x39A */ DEFINE_ENTRANCE(ENTR_DOG_LADY_HOUSE_0_2, SCENE_DOG_LADY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x39B */ DEFINE_ENTRANCE(ENTR_DOG_LADY_HOUSE_0_3, SCENE_DOG_LADY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x39C */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_0, SCENE_IMPAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x39C */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_FRONT, SCENE_IMPAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x39D */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_0_1, SCENE_IMPAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x39E */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_0_2, SCENE_IMPAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x39F */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_0_3, SCENE_IMPAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) @@ -1161,12 +1161,12 @@ /* 0x3A6 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_13_2, SCENE_GERUDOS_FORTRESS, 13, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x3A7 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_13_3, SCENE_GERUDOS_FORTRESS, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x3A8 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_14, SCENE_GERUDOS_FORTRESS, 14, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE_FAST) +/* 0x3A8 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND, SCENE_GERUDOS_FORTRESS, 14, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE_FAST) /* 0x3A9 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_14_1, SCENE_GERUDOS_FORTRESS, 14, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK_FAST) /* 0x3AA */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_14_2, SCENE_GERUDOS_FORTRESS, 14, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE_FAST) /* 0x3AB */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_14_3, SCENE_GERUDOS_FORTRESS, 14, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x3AC */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_15, SCENE_GERUDOS_FORTRESS, 15, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) +/* 0x3AC */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_GATE_EXIT, SCENE_GERUDOS_FORTRESS, 15, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) /* 0x3AD */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_15_1, SCENE_GERUDOS_FORTRESS, 15, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) /* 0x3AE */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_15_2, SCENE_GERUDOS_FORTRESS, 15, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) /* 0x3AF */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_15_3, SCENE_GERUDOS_FORTRESS, 15, true, true, TRANS_TYPE_SANDSTORM_END, TRANS_TYPE_SANDSTORM_END) @@ -1181,22 +1181,22 @@ /* 0x3B6 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_17_2, SCENE_GERUDOS_FORTRESS, 17, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x3B7 */ DEFINE_ENTRANCE(ENTR_GERUDOS_FORTRESS_17_3, SCENE_GERUDOS_FORTRESS, 17, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x3B8 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_6, SCENE_MARKET_DAY, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3B8 */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_OUTSIDE_BAZAAR, SCENE_MARKET_DAY, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3B9 */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_6_1, SCENE_MARKET_NIGHT, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3BA */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_6_2, SCENE_MARKET_RUINS, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3BB */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_6_3, SCENE_MARKET_RUINS, 6, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x3BC */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_7, SCENE_MARKET_DAY, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3BC */ DEFINE_ENTRANCE(ENTR_MARKET_DAY_OUTSIDE_BOMBCHU_BOWLING, SCENE_MARKET_DAY, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3BD */ DEFINE_ENTRANCE(ENTR_MARKET_NIGHT_7_1, SCENE_MARKET_NIGHT, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3BE */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_7_2, SCENE_MARKET_RUINS, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3BF */ DEFINE_ENTRANCE(ENTR_MARKET_RUINS_7_3, SCENE_MARKET_RUINS, 7, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x3C0 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_2, SCENE_BACK_ALLEY_DAY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3C0 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP, SCENE_BACK_ALLEY_DAY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3C1 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_2_1, SCENE_BACK_ALLEY_NIGHT, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3C2 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_DAY_2_2, SCENE_BACK_ALLEY_DAY, 2, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x3C3 */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_NIGHT_2_3, SCENE_BACK_ALLEY_NIGHT, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x3C4 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_2, SCENE_ZORAS_DOMAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x3C4 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_OUTSIDE_SHOP, SCENE_ZORAS_DOMAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x3C5 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_2_1, SCENE_ZORAS_DOMAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x3C6 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_2_2, SCENE_ZORAS_DOMAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x3C7 */ DEFINE_ENTRANCE(ENTR_ZORAS_DOMAIN_2_3, SCENE_ZORAS_DOMAIN, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1206,17 +1206,17 @@ /* 0x3CA */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_3_2, SCENE_LAKE_HYLIA, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x3CB */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_3_3, SCENE_LAKE_HYLIA, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x3CC */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_4, SCENE_LAKE_HYLIA, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3CC */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_OUTSIDE_LAB, SCENE_LAKE_HYLIA, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3CD */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_4_1, SCENE_LAKE_HYLIA, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3CE */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_4_2, SCENE_LAKE_HYLIA, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3CF */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_4_3, SCENE_LAKE_HYLIA, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x3D0 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_4, SCENE_GERUDO_VALLEY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3D0 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_OUTSIDE_TENT, SCENE_GERUDO_VALLEY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3D1 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_4_1, SCENE_GERUDO_VALLEY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3D2 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_4_2, SCENE_GERUDO_VALLEY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3D3 */ DEFINE_ENTRANCE(ENTR_GERUDO_VALLEY_4_3, SCENE_GERUDO_VALLEY, 4, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x3D4 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_3, SCENE_ZORAS_FOUNTAIN, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x3D4 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN, SCENE_ZORAS_FOUNTAIN, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x3D5 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_3_1, SCENE_ZORAS_FOUNTAIN, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x3D6 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_3_2, SCENE_ZORAS_FOUNTAIN, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x3D7 */ DEFINE_ENTRANCE(ENTR_ZORAS_FOUNTAIN_3_3, SCENE_ZORAS_FOUNTAIN, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1246,7 +1246,7 @@ /* 0x3EA */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_1_2, SCENE_POTION_SHOP_KAKARIKO, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x3EB */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_1_3, SCENE_POTION_SHOP_KAKARIKO, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x3EC */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_2, SCENE_POTION_SHOP_KAKARIKO, 2, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x3EC */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_BACK, SCENE_POTION_SHOP_KAKARIKO, 2, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x3ED */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_2_1, SCENE_POTION_SHOP_KAKARIKO, 2, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x3EE */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_2_2, SCENE_POTION_SHOP_KAKARIKO, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x3EF */ DEFINE_ENTRANCE(ENTR_POTION_SHOP_KAKARIKO_2_3, SCENE_POTION_SHOP_KAKARIKO, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) @@ -1266,7 +1266,7 @@ /* 0x3FA */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_4_2, SCENE_SPIRIT_TEMPLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x3FB */ DEFINE_ENTRANCE(ENTR_SPIRIT_TEMPLE_4_3, SCENE_SPIRIT_TEMPLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x3FC */ DEFINE_ENTRANCE(ENTR_GORON_CITY_2, SCENE_GORON_CITY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x3FC */ DEFINE_ENTRANCE(ENTR_GORON_CITY_OUTSIDE_SHOP, SCENE_GORON_CITY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3FD */ DEFINE_ENTRANCE(ENTR_GORON_CITY_2_1, SCENE_GORON_CITY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3FE */ DEFINE_ENTRANCE(ENTR_GORON_CITY_2_2, SCENE_GORON_CITY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x3FF */ DEFINE_ENTRANCE(ENTR_GORON_CITY_2_3, SCENE_GORON_CITY, 2, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -1279,27 +1279,27 @@ /* 0x405 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_0_5, SCENE_CASTLE_COURTYARD_ZELDA, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x406 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_0_6, SCENE_CASTLE_COURTYARD_ZELDA, 0, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x407 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_1, SCENE_JABU_JABU, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x407 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_BOSS_DOOR, SCENE_JABU_JABU, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x408 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_1_1, SCENE_JABU_JABU, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x409 */ DEFINE_ENTRANCE(ENTR_JABU_JABU_1_2, SCENE_JABU_JABU, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x40A */ DEFINE_ENTRANCE(ENTR_JABU_JABU_1_3, SCENE_JABU_JABU, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x40B */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_BOSS_0, SCENE_DODONGOS_CAVERN_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x40B */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE, SCENE_DODONGOS_CAVERN_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x40C */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_BOSS_0_1, SCENE_DODONGOS_CAVERN_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x40D */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_BOSS_0_2, SCENE_DODONGOS_CAVERN_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x40E */ DEFINE_ENTRANCE(ENTR_DODONGOS_CAVERN_BOSS_0_3, SCENE_DODONGOS_CAVERN_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x40F */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_BOSS_0, SCENE_DEKU_TREE_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x40F */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_BOSS_ENTRANCE, SCENE_DEKU_TREE_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x410 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_BOSS_0_1, SCENE_DEKU_TREE_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x411 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_BOSS_0_2, SCENE_DEKU_TREE_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x412 */ DEFINE_ENTRANCE(ENTR_DEKU_TREE_BOSS_0_3, SCENE_DEKU_TREE_BOSS, 0, true, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x413 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_BOSS_0, SCENE_SHADOW_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x413 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE, SCENE_SHADOW_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x414 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_BOSS_0_1, SCENE_SHADOW_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x415 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_BOSS_0_2, SCENE_SHADOW_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x416 */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_BOSS_0_3, SCENE_SHADOW_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x417 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_BOSS_0, SCENE_WATER_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x417 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_BOSS_ENTRANCE, SCENE_WATER_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x418 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_BOSS_0_1, SCENE_WATER_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x419 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_BOSS_0_2, SCENE_WATER_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x41A */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_BOSS_0_3, SCENE_WATER_TEMPLE_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1314,7 +1314,7 @@ /* 0x421 */ DEFINE_ENTRANCE(ENTR_GANONDORF_BOSS_0_2, SCENE_GANONDORF_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x422 */ DEFINE_ENTRANCE(ENTR_GANONDORF_BOSS_0_3, SCENE_GANONDORF_BOSS, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x423 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_1, SCENE_WATER_TEMPLE, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_BLACK) +/* 0x423 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_BOSS_DOOR, SCENE_WATER_TEMPLE, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_BLACK) /* 0x424 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_1_1, SCENE_WATER_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x425 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_1_2, SCENE_WATER_TEMPLE, 1, true, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_BLACK) /* 0x426 */ DEFINE_ENTRANCE(ENTR_WATER_TEMPLE_1_3, SCENE_WATER_TEMPLE, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1329,7 +1329,7 @@ /* 0x42D */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_2_2, SCENE_GANONS_TOWER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x42E */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_2_3, SCENE_GANONS_TOWER, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x42F */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_5, SCENE_LON_LON_RANCH, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x42F */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_OUTSIDE_STABLES, SCENE_LON_LON_RANCH, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x430 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_5_1, SCENE_LON_LON_RANCH, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x431 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_5_2, SCENE_LON_LON_RANCH, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x432 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_5_3, SCENE_LON_LON_RANCH, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -1344,7 +1344,7 @@ /* 0x439 */ DEFINE_ENTRANCE(ENTR_SARIAS_HOUSE_0_2, SCENE_SARIAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x43A */ DEFINE_ENTRANCE(ENTR_SARIAS_HOUSE_0_3, SCENE_SARIAS_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x43B */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_HOUSE_0, SCENE_BACK_ALLEY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x43B */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_MAN_IN_GREEN_HOUSE, SCENE_BACK_ALLEY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x43C */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_HOUSE_0_1, SCENE_BACK_ALLEY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x43D */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_HOUSE_0_2, SCENE_BACK_ALLEY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x43E */ DEFINE_ENTRANCE(ENTR_BACK_ALLEY_HOUSE_0_3, SCENE_BACK_ALLEY_HOUSE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) @@ -1354,37 +1354,37 @@ /* 0x441 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x442 */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 0, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x443 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_9, SCENE_KOKIRI_FOREST, 9, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x443 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_OUTSIDE_MIDOS_HOUSE, SCENE_KOKIRI_FOREST, 9, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x444 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_9_1, SCENE_KOKIRI_FOREST, 9, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x445 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_9_2, SCENE_KOKIRI_FOREST, 9, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x446 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_9_3, SCENE_KOKIRI_FOREST, 9, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x447 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_10, SCENE_KOKIRI_FOREST, 10, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x447 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_OUTSIDE_SARIAS_HOUSE, SCENE_KOKIRI_FOREST, 10, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x448 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_10_1, SCENE_KOKIRI_FOREST, 10, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x449 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_10_2, SCENE_KOKIRI_FOREST, 10, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x44A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_10_3, SCENE_KOKIRI_FOREST, 10, false, false, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x44B */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_9, SCENE_KAKARIKO_VILLAGE, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x44B */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_FRONT, SCENE_KAKARIKO_VILLAGE, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x44C */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_9_1, SCENE_KAKARIKO_VILLAGE, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x44D */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_9_2, SCENE_KAKARIKO_VILLAGE, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x44E */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_9_3, SCENE_KAKARIKO_VILLAGE, 9, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x44F */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_0, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) +/* 0x44F */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_GRAVE, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) /* 0x450 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_0_1, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) /* 0x451 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_0_2, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) /* 0x452 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_0_3, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_STARBURST,TCC_BLACK, TCS_FAST)) -/* 0x453 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_1, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x453 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_WINDMILL, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x454 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_1_1, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x455 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_1_2, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x456 */ DEFINE_ENTRANCE(ENTR_WINDMILL_AND_DAMPES_GRAVE_1_3, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x457 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_11, SCENE_KOKIRI_FOREST, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x457 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP, SCENE_KOKIRI_FOREST, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x458 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_11_1, SCENE_KOKIRI_FOREST, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x459 */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_11_2, SCENE_KOKIRI_FOREST, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x45A */ DEFINE_ENTRANCE(ENTR_KOKIRI_FOREST_11_3, SCENE_KOKIRI_FOREST, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x45B */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_4, SCENE_DEATH_MOUNTAIN_TRAIL, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x45B */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT, SCENE_DEATH_MOUNTAIN_TRAIL, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x45C */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_4_1, SCENE_DEATH_MOUNTAIN_TRAIL, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x45D */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_4_2, SCENE_DEATH_MOUNTAIN_TRAIL, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x45E */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_4_3, SCENE_DEATH_MOUNTAIN_TRAIL, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1394,12 +1394,12 @@ /* 0x461 */ DEFINE_ENTRANCE(ENTR_FISHING_POND_0_2, SCENE_FISHING_POND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x462 */ DEFINE_ENTRANCE(ENTR_FISHING_POND_0_3, SCENE_FISHING_POND, 0, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x463 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_10, SCENE_KAKARIKO_VILLAGE, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x463 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY, SCENE_KAKARIKO_VILLAGE, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x464 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_10_1, SCENE_KAKARIKO_VILLAGE, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x465 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_10_2, SCENE_KAKARIKO_VILLAGE, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x466 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_10_3, SCENE_KAKARIKO_VILLAGE, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x467 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x467 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_ENTRANCE, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x468 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_1, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x469 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_2, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x46A */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_3, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -1411,7 +1411,7 @@ /* 0x470 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_9, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x471 */ DEFINE_ENTRANCE(ENTR_INSIDE_GANONS_CASTLE_0_10, SCENE_INSIDE_GANONS_CASTLE, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x472 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_1, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x472 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x473 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_NIGHT_1_1, SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x474 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_RUINS_1_2, SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x475 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_EXTERIOR_RUINS_1_3, SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -1421,7 +1421,7 @@ /* 0x478 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_15_2, SCENE_HYRULE_FIELD, 15, false, true, TRANS_TYPE_FADE_WHITE_FAST, TRANS_TYPE_FADE_WHITE_FAST) /* 0x479 */ DEFINE_ENTRANCE(ENTR_HYRULE_FIELD_15_3, SCENE_HYRULE_FIELD, 15, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) -/* 0x47A */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_5, SCENE_DEATH_MOUNTAIN_TRAIL, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x47A */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP, SCENE_DEATH_MOUNTAIN_TRAIL, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x47B */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_5_1, SCENE_DEATH_MOUNTAIN_TRAIL, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x47C */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_5_2, SCENE_DEATH_MOUNTAIN_TRAIL, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x47D */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_TRAIL_5_3, SCENE_DEATH_MOUNTAIN_TRAIL, 5, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -1431,7 +1431,7 @@ /* 0x480 */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_4_2, SCENE_OUTSIDE_GANONS_CASTLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x481 */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_4_3, SCENE_OUTSIDE_GANONS_CASTLE, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x482 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_3, SCENE_DEATH_MOUNTAIN_CRATER, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x482 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT, SCENE_DEATH_MOUNTAIN_CRATER, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x483 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_3_1, SCENE_DEATH_MOUNTAIN_CRATER, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x484 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_3_2, SCENE_DEATH_MOUNTAIN_CRATER, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x485 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_3_3, SCENE_DEATH_MOUNTAIN_CRATER, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1506,12 +1506,12 @@ /* 0x4BC */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_1_2, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4BD */ DEFINE_ENTRANCE(ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_1_3, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, 1, true, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x4BE */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4BE */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4BF */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1_1, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4C0 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1_2, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4C1 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1_3, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x4C2 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4C2 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4C3 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2_1, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4C4 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2_2, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4C5 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2_3, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1536,22 +1536,22 @@ /* 0x4D4 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_5_2, SCENE_LOST_WOODS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4D5 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_5_3, SCENE_LOST_WOODS, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x4D6 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_6, SCENE_LOST_WOODS, 6, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4D6 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_TUNNEL_SHORTCUT, SCENE_LOST_WOODS, 6, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x4D7 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_6_1, SCENE_LOST_WOODS, 6, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x4D8 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_6_2, SCENE_LOST_WOODS, 6, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x4D9 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_6_3, SCENE_LOST_WOODS, 6, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) -/* 0x4DA */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_7, SCENE_LOST_WOODS, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4DA */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_UNDERWATER_SHORTCUT, SCENE_LOST_WOODS, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x4DB */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_7_1, SCENE_LOST_WOODS, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x4DC */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_7_2, SCENE_LOST_WOODS, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x4DD */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_7_3, SCENE_LOST_WOODS, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) -/* 0x4DE */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_8, SCENE_LOST_WOODS, 8, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4DE */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_BRIDGE_WEST_EXIT, SCENE_LOST_WOODS, 8, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4DF */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_8_1, SCENE_LOST_WOODS, 8, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4E0 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_8_2, SCENE_LOST_WOODS, 8, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4E1 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_8_3, SCENE_LOST_WOODS, 8, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x4E2 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_3, SCENE_GORON_CITY, 3, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x4E2 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_TUNNEL_SHORTCUT, SCENE_GORON_CITY, 3, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x4E3 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_3_1, SCENE_GORON_CITY, 3, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x4E4 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_3_2, SCENE_GORON_CITY, 3, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x4E5 */ DEFINE_ENTRANCE(ENTR_GORON_CITY_3_3, SCENE_GORON_CITY, 3, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) @@ -1566,7 +1566,7 @@ /* 0x4EC */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_3_2, SCENE_SHADOW_TEMPLE, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4ED */ DEFINE_ENTRANCE(ENTR_SHADOW_TEMPLE_3_3, SCENE_SHADOW_TEMPLE, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x4EE */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_11, SCENE_KAKARIKO_VILLAGE, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x4EE */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_SKULKLTULA_HOUSE, SCENE_KAKARIKO_VILLAGE, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x4EF */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_11_1, SCENE_KAKARIKO_VILLAGE, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x4F0 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_11_2, SCENE_KAKARIKO_VILLAGE, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x4F1 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_11_3, SCENE_KAKARIKO_VILLAGE, 11, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -1576,7 +1576,7 @@ /* 0x4F4 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_3_2, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4F5 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_3_3, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x4F6 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_4, SCENE_DEATH_MOUNTAIN_CRATER, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x4F6 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, SCENE_DEATH_MOUNTAIN_CRATER, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4F7 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_4_1, SCENE_DEATH_MOUNTAIN_CRATER, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4F8 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_4_2, SCENE_DEATH_MOUNTAIN_CRATER, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4F9 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_4_3, SCENE_DEATH_MOUNTAIN_CRATER, 4, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1587,7 +1587,7 @@ /* 0x4FD */ DEFINE_ENTRANCE(ENTR_OUTSIDE_GANONS_CASTLE_3_3, SCENE_OUTSIDE_GANONS_CASTLE, 3, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x4FE */ DEFINE_ENTRANCE(ENTR_HYRULE_CASTLE_3_4, SCENE_HYRULE_CASTLE, 3, false, true, TRANS_TYPE_WIPE, TRANS_TYPE_WIPE) -/* 0x4FF */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_12, SCENE_KAKARIKO_VILLAGE, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x4FF */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_BACK, SCENE_KAKARIKO_VILLAGE, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x500 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_12_1, SCENE_KAKARIKO_VILLAGE, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x501 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_12_2, SCENE_KAKARIKO_VILLAGE, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x502 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_12_3, SCENE_KAKARIKO_VILLAGE, 12, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -1602,7 +1602,7 @@ /* 0x509 */ DEFINE_ENTRANCE(ENTR_BOMBCHU_BOWLING_ALLEY_0_2, SCENE_BOMBCHU_BOWLING_ALLEY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x50A */ DEFINE_ENTRANCE(ENTR_BOMBCHU_BOWLING_ALLEY_0_3, SCENE_BOMBCHU_BOWLING_ALLEY, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x50B */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_6, SCENE_GRAVEYARD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x50B */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_ROYAL_TOMB_EXIT, SCENE_GRAVEYARD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x50C */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_6_1, SCENE_GRAVEYARD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x50D */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_6_2, SCENE_GRAVEYARD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x50E */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_6_3, SCENE_GRAVEYARD, 6, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) @@ -1693,7 +1693,7 @@ /* 0x552 */ DEFINE_ENTRANCE(ENTR_HOUSE_OF_SKULLTULA_0_2, SCENE_HOUSE_OF_SKULLTULA, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x553 */ DEFINE_ENTRANCE(ENTR_HOUSE_OF_SKULLTULA_0_3, SCENE_HOUSE_OF_SKULLTULA, 0, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x554 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_14, SCENE_KAKARIKO_VILLAGE, 14, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x554 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OWL_DROP, SCENE_KAKARIKO_VILLAGE, 14, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x555 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_14_1, SCENE_KAKARIKO_VILLAGE, 14, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x556 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_14_2, SCENE_KAKARIKO_VILLAGE, 14, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x557 */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_14_3, SCENE_KAKARIKO_VILLAGE, 14, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1708,17 +1708,17 @@ /* 0x55E */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_9_2, SCENE_LON_LON_RANCH, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x55F */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_9_3, SCENE_LON_LON_RANCH, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x560 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_7, SCENE_LAKE_HYLIA, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) +/* 0x560 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT, SCENE_LAKE_HYLIA, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x561 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_7_1, SCENE_LAKE_HYLIA, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x562 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_7_2, SCENE_LAKE_HYLIA, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) /* 0x563 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_7_3, SCENE_LAKE_HYLIA, 7, false, true, TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST), TRANS_TYPE_CIRCLE(TCA_RIPPLE, TCC_WHITE, TCS_FAST)) -/* 0x564 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_5, SCENE_DEATH_MOUNTAIN_CRATER, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x564 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP, SCENE_DEATH_MOUNTAIN_CRATER, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x565 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_5_1, SCENE_DEATH_MOUNTAIN_CRATER, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x566 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_5_2, SCENE_DEATH_MOUNTAIN_CRATER, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x567 */ DEFINE_ENTRANCE(ENTR_DEATH_MOUNTAIN_CRATER_5_3, SCENE_DEATH_MOUNTAIN_CRATER, 5, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x568 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_7, SCENE_GRAVEYARD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x568 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_WARP_PAD, SCENE_GRAVEYARD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x569 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_7_1, SCENE_GRAVEYARD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x56A */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_7_2, SCENE_GRAVEYARD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x56B */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_7_3, SCENE_GRAVEYARD, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) @@ -1738,17 +1738,17 @@ /* 0x576 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_1_2, SCENE_ROYAL_FAMILYS_TOMB, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x577 */ DEFINE_ENTRANCE(ENTR_ROYAL_FAMILYS_TOMB_1_3, SCENE_ROYAL_FAMILYS_TOMB, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x578 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) +/* 0x578 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x579 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1_1, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x57A */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1_2, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x57B */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1_3, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x57C */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_7, SCENE_DESERT_COLOSSUS, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x57C */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT, SCENE_DESERT_COLOSSUS, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x57D */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_7_1, SCENE_DESERT_COLOSSUS, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x57E */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_7_2, SCENE_DESERT_COLOSSUS, 7, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x57F */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_7_3, SCENE_DESERT_COLOSSUS, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x580 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_8, SCENE_GRAVEYARD, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x580 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP, SCENE_GRAVEYARD, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x581 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_8_1, SCENE_GRAVEYARD, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x582 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_8_2, SCENE_GRAVEYARD, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x583 */ DEFINE_ENTRANCE(ENTR_GRAVEYARD_8_3, SCENE_GRAVEYARD, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) @@ -1758,7 +1758,7 @@ /* 0x586 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_2_2, SCENE_FOREST_TEMPLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x587 */ DEFINE_ENTRANCE(ENTR_FOREST_TEMPLE_2_3, SCENE_FOREST_TEMPLE, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x588 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x588 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_NAYRUS_COLOSSUS, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x589 */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2_1, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x58A */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2_2, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x58B */ DEFINE_ENTRANCE(ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2_3, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1838,7 +1838,7 @@ /* 0x5C6 */ DEFINE_ENTRANCE(ENTR_GROTTOS_12_2, SCENE_GROTTOS, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x5C7 */ DEFINE_ENTRANCE(ENTR_GROTTOS_12_3, SCENE_GROTTOS, 12, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x5C8 */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_1, SCENE_IMPAS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5C8 */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_BACK, SCENE_IMPAS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x5C9 */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_1_1, SCENE_IMPAS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x5CA */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_1_2, SCENE_IMPAS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x5CB */ DEFINE_ENTRANCE(ENTR_IMPAS_HOUSE_1_3, SCENE_IMPAS_HOUSE, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) @@ -1848,12 +1848,12 @@ /* 0x5CE */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_1_2, SCENE_BOTTOM_OF_THE_WELL, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) /* 0x5CF */ DEFINE_ENTRANCE(ENTR_BOTTOM_OF_THE_WELL_1_3, SCENE_BOTTOM_OF_THE_WELL, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK_FAST) -/* 0x5D0 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_1, SCENE_LON_LON_BUILDINGS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) +/* 0x5D0 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_TOWER, SCENE_LON_LON_BUILDINGS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x5D1 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_1_1, SCENE_LON_LON_BUILDINGS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x5D2 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_1_2, SCENE_LON_LON_BUILDINGS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) /* 0x5D3 */ DEFINE_ENTRANCE(ENTR_LON_LON_BUILDINGS_1_3, SCENE_LON_LON_BUILDINGS, 1, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_BLACK, TCS_FAST)) -/* 0x5D4 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_10, SCENE_LON_LON_RANCH, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) +/* 0x5D4 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_OUTSIDE_TOWER, SCENE_LON_LON_RANCH, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x5D5 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_10_1, SCENE_LON_LON_RANCH, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x5D6 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_10_2, SCENE_LON_LON_RANCH, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) /* 0x5D7 */ DEFINE_ENTRANCE(ENTR_LON_LON_RANCH_10_3, SCENE_LON_LON_RANCH, 10, false, true, TRANS_TYPE_FADE_BLACK_FAST, TRANS_TYPE_FADE_BLACK) @@ -1863,12 +1863,12 @@ /* 0x5DA */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_1_2, SCENE_ICE_CAVERN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x5DB */ DEFINE_ENTRANCE(ENTR_ICE_CAVERN_1_3, SCENE_ICE_CAVERN, 1, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x5DC */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_15, SCENE_KAKARIKO_VILLAGE, 15, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x5DC */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_BACK, SCENE_KAKARIKO_VILLAGE, 15, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x5DD */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_15_1, SCENE_KAKARIKO_VILLAGE, 15, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x5DE */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_15_2, SCENE_KAKARIKO_VILLAGE, 15, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x5DF */ DEFINE_ENTRANCE(ENTR_KAKARIKO_VILLAGE_15_3, SCENE_KAKARIKO_VILLAGE, 15, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x5E0 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_9, SCENE_LOST_WOODS, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5E0 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_BRIDGE_EAST_EXIT, SCENE_LOST_WOODS, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x5E1 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_9_1, SCENE_LOST_WOODS, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x5E2 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_9_2, SCENE_LOST_WOODS, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x5E3 */ DEFINE_ENTRANCE(ENTR_LOST_WOODS_9_3, SCENE_LOST_WOODS, 9, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1893,7 +1893,7 @@ /* 0x5F2 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_1_2, SCENE_CASTLE_COURTYARD_ZELDA, 1, false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x5F3 */ DEFINE_ENTRANCE(ENTR_CASTLE_COURTYARD_ZELDA_1_3, SCENE_CASTLE_COURTYARD_ZELDA, 1, false, false, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x5F4 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_7, SCENE_TEMPLE_OF_TIME, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x5F4 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_WARP_PAD, SCENE_TEMPLE_OF_TIME, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x5F5 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_7_1, SCENE_TEMPLE_OF_TIME, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x5F6 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_7_2, SCENE_TEMPLE_OF_TIME, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x5F7 */ DEFINE_ENTRANCE(ENTR_TEMPLE_OF_TIME_7_3, SCENE_TEMPLE_OF_TIME, 7, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) @@ -1908,27 +1908,27 @@ /* 0x5FE */ DEFINE_ENTRANCE(ENTR_GROTTOS_13_2, SCENE_GROTTOS, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x5FF */ DEFINE_ENTRANCE(ENTR_GROTTOS_13_3, SCENE_GROTTOS, 13, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x600 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_2, SCENE_SACRED_FOREST_MEADOW, 2, false, true, TRANS_TYPE_FADE_GREEN, TRANS_TYPE_FADE_GREEN) +/* 0x600 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_WARP_PAD, SCENE_SACRED_FOREST_MEADOW, 2, false, true, TRANS_TYPE_FADE_GREEN, TRANS_TYPE_FADE_GREEN) /* 0x601 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_2_1, SCENE_SACRED_FOREST_MEADOW, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x602 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_2_2, SCENE_SACRED_FOREST_MEADOW, 2, false, true, TRANS_TYPE_FADE_GREEN, TRANS_TYPE_FADE_GREEN) /* 0x603 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_2_3, SCENE_SACRED_FOREST_MEADOW, 2, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x604 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_8, SCENE_LAKE_HYLIA, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) +/* 0x604 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_WARP_PAD, SCENE_LAKE_HYLIA, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x605 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_8_1, SCENE_LAKE_HYLIA, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x606 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_8_2, SCENE_LAKE_HYLIA, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) /* 0x607 */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_8_3, SCENE_LAKE_HYLIA, 8, false, true, TRANS_TYPE_FADE_BLACK, TRANS_TYPE_FADE_BLACK) -/* 0x608 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_3, SCENE_SACRED_FOREST_MEADOW, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x608 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP, SCENE_SACRED_FOREST_MEADOW, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x609 */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_3_1, SCENE_SACRED_FOREST_MEADOW, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x60A */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_3_2, SCENE_SACRED_FOREST_MEADOW, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x60B */ DEFINE_ENTRANCE(ENTR_SACRED_FOREST_MEADOW_3_3, SCENE_SACRED_FOREST_MEADOW, 3, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x60C */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_9, SCENE_LAKE_HYLIA, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x60C */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP, SCENE_LAKE_HYLIA, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x60D */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_9_1, SCENE_LAKE_HYLIA, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x60E */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_9_2, SCENE_LAKE_HYLIA, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x60F */ DEFINE_ENTRANCE(ENTR_LAKE_HYLIA_9_3, SCENE_LAKE_HYLIA, 9, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) -/* 0x610 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_8, SCENE_DESERT_COLOSSUS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) +/* 0x610 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP, SCENE_DESERT_COLOSSUS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x611 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_8_1, SCENE_DESERT_COLOSSUS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x612 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_8_2, SCENE_DESERT_COLOSSUS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) /* 0x613 */ DEFINE_ENTRANCE(ENTR_DESERT_COLOSSUS_8_3, SCENE_DESERT_COLOSSUS, 8, false, true, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE) \ No newline at end of file diff --git a/soh/include/variables.h b/soh/include/variables.h index 5c97b26b8..f5486f761 100644 --- a/soh/include/variables.h +++ b/soh/include/variables.h @@ -120,7 +120,7 @@ extern "C" extern KaleidoMgrOverlay gKaleidoMgrOverlayTable[KALEIDO_OVL_MAX]; extern KaleidoMgrOverlay* gKaleidoMgrCurOvl; extern u8 gBossMarkState; - extern void* D_8012D1F0; + extern void* gDebugCutsceneScript; extern s32 gScreenWidth; extern s32 gScreenHeight; extern Mtx gMtxClear; @@ -158,9 +158,9 @@ extern "C" extern char D_80133398[]; extern SoundBankEntry* gSoundBanks[7]; extern u8 gSfxChannelLayout; - extern Vec3f D_801333D4; - extern f32 D_801333E0; - extern s8 D_801333E8; + extern Vec3f gSfxDefaultPos; + extern f32 gSfxDefaultFreqAndVolScale; + extern s8 gSfxDefaultReverb; extern u8 D_801333F0; extern u8 gAudioSfxSwapOff; extern u8 D_80133408; @@ -203,7 +203,7 @@ extern "C" extern f32 gBossMarkScale; extern PauseMapMarksData* gLoadedPauseMarkDataTable; extern s32 gTrnsnUnkState; - extern Color_RGBA8_u32 D_801614B0; + extern Color_RGBA8_u32 gVisMonoColor; extern PreNmiBuff* gAppNmiBufferPtr; extern SchedContext gSchedContext; extern PadMgr gPadMgr; diff --git a/soh/include/z64.h b/soh/include/z64.h index f4cec6e82..7cd99372d 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -3,6 +3,7 @@ #include #include "unk.h" // this used to get pulled in via ultra64.h +#include "attributes.h" #include "z64save.h" #include "z64light.h" #include "z64bgcheck.h" @@ -24,12 +25,14 @@ #include "z64skin.h" #include "z64transition.h" #include "z64interface.h" +#include "z64vis.h" #include "alignment.h" #include "sequence.h" #include "sfx.h" #include #include "ichain.h" #include "regs.h" +#include "gfx.h" #if defined(__LP64__) #define _SOH64 @@ -43,6 +46,8 @@ namespace LUS { class IResource; class Scene; +}; +namespace Fast { class DisplayList; }; #include @@ -1592,6 +1597,9 @@ typedef struct { uint8_t bossRushOffset; int16_t bossRushUIAlpha; uint16_t bossRushArrowOffset; + uint8_t randomizerIndex; + int16_t randomizerUIAlpha; + uint16_t randomizerArrowOffset; } FileChooseContext; // size = 0x1CAE0 // Macros for `EntranceInfo.field` @@ -2035,13 +2043,13 @@ typedef struct ArenaNode { /* 0x04 */ size_t size; /* 0x08 */ struct ArenaNode* next; /* 0x0C */ struct ArenaNode* prev; - ///* 0x10 */ const char* filename; - ///* 0x14 */ s32 line; - ///* 0x18 */ OSId threadId; - ///* 0x1C */ Arena* arena; - ///* 0x20 */ OSTime time; - ///* 0x28 */ u8 unk_28[0x30-0x28]; // probably padding -} ArenaNode; // size = 0x10 + // /* 0x10 */ const char* filename; + // /* 0x14 */ s32 line; + // /* 0x18 */ OSId threadId; + // /* 0x1C */ Arena* arena; + // /* 0x20 */ OSTime time; + // /* 0x28 */ u8 unk_28[0x30-0x28]; // probably padding +} ArenaNode; // size = 0x30 typedef struct OverlayRelocationSection { /* 0x00 */ u32 textSize; @@ -2224,31 +2232,6 @@ typedef struct { /* 0x0084 */ u32 unk_84; } ViMode; -// Vis... -typedef struct { - /* 0x00 */ u32 type; - /* 0x04 */ u32 setScissor; - /* 0x08 */ Color_RGBA8_u32 color; - /* 0x0C */ Color_RGBA8_u32 envColor; -} struct_801664F0; // size = 0x10 - -typedef struct { - /* 0x00 */ u32 unk_00; - /* 0x04 */ u32 setScissor; - /* 0x08 */ Color_RGBA8_u32 primColor; - /* 0x0C */ Color_RGBA8_u32 envColor; - /* 0x10 */ u16* tlut; - /* 0x14 */ Gfx* monoDl; -} VisMono; // size = 0x18 - -// Vis... -typedef struct { - /* 0x00 */ u32 useRgba; - /* 0x04 */ u32 setScissor; - /* 0x08 */ Color_RGBA8_u32 primColor; - /* 0x08 */ Color_RGBA8_u32 envColor; -} struct_80166500; // size = 0x10 - typedef struct { /* 0x000 */ u8 rumbleEnable[4]; /* 0x004 */ u8 unk_04[0x40]; diff --git a/soh/include/z64actor.h b/soh/include/z64actor.h index 156f1d679..272237d21 100644 --- a/soh/include/z64actor.h +++ b/soh/include/z64actor.h @@ -214,6 +214,13 @@ if neither of the above are set : blue 0x2000 : translucent, else opaque */ +#define DYNA_INTERACT_ACTOR_ON_TOP (1 << 0) // There is an actor standing on the collision of the dynapoly actor +#define DYNA_INTERACT_PLAYER_ON_TOP (1 << 1) // The player actor is standing on the collision of the dynapoly actor +#define DYNA_INTERACT_PLAYER_ABOVE \ + (1 << 2) // The player is directly above the collision of the dynapoly actor (any distance above) +#define DYNA_INTERACT_ACTOR_SWITCH_PRESSED \ + (1 << 3) // An actor that is capable of pressing switches is on top of the dynapoly actor + typedef struct DynaPolyActor { /* 0x000 */ struct Actor actor; /* 0x14C */ s32 bgId; @@ -221,8 +228,8 @@ typedef struct DynaPolyActor { /* 0x154 */ f32 unk_154; /* 0x158 */ s16 unk_158; // y rotation? /* 0x15A */ u16 unk_15A; - /* 0x15C */ u32 unk_15C; - /* 0x160 */ u8 unk_160; + /* 0x15C */ u32 transformFlags; + /* 0x160 */ u8 interactFlags; /* 0x162 */ s16 unk_162; } DynaPolyActor; // size = 0x164 @@ -290,7 +297,6 @@ typedef struct EnItem00 { /* 0x15C */ f32 scale; /* 0x160 */ ColliderCylinder collider; // #region SOH [Randomizer] - GetItemEntry randoGiEntry; RandomizerCheck randoCheck; RandomizerInf randoInf; /* */ s16 ogParams; diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 0233819ce..47a2d18c4 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -284,7 +284,7 @@ typedef struct { // #endregion // #region SOH [Randomizer] // Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer - /* */ u16 randomizerInf[17]; + /* */ u16 randomizerInf[(RAND_INF_MAX + 15) / 16]; /* */ u8 mqDungeonCount; /* */ u16 adultTradeItems; /* */ u8 triforcePiecesCollected; @@ -361,7 +361,7 @@ typedef enum { /* 4 */ SCENE_LAYER_CUTSCENE_FIRST } SceneLayer; -#define IS_CUTSCENE_LAYER (gSaveContext.sceneLayer >= SCENE_LAYER_CUTSCENE_FIRST) +#define IS_CUTSCENE_LAYER (gSaveContext.sceneSetupIndex >= SCENE_LAYER_CUTSCENE_FIRST) typedef enum { /* 0 */ LINK_AGE_ADULT, @@ -735,14 +735,14 @@ typedef enum { #define INFTABLE_12A 0x12A #define INFTABLE_138 0x138 #define INFTABLE_139 0x139 -#define INFTABLE_140 0x140 -#define INFTABLE_RUTO_IN_JJ_MEET_RUTO 0x141 -#define INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME 0x142 -#define INFTABLE_143 0x143 -#define INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE 0x144 -#define INFTABLE_145 0x145 -#define INFTABLE_146 0x146 -#define INFTABLE_147 0x147 +#define INFTABLE_140 0x140 // Left her on blue switch in fork room (causes her to spawn in fork room) +#define INFTABLE_RUTO_IN_JJ_MEET_RUTO 0x141 // Jumped down hole from hole room +#define INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME 0x142 // in the basement +#define INFTABLE_143 0x143 // Sat down in basement (causes her to get upset if this is set when actor is spawned) +#define INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE 0x144 // Entered the room with the sapphire +#define INFTABLE_145 0x145 // Thrown to sapphire (not kidnapped yet) +#define INFTABLE_146 0x146 // Kidnapped +#define INFTABLE_147 0x147 // Brought ruto back up to holes room, causes her to spawn in holes room instead of basement #define INFTABLE_160 0x160 #define INFTABLE_161 0x161 #define INFTABLE_162 0x162 diff --git a/soh/include/z64vis.h b/soh/include/z64vis.h new file mode 100644 index 000000000..1798baa1f --- /dev/null +++ b/soh/include/z64vis.h @@ -0,0 +1,101 @@ +#ifndef Z64_VIS_H +#define Z64_VIS_H + +// #include "ultra64.h" +// #include "color.h" +#include + + +#ifdef __cplusplus +#define this thisx +extern "C" +{ +#endif + +typedef enum FramebufferFilterType { + /* 0 */ FB_FILTER_NONE, + /* 1 */ FB_FILTER_CVG_RGB, + /* 2 */ FB_FILTER_CVG_RGB_UNIFORM, + /* 3 */ FB_FILTER_CVG_ONLY, + /* 4 */ FB_FILTER_CVG_RGB_FOG, // Not recommended, easily overflows blender + /* 5 */ FB_FILTER_ZBUF_IA, + /* 6 */ FB_FILTER_ZBUF_RGBA, + /* 7 */ FB_FILTER_MONO +} FramebufferFilterType; + +typedef enum VisScissorType { + /* 0 */ VIS_NO_SETSCISSOR, + /* 1 */ VIS_SETSCISSOR +} VisScissorType; + +typedef struct Vis { + /* 0x00 */ u32 type; + /* 0x04 */ u32 scissorType; + /* 0x08 */ Color_RGBA8_u32 primColor; + /* 0x0C */ Color_RGBA8_u32 envColor; +} Vis; // size = 0x10 + + + +/* Cvg: Coverage */ + +#define FB_FILTER_TO_CVG_TYPE(filter) (filter) + +typedef enum VisCvgType { + /* 0 */ VIS_CVG_TYPE_NONE = FB_FILTER_TO_CVG_TYPE(FB_FILTER_NONE), + /* 1 */ VIS_CVG_TYPE_CVG_RGB = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_RGB), + /* 2 */ VIS_CVG_TYPE_CVG_RGB_UNIFORM = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_RGB_UNIFORM), + /* 3 */ VIS_CVG_TYPE_CVG_ONLY = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_ONLY), + /* 4 */ VIS_CVG_TYPE_CVG_RGB_FOG = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_RGB_FOG) +} VisCvgType; + +typedef struct VisCvg { + /* 0x00 */ Vis vis; +} VisCvg; // size = 0x10 + +void VisCvg_Init(VisCvg* this); +void VisCvg_Destroy(VisCvg* this); +void VisCvg_Draw(VisCvg* this, Gfx** gfxP); + + + +/* Mono: Desaturation */ + +// Only one type + +typedef struct VisMono { + /* 0x00 */ Vis vis; + /* 0x10 */ u16* tlut; + /* 0x14 */ Gfx* dList; +} VisMono; // size = 0x18 + +void VisMono_Init(VisMono* this); +void VisMono_Destroy(VisMono* this); +void VisMono_Draw(VisMono* this, Gfx** gfxP); + + + +/* ZBuf: Z-Buffer */ + +#define FB_FILTER_TO_ZBUF_TYPE(filter) ((filter) - FB_FILTER_ZBUF_IA) + +typedef enum VisZBufType { + /* 0 */ VIS_ZBUF_TYPE_IA = FB_FILTER_TO_ZBUF_TYPE(FB_FILTER_ZBUF_IA), + /* 1 */ VIS_ZBUF_TYPE_RGBA = FB_FILTER_TO_ZBUF_TYPE(FB_FILTER_ZBUF_RGBA) +} VisZBufType; + +typedef struct VisZBuf { + /* 0x00 */ Vis vis; +} VisZBuf; // size = 0x10 + +void VisZBuf_Init(VisZBuf* this); +void VisZBuf_Destroy(VisZBuf* this); +void VisZBuf_Draw(VisZBuf* this, Gfx** gfxP); + + +#ifdef __cplusplus +#undef this +} +#endif + +#endif diff --git a/soh/soh/ActorDB.cpp b/soh/soh/ActorDB.cpp index de2538888..604d48804 100644 --- a/soh/soh/ActorDB.cpp +++ b/soh/soh/ActorDB.cpp @@ -453,7 +453,7 @@ static constexpr std::pair actorDescriptionData[] = { { ACTOR_EN_KAKASI3, "Bonooru the Scarecrow" }, { ACTOR_OCEFF_WIPE4, "Scarecrow's Song Ocarina Effect" }, { ACTOR_EN_EG, "Void-out Trigger (Tower Collapse)" }, - { ACTOR_BG_MENKURI_NISEKABE, "False Stone Walls (Gerudo Training Grounds)" }, + { ACTOR_BG_MENKURI_NISEKABE, "False Stone Walls (Gerudo Training Ground)" }, { ACTOR_EN_ZO, "Zora" }, { ACTOR_OBJ_MAKEKINSUTA, "Skulltula Sprouting from Bean Spot" }, { ACTOR_EN_GE3, "Gerudo Fortress Leader" }, diff --git a/soh/soh/Enhancements/Cheats/MoonJump.cpp b/soh/soh/Enhancements/Cheats/MoonJump.cpp new file mode 100644 index 000000000..e741fbb82 --- /dev/null +++ b/soh/soh/Enhancements/Cheats/MoonJump.cpp @@ -0,0 +1,26 @@ +#include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "macros.h" +extern PlayState* gPlayState; +} + +#define CVAR_MOON_JUMP_NAME "gCheats.MoonJumpOnL" +#define CVAR_MOON_JUMP_DEFAULT 0 +#define CVAR_MOON_JUMP_VALUE CVarGetInteger(CVAR_MOON_JUMP_NAME, CVAR_MOON_JUMP_DEFAULT) + +void OnPlayerUpdateMoonJump() { + Player* player = GET_PLAYER(gPlayState); + + if (player != nullptr && CHECK_BTN_ANY(gPlayState->state.input[0].cur.button, BTN_L)) { + player->actor.velocity.y = 6.34375f; + } +} + +void RegisterMoonJump() { + COND_HOOK(OnPlayerUpdate, CVAR_MOON_JUMP_VALUE, OnPlayerUpdateMoonJump); +} + +static RegisterShipInitFunc initFunc(RegisterMoonJump, { CVAR_MOON_JUMP_NAME }); diff --git a/soh/soh/Enhancements/FileSelectEnhancements.cpp b/soh/soh/Enhancements/FileSelectEnhancements.cpp new file mode 100644 index 000000000..43b2f1966 --- /dev/null +++ b/soh/soh/Enhancements/FileSelectEnhancements.cpp @@ -0,0 +1,69 @@ +#include "FileSelectEnhancements.h" + +#include "soh/OTRGlobals.h" + +#include +#include +#include + +std::array RandomizerSettingsMenuText[RSM_MAX] = { + { + // English + "Start Randomizer", + // German + "Start Randomizer", + // French + "Start Randomizer", + }, + { + // English + "Generate New Randomizer Seed", + // German + "Generate New Randomizer Seed", + // French + "Generate New Randomizer Seed", + }, + { + // English + "Open Randomizer Settings", + // German + "Open Randomizer Settings", + // French + "Open Randomizer Settings", + }, + { + // English + "Generating...", + // German + "Generating...", + // French + "Generating...", + }, + { + // English + "No randomizer seed loaded.\nPlease generate one first" + #if defined(__WIIU__) || defined(__SWITCH__) + ".", + #else + ",\nor drop a spoiler log on the game window.", + #endif + // German + "No randomizer seed loaded.\nPlease generate one first" + #if defined(__WIIU__) || defined(__SWITCH__) + ".", + #else + ",\nor drop a spoiler log on the game window.", + #endif + // French + "Aucune Seed de Randomizer actuellement disponible.\nGénérez-en une dans les \"Randomizer Settings\"" + #if (defined(__WIIU__) || defined(__SWITCH__)) + "." + #else + "\nou glissez un spoilerlog sur la fenêtre du jeu." + #endif + }, +}; + +const char* SohFileSelect_GetSettingText(uint8_t optionIndex, uint8_t language) { + return RandomizerSettingsMenuText[optionIndex][language].c_str(); +} diff --git a/soh/soh/Enhancements/FileSelectEnhancements.h b/soh/soh/Enhancements/FileSelectEnhancements.h new file mode 100644 index 000000000..070d270dc --- /dev/null +++ b/soh/soh/Enhancements/FileSelectEnhancements.h @@ -0,0 +1,23 @@ +#ifndef FILE_SELECT_ENHANCEMENTS_H +#define FILE_SELECT_ENHANCEMENTS_H + +#include "z64.h" + +#ifdef __cplusplus +extern "C" { +#endif +const char* SohFileSelect_GetSettingText(u8 optionIndex, u8 language); +#ifdef __cplusplus +}; +#endif + +typedef enum { + RSM_START_RANDOMIZER, + RSM_GENERATE_RANDOMIZER, + RSM_OPEN_RANDOMIZER_SETTINGS, + RSM_GENERATING, + RSM_NO_RANDOMIZER_GENERATED, + RSM_MAX, +} RandomizerSettingsMenuEnums; + +#endif diff --git a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp new file mode 100644 index 000000000..cb9dfbb46 --- /dev/null +++ b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp @@ -0,0 +1,262 @@ +#include "TimeDisplay.h" +#include "soh/Enhancements/gameplaystats.h" +#include + +#include "assets/textures/parameter_static/parameter_static.h" +#include "assets/soh_assets.h" +#include "soh/ImGuiUtils.h" + +extern "C" { +#include "macros.h" +#include "functions.h" +#include "variables.h" +extern PlayState* gPlayState; +uint64_t GetUnixTimestamp(); +} + +float fontScale = 1.0f; +std::string timeDisplayTime = ""; +ImTextureID textureDisplay = 0; +ImVec4 windowBG = ImVec4(0, 0, 0, 0.5f); +ImVec4 textColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); + +// ImVec4 Colors +#define COLOR_WHITE ImVec4(1.0f, 1.0f, 1.0f, 1.0f) +#define COLOR_LIGHT_RED ImVec4(1.0f, 0.05f, 0, 1.0f) +#define COLOR_LIGHT_BLUE ImVec4(0, 0.88f, 1.0f, 1.0f) +#define COLOR_LIGHT_GREEN ImVec4(0.52f, 1.0f, 0.23f, 1.0f) +#define COLOR_GREY ImVec4(0.78f, 0.78f, 0.78f, 1.0f) + +const static std::vector> digitList = { + { "DIGIT_0_TEXTURE", gCounterDigit0Tex }, { "DIGIT_1_TEXTURE", gCounterDigit1Tex }, + { "DIGIT_2_TEXTURE", gCounterDigit2Tex }, { "DIGIT_3_TEXTURE", gCounterDigit3Tex }, + { "DIGIT_4_TEXTURE", gCounterDigit4Tex }, { "DIGIT_5_TEXTURE", gCounterDigit5Tex }, + { "DIGIT_6_TEXTURE", gCounterDigit6Tex }, { "DIGIT_7_TEXTURE", gCounterDigit7Tex }, + { "DIGIT_8_TEXTURE", gCounterDigit8Tex }, { "DIGIT_9_TEXTURE", gCounterDigit9Tex }, + { "COLON_TEXTURE", gCounterColonTex }, +}; + +const std::vector timeDisplayList = { + { DISPLAY_IN_GAME_TIMER, "Display Gameplay Timer", CVAR_ENHANCEMENT("TimeDisplay.Timers.InGameTimer") }, + { DISPLAY_TIME_OF_DAY, "Display Time of Day", CVAR_ENHANCEMENT("TimeDisplay.Timers.TimeofDay") }, + { DISPLAY_CONDITIONAL_TIMER, "Display Conditional Timer", CVAR_ENHANCEMENT("TimeDisplay.Timers.HotWater") }, + { DISPLAY_NAVI_TIMER, "Display Navi Timer", CVAR_ENHANCEMENT("TimeDisplay.Timers.NaviTimer") } +}; + +static std::vector activeTimers; + +std::string convertDayTime(uint32_t dayTime) { + uint32_t totalSeconds = 24 * 60 * 60; + uint32_t ss = static_cast(static_cast(dayTime) * (totalSeconds - 1) / 65535); + uint32_t hh = ss / 3600; + uint32_t mm = (ss % 3600) / 60; + return fmt::format("{:0>2}:{:0>2}", hh, mm); +} + +std::string convertNaviTime(uint32_t value) { + uint32_t totalSeconds = value * 0.05; + uint32_t ss = totalSeconds % 60; + uint32_t mm = totalSeconds / 60; + return fmt::format("{:0>2}:{:0>2}", mm, ss); +} + +std::string formatHotWaterDisplay(uint32_t value) { + uint32_t ss = value % 60; + uint32_t mm = value / 60; + return fmt::format("{:0>2}:{:0>2}", mm, ss); +} + +std::string formatTimeDisplay(uint32_t value) { + uint32_t sec = value / 10; + uint32_t hh = sec / 3600; + uint32_t mm = (sec - hh * 3600) / 60; + uint32_t ss = sec - hh * 3600 - mm * 60; + uint32_t ds = value % 10; + return fmt::format("{}:{:0>2}:{:0>2}.{}", hh, mm, ss, ds); +} + +static void TimeDisplayGetTimer(uint32_t timeID) { + timeDisplayTime = ""; + textureDisplay = 0; + textColor = COLOR_WHITE; + + Player* player = GET_PLAYER(gPlayState); + uint32_t timer1 = gSaveContext.timer1Value; + + switch (timeID) { + case DISPLAY_IN_GAME_TIMER: + textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("GAMEPLAY_TIMER"); + timeDisplayTime = formatTimeDisplay(GAMEPLAYSTAT_TOTAL_TIME).c_str(); + break; + case DISPLAY_TIME_OF_DAY: + if (gSaveContext.dayTime >= DAY_BEGINS && gSaveContext.dayTime < NIGHT_BEGINS) { + textureDisplay = + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("DAY_TIME_TIMER"); + } else { + textureDisplay = + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("NIGHT_TIME_TIMER"); + } + timeDisplayTime = convertDayTime(gSaveContext.dayTime).c_str(); + break; + case DISPLAY_CONDITIONAL_TIMER: + if (gSaveContext.timer1State > 0) { + timeDisplayTime = formatHotWaterDisplay(gSaveContext.timer1Value).c_str(); + textColor = + gSaveContext.timer1State <= 4 + ? (gPlayState->roomCtx.curRoom.behaviorType2 == ROOM_BEHAVIOR_TYPE2_3 ? COLOR_LIGHT_RED + : COLOR_LIGHT_BLUE) + : COLOR_WHITE; + if (gSaveContext.timer1State <= 4) { + textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + gPlayState->roomCtx.curRoom.behaviorType2 == ROOM_BEHAVIOR_TYPE2_3 + ? itemMapping[ITEM_TUNIC_GORON].name + : itemMapping[ITEM_TUNIC_ZORA].name); + } + if (gSaveContext.timer1State >= 6) { + textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + itemMapping[ITEM_SWORD_MASTER].name); + } + } else { + textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + itemMapping[ITEM_TUNIC_KOKIRI].name); + timeDisplayTime = "-:--"; + } + break; + case DISPLAY_NAVI_TIMER: + if (gSaveContext.naviTimer <= NAVI_PREPARE) { + timeDisplayTime = convertNaviTime(NAVI_PREPARE - gSaveContext.naviTimer).c_str(); + } else if (gSaveContext.naviTimer <= NAVI_ACTIVE) { + timeDisplayTime = convertNaviTime(NAVI_ACTIVE - gSaveContext.naviTimer).c_str(); + textColor = COLOR_LIGHT_GREEN; + } else { + timeDisplayTime = convertNaviTime(NAVI_COOLDOWN - gSaveContext.naviTimer).c_str(); + textColor = COLOR_GREY; + } + textureDisplay = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("NAVI_TIMER"); + break; + default: + break; + } +} + +void TimeDisplayUpdateDisplayOptions() { + activeTimers.clear(); + for (auto& timer : timeDisplayList) { + if (CVarGetInteger(timer.timeEnable, 0)) { + activeTimers.push_back(timer); + } + } + + //if (pushBack) { + // activeTimers.push_back(timeDisplayList[timeID]); + //} else { + // uint32_t index = 0; + // for (auto& check : activeTimers) { + // if (check.timeID == timeID) { + // activeTimers.erase(activeTimers.begin() + index); + // return; + // } + // index++; + // } + //} +} + +void TimeDisplayWindow::Draw() { + if (!gPlayState) { + return; + } + if (!CVarGetInteger(CVAR_WINDOW("TimeDisplayEnabled"), 0)) { + return; + } + + ImGui::PushStyleColor(ImGuiCol_WindowBg, windowBG); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f); + + ImGui::Begin("TimerDisplay", nullptr, + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoFocusOnAppearing | + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar); + ImGui::SetWindowFontScale(fontScale); + if (activeTimers.size() == 0) { + ImGui::Text("No Enabled Timers..."); + } else { + ImGui::BeginTable("Timer List", 2, ImGuiTableFlags_NoClip); + for (auto& timers : activeTimers) { + ImGui::PushID(timers.timeID); + TimeDisplayGetTimer(timers.timeID); + ImGui::TableNextColumn(); + ImGui::Image(textureDisplay, ImVec2(16.0f * fontScale, 16.0f * fontScale)); + ImGui::TableNextColumn(); + + if (timeDisplayTime != "-:--") { + char* textToDecode = new char[timeDisplayTime.size() + 1]; + textToDecode = std::strcpy(textToDecode, timeDisplayTime.c_str()); + size_t textLength = timeDisplayTime.length(); + uint16_t textureIndex = 0; + + for (size_t i = 0; i < textLength; i++) { + ImVec2 originalCursorPos = ImGui::GetCursorPos(); + if (textToDecode[i] == ':' || textToDecode[i] == '.') { + textureIndex = 10; + } else { + textureIndex = textToDecode[i] - '0'; + } + if (textToDecode[i] == '.') { + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (8.0f * fontScale)); + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + digitList[textureIndex].first), + ImVec2(8.0f * fontScale, 8.0f * fontScale), ImVec2(0, 0.5f), ImVec2(1, 1), + textColor, ImVec4(0, 0, 0, 0)); + } else { + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + digitList[textureIndex].first), + ImVec2(8.0f * fontScale, 16.0f * fontScale), ImVec2(0, 0), ImVec2(1, 1), textColor, + ImVec4(0, 0, 0, 0)); + } + ImGui::SameLine(0, 0); + } + } + ImGui::PopID(); + } + ImGui::EndTable(); + } + ImGui::End(); + + ImGui::PopStyleColor(2); + ImGui::PopStyleVar(1); +} + +void TimeDisplayInitSettings() { + fontScale = CVarGetFloat(CVAR_ENHANCEMENT("TimeDisplay.FontScale"), 1.0f); + if (fontScale < 1.0f) { + fontScale = 1.0f; + } + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeDisplay.ShowWindowBG"), 0)) { + windowBG = ImVec4(0, 0, 0, 0); + } else { + windowBG = ImVec4(0, 0, 0, 0.5f); + } +} + +static void TimeDisplayInitTimers() { + for (auto& update : timeDisplayList) { + if (CVarGetInteger(update.timeEnable, 0)) { + activeTimers.push_back(update); + } + } +} + +void TimeDisplayWindow::InitElement() { + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("GAMEPLAY_TIMER", gClockIconTex, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("DAY_TIME_TIMER", gSunIconTex, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("NIGHT_TIME_TIMER", gMoonIconTex, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("NAVI_TIMER", gNaviIconTex, ImVec4(1, 1, 1, 1)); + + for (auto& load : digitList) { + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(load.first.c_str(), load.second, ImVec4(1, 1, 1, 1)); + } + + TimeDisplayInitSettings(); + TimeDisplayInitTimers(); +} diff --git a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h new file mode 100644 index 000000000..090ac2901 --- /dev/null +++ b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h @@ -0,0 +1,37 @@ +#include + +class TimeDisplayWindow : public Ship::GuiWindow { + public: + using GuiWindow::GuiWindow; + + void InitElement() override; + void DrawElement() override {}; + void Draw() override; + void UpdateElement() override {}; +}; + +void TimeDisplayUpdateDisplayOptions(); +void TimeDisplayInitSettings(); + +typedef enum { + DISPLAY_IN_GAME_TIMER, + DISPLAY_TIME_OF_DAY, + DISPLAY_CONDITIONAL_TIMER, + DISPLAY_NAVI_TIMER +}; + +typedef enum { + NAVI_PREPARE = 600, + NAVI_ACTIVE = 3000, + NAVI_COOLDOWN = 25800, + DAY_BEGINS = 17759, + NIGHT_BEGINS = 49155 +}; + +typedef struct { + uint32_t timeID; + std::string timeLabel; + const char* timeEnable; +} TimeObject; + +extern const std::vector timeDisplayList; \ No newline at end of file diff --git a/soh/soh/Enhancements/TimeSavers/FasterRupeeAccumulator.cpp b/soh/soh/Enhancements/TimeSavers/FasterRupeeAccumulator.cpp new file mode 100644 index 000000000..b7b6587ba --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/FasterRupeeAccumulator.cpp @@ -0,0 +1,47 @@ +#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; +} + +void FasterRupeeAccumulator_Register() { + GameInteractor::Instance->RegisterGameHook([]() { + if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.FasterRupeeAccumulator"), 0)) return; + + if (gSaveContext.rupeeAccumulator == 0) { + return; + } + + // Gaining rupees + if (gSaveContext.rupeeAccumulator > 0) { + // Wallet is full + if (gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET)) { + return; + } + + if (gSaveContext.rupeeAccumulator >= 10 && gSaveContext.rupees + 10 < CUR_CAPACITY(UPG_WALLET)) { + gSaveContext.rupeeAccumulator-= 10; + gSaveContext.rupees += 10; + } + // Losing rupees + } else if (gSaveContext.rupeeAccumulator < 0) { + // No rupees to lose + if (gSaveContext.rupees == 0) { + return; + } + + if (gSaveContext.rupeeAccumulator <= -10 && gSaveContext.rupees > 10) { + gSaveContext.rupeeAccumulator += 10; + gSaveContext.rupees -= 10; + } + } + }); +} diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp index 0b7efd267..f7db9de32 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipIntro.cpp @@ -20,17 +20,17 @@ void SkipIntro_Register() { (IS_RANDO && (adultStart || shuffleEntrances))) && gSaveContext.cutsceneIndex == 0xFFF1) { // Calculate spawn location. Start with vanilla, Link's house. - int32_t spawnEntrance = ENTR_LINKS_HOUSE_0; + int32_t spawnEntrance = ENTR_LINKS_HOUSE_CHILD_SPAWN; // 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; + spawnEntrance = ENTR_TEMPLE_OF_TIME_WARP_PAD; } // If we're shuffling any entrances we'll need to get the Entrance Override if (shuffleEntrances) { // If we're shuffling any entrances, 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. + // ENTR_TEMPLE_OF_TIME_WARP_PAD, so that spawn and Prelude don't share an entrance. if (adultStart) { spawnEntrance = ENTR_HYRULE_FIELD_10; } diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp index 748982843..9f9b67fec 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp @@ -3,14 +3,16 @@ #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" +#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() +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetContextOptionIndex() + +static bool sEnteredBlueWarp = false; /** * This will override the transitions into the blue warp cutscenes, set any appropriate flags, and @@ -18,59 +20,65 @@ extern "C" { * 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; + bool overrideBlueWarpDestinations = + IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || + RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF); + + // Force blue warp skip on when ER needs to place Link somewhere else. + // This is preferred over having story cutscenes play in the overworld and then reloading Link somewhere else after. + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) || overrideBlueWarpDestinations) { + bool isBlueWarpCutscene = false; // Deku Tree Blue warp if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) { - gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_11; - isBlueWarpCutscene = 1; + gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP; + isBlueWarpCutscene = true; // 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; + } else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT && gSaveContext.cutsceneIndex == 0xFFF1) { + gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP; + isBlueWarpCutscene = true; // Jabu Jabu's Blue warp - } else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_0 && gSaveContext.cutsceneIndex == 0xFFF0) { - gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_0; - isBlueWarpCutscene = 1; + } else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP && gSaveContext.cutsceneIndex == 0xFFF0) { + gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP; + isBlueWarpCutscene = true; // Forest Temple Blue warp } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) { // Normally set in the blue warp cutscene Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_DEKU_TREE_SPROUT); if (IS_RANDO) { - gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_3; + gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP; } else { gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12; } - isBlueWarpCutscene = 1; + isBlueWarpCutscene = true; // Fire Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 && gSaveContext.cutsceneIndex == 0xFFF3) { + } else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && gSaveContext.cutsceneIndex == 0xFFF3) { // Normally set in the blue warp cutscene Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED); - gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; - isBlueWarpCutscene = 1; + gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP; + isBlueWarpCutscene = true; // Water Temple Blue warp } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) { // Normally set in the blue warp cutscene gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4800; Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); - gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_9; - isBlueWarpCutscene = 1; + gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP; + isBlueWarpCutscene = true; // Spirit Temple Blue warp } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) { - gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_8; - isBlueWarpCutscene = 1; + gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP; + isBlueWarpCutscene = true; // Shadow Temple Blue warp } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) { - gSaveContext.entranceIndex = ENTR_GRAVEYARD_8; - isBlueWarpCutscene = 1; + gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP; + isBlueWarpCutscene = true; } if (isBlueWarpCutscene) { - if (gSaveContext.entranceIndex != ENTR_LAKE_HYLIA_9) { + if (gSaveContext.entranceIndex != ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP) { // Normally set in the blue warp cutscene gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000; } @@ -80,10 +88,20 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l } // 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)) { + if (sEnteredBlueWarp && overrideBlueWarpDestinations) { Entrance_OverrideBlueWarp(); } } + + sEnteredBlueWarp = false; +} + +/** + * Using this hook to simply observe that Link has entered a bluewarp + * This way we know to allow entrance rando overrides to be processed on the next tranisition hook + */ +void SkipBlueWarp_ShouldPlayBlueWarpCS(GIVanillaBehavior _, bool* should, va_list originalArgs) { + sEnteredBlueWarp = true; } /** @@ -134,7 +152,7 @@ void SkipBlueWarp_OnActorUpdate(void* actorPtr) { */ 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) { + if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP && gSaveContext.cutsceneIndex == 0xFFF1) { *should = Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); } } @@ -143,6 +161,7 @@ void SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished(GIVanillaBehavior _, void SkipBlueWarp_Register() { GameInteractor::Instance->RegisterGameHookForID(ACTOR_EN_KO, SkipBlueWarp_OnActorUpdate); GameInteractor::Instance->RegisterGameHookForID(VB_PLAY_TRANSITION_CS, SkipBlueWarp_ShouldPlayTransitionCS); + GameInteractor::Instance->RegisterGameHookForID(VB_PLAY_BLUE_WARP_CS, SkipBlueWarp_ShouldPlayBlueWarpCS); 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 index 7000aa391..e1cc1db21 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipDekuTreeIntro.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipDekuTreeIntro.cpp @@ -14,7 +14,7 @@ void SkipDekuTreeIntro_Register() { 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); + Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); 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 index 7fa7b99f6..d487c1f47 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp @@ -15,7 +15,7 @@ void SkipLostWoodsBridge_Register() { */ 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)) { + if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_BRIDGE_EAST_EXIT) && !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); diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp index fe578c831..1cb331539 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp @@ -10,7 +10,7 @@ extern "C" { 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) { + if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN && gSaveContext.cutsceneIndex == 0xFFF1) { // Normally set in the cutscene gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4AAA; diff --git a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveJabuJabuElevator.cpp b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveJabuJabuElevator.cpp new file mode 100644 index 000000000..1e1c6ceb5 --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveJabuJabuElevator.cpp @@ -0,0 +1,27 @@ +#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_Bdan_Objects/z_bg_bdan_objects.h" +} + +/** + * Adjusts the behavior of the elevator to start near the bottom if you are entering the room from the bottom + */ +void MoveJabuJabuElevator_Register() { + GameInteractor::Instance->RegisterGameHookForID(ACTOR_BG_BDAN_OBJECTS, [](void* actorRef) { + Player* player = GET_PLAYER(gPlayState); + BgBdanObjects* bgBdanObjects = static_cast(actorRef); + + if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { + return; + } + + if (bgBdanObjects->dyna.actor.params == 1) { + if (player->actor.world.pos.y < -500.0f) { + bgBdanObjects->timer = 220; + } + } + }); +} diff --git a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp index 78a680175..59381968a 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp @@ -21,7 +21,8 @@ void MoveMidoInKokiriForest_Register() { 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) + (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI) && + gSaveContext.cutsceneIndex == 0 ) { Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD); *should = true; diff --git a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/SkipChildRutoInteractions.cpp b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/SkipChildRutoInteractions.cpp new file mode 100644 index 000000000..aaaf1b39f --- /dev/null +++ b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/SkipChildRutoInteractions.cpp @@ -0,0 +1,93 @@ +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" + +extern "C" { +#include "overlays/actors/ovl_En_Ru1/z_en_ru1.h" +#include "assets/objects/object_ru1/object_ru1.h" + +Actor* func_80AEB124(PlayState* play); +} + +void SkipChildRutoInteractions_Register() { + // Skips the Child Ruto introduction cutscene, where she drops down into the hole in Jabu-Jabu's Belly + REGISTER_VB_SHOULD(VB_PLAY_CHILD_RUTO_INTRO, { + EnRu1* enRu1 = va_arg(args, EnRu1*); + + if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { + return; + } + + Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_MEET_RUTO); + Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME); + Flags_SetInfTable(INFTABLE_143); + enRu1->drawConfig = 1; + enRu1->actor.world.pos.x = 127.0f; + enRu1->actor.world.pos.y = -340.0f; + enRu1->actor.world.pos.z = -3041.0f; + enRu1->actor.shape.rot.y = enRu1->actor.world.rot.y = -5098; + + if (*should) { + Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildTurnAroundAnim, 1.0f, 0, + Animation_GetLastFrame((void*)&gRutoChildTurnAroundAnim), ANIMMODE_ONCE, -8.0f); + enRu1->action = 10; + } + + *should = false; + }); + + // Skips a short dialogue sequence where Ruto tells you to throw her to the Sapphire + REGISTER_VB_SHOULD(VB_RUTO_WANT_TO_BE_TOSSED_TO_SAPPHIRE, { + if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { + return; + } + + if (*should) { + Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE); + *should = false; + } + }); + + // Prevents Ruto from running to the Sapphire when she wants to be tossed to it, instead she just stands up and waits for link to get closer + REGISTER_VB_SHOULD(VB_RUTO_RUN_TO_SAPPHIRE, { + EnRu1* enRu1 = va_arg(args, EnRu1*); + DynaPolyActor* dynaPolyActor = va_arg(args, DynaPolyActor*); + + if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { + return; + } + + if (*should) { + enRu1->unk_28C = (BgBdanObjects*)dynaPolyActor; + Flags_SetInfTable(INFTABLE_145); + Flags_SetSwitch(gPlayState, 0x02); + Flags_SetSwitch(gPlayState, 0x1F); + enRu1->action = 42; + Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildWait2Anim, 1.0f, 0, + Animation_GetLastFrame((void*)&gRutoChildWait2Anim), ANIMMODE_LOOP, -8.0f); + enRu1->unk_28C->cameraSetting = 1; + Actor* sapphire = func_80AEB124(gPlayState); + if (sapphire != NULL) { + Actor_Kill(sapphire); + } + enRu1->actor.room = gPlayState->roomCtx.curRoom.num; + *should = false; + } + }); + + // This overrides the behavior that causes Ruto to get upset at you before sitting back down again when INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME is set + GameInteractor::Instance->RegisterGameHookForID(ACTOR_EN_RU1, [](void* actorRef) { + EnRu1* enRu1 = static_cast(actorRef); + if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { + return; + } + + if (enRu1->action == 22) { + enRu1->action = 27; + enRu1->drawConfig = 1; + enRu1->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY; + Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildSittingAnim, 1.0f, 0.0f, + Animation_GetLastFrame((void*)&gRutoChildSittingAnim), ANIMMODE_LOOP, 0.0f); + } + }); +} diff --git a/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp b/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp index 68fe71da6..a198f8289 100644 --- a/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp +++ b/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp @@ -10,6 +10,9 @@ void TimeSavers_Register() { SkipZeldaFleeingCastle_Register(); SkipIntro_Register(); // SkipMiscInteractions + MoveJabuJabuElevator_Register(); MoveMidoInKokiriForest_Register(); + SkipChildRutoInteractions_Register(); FasterHeavyBlockLift_Register(); + FasterRupeeAccumulator_Register(); } diff --git a/soh/soh/Enhancements/TimeSavers/TimeSavers.h b/soh/soh/Enhancements/TimeSavers/TimeSavers.h index d45ed7f10..ad521c6c2 100644 --- a/soh/soh/Enhancements/TimeSavers/TimeSavers.h +++ b/soh/soh/Enhancements/TimeSavers/TimeSavers.h @@ -12,7 +12,10 @@ void TimeSavers_Register(); void SkipZeldaFleeingCastle_Register(); void SkipIntro_Register(); // SkipMiscInteractions + void MoveJabuJabuElevator_Register(); void MoveMidoInKokiriForest_Register(); + void SkipChildRutoInteractions_Register(); void FasterHeavyBlockLift_Register(); +void FasterRupeeAccumulator_Register(); #endif // TIME_SAVERS_H diff --git a/soh/soh/Enhancements/audio/AudioCollection.cpp b/soh/soh/Enhancements/audio/AudioCollection.cpp index dadcbf2ac..28e8d3d99 100644 --- a/soh/soh/Enhancements/audio/AudioCollection.cpp +++ b/soh/soh/Enhancements/audio/AudioCollection.cpp @@ -1,6 +1,7 @@ #include "AudioCollection.h" #include "sequence.h" #include "sfx.h" +#include "soh/cvar_prefixes.h" #include #include #include @@ -388,7 +389,7 @@ void AudioCollection::RemoveFromShufflePool(SequenceInfo* seqInfo) { excludedSequences.insert(seqInfo); includedSequences.erase(seqInfo); CVarSetInteger(cvarKey.c_str(), 1); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } void AudioCollection::AddToShufflePool(SequenceInfo* seqInfo) { @@ -396,7 +397,7 @@ void AudioCollection::AddToShufflePool(SequenceInfo* seqInfo) { includedSequences.insert(seqInfo); excludedSequences.erase(seqInfo); CVarClear(cvarKey.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } void AudioCollection::InitializeShufflePool() { diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index a9fefbe71..d56c8269c 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -8,9 +8,10 @@ #include #include #include "../randomizer/3drando/random.hpp" -#include "../../OTRGlobals.h" +#include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" #include -#include "../../UIWidgets.hpp" +#include "soh/UIWidgets.hpp" #include "AudioCollection.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" @@ -203,7 +204,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); ResetGroup(map, type); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) { ReplayCurrentBGM(); @@ -214,7 +215,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); RandomizeGroup(type); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) { ReplayCurrentBGM(); @@ -225,7 +226,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); LockGroup(map, type); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) { ReplayCurrentBGM(); @@ -236,7 +237,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); UnlockGroup(map, type); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) { ReplayCurrentBGM(); @@ -281,7 +282,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { if (ImGui::Selectable(seqData.label.c_str())) { CVarSetInteger(cvarKey.c_str(), value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); UpdateCurrentBGM(defaultValue, type); } @@ -301,7 +302,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { if (ImGui::Button(resetButton.c_str())) { CVarClear(cvarKey.c_str()); CVarClear(cvarLockKey.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); UpdateCurrentBGM(defaultValue, seqData.category); } UIWidgets::Tooltip("Reset to default"); @@ -322,7 +323,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { if (locked) { CVarClear(cvarLockKey.c_str()); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); UpdateCurrentBGM(defaultValue, type); } } @@ -335,7 +336,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) { } else { CVarSetInteger(cvarLockKey.c_str(), 1); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } UIWidgets::Tooltip(locked ? "Sound locked" : "Sound unlocked"); } @@ -515,7 +516,7 @@ void AudioEditor::DrawElement() { const std::string resetButton = "Reset##linkVoiceFreqMultiplier"; if (ImGui::Button(resetButton.c_str())) { CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::NewLine(); @@ -703,14 +704,14 @@ void AudioEditor_RandomizeAll() { RandomizeGroup(type); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ReplayCurrentBGM(); } void AudioEditor_RandomizeGroup(SeqType group) { RandomizeGroup(group); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ReplayCurrentBGM(); } @@ -719,14 +720,14 @@ void AudioEditor_ResetAll() { ResetGroup(AudioCollection::Instance->GetAllSequences(), type); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ReplayCurrentBGM(); } void AudioEditor_ResetGroup(SeqType group) { ResetGroup(AudioCollection::Instance->GetAllSequences(), group); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ReplayCurrentBGM(); } @@ -735,7 +736,7 @@ void AudioEditor_LockAll() { LockGroup(AudioCollection::Instance->GetAllSequences(), type); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } void AudioEditor_UnlockAll() { @@ -743,5 +744,5 @@ void AudioEditor_UnlockAll() { UnlockGroup(AudioCollection::Instance->GetAllSequences(), type); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } diff --git a/soh/soh/Enhancements/bootcommands.c b/soh/soh/Enhancements/bootcommands.c index 16ad651fc..c010067da 100644 --- a/soh/soh/Enhancements/bootcommands.c +++ b/soh/soh/Enhancements/bootcommands.c @@ -10,6 +10,7 @@ #include #include #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" uint8_t gLoadFileSelect = 0, gSkipLogoTest = 0; diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index c83078581..d4997cca9 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -225,30 +225,30 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { // Gohma & Phantom Ganon if (warpPosX == -100 && warpPosZ == -170) { if (gSaveContext.linkAge == LINK_AGE_CHILD) { - play->nextEntranceIndex = ENTR_DEKU_TREE_BOSS_0; + play->nextEntranceIndex = ENTR_DEKU_TREE_BOSS_ENTRANCE; } else { - play->nextEntranceIndex = ENTR_FOREST_TEMPLE_BOSS_0; + play->nextEntranceIndex = ENTR_FOREST_TEMPLE_BOSS_ENTRANCE; } // King Dodongo & Volvagia } else if (warpPosX == 100 && warpPosZ == -170) { if (gSaveContext.linkAge == LINK_AGE_CHILD) { - play->nextEntranceIndex = ENTR_DODONGOS_CAVERN_BOSS_0; + play->nextEntranceIndex = ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE; } else { - play->nextEntranceIndex = ENTR_FIRE_TEMPLE_BOSS_0; + play->nextEntranceIndex = ENTR_FIRE_TEMPLE_BOSS_ENTRANCE; } // Barinade & Morb } else if (warpPosX == 199 && warpPosZ == 0) { if (gSaveContext.linkAge == LINK_AGE_CHILD) { - play->nextEntranceIndex = ENTR_JABU_JABU_BOSS_0; + play->nextEntranceIndex = ENTR_JABU_JABU_BOSS_ENTRANCE; } else { - play->nextEntranceIndex = ENTR_WATER_TEMPLE_BOSS_0; + play->nextEntranceIndex = ENTR_WATER_TEMPLE_BOSS_ENTRANCE; } // Twinrova } else if (warpPosX == 100 && warpPosZ == 170) { play->nextEntranceIndex = ENTR_SPIRIT_TEMPLE_BOSS_2; // Bongo Bongo } else if (warpPosX == -100 && warpPosZ == 170) { - play->nextEntranceIndex = ENTR_SHADOW_TEMPLE_BOSS_0; + play->nextEntranceIndex = ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE; // Ganondork } else if (warpPosX == -199 && warpPosZ == 0) { play->nextEntranceIndex = ENTR_GANONDORF_BOSS_0; diff --git a/soh/soh/Enhancements/cheat_hook_handlers.cpp b/soh/soh/Enhancements/cheat_hook_handlers.cpp index 9cdb7ed62..20c85d4d4 100644 --- a/soh/soh/Enhancements/cheat_hook_handlers.cpp +++ b/soh/soh/Enhancements/cheat_hook_handlers.cpp @@ -41,6 +41,8 @@ void CheatsOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list } break; } + default: + break; } } diff --git a/soh/soh/Enhancements/controls/InputViewer.cpp b/soh/soh/Enhancements/controls/InputViewer.cpp index 75a1ea5e7..0a4f83b0f 100644 --- a/soh/soh/Enhancements/controls/InputViewer.cpp +++ b/soh/soh/Enhancements/controls/InputViewer.cpp @@ -4,6 +4,7 @@ #include "libultraship/libultra/controller.h" #include "Context.h" #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" #ifndef IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS #endif @@ -169,7 +170,7 @@ void InputViewer::DrawElement() { ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); - OSContPad* pads = Ship::Context::GetInstance()->GetControlDeck()->GetPads(); + OSContPad* pads = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground | diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp index dd2187971..492517738 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp @@ -3,6 +3,7 @@ #include "soh/OTRGlobals.h" #include "../../UIWidgets.hpp" #include "z64.h" +#include "soh/cvar_prefixes.h" #ifndef __WIIU__ #include "controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.h" #endif @@ -83,7 +84,7 @@ void SohInputEditorWindow::UpdateElement() { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->BlockImGuiGamepadNavigation(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->BlockGamepadNavigation(); } else { if (mGameInputBlockTimer != INT32_MAX) { mGameInputBlockTimer--; @@ -94,13 +95,13 @@ void SohInputEditorWindow::UpdateElement() { } } - if (Ship::Context::GetInstance()->GetWindow()->GetGui()->ImGuiGamepadNavigationEnabled()) { + if (Ship::Context::GetInstance()->GetWindow()->GetGui()->GamepadNavigationEnabled()) { mMappingInputBlockTimer = ImGui::GetIO().Framerate / 3; } else { mMappingInputBlockTimer = INT32_MAX; } - Ship::Context::GetInstance()->GetWindow()->GetGui()->UnblockImGuiGamepadNavigation(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->UnblockGamepadNavigation(); } } @@ -297,7 +298,7 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt ImGui::OpenPopup(popupId.c_str()); } if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay)) { - ImGui::SetTooltip(mapping->GetPhysicalDeviceName().c_str()); + ImGui::SetTooltip("%s", mapping->GetPhysicalDeviceName().c_str()); } ImGui::PopStyleColor(); ImGui::PopStyleColor(); @@ -571,7 +572,7 @@ void SohInputEditorWindow::DrawStickDirectionLineEditMappingButton(uint8_t port, ImGui::OpenPopup(popupId.c_str()); } if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay)) { - ImGui::SetTooltip(mapping->GetPhysicalDeviceName().c_str()); + ImGui::SetTooltip("%s", mapping->GetPhysicalDeviceName().c_str()); } ImGui::PopStyleColor(); ImGui::PopStyleColor(); @@ -1108,7 +1109,7 @@ void SohInputEditorWindow::DrawLEDSection(uint8_t port) { color.b = colorVec.z * 255.0; CVarSetColor24(CVAR_SETTING("LEDPort1Color"), color); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); ImGui::Text("Custom Color"); @@ -1178,7 +1179,7 @@ void SohInputEditorWindow::DrawGyroSection(uint8_t port) { auto id = mapping->GetGyroMappingId(); ImGui::AlignTextToFramePadding(); ImGui::SetNextItemOpen(true, ImGuiCond_Once); - ImGui::BulletText(mapping->GetPhysicalDeviceName().c_str()); + ImGui::BulletText("%s", mapping->GetPhysicalDeviceName().c_str()); DrawRemoveGyroMappingButton(port, id); static float sPitch, sYaw = 0.0f; @@ -1303,7 +1304,7 @@ void SohInputEditorWindow::DrawButtonDeviceIcons(uint8_t portIndex, std::set allLusDeviceIndices; allLusDeviceIndices.insert(Ship::ShipDeviceIndex::Keyboard); for (auto [lusIndex, mapping] : Ship::Context::GetInstance() @@ -1316,7 +1317,7 @@ void SohInputEditorWindow::DrawAnalogStickDeviceIcons(uint8_t portIndex, Ship::S std::vector> lusDeviceIndiciesWithMappings; for (auto lusIndex : allLusDeviceIndices) { auto controllerStick = - stick == Ship::Stick::LEFT_STICK + stickIndex == Ship::StickIndex::LEFT_STICK ? Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetLeftStick() : Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetRightStick(); if (controllerStick->HasMappingsForShipDeviceIndex(lusIndex)) { @@ -1524,7 +1525,7 @@ void SohInputEditorWindow::DrawMapping(CustomButtonMap& mapping, float labelWidt } if (ImGui::Selectable(i->second, i->first == currentButton)) { CVarSetInteger(mapping.cVarName, i->first); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } ImGui::EndCombo(); @@ -1534,8 +1535,10 @@ void SohInputEditorWindow::DrawMapping(CustomButtonMap& mapping, float labelWidt void SohInputEditorWindow::DrawOcarinaControlPanel() { ImVec2 cursor = ImGui::GetCursorPos(); - ImGui::SetCursorPos(ImVec2(cursor.x + 24, cursor.y + 5)); - + ImGui::SetCursorPos(ImVec2(cursor.x, cursor.y + 5)); + + UIWidgets::EnhancementCheckbox("Dpad Ocarina Playback", CVAR_SETTING("CustomOcarina.Dpad")); + UIWidgets::EnhancementCheckbox("Right Stick Ocarina Playback", CVAR_SETTING("CustomOcarina.RightStick")); UIWidgets::EnhancementCheckbox("Customize Ocarina Controls", CVAR_SETTING("CustomOcarina.Enabled")); if (!CVarGetInteger(CVAR_SETTING("CustomOcarina.Enabled"), 0)) { @@ -1578,10 +1581,10 @@ void SohInputEditorWindow::DrawCameraControlPanel() { UIWidgets::Tooltip("Inverts the Camera X Axis in:\n-First-Person/C-Up view\n-Weapon Aiming"); UIWidgets::PaddedEnhancementCheckbox("Invert Aiming Y Axis", CVAR_SETTING("Controls.InvertAimingYAxis"), true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true); UIWidgets::Tooltip("Inverts the Camera Y Axis in:\n-First-Person/C-Up view\n-Weapon Aiming"); - UIWidgets::PaddedEnhancementCheckbox("Invert Shield Aiming Y Axis", CVAR_SETTING("Controls.InvertShieldAimingYAxis"), true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true); - UIWidgets::Tooltip("Inverts the Shield Aiming Y Axis"); - UIWidgets::PaddedEnhancementCheckbox("Invert Shield Aiming X Axis", CVAR_SETTING("Controls.InvertShieldAimingYAxis")); + UIWidgets::PaddedEnhancementCheckbox("Invert Shield Aiming X Axis", CVAR_SETTING("Controls.InvertShieldAimingXAxis"), true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true); UIWidgets::Tooltip("Inverts the Shield Aiming X Axis"); + UIWidgets::PaddedEnhancementCheckbox("Invert Shield Aiming Y Axis", CVAR_SETTING("Controls.InvertShieldAimingYAxis")); + UIWidgets::Tooltip("Inverts the Shield Aiming Y Axis"); UIWidgets::PaddedEnhancementCheckbox("Invert Z-Weapon Aiming Y Axis", CVAR_SETTING("Controls.InvertZAimingYAxis"), true, true, false, "", UIWidgets::CheckboxGraphics::Cross, true); UIWidgets::Tooltip("Inverts the Camera Y Axis in:\n-Z-Weapon Aiming"); UIWidgets::PaddedEnhancementCheckbox("Disable Auto-Centering in First-Person View", CVAR_SETTING("DisableFirstPersonAutoCenterView")); diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.h b/soh/soh/Enhancements/controls/SohInputEditorWindow.h index 1b38e8f28..ee0942902 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.h +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.h @@ -96,7 +96,7 @@ class SohInputEditorWindow : public Ship::GuiWindow { std::set mModifierButtonsBitmasks; std::set mCustomOcarinaButtonsBitmasks; void DrawButtonDeviceIcons(uint8_t portIndex, std::set bitmasks); - void DrawAnalogStickDeviceIcons(uint8_t portIndex, Ship::Stick stick); + void DrawAnalogStickDeviceIcons(uint8_t portIndex, Ship::StickIndex stickIndex); void DrawRumbleDeviceIcons(uint8_t portIndex); void DrawGyroDeviceIcons(uint8_t portIndex); void DrawLEDDeviceIcons(uint8_t portIndex); diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 4f54e4645..6274de469 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -8,17 +8,16 @@ #include #include #include -#include -#include "soh/Enhancements/randomizer/3drando/random.hpp" #include #include "soh/UIWidgets.hpp" #include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" extern "C" { -#include +#include "z64.h" #include "macros.h" -extern PlayState* gPlayState; +#include "soh/cvar_prefixes.h" #include "objects/object_link_boy/object_link_boy.h" #include "objects/object_link_child/object_link_child.h" #include "objects/object_gi_shield_3/object_gi_shield_3.h" @@ -48,34 +47,46 @@ extern PlayState* gPlayState; #include "objects/object_gjyo_objects/object_gjyo_objects.h" #include "textures/nintendo_rogo_static/nintendo_rogo_static.h" #include "objects/object_gi_rabit_mask/object_gi_rabit_mask.h" +#include "overlays/ovl_Boss_Ganon2/ovl_Boss_Ganon2.h" +#include "overlays/ovl_Magic_Wind/ovl_Magic_Wind.h" +#include "textures/nintendo_rogo_static/nintendo_rogo_static.h" +extern PlayState* gPlayState; void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction); void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex, int sourceIndex); void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName); u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); } +#define PATCH_GFX(path, name, cvar, index, instruction) \ + if (CVarGetInteger(cvar, 0)) { \ + ResourceMgr_PatchGfxByName(path, name, index, instruction); \ + } else { \ + ResourceMgr_UnpatchGfxByName(path, name); \ + } + // This is used for the greg bridge #define dgEndGrayscaleAndEndDlistDL "__OTR__helpers/cosmetics/gEndGrayscaleAndEndDlistDL" static const ALIGN_ASSET(2) char gEndGrayscaleAndEndDlistDL[] = dgEndGrayscaleAndEndDlistDL; std::map groupLabels = { - { COSMETICS_GROUP_LINK, "Link" }, + { COSMETICS_GROUP_LINK, "Link" }, { COSMETICS_GROUP_MIRRORSHIELD, "Mirror Shield" }, - { COSMETICS_GROUP_SWORDS, "Swords" }, - { COSMETICS_GROUP_GLOVES, "Gloves" }, - { COSMETICS_GROUP_EQUIPMENT, "Equipment" }, - { COSMETICS_GROUP_CONSUMABLE, "Consumables" }, - { COSMETICS_GROUP_HUD, "HUD" }, - { COSMETICS_GROUP_KALEIDO, "Pause Menu" }, - { COSMETICS_GROUP_TITLE, "Title Screen" }, - { COSMETICS_GROUP_NPC, "NPCs" }, - { COSMETICS_GROUP_WORLD, "World" }, - { COSMETICS_GROUP_MAGIC, "Magic Effects" }, - { COSMETICS_GROUP_ARROWS, "Arrow Effects" }, - { COSMETICS_GROUP_SPIN_ATTACK, "Spin Attack" }, - { COSMETICS_GROUP_TRAILS, "Trails" }, - { COSMETICS_GROUP_NAVI, "Navi" }, - { COSMETICS_GROUP_IVAN, "Ivan" } + { COSMETICS_GROUP_SWORDS, "Swords" }, + { COSMETICS_GROUP_GLOVES, "Gloves" }, + { COSMETICS_GROUP_EQUIPMENT, "Equipment" }, + { COSMETICS_GROUP_CONSUMABLE, "Consumables" }, + { COSMETICS_GROUP_HUD, "HUD" }, + { COSMETICS_GROUP_KALEIDO, "Pause Menu" }, + { COSMETICS_GROUP_TITLE, "Title Screen" }, + { COSMETICS_GROUP_NPC, "NPCs" }, + { COSMETICS_GROUP_WORLD, "World" }, + { COSMETICS_GROUP_MAGIC, "Magic Effects" }, + { COSMETICS_GROUP_ARROWS, "Arrow Effects" }, + { COSMETICS_GROUP_SPIN_ATTACK, "Spin Attack" }, + { COSMETICS_GROUP_TRAILS, "Trails" }, + { COSMETICS_GROUP_NAVI, "Navi" }, + { COSMETICS_GROUP_IVAN, "Ivan" }, + { COSMETICS_GROUP_MESSAGE, "Message" }, }; typedef struct { @@ -86,17 +97,22 @@ typedef struct { std::string label; CosmeticGroup group; ImVec4 currentColor; - ImVec4 defaultColor; + Color_RGBA8 defaultColor; bool supportsAlpha; bool supportsRainbow; bool advancedOption; } CosmeticOption; -#define COSMETIC_OPTION(id, label, group, defaultColor, supportsAlpha, supportsRainbow, advancedOption) \ - { id, { \ +Color_RGBA8 ColorRGBA8(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { + Color_RGBA8 color = { r, g, b, a }; + return color; +} + +#define COSMETIC_OPTION(id, label, group, defaultColor, supportsAlpha, supportsRainbow, advancedOption) \ + { id, { \ CVAR_COSMETIC(id ".Value"), CVAR_COSMETIC(id ".Rainbow"), CVAR_COSMETIC(id ".Locked"), CVAR_COSMETIC(id ".Changed"), label, group, \ - defaultColor, defaultColor, \ - supportsAlpha, supportsRainbow, advancedOption \ + ImVec4(defaultColor.r / 255.0f, defaultColor.g / 255.0f, defaultColor.b / 255.0f, defaultColor.a / 255.0f), defaultColor, \ + supportsAlpha, supportsRainbow, advancedOption \ } } /* @@ -107,7 +123,7 @@ typedef struct { # Silly Options Lets get this one out of the way, probably the only thing that will be consistent between silly options is how they are rendered on the ImGui tab. So when adding one just make sure it follows the same general pattern as the rest. Notably: - - Make sure to SaveConsoleVariablesOnNextTick(), forgetting this will not persist your changes + - Make sure to SaveConsoleVariablesNextFrame(), forgetting this will not persist your changes - Make sure reset properly resets the value - Depending on your use case you may or may not have to split the cvar into two values (cvar.Changed & cvar.Value) @@ -173,195 +189,250 @@ typedef struct { colors were darker than the gDPSetPrimColor. You will see many more examples of this below in the `ApplyOrResetCustomGfxPatches` method */ static std::map cosmeticOptions = { - COSMETIC_OPTION("Link.KokiriTunic", "Kokiri Tunic", COSMETICS_GROUP_LINK, ImVec4( 30, 105, 27, 255), false, true, false), - COSMETIC_OPTION("Link.GoronTunic", "Goron Tunic", COSMETICS_GROUP_LINK, ImVec4(100, 20, 0, 255), false, true, false), - COSMETIC_OPTION("Link.ZoraTunic", "Zora Tunic", COSMETICS_GROUP_LINK, ImVec4( 0, 60, 100, 255), false, true, false), - COSMETIC_OPTION("Link.Hair", "Hair", COSMETICS_GROUP_LINK, ImVec4(255, 173, 27, 255), false, true, true), - COSMETIC_OPTION("Link.Linen", "Linen", COSMETICS_GROUP_LINK, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Link.Boots", "Boots", COSMETICS_GROUP_LINK, ImVec4( 93, 44, 18, 255), false, true, true), + COSMETIC_OPTION("Link.KokiriTunic", "Kokiri Tunic", COSMETICS_GROUP_LINK, ColorRGBA8( 30, 105, 27, 255), false, true, false), + COSMETIC_OPTION("Link.GoronTunic", "Goron Tunic", COSMETICS_GROUP_LINK, ColorRGBA8(100, 20, 0, 255), false, true, false), + COSMETIC_OPTION("Link.ZoraTunic", "Zora Tunic", COSMETICS_GROUP_LINK, ColorRGBA8( 0, 60, 100, 255), false, true, false), + COSMETIC_OPTION("Link.Hair", "Hair", COSMETICS_GROUP_LINK, ColorRGBA8(255, 173, 27, 255), false, true, true), + COSMETIC_OPTION("Link.Linen", "Linen", COSMETICS_GROUP_LINK, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Link.Boots", "Boots", COSMETICS_GROUP_LINK, ColorRGBA8( 93, 44, 18, 255), false, true, true), - COSMETIC_OPTION("MirrorShield.Body", "Body", COSMETICS_GROUP_MIRRORSHIELD, ImVec4(215, 0, 0, 255), false, true, false), - COSMETIC_OPTION("MirrorShield.Mirror", "Mirror", COSMETICS_GROUP_MIRRORSHIELD, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("MirrorShield.Emblem", "Emblem", COSMETICS_GROUP_MIRRORSHIELD, ImVec4(205, 225, 255, 255), false, true, true), + COSMETIC_OPTION("MirrorShield.Body", "Body", COSMETICS_GROUP_MIRRORSHIELD, ColorRGBA8(215, 0, 0, 255), false, true, false), + COSMETIC_OPTION("MirrorShield.Mirror", "Mirror", COSMETICS_GROUP_MIRRORSHIELD, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("MirrorShield.Emblem", "Emblem", COSMETICS_GROUP_MIRRORSHIELD, ColorRGBA8(205, 225, 255, 255), false, true, true), - COSMETIC_OPTION("Swords.KokiriBlade", "Kokiri Sword Blade", COSMETICS_GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false), - // COSMETIC_OPTION("Swords.KokiriHilt", "Kokiri Sword Hilt", COSMETICS_GROUP_SWORDS, ImVec4(160, 100, 15, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale - COSMETIC_OPTION("Swords.MasterBlade", "Master Sword Blade", COSMETICS_GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false), - // COSMETIC_OPTION("Swords.MasterHilt", "Master Sword Hilt", COSMETICS_GROUP_SWORDS, ImVec4( 80, 80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale - COSMETIC_OPTION("Swords.BiggoronBlade", "Biggoron Sword Blade", COSMETICS_GROUP_SWORDS, ImVec4(255, 255, 255, 255), false, true, false), - // COSMETIC_OPTION("Swords.BiggoronHilt", "Biggoron Sword Hilt", COSMETICS_GROUP_SWORDS, ImVec4( 80, 80, 168, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale + COSMETIC_OPTION("Swords.KokiriBlade", "Kokiri Sword Blade", COSMETICS_GROUP_SWORDS, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Swords.MasterBlade", "Master Sword Blade", COSMETICS_GROUP_SWORDS, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Swords.BiggoronBlade", "Biggoron Sword Blade", COSMETICS_GROUP_SWORDS, ColorRGBA8(255, 255, 255, 255), false, true, false), + /* Todo (Cosmetics): Broken, need a better way to grayscale + COSMETIC_OPTION("Swords.KokiriHilt", "Kokiri Sword Hilt", COSMETICS_GROUP_SWORDS, ColorRGBA8(160, 100, 15, 255), false, true, true), + COSMETIC_OPTION("Swords.MasterHilt", "Master Sword Hilt", COSMETICS_GROUP_SWORDS, ColorRGBA8( 80, 80, 168, 255), false, true, true), + COSMETIC_OPTION("Swords.BiggoronHilt", "Biggoron Sword Hilt", COSMETICS_GROUP_SWORDS, ColorRGBA8( 80, 80, 168, 255), false, true, true), + */ - COSMETIC_OPTION("Gloves.GoronBracelet", "Goron Bracelet", COSMETICS_GROUP_GLOVES, ImVec4(255, 255, 170, 255), false, true, false), - COSMETIC_OPTION("Gloves.SilverGauntlets", "Silver Gauntlets", COSMETICS_GROUP_GLOVES, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Gloves.GoldenGauntlets", "Golden Gauntlets", COSMETICS_GROUP_GLOVES, ImVec4(254, 207, 15, 255), false, true, false), - COSMETIC_OPTION("Gloves.GauntletsGem", "Gauntlets Gem", COSMETICS_GROUP_GLOVES, ImVec4(255, 60, 100, 255), false, true, true), + COSMETIC_OPTION("Gloves.GoronBracelet", "Goron Bracelet", COSMETICS_GROUP_GLOVES, ColorRGBA8(255, 255, 170, 255), false, true, false), + COSMETIC_OPTION("Gloves.SilverGauntlets", "Silver Gauntlets", COSMETICS_GROUP_GLOVES, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Gloves.GoldenGauntlets", "Golden Gauntlets", COSMETICS_GROUP_GLOVES, ColorRGBA8(254, 207, 15, 255), false, true, false), + COSMETIC_OPTION("Gloves.GauntletsGem", "Gauntlets Gem", COSMETICS_GROUP_GLOVES, ColorRGBA8(255, 60, 100, 255), false, true, true), - COSMETIC_OPTION("Equipment.BoomerangBody", "Boomerang Body", COSMETICS_GROUP_EQUIPMENT, ImVec4(160, 100, 0, 255), false, true, false), - COSMETIC_OPTION("Equipment.BoomerangGem", "Boomerang Gem", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 50, 150, 255), false, true, true), - // COSMETIC_OPTION("Equipment.SlingshotBody", "Slingshot Body", COSMETICS_GROUP_EQUIPMENT, ImVec4(160, 100, 0, 255), false, true, true), // Todo (Cosmetics): Broken, need a better way to grayscale - COSMETIC_OPTION("Equipment.SlingshotString", "Slingshot String", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Equipment.HammerHead", "Hammer Head", COSMETICS_GROUP_EQUIPMENT, ImVec4(155, 192, 201, 255), false, true, false), - COSMETIC_OPTION("Equipment.HammerHandle", "Hammer Handle", COSMETICS_GROUP_EQUIPMENT, ImVec4(110, 60, 0, 255), false, true, true), - // COSMETIC_OPTION("Equipment.HookshotChain", "Hookshot Chain", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Implement - // COSMETIC_OPTION("Equipment.HookshotTip", "Hookshot Tip", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Implement - COSMETIC_OPTION("HookshotReticle.Target", "Hookshotable Reticle", COSMETICS_GROUP_EQUIPMENT, ImVec4( 0, 255, 0, 255), false, false, false), - COSMETIC_OPTION("HookshotReticle.NonTarget", "Non-Hookshotable Reticle", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 0, 0, 255), false, false, false), - COSMETIC_OPTION("Equipment.BowTips", "Bow Tips", COSMETICS_GROUP_EQUIPMENT, ImVec4(200, 0, 0, 255), false, true, true), - COSMETIC_OPTION("Equipment.BowString", "Bow String", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Equipment.BowBody", "Bow Body", COSMETICS_GROUP_EQUIPMENT, ImVec4(140, 90, 10, 255), false, true, false), - COSMETIC_OPTION("Equipment.BowHandle", "Bow Handle", COSMETICS_GROUP_EQUIPMENT, ImVec4( 50, 150, 255, 255), false, true, true), - COSMETIC_OPTION("Equipment.ChuFace", "Bombchu Face", COSMETICS_GROUP_EQUIPMENT, ImVec4( 0, 100, 150, 255), false, true, true), - COSMETIC_OPTION("Equipment.ChuBody", "Bombchu Body", COSMETICS_GROUP_EQUIPMENT, ImVec4(180, 130, 50, 255), false, true, true), - COSMETIC_OPTION("Equipment.BunnyHood", "Bunny Hood", COSMETICS_GROUP_EQUIPMENT, ImVec4(255, 235, 109, 255), false, true, true), + COSMETIC_OPTION("Equipment.BoomerangBody", "Boomerang Body", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(160, 100, 0, 255), false, true, false), + COSMETIC_OPTION("Equipment.BoomerangGem", "Boomerang Gem", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(255, 50, 150, 255), false, true, true), + /* Todo (Cosmetics): Broken, need a better way to grayscale + COSMETIC_OPTION("Equipment.SlingshotBody", "Slingshot Body", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(160, 100, 0, 255), false, true, true), + */ + COSMETIC_OPTION("Equipment.SlingshotString", "Slingshot String", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Equipment.HammerHead", "Hammer Head", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(155, 192, 201, 255), false, true, false), + COSMETIC_OPTION("Equipment.HammerHandle", "Hammer Handle", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(110, 60, 0, 255), false, true, true), + COSMETIC_OPTION("Equipment.HookshotChain", "Hookshot Chain", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(255, 255, 255, 255), false, true, true), + /* Todo (Cosmetics): Implement + COSMETIC_OPTION("Equipment.HookshotTip", "Hookshot Tip", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(255, 255, 255, 255), false, true, false), + */ + COSMETIC_OPTION("HookshotReticle.Target", "Hookshotable Reticle", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8( 0, 255, 0, 255), false, true, false), + COSMETIC_OPTION("HookshotReticle.NonTarget", "Non-Hookshotable Reticle", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(255, 0, 0, 255), false, true, false), + COSMETIC_OPTION("Equipment.BowTips", "Bow Tips", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(200, 0, 0, 255), false, true, true), + COSMETIC_OPTION("Equipment.BowString", "Bow String", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Equipment.BowBody", "Bow Body", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(140, 90, 10, 255), false, true, false), + COSMETIC_OPTION("Equipment.BowHandle", "Bow Handle", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8( 50, 150, 255, 255), false, true, true), + COSMETIC_OPTION("Equipment.ChuFace", "Bombchu Face", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8( 0, 100, 150, 255), false, true, true), + COSMETIC_OPTION("Equipment.ChuBody", "Bombchu Body", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(180, 130, 50, 255), false, true, true), + COSMETIC_OPTION("Equipment.BunnyHood", "Bunny Hood", COSMETICS_GROUP_EQUIPMENT, ColorRGBA8(255, 235, 109, 255), false, true, true), - COSMETIC_OPTION("Consumable.Hearts", "Hearts", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 70, 50, 255), false, true, false), - COSMETIC_OPTION("Consumable.HeartBorder", "Heart Border", COSMETICS_GROUP_CONSUMABLE, ImVec4( 50, 40, 60, 255), false, true, true), - COSMETIC_OPTION("Consumable.DDHearts", "DD Hearts", COSMETICS_GROUP_CONSUMABLE, ImVec4(200, 0, 0, 255), false, true, false), - 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), - COSMETIC_OPTION("Consumable.BlueRupee", "Blue Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4( 50, 50, 255, 255), false, true, true), - COSMETIC_OPTION("Consumable.RedRupee", "Red Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 50, 50, 255), false, true, true), - COSMETIC_OPTION("Consumable.PurpleRupee", "Purple Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4(150, 50, 255, 255), false, true, true), - COSMETIC_OPTION("Consumable.GoldRupee", "Gold Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 190, 55, 255), false, true, true), - COSMETIC_OPTION("Consumable.SilverRupee", "Silver Rupee", COSMETICS_GROUP_CONSUMABLE, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Consumable.Hearts", "Hearts", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(255, 70, 50, 255), false, true, false), + COSMETIC_OPTION("Consumable.HeartBorder", "Heart Border", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8( 50, 40, 60, 255), false, true, true), + COSMETIC_OPTION("Consumable.DDHearts", "DD Hearts", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(200, 0, 0, 255), false, true, false), + COSMETIC_OPTION("Consumable.DDHeartBorder", "DD Heart Border", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Consumable.Magic", "Magic", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8( 0, 200, 0, 255), false, true, false), + COSMETIC_OPTION("Consumable.MagicActive", "Magic Active", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(250, 250, 0, 255), false, true, true), + COSMETIC_OPTION("Consumable_MagicInfinite", "Infinite Magic", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8( 0, 0, 200, 255), false, true, true), + COSMETIC_OPTION("Consumable.MagicBorder", "Magic Border", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Consumable.MagicBorderActive", "Magic Border Active", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Consumable.GreenRupee", "Green Rupee", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8( 50, 255, 50, 255), false, true, true), + COSMETIC_OPTION("Consumable.BlueRupee", "Blue Rupee", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8( 50, 50, 255, 255), false, true, true), + COSMETIC_OPTION("Consumable.RedRupee", "Red Rupee", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(255, 50, 50, 255), false, true, true), + COSMETIC_OPTION("Consumable.PurpleRupee", "Purple Rupee", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(150, 50, 255, 255), false, true, true), + COSMETIC_OPTION("Consumable.GoldRupee", "Gold Rupee", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(255, 190, 55, 255), false, true, true), + COSMETIC_OPTION("Consumable.SilverRupee", "Silver Rupee", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("HUD.AButton", "A Button", COSMETICS_GROUP_HUD, ImVec4( 90, 90, 255, 255), false, true, false), - COSMETIC_OPTION("HUD.BButton", "B Button", COSMETICS_GROUP_HUD, ImVec4( 0, 150, 0, 255), false, true, false), - COSMETIC_OPTION("HUD.CButtons", "C Buttons", COSMETICS_GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, false), - COSMETIC_OPTION("HUD.CUpButton", "C Up Button", COSMETICS_GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), - COSMETIC_OPTION("HUD.CDownButton", "C Down Button", COSMETICS_GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), - COSMETIC_OPTION("HUD.CLeftButton", "C Left Button", COSMETICS_GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), - COSMETIC_OPTION("HUD.CRightButton", "C Right Button", COSMETICS_GROUP_HUD, ImVec4(255, 160, 0, 255), false, true, true), - COSMETIC_OPTION("HUD.StartButton", "Start Button", COSMETICS_GROUP_HUD, ImVec4(200, 0, 0, 255), false, true, false), - COSMETIC_OPTION("HUD.Dpad", "Dpad", COSMETICS_GROUP_HUD, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("HUD.KeyCount", "Key Count", COSMETICS_GROUP_HUD, ImVec4(200, 230, 255, 255), false, true, true), - COSMETIC_OPTION("HUD.StoneOfAgony", "Stone of Agony", COSMETICS_GROUP_HUD, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("HUD.Minimap", "Minimap", COSMETICS_GROUP_HUD, ImVec4( 0, 255, 255, 255), false, true, false), - COSMETIC_OPTION("HUD.MinimapPosition", "Minimap Position", COSMETICS_GROUP_HUD, ImVec4(200, 255, 0, 255), false, true, true), - COSMETIC_OPTION("HUD.MinimapEntrance", "Minimap Entrance", COSMETICS_GROUP_HUD, ImVec4(200, 0, 0, 255), false, true, true), - COSMETIC_OPTION("HUD.EnemyHealthBar", "Enemy Health Bar", COSMETICS_GROUP_HUD, ImVec4(255, 0, 0, 255), true, true, false), - COSMETIC_OPTION("HUD.EnemyHealthBorder", "Enemy Health Border", COSMETICS_GROUP_HUD, ImVec4(255, 255, 255, 255), true, false, true), - COSMETIC_OPTION("HUD.NameTagActorText", "Nametag Text", COSMETICS_GROUP_HUD, ImVec4(255, 255, 255, 255), true, true, false), - COSMETIC_OPTION("HUD.NameTagActorBackground", "Nametag Background", COSMETICS_GROUP_HUD, ImVec4(0, 0, 0, 80), true, false, true), - // Todo (Cosmetics): re-implement title card colors + COSMETIC_OPTION("HUD.AButton", "A Button", COSMETICS_GROUP_HUD, ColorRGBA8( 90, 90, 255, 255), false, true, false), + COSMETIC_OPTION("HUD.BButton", "B Button", COSMETICS_GROUP_HUD, ColorRGBA8( 0, 150, 0, 255), false, true, false), + COSMETIC_OPTION("HUD.CButtons", "C Buttons", COSMETICS_GROUP_HUD, ColorRGBA8(255, 160, 0, 255), false, true, false), + COSMETIC_OPTION("HUD.CUpButton", "C Up Button", COSMETICS_GROUP_HUD, ColorRGBA8(255, 160, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.CDownButton", "C Down Button", COSMETICS_GROUP_HUD, ColorRGBA8(255, 160, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.CLeftButton", "C Left Button", COSMETICS_GROUP_HUD, ColorRGBA8(255, 160, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.CRightButton", "C Right Button", COSMETICS_GROUP_HUD, ColorRGBA8(255, 160, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.StartButton", "Start Button", COSMETICS_GROUP_HUD, ColorRGBA8(200, 0, 0, 255), false, true, false), + COSMETIC_OPTION("HUD.Dpad", "Dpad", COSMETICS_GROUP_HUD, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("HUD.KeyCount", "Key Count", COSMETICS_GROUP_HUD, ColorRGBA8(200, 230, 255, 255), false, true, true), + COSMETIC_OPTION("HUD.StoneOfAgony", "Stone of Agony", COSMETICS_GROUP_HUD, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("HUD.Minimap", "Minimap", COSMETICS_GROUP_HUD, ColorRGBA8( 0, 255, 255, 255), false, true, false), + COSMETIC_OPTION("HUD.MinimapPosition", "Minimap Position", COSMETICS_GROUP_HUD, ColorRGBA8(200, 255, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.MinimapEntrance", "Minimap Entrance", COSMETICS_GROUP_HUD, ColorRGBA8(200, 0, 0, 255), false, true, true), + COSMETIC_OPTION("HUD.EnemyHealthBar", "Enemy Health Bar", COSMETICS_GROUP_HUD, ColorRGBA8(255, 0, 0, 255), true, true, false), + COSMETIC_OPTION("HUD.EnemyHealthBorder", "Enemy Health Border", COSMETICS_GROUP_HUD, ColorRGBA8(255, 255, 255, 255), true, true, true), + COSMETIC_OPTION("HUD.NameTagActorText", "Nametag Text", COSMETICS_GROUP_HUD, ColorRGBA8(255, 255, 255, 255), true, true, false), + COSMETIC_OPTION("HUD.NameTagActorBackground", "Nametag Background", COSMETICS_GROUP_HUD, ColorRGBA8( 0, 0, 0, 80), true, true, true), + COSMETIC_OPTION("HUD.TitleCard.Map", "Map Title Card", COSMETICS_GROUP_HUD, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("HUD.TitleCard.Boss", "Boss Title Card", COSMETICS_GROUP_HUD, ColorRGBA8(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Kaleido.ItemSelA", "Item Select Color", COSMETICS_GROUP_KALEIDO, ImVec4(10, 50, 80, 255), false, true, false), - COSMETIC_OPTION("Kaleido.ItemSelB", "Item Select Color B", COSMETICS_GROUP_KALEIDO, ImVec4(70, 100, 130, 255), false, true, true), - COSMETIC_OPTION("Kaleido.ItemSelC", "Item Select Color C", COSMETICS_GROUP_KALEIDO, ImVec4(70, 100, 130, 255), false, true, true), - COSMETIC_OPTION("Kaleido.ItemSelD", "Item Select Color D", COSMETICS_GROUP_KALEIDO, ImVec4(10, 50, 80, 255), false, true, true), + #define MESSAGE_COSMETIC_OPTION(id, label, r, g, b) COSMETIC_OPTION("Message." id, label, COSMETICS_GROUP_MESSAGE, ColorRGBA8(r, g, b, 255), false, true, true) - COSMETIC_OPTION("Kaleido.EquipSelA", "Equip Select Color", COSMETICS_GROUP_KALEIDO, ImVec4(10, 50, 40, 255), false, true, false), - COSMETIC_OPTION("Kaleido.EquipSelB", "Equip Select Color B", COSMETICS_GROUP_KALEIDO, ImVec4(90, 100, 60, 255), false, true, true), - COSMETIC_OPTION("Kaleido.EquipSelC", "Equip Select Color C", COSMETICS_GROUP_KALEIDO, ImVec4(90, 100, 60, 255), false, true, true), - COSMETIC_OPTION("Kaleido.EquipSelD", "Equip Select Color D", COSMETICS_GROUP_KALEIDO, ImVec4(10, 50, 80, 255), false, true, true), + MESSAGE_COSMETIC_OPTION("Default.Normal", "Message Default Color", 255, 255, 255), + MESSAGE_COSMETIC_OPTION("Default.NoneNoShadow", "Message Default (None No Shadow) Color", 0, 0, 0), + MESSAGE_COSMETIC_OPTION("Red.Normal", "Message Red Color", 255, 60, 60), + MESSAGE_COSMETIC_OPTION("Red.Wooden", "Message Red (Wooden) Color", 255, 120, 0), + MESSAGE_COSMETIC_OPTION("Adjustable.Normal", "Message Adjustable Color", 70, 255, 80), + MESSAGE_COSMETIC_OPTION("Adjustable.Wooden", "Message Adjustable (Wooden) Color", 70, 255, 80), + MESSAGE_COSMETIC_OPTION("Blue.Normal", "Message Blue Color", 80, 90, 255), + MESSAGE_COSMETIC_OPTION("Blue.Wooden", "Message Blue (Wooden) Color", 80, 110, 255), + MESSAGE_COSMETIC_OPTION("LightBlue.Normal", "Message Light Blue Color", 100, 180, 255), + MESSAGE_COSMETIC_OPTION("LightBlue.Wooden", "Message Light Blue (Wooden) Color", 90, 180, 255), + MESSAGE_COSMETIC_OPTION("LightBlue.LightBlue.NoneNoShadow", "Message Light Blue (None No Shadow) Color", 80, 150, 180), + MESSAGE_COSMETIC_OPTION("Purple.Normal", "Message Purple Color", 255, 150, 180), + MESSAGE_COSMETIC_OPTION("Purple.Wooden", "Message Purple (Wooden) Color", 210, 100, 255), + MESSAGE_COSMETIC_OPTION("Yellow.Normal", "Message Yellow Color", 255, 255, 50), + MESSAGE_COSMETIC_OPTION("Yellow.Wooden", "Message Yellow (Wooden) Color", 255, 255, 30), + MESSAGE_COSMETIC_OPTION("Black", "Message Black Color", 0, 0, 0), - COSMETIC_OPTION("Kaleido.MapSelDunA", "Map Dungeon Color", COSMETICS_GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, true), - COSMETIC_OPTION("Kaleido.MapSelDunB", "Map Dungeon Color B", COSMETICS_GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, true), - COSMETIC_OPTION("Kaleido.MapSelDunC", "Map Dungeon Color C", COSMETICS_GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, true), - COSMETIC_OPTION("Kaleido.MapSelDunD", "Map Dungeon Color D", COSMETICS_GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, true), + #undef MESSAGE_COSMETIC_OPTION - COSMETIC_OPTION("Kaleido.QuestStatusA", "Quest Status Color", COSMETICS_GROUP_KALEIDO, ImVec4(80, 80, 50, 255), false, true, false), - COSMETIC_OPTION("Kaleido.QuestStatusB", "Quest Status Color B", COSMETICS_GROUP_KALEIDO, ImVec4(120, 120, 70, 255), false, true, true), - COSMETIC_OPTION("Kaleido.QuestStatusC", "Quest Status Color C", COSMETICS_GROUP_KALEIDO, ImVec4(120, 120, 70, 255), false, true, true), - COSMETIC_OPTION("Kaleido.QuestStatusD", "Quest Status Color D", COSMETICS_GROUP_KALEIDO, ImVec4(80, 80, 50, 255), false, true, true), + COSMETIC_OPTION("Kaleido.ItemSelA", "Item Select Color", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 10, 50, 80, 255), false, true, false), + COSMETIC_OPTION("Kaleido.ItemSelB", "Item Select Color B", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 70, 100, 130, 255), false, true, true), + COSMETIC_OPTION("Kaleido.ItemSelC", "Item Select Color C", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 70, 100, 130, 255), false, true, true), + COSMETIC_OPTION("Kaleido.ItemSelD", "Item Select Color D", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 10, 50, 80, 255), false, true, true), - COSMETIC_OPTION("Kaleido.MapSelectA", "Map Color", COSMETICS_GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, false), - COSMETIC_OPTION("Kaleido.MapSelectB", "Map Color B", COSMETICS_GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, true), - COSMETIC_OPTION("Kaleido.MapSelectC", "Map Color C", COSMETICS_GROUP_KALEIDO, ImVec4(140, 60, 60, 255), false, true, true), - COSMETIC_OPTION("Kaleido.MapSelectD", "Map Color D", COSMETICS_GROUP_KALEIDO, ImVec4(80, 40, 30, 255), false, true, true), + COSMETIC_OPTION("Kaleido.EquipSelA", "Equip Select Color", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 10, 50, 40, 255), false, true, false), + COSMETIC_OPTION("Kaleido.EquipSelB", "Equip Select Color B", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 90, 100, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.EquipSelC", "Equip Select Color C", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 90, 100, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.EquipSelD", "Equip Select Color D", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 10, 50, 80, 255), false, true, true), - COSMETIC_OPTION("Kaleido.SaveA", "Save Color", COSMETICS_GROUP_KALEIDO, ImVec4(50, 50, 50, 255), false, true, false), - COSMETIC_OPTION("Kaleido.SaveB", "Save Color B", COSMETICS_GROUP_KALEIDO, ImVec4(110, 110, 110, 255), false, true, true), - COSMETIC_OPTION("Kaleido.SaveC", "Save Color C", COSMETICS_GROUP_KALEIDO, ImVec4(110, 110, 110, 255), false, true, true), - COSMETIC_OPTION("Kaleido.SaveD", "Save Color D", COSMETICS_GROUP_KALEIDO, ImVec4(50, 50, 50, 255), false, true, true), - - COSMETIC_OPTION("Kaleido.NamePanel", "Name Panel", COSMETICS_GROUP_KALEIDO, ImVec4(90,100,130,255), true, true, false), - - COSMETIC_OPTION("Title.FileChoose", "File Choose", COSMETICS_GROUP_TITLE, ImVec4(100, 150, 255, 255), false, true, false), - COSMETIC_OPTION("Title.NintendoLogo", "Nintendo Logo", COSMETICS_GROUP_TITLE, ImVec4( 0, 0, 255, 255), false, true, true), - COSMETIC_OPTION("Title.N64LogoRed", "N64 Red", COSMETICS_GROUP_TITLE, ImVec4(150, 0, 0, 255), false, true, true), - COSMETIC_OPTION("Title.N64LogoBlue", "N64 Blue", COSMETICS_GROUP_TITLE, ImVec4( 0, 50, 150, 255), false, true, true), - COSMETIC_OPTION("Title.N64LogoGreen", "N64 Green", COSMETICS_GROUP_TITLE, ImVec4( 50, 100, 0, 255), false, true, true), - COSMETIC_OPTION("Title.N64LogoYellow", "N64 Yellow", COSMETICS_GROUP_TITLE, ImVec4(200, 150, 0, 255), false, true, true), - // COSMETIC_OPTION("Title.FirePrimary", "Title Fire Primary", COSMETICS_GROUP_TITLE, ImVec4(255, 255, 170, 255), false, true, false), // Todo (Cosmetics): Kinda complicated - // COSMETIC_OPTION("Title.FireSecondary", "Title Fire Secondary", COSMETICS_GROUP_TITLE, ImVec4(255, 100, 0, 255), false, true, true), // Todo (Cosmetics): Kinda complicated - - COSMETIC_OPTION("Arrows.NormalPrimary", "Normal Primary", COSMETICS_GROUP_ARROWS, ImVec4( 0, 150, 0, 0), false, true, false), - COSMETIC_OPTION("Arrows.NormalSecondary", "Normal Secondary", COSMETICS_GROUP_ARROWS, ImVec4(255, 255, 170, 255), false, true, true), - COSMETIC_OPTION("Arrows.FirePrimary", "Fire Primary", COSMETICS_GROUP_ARROWS, ImVec4(255, 200, 0, 0), false, true, false), - COSMETIC_OPTION("Arrows.FireSecondary", "Fire Secondary", COSMETICS_GROUP_ARROWS, ImVec4(255, 0, 0, 255), false, true, true), - COSMETIC_OPTION("Arrows.IcePrimary", "Ice Primary", COSMETICS_GROUP_ARROWS, ImVec4( 0, 0, 255, 255), false, true, false), - COSMETIC_OPTION("Arrows.IceSecondary", "Ice Secondary", COSMETICS_GROUP_ARROWS, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Arrows.LightPrimary", "Light Primary", COSMETICS_GROUP_ARROWS, ImVec4(255, 255, 0, 255), false, true, false), - COSMETIC_OPTION("Arrows.LightSecondary", "Light Secondary", COSMETICS_GROUP_ARROWS, ImVec4(255, 255, 170, 0), false, true, true), - - // COSMETIC_OPTION("Magic.DinsPrimary", "Din's Primary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, false), - // COSMETIC_OPTION("Magic.DinsSecondary", "Din's Secondary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, true), - // COSMETIC_OPTION("Magic.FaroresPrimary", "Farore's Primary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, false), // Todo (Cosmetics): Implement - // COSMETIC_OPTION("Magic.FaroresSecondary", "Farore's Secondary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Implement - // COSMETIC_OPTION("Magic.NayrusPrimary", "Nayru's Primary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, false), - // COSMETIC_OPTION("Magic.NayrusSecondary", "Nayru's Secondary", COSMETICS_GROUP_MAGIC, ImVec4(255, 255, 255, 255), false, true, true), - - COSMETIC_OPTION("SpinAttack.Level1Primary", "Level 1 Primary", COSMETICS_GROUP_SPIN_ATTACK, ImVec4(170, 255, 255, 255), false, true, true), - COSMETIC_OPTION("SpinAttack.Level1Secondary", "Level 1 Secondary", COSMETICS_GROUP_SPIN_ATTACK, ImVec4( 0, 100, 255, 255), false, true, false), - COSMETIC_OPTION("SpinAttack.Level2Primary", "Level 2 Primary", COSMETICS_GROUP_SPIN_ATTACK, ImVec4(255, 255, 170, 255), false, true, true), - COSMETIC_OPTION("SpinAttack.Level2Secondary", "Level 2 Secondary", COSMETICS_GROUP_SPIN_ATTACK, ImVec4(255, 100, 0, 255), false, true, false), - - COSMETIC_OPTION("Trails.Bombchu", "Bombchu", COSMETICS_GROUP_TRAILS, ImVec4(250, 0, 0, 255), false, true, true), - COSMETIC_OPTION("Trails.Boomerang", "Boomerang", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 100, 255), false, true, true), - COSMETIC_OPTION("Trails.KokiriSword", "Kokiri Sword", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Trails.MasterSword", "Master Sword", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Trails.BiggoronSword", "Biggoron Sword", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Trails.Stick", "Stick", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("Trails.Hammer", "Hammer", COSMETICS_GROUP_TRAILS, ImVec4(255, 255, 255, 255), false, true, true), - - COSMETIC_OPTION("World.BlockOfTime", "Block of Time", COSMETICS_GROUP_WORLD, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("World.Moon", "Moon", COSMETICS_GROUP_WORLD, ImVec4(240, 255, 180, 255), false, true, true), - COSMETIC_OPTION("World.GossipStone", "Gossip Stone", COSMETICS_GROUP_WORLD, ImVec4(200, 200, 200, 255), false, true, true), - COSMETIC_OPTION("World.RedIce", "Red Ice", COSMETICS_GROUP_WORLD, ImVec4(255, 0, 0, 255), false, true, false), - COSMETIC_OPTION("World.MysteryItem", "Mystery Item", COSMETICS_GROUP_WORLD, ImVec4(0, 60, 100, 255), false, true, false), - - COSMETIC_OPTION("Navi.IdlePrimary", "Idle Primary", COSMETICS_GROUP_NAVI, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Navi.IdleSecondary", "Idle Secondary", COSMETICS_GROUP_NAVI, ImVec4( 0, 0, 255, 0), false, true, true), - COSMETIC_OPTION("Navi.NPCPrimary", "NPC Primary", COSMETICS_GROUP_NAVI, ImVec4(150, 150, 255, 255), false, true, false), - COSMETIC_OPTION("Navi.NPCSecondary", "NPC Secondary", COSMETICS_GROUP_NAVI, ImVec4(150, 150, 255, 0), false, true, true), - COSMETIC_OPTION("Navi.EnemyPrimary", "Enemy Primary", COSMETICS_GROUP_NAVI, ImVec4(255, 255, 0, 255), false, true, false), - COSMETIC_OPTION("Navi.EnemySecondary", "Enemy Secondary", COSMETICS_GROUP_NAVI, ImVec4(200, 155, 0, 0), false, true, true), - COSMETIC_OPTION("Navi.PropsPrimary", "Props Primary", COSMETICS_GROUP_NAVI, ImVec4( 0, 255, 0, 255), false, true, false), - COSMETIC_OPTION("Navi.PropsSecondary", "Props Secondary", COSMETICS_GROUP_NAVI, ImVec4( 0, 255, 0, 0), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelDunA", "Map Dungeon Color", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 80, 40, 30, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelDunB", "Map Dungeon Color B", COSMETICS_GROUP_KALEIDO, ColorRGBA8(140, 60, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelDunC", "Map Dungeon Color C", COSMETICS_GROUP_KALEIDO, ColorRGBA8(140, 60, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelDunD", "Map Dungeon Color D", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 80, 40, 30, 255), false, true, true), - COSMETIC_OPTION("Ivan.IdlePrimary", "Ivan Idle Primary", COSMETICS_GROUP_IVAN, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("Ivan.IdleSecondary", "Ivan Idle Secondary", COSMETICS_GROUP_IVAN, ImVec4( 0, 255, 0, 255), false, true, true), + COSMETIC_OPTION("Kaleido.QuestStatusA", "Quest Status Color", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 80, 80, 50, 255), false, true, false), + COSMETIC_OPTION("Kaleido.QuestStatusB", "Quest Status Color B", COSMETICS_GROUP_KALEIDO, ColorRGBA8(120, 120, 70, 255), false, true, true), + COSMETIC_OPTION("Kaleido.QuestStatusC", "Quest Status Color C", COSMETICS_GROUP_KALEIDO, ColorRGBA8(120, 120, 70, 255), false, true, true), + COSMETIC_OPTION("Kaleido.QuestStatusD", "Quest Status Color D", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 80, 80, 50, 255), false, true, true), - COSMETIC_OPTION("NPC.FireKeesePrimary", "Fire Keese Primary", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("NPC.FireKeeseSecondary", "Fire Keese Secondary", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("NPC.IceKeesePrimary", "Ice Keese Primary", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("NPC.IceKeeseSecondary", "Ice Keese Secondary", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelectA", "Map Color", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 80, 40, 30, 255), false, true, false), + COSMETIC_OPTION("Kaleido.MapSelectB", "Map Color B", COSMETICS_GROUP_KALEIDO, ColorRGBA8(140, 60, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelectC", "Map Color C", COSMETICS_GROUP_KALEIDO, ColorRGBA8(140, 60, 60, 255), false, true, true), + COSMETIC_OPTION("Kaleido.MapSelectD", "Map Color D", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 80, 40, 30, 255), false, true, true), + + COSMETIC_OPTION("Kaleido.SaveA", "Save Color", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 50, 50, 50, 255), false, true, false), + COSMETIC_OPTION("Kaleido.SaveB", "Save Color B", COSMETICS_GROUP_KALEIDO, ColorRGBA8(110, 110, 110, 255), false, true, true), + COSMETIC_OPTION("Kaleido.SaveC", "Save Color C", COSMETICS_GROUP_KALEIDO, ColorRGBA8(110, 110, 110, 255), false, true, true), + COSMETIC_OPTION("Kaleido.SaveD", "Save Color D", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 50, 50, 50, 255), false, true, true), + + COSMETIC_OPTION("Kaleido.NamePanel", "Name Panel", COSMETICS_GROUP_KALEIDO, ColorRGBA8( 90, 100, 130, 255), true, true, false), + + COSMETIC_OPTION("Title.FileChoose", "File Choose", COSMETICS_GROUP_TITLE, ColorRGBA8(100, 150, 255, 255), false, true, false), + COSMETIC_OPTION("Title.NintendoLogo", "Nintendo Logo", COSMETICS_GROUP_TITLE, ColorRGBA8( 0, 0, 255, 255), false, true, true), + COSMETIC_OPTION("Title.N64LogoRed", "N64 Red", COSMETICS_GROUP_TITLE, ColorRGBA8(150, 0, 0, 255), false, true, true), + COSMETIC_OPTION("Title.N64LogoBlue", "N64 Blue", COSMETICS_GROUP_TITLE, ColorRGBA8( 0, 50, 150, 255), false, true, true), + COSMETIC_OPTION("Title.N64LogoGreen", "N64 Green", COSMETICS_GROUP_TITLE, ColorRGBA8( 50, 100, 0, 255), false, true, true), + COSMETIC_OPTION("Title.N64LogoYellow", "N64 Yellow", COSMETICS_GROUP_TITLE, ColorRGBA8(200, 150, 0, 255), false, true, true), + + /* Todo (Cosmetics): Kinda complicated + COSMETIC_OPTION("Title.FirePrimary", "Title Fire Primary", COSMETICS_GROUP_TITLE, ColorRGBA8(255, 255, 170, 255), false, true, false), + COSMETIC_OPTION("Title.FireSecondary", "Title Fire Secondary", COSMETICS_GROUP_TITLE, ColorRGBA8(255, 100, 0, 255), false, true, true), + */ + COSMETIC_OPTION("Title.Copyright", "Copyright Text", COSMETICS_GROUP_TITLE, ColorRGBA8(255, 255, 255, 255), true, true, false), + + COSMETIC_OPTION("Arrows.NormalPrimary", "Normal Primary", COSMETICS_GROUP_ARROWS, ColorRGBA8( 0, 150, 0, 0), false, true, false), + COSMETIC_OPTION("Arrows.NormalSecondary", "Normal Secondary", COSMETICS_GROUP_ARROWS, ColorRGBA8(255, 255, 170, 255), false, true, true), + COSMETIC_OPTION("Arrows.FirePrimary", "Fire Primary", COSMETICS_GROUP_ARROWS, ColorRGBA8(255, 200, 0, 0), false, true, false), + COSMETIC_OPTION("Arrows.FireSecondary", "Fire Secondary", COSMETICS_GROUP_ARROWS, ColorRGBA8(255, 0, 0, 255), false, true, true), + COSMETIC_OPTION("Arrows.IcePrimary", "Ice Primary", COSMETICS_GROUP_ARROWS, ColorRGBA8( 0, 0, 255, 255), false, true, false), + COSMETIC_OPTION("Arrows.IceSecondary", "Ice Secondary", COSMETICS_GROUP_ARROWS, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Arrows.LightPrimary", "Light Primary", COSMETICS_GROUP_ARROWS, ColorRGBA8(255, 255, 0, 255), false, true, false), + COSMETIC_OPTION("Arrows.LightSecondary", "Light Secondary", COSMETICS_GROUP_ARROWS, ColorRGBA8(255, 255, 170, 0), false, true, true), + + COSMETIC_OPTION("Magic.DinsPrimary", "Din's Primary", COSMETICS_GROUP_MAGIC, ColorRGBA8(255, 200, 0, 255), false, true, false), + COSMETIC_OPTION("Magic.DinsSecondary", "Din's Secondary", COSMETICS_GROUP_MAGIC, ColorRGBA8(255, 0, 0, 255), false, true, true), + COSMETIC_OPTION("Magic.FaroresPrimary", "Farore's Primary", COSMETICS_GROUP_MAGIC, ColorRGBA8(255, 255, 0, 255), false, true, false), + COSMETIC_OPTION("Magic.FaroresSecondary", "Farore's Secondary", COSMETICS_GROUP_MAGIC, ColorRGBA8(100, 200, 0, 255), false, true, true), + COSMETIC_OPTION("Magic.NayrusPrimary", "Nayru's Primary", COSMETICS_GROUP_MAGIC, ColorRGBA8(170, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Magic.NayrusSecondary", "Nayru's Secondary", COSMETICS_GROUP_MAGIC, ColorRGBA8( 0, 100, 255, 255), false, true, true), + + COSMETIC_OPTION("SpinAttack.Level1Primary", "Level 1 Primary", COSMETICS_GROUP_SPIN_ATTACK, ColorRGBA8(170, 255, 255, 255), false, true, true), + COSMETIC_OPTION("SpinAttack.Level1Secondary", "Level 1 Secondary", COSMETICS_GROUP_SPIN_ATTACK, ColorRGBA8( 0, 100, 255, 255), false, true, false), + COSMETIC_OPTION("SpinAttack.Level2Primary", "Level 2 Primary", COSMETICS_GROUP_SPIN_ATTACK, ColorRGBA8(255, 255, 170, 255), false, true, true), + COSMETIC_OPTION("SpinAttack.Level2Secondary", "Level 2 Secondary", COSMETICS_GROUP_SPIN_ATTACK, ColorRGBA8(255, 100, 0, 255), false, true, false), + + COSMETIC_OPTION("Trails.Bombchu", "Bombchu", COSMETICS_GROUP_TRAILS, ColorRGBA8(250, 0, 0, 255), false, true, true), + COSMETIC_OPTION("Trails.Boomerang", "Boomerang", COSMETICS_GROUP_TRAILS, ColorRGBA8(255, 255, 100, 255), false, true, true), + COSMETIC_OPTION("Trails.KokiriSword", "Kokiri Sword", COSMETICS_GROUP_TRAILS, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Trails.MasterSword", "Master Sword", COSMETICS_GROUP_TRAILS, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Trails.BiggoronSword", "Biggoron Sword", COSMETICS_GROUP_TRAILS, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Trails.Stick", "Stick", COSMETICS_GROUP_TRAILS, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("Trails.Hammer", "Hammer", COSMETICS_GROUP_TRAILS, ColorRGBA8(255, 255, 255, 255), false, true, true), + + COSMETIC_OPTION("World.BlockOfTime", "Block of Time", COSMETICS_GROUP_WORLD, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("World.Moon", "Moon", COSMETICS_GROUP_WORLD, ColorRGBA8(240, 255, 180, 255), false, true, true), + COSMETIC_OPTION("World.GossipStone", "Gossip Stone", COSMETICS_GROUP_WORLD, ColorRGBA8(200, 200, 200, 255), false, true, true), + COSMETIC_OPTION("World.RedIce", "Red Ice", COSMETICS_GROUP_WORLD, ColorRGBA8(255, 0, 0, 255), false, true, false), + COSMETIC_OPTION("World.MysteryItem", "Mystery Item", COSMETICS_GROUP_WORLD, ColorRGBA8( 0, 60, 100, 255), false, true, false), + + COSMETIC_OPTION("Navi.IdlePrimary", "Idle Primary", COSMETICS_GROUP_NAVI, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Navi.IdleSecondary", "Idle Secondary", COSMETICS_GROUP_NAVI, ColorRGBA8( 0, 0, 255, 0), false, true, true), + COSMETIC_OPTION("Navi.NPCPrimary", "NPC Primary", COSMETICS_GROUP_NAVI, ColorRGBA8(150, 150, 255, 255), false, true, false), + COSMETIC_OPTION("Navi.NPCSecondary", "NPC Secondary", COSMETICS_GROUP_NAVI, ColorRGBA8(150, 150, 255, 0), false, true, true), + COSMETIC_OPTION("Navi.EnemyPrimary", "Enemy Primary", COSMETICS_GROUP_NAVI, ColorRGBA8(255, 255, 0, 255), false, true, false), + COSMETIC_OPTION("Navi.EnemySecondary", "Enemy Secondary", COSMETICS_GROUP_NAVI, ColorRGBA8(200, 155, 0, 0), false, true, true), + COSMETIC_OPTION("Navi.PropsPrimary", "Props Primary", COSMETICS_GROUP_NAVI, ColorRGBA8( 0, 255, 0, 255), false, true, false), + COSMETIC_OPTION("Navi.PropsSecondary", "Props Secondary", COSMETICS_GROUP_NAVI, ColorRGBA8( 0, 255, 0, 0), false, true, true), + + COSMETIC_OPTION("Ivan.IdlePrimary", "Ivan Idle Primary", COSMETICS_GROUP_IVAN, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("Ivan.IdleSecondary", "Ivan Idle Secondary", COSMETICS_GROUP_IVAN, ColorRGBA8( 0, 255, 0, 255), false, true, true), + + COSMETIC_OPTION("NPC.FireKeesePrimary", "Fire Keese Primary", COSMETICS_GROUP_NPC, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("NPC.FireKeeseSecondary", "Fire Keese Secondary", COSMETICS_GROUP_NPC, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("NPC.IceKeesePrimary", "Ice Keese Primary", COSMETICS_GROUP_NPC, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("NPC.IceKeeseSecondary", "Ice Keese Secondary", COSMETICS_GROUP_NPC, ColorRGBA8(255, 255, 255, 255), false, true, true), // Todo (Cosmetics): Health fairy - COSMETIC_OPTION("NPC.Dog1", "Dog 1", COSMETICS_GROUP_NPC, ImVec4(255, 255, 200, 255), false, true, true), - COSMETIC_OPTION("NPC.Dog2", "Dog 2", COSMETICS_GROUP_NPC, ImVec4(150, 100, 50, 255), false, true, true), - COSMETIC_OPTION("NPC.GoldenSkulltula", "Golden Skulltula", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, false), - COSMETIC_OPTION("NPC.Kokiri", "Kokiri", COSMETICS_GROUP_NPC, ImVec4( 0, 130, 70, 255), false, true, false), - COSMETIC_OPTION("NPC.Gerudo", "Gerudo", COSMETICS_GROUP_NPC, ImVec4( 90, 0, 140, 255), false, true, false), - COSMETIC_OPTION("NPC.MetalTrap", "Metal Trap", COSMETICS_GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, true), - COSMETIC_OPTION("NPC.IronKnuckles", "Iron Knuckles", COSMETICS_GROUP_NPC, ImVec4(245, 255, 205, 255), false, true, false), + COSMETIC_OPTION("NPC.Dog1", "Dog 1", COSMETICS_GROUP_NPC, ColorRGBA8(255, 255, 200, 255), false, true, true), + COSMETIC_OPTION("NPC.Dog2", "Dog 2", COSMETICS_GROUP_NPC, ColorRGBA8(150, 100, 50, 255), false, true, true), + COSMETIC_OPTION("NPC.GoldenSkulltula", "Golden Skulltula", COSMETICS_GROUP_NPC, ColorRGBA8(255, 255, 255, 255), false, true, false), + COSMETIC_OPTION("NPC.Kokiri", "Kokiri", COSMETICS_GROUP_NPC, ColorRGBA8( 0, 130, 70, 255), false, true, false), + COSMETIC_OPTION("NPC.Gerudo", "Gerudo", COSMETICS_GROUP_NPC, ColorRGBA8( 90, 0, 140, 255), false, true, false), + COSMETIC_OPTION("NPC.MetalTrap", "Metal Trap", COSMETICS_GROUP_NPC, ColorRGBA8(255, 255, 255, 255), false, true, true), + COSMETIC_OPTION("NPC.IronKnuckles", "Iron Knuckles", COSMETICS_GROUP_NPC, ColorRGBA8(245, 255, 205, 255), false, true, false), }; static const char* MarginCvarList[] { - CVAR_COSMETIC("HUD.Hearts"), CVAR_COSMETIC("HUD.HeartsCount"), CVAR_COSMETIC("HUD.MagicBar"), CVAR_COSMETIC("HUD.VisualSoA"), CVAR_COSMETIC("HUD.BButton"), CVAR_COSMETIC("HUD.AButton"), CVAR_COSMETIC("HUD.StartButton"), - CVAR_COSMETIC("HUD.CUpButton"), CVAR_COSMETIC("HUD.CDownButton"), CVAR_COSMETIC("HUD.CLeftButton"), CVAR_COSMETIC("HUD.CRightButton"), CVAR_COSMETIC("HUD.Dpad"), CVAR_COSMETIC("HUD.Minimap"), - CVAR_COSMETIC("HUD.SmallKey"), CVAR_COSMETIC("HUD.Rupees"), CVAR_COSMETIC("HUD.Carrots"), CVAR_COSMETIC("HUD.Timers"), CVAR_COSMETIC("HUD.ArcheryScore"), CVAR_COSMETIC("HUD.TitleCard.Map"), CVAR_COSMETIC("HUD.TitleCard.Boss"), CVAR_COSMETIC("HUD.IGT") + CVAR_COSMETIC("HUD.Hearts"), + CVAR_COSMETIC("HUD.HeartsCount"), + CVAR_COSMETIC("HUD.MagicBar"), + CVAR_COSMETIC("HUD.VisualSoA"), + CVAR_COSMETIC("HUD.BButton"), + CVAR_COSMETIC("HUD.AButton"), + CVAR_COSMETIC("HUD.StartButton"), + CVAR_COSMETIC("HUD.CUpButton"), + CVAR_COSMETIC("HUD.CDownButton"), + CVAR_COSMETIC("HUD.CLeftButton"), + CVAR_COSMETIC("HUD.CRightButton"), + CVAR_COSMETIC("HUD.Dpad"), + CVAR_COSMETIC("HUD.Minimap"), + CVAR_COSMETIC("HUD.SmallKey"), + CVAR_COSMETIC("HUD.Rupees"), + CVAR_COSMETIC("HUD.Carrots"), + CVAR_COSMETIC("HUD.Timers"), + CVAR_COSMETIC("HUD.ArcheryScore"), + CVAR_COSMETIC("HUD.TitleCard.Map"), + CVAR_COSMETIC("HUD.TitleCard.Boss"), + CVAR_COSMETIC("HUD.IGT") }; -static const char* MarginCvarNonAnchor[]{ CVAR_COSMETIC("HUD.Carrots"), CVAR_COSMETIC("HUD.Timers"), CVAR_COSMETIC("HUD.ArcheryScore"), CVAR_COSMETIC("HUD.TitleCard.Map"),CVAR_COSMETIC("HUD.TitleCard.Boss") }; -ImVec4 GetRandomValue(int MaximumPossible){ - ImVec4 NewColor; - unsigned long range = 255 - 0; +static const char* MarginCvarNonAnchor[] { + CVAR_COSMETIC("HUD.Carrots"), + CVAR_COSMETIC("HUD.Timers"), + CVAR_COSMETIC("HUD.ArcheryScore"), + CVAR_COSMETIC("HUD.TitleCard.Map"), + CVAR_COSMETIC("HUD.TitleCard.Boss") +}; + +ImVec4 GetRandomValue() { #if !defined(__SWITCH__) && !defined(__WIIU__) std::random_device rd; std::mt19937 rng(rd()); @@ -370,10 +441,11 @@ ImVec4 GetRandomValue(int MaximumPossible){ std::mt19937_64 rng(seed); #endif std::uniform_int_distribution dist(0, 255 - 1); - - NewColor.x = (float)(dist(rng)) / 255; - NewColor.y = (float)(dist(rng)) / 255; - NewColor.z = (float)(dist(rng)) / 255; + + ImVec4 NewColor; + NewColor.x = (float)(dist(rng)) / 255.0f; + NewColor.y = (float)(dist(rng)) / 255.0f; + NewColor.z = (float)(dist(rng)) / 255.0f; return NewColor; } @@ -385,24 +457,22 @@ void SetMarginAll(const char* ButtonName, bool SetActivated) { std::string cvarPosType = std::string(cvarName).append(".PosType"); std::string cvarNameMargins = std::string(cvarName).append(".UseMargins"); if (CVarGetInteger(cvarPosType.c_str(),0) <= 2 && SetActivated) { //Our element is not Hidden or Non anchor - for (int i = 0; i < arrayLengthNonMargin; i++){ + for (int i = 0; i < arrayLengthNonMargin; i++) { if ((strcmp(cvarName, MarginCvarNonAnchor[i]) == 0) && (CVarGetInteger(cvarPosType.c_str(), 0) == 0)) { //Our element is both in original position and do not have anchor by default so we skip it. CVarSetInteger(cvarNameMargins.c_str(), false); //force set off - } - else if ((strcmp(cvarName, MarginCvarNonAnchor[i]) == 0) && (CVarGetInteger(cvarPosType.c_str(), 0) != 0)) { //Our element is not in original position regarless it has no anchor by default since player made it anchored we can toggle margins + } else if ((strcmp(cvarName, MarginCvarNonAnchor[i]) == 0) && (CVarGetInteger(cvarPosType.c_str(), 0) != 0)) { //Our element is not in original position regarless it has no anchor by default since player made it anchored we can toggle margins CVarSetInteger(cvarNameMargins.c_str(), SetActivated); - } - else if (strcmp(cvarName, MarginCvarNonAnchor[i]) != 0) { //Our elements has an anchor by default so regarless of it's position right now that okay to toggle margins. + } else if (strcmp(cvarName, MarginCvarNonAnchor[i]) != 0) { //Our elements has an anchor by default so regarless of it's position right now that okay to toggle margins. CVarSetInteger(cvarNameMargins.c_str(), SetActivated); } } - } - else { //Since the user requested to turn all margin off no need to do any check there. + } else { //Since the user requested to turn all margin off no need to do any check there. CVarSetInteger(cvarNameMargins.c_str(), SetActivated); } } } } + void ResetPositionAll() { if (ImGui::Button("Reset all positions")) { for (auto cvarName : MarginCvarList) { @@ -422,21 +492,21 @@ void CosmeticsUpdateTick() { float rainbowSpeed = CVarGetFloat(CVAR_COSMETIC("RainbowSpeed"), 0.6f); for (auto& [id, cosmeticOption] : cosmeticOptions) { if (cosmeticOption.supportsRainbow && CVarGetInteger(cosmeticOption.rainbowCvar, 0)) { - float frequency = 2 * M_PI / (360 * rainbowSpeed); + double frequency = 2 * M_PI / (360 * rainbowSpeed); Color_RGBA8 newColor; - newColor.r = sin(frequency * (hue + index) + 0) * 127 + 128; - newColor.g = sin(frequency * (hue + index) + (2 * M_PI / 3)) * 127 + 128; - newColor.b = sin(frequency * (hue + index) + (4 * M_PI / 3)) * 127 + 128; + newColor.r = static_cast(sin(frequency * (hue + index) + 0) * 127) + 128; + newColor.g = static_cast(sin(frequency * (hue + index) + (2 * M_PI / 3)) * 127) + 128; + newColor.b = static_cast(sin(frequency * (hue + index) + (4 * M_PI / 3)) * 127) + 128; newColor.a = 255; // For alpha supported options, retain the last set alpha instead of overwriting if (cosmeticOption.supportsAlpha) { - newColor.a = cosmeticOption.currentColor.w * 255; + newColor.a = static_cast(cosmeticOption.currentColor.w * 255.0f); } - cosmeticOption.currentColor.x = newColor.r / 255.0; - cosmeticOption.currentColor.y = newColor.g / 255.0; - cosmeticOption.currentColor.z = newColor.b / 255.0; - cosmeticOption.currentColor.w = newColor.a / 255.0; + cosmeticOption.currentColor.x = newColor.r / 255.0f; + cosmeticOption.currentColor.y = newColor.g / 255.0f; + cosmeticOption.currentColor.z = newColor.b / 255.0f; + cosmeticOption.currentColor.w = newColor.a / 255.0f; CVarSetColor(cosmeticOption.cvar, newColor); } @@ -444,12 +514,14 @@ void CosmeticsUpdateTick() { // Technically this would work if you replaced "60" with 1 but the hue would be so close it's // indistinguishable, 60 gives us a big enough gap to notice the difference. if (!CVarGetInteger(CVAR_COSMETIC("RainbowSync"), 0)) { - index+= (60 * rainbowSpeed); + index += static_cast(60 * rainbowSpeed); } } ApplyOrResetCustomGfxPatches(false); hue++; - if (hue >= (360 * rainbowSpeed)) hue = 0; + if (hue >= (360 * rainbowSpeed)) { + hue = 0; + } } /* @@ -462,10 +534,23 @@ void CosmeticsUpdateTick() { 5. GFX Command: The GFX command you want to insert */ void ApplyOrResetCustomGfxPatches(bool manualChange) { + static CosmeticOption& magicFaroresPrimary = cosmeticOptions.at("Magic.FaroresPrimary"); + if (manualChange || CVarGetInteger(magicFaroresPrimary.rainbowCvar, 0)) { + Color_RGBA8 color = CVarGetColor(magicFaroresPrimary.cvar, magicFaroresPrimary.defaultColor); + PATCH_GFX(sInnerCylinderDL, "Magic_FaroresPrimary1", magicFaroresPrimary.changedCvar, 24, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(sOuterCylinderDL, "Magic_FaroresPrimary2", magicFaroresPrimary.changedCvar, 24, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + } + + static CosmeticOption& magicFaroresSecondary = cosmeticOptions.at("Magic.FaroresSecondary"); + if (manualChange || CVarGetInteger(magicFaroresSecondary.rainbowCvar, 0)) { + Color_RGBA8 color = CVarGetColor(magicFaroresSecondary.cvar, magicFaroresSecondary.defaultColor); + PATCH_GFX(sInnerCylinderDL, "Magic_FaroresSecondary1", magicFaroresSecondary.changedCvar, 25, gsDPSetEnvColor(color.r, color.g, color.b, 255)); + PATCH_GFX(sOuterCylinderDL, "Magic_FaroresSecondary2", magicFaroresSecondary.changedCvar, 25, gsDPSetEnvColor(color.r, color.g, color.b, 255)); + } + static CosmeticOption& linkGoronTunic = cosmeticOptions.at("Link.GoronTunic"); if (manualChange || CVarGetInteger(linkGoronTunic.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {linkGoronTunic.defaultColor.x, linkGoronTunic.defaultColor.y, linkGoronTunic.defaultColor.z, linkGoronTunic.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(linkGoronTunic.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(linkGoronTunic.cvar, linkGoronTunic.defaultColor); PATCH_GFX(gGiGoronTunicColorDL, "Link_GoronTunic1", linkGoronTunic.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiGoronCollarColorDL, "Link_GoronTunic2", linkGoronTunic.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r / 2, color.g / 2, color.b / 2, 255)); PATCH_GFX(gGiGoronTunicColorDL, "Link_GoronTunic3", linkGoronTunic.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); @@ -474,8 +559,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& linkZoraTunic = cosmeticOptions.at("Link.ZoraTunic"); if (manualChange || CVarGetInteger(linkZoraTunic.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {linkZoraTunic.defaultColor.x, linkZoraTunic.defaultColor.y, linkZoraTunic.defaultColor.z, linkZoraTunic.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(linkZoraTunic.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(linkZoraTunic.cvar, linkZoraTunic.defaultColor); PATCH_GFX(gGiZoraTunicColorDL, "Link_ZoraTunic1", linkZoraTunic.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiZoraCollarColorDL, "Link_ZoraTunic2", linkZoraTunic.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r / 2, color.g / 2, color.b / 2, 255)); PATCH_GFX(gGiZoraTunicColorDL, "Link_ZoraTunic3", linkZoraTunic.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); @@ -484,31 +568,29 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& linkHair = cosmeticOptions.at("Link.Hair"); if (manualChange || CVarGetInteger(linkHair.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {linkHair.defaultColor.x, linkHair.defaultColor.y, linkHair.defaultColor.z, linkHair.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(linkHair.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(linkHair.cvar, linkHair.defaultColor); PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair1", linkHair.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair2", linkHair.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair3", linkHair.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair4", linkHair.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair5", linkHair.changedCvar, 46, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair6", linkHair.changedCvar, 54, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair7", linkHair.changedCvar, 136, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair8", linkHair.changedCvar, 162, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair9", linkHair.changedCvar, 101, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair10", linkHair.changedCvar, 118, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair11", linkHair.changedCvar, 125, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair12", linkHair.changedCvar, 159, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair13", linkHair.changedCvar, 102, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair14", linkHair.changedCvar, 122, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair5", linkHair.changedCvar, 46, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair6", linkHair.changedCvar, 54, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair7", linkHair.changedCvar, 136, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair8", linkHair.changedCvar, 162, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair9", linkHair.changedCvar, 101, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair10", linkHair.changedCvar, 118, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair11", linkHair.changedCvar, 125, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair12", linkHair.changedCvar, 159, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair13", linkHair.changedCvar, 102, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair14", linkHair.changedCvar, 122, gsSPGrayscale(false)); } } static CosmeticOption& linkLinen = cosmeticOptions.at("Link.Linen"); if (manualChange || CVarGetInteger(linkLinen.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {linkLinen.defaultColor.x, linkLinen.defaultColor.y, linkLinen.defaultColor.z, linkLinen.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(linkLinen.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(linkLinen.cvar, linkLinen.defaultColor); PATCH_GFX(gLinkAdultLeftArmNearDL, "Link_Linen1", linkLinen.changedCvar, 30, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultLeftArmNearDL, "Link_Linen2", linkLinen.changedCvar, 83, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultLeftArmOutNearDL, "Link_Linen3", linkLinen.changedCvar, 25, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -533,61 +615,59 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Linen22", linkLinen.changedCvar, 30, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen23", linkLinen.changedCvar, 35, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultLeftArmOutNearDL, "Link_Linen24", linkLinen.changedCvar, 45, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultLeftArmNearDL, "Link_Linen25", linkLinen.changedCvar, 40, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen26", linkLinen.changedCvar, 77, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen27", linkLinen.changedCvar, 35, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen28", linkLinen.changedCvar, 77, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultRightArmNearDL, "Link_Linen29", linkLinen.changedCvar, 42, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Linen30", linkLinen.changedCvar, 43, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultLeftLegNearDL, "Link_Linen31", linkLinen.changedCvar, 43, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Linen32", linkLinen.changedCvar, 38, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Linen33", linkLinen.changedCvar, 38, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen23", linkLinen.changedCvar, 35, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftArmOutNearDL, "Link_Linen24", linkLinen.changedCvar, 45, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftArmNearDL, "Link_Linen25", linkLinen.changedCvar, 40, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen26", linkLinen.changedCvar, 77, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen27", linkLinen.changedCvar, 35, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen28", linkLinen.changedCvar, 77, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultRightArmNearDL, "Link_Linen29", linkLinen.changedCvar, 42, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Linen30", linkLinen.changedCvar, 43, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftLegNearDL, "Link_Linen31", linkLinen.changedCvar, 43, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Linen32", linkLinen.changedCvar, 38, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Linen33", linkLinen.changedCvar, 38, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); } } static CosmeticOption& linkBoots = cosmeticOptions.at("Link.Boots"); if (manualChange || CVarGetInteger(linkBoots.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {linkBoots.defaultColor.x, linkBoots.defaultColor.y, linkBoots.defaultColor.z, linkBoots.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(linkBoots.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(linkBoots.cvar, linkBoots.defaultColor); PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots1", linkBoots.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots2", linkBoots.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Boots3", linkBoots.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Boots4", linkBoots.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots5", linkBoots.changedCvar, 53, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots6", linkBoots.changedCvar, 69, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots7", linkBoots.changedCvar, 52, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots8", linkBoots.changedCvar, 61, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildLeftShinNearDL, "Link_Boots9", linkBoots.changedCvar, 53, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftShinNearDL, "Link_Boots10", linkBoots.changedCvar, 69, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildLeftShinFarDL, "Link_Boots11", linkBoots.changedCvar, 52, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftShinFarDL, "Link_Boots12", linkBoots.changedCvar, 61, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildRightFootNearDL, "Link_Boots13", linkBoots.changedCvar, 30, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildRightFootFarDL, "Link_Boots14", linkBoots.changedCvar, 30, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftFootNearDL, "Link_Boots15", linkBoots.changedCvar, 30, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftFootFarDL, "Link_Boots16", linkBoots.changedCvar, 30, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftThighNearDL, "Link_Boots17", linkBoots.changedCvar, 10, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildLeftThighFarDL, "Link_Boots18", linkBoots.changedCvar, 10, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildHeadNearDL, "Link_Boots19", linkBoots.changedCvar, 20, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildHeadFarDL, "Link_Boots20", linkBoots.changedCvar, 20, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Boots21", linkBoots.changedCvar, 57, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Boots22", linkBoots.changedCvar, 52, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultLeftLegNearDL, "Link_Boots23", linkBoots.changedCvar, 57, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Boots24", linkBoots.changedCvar, 52, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultLeftThighNearDL, "Link_Boots25", linkBoots.changedCvar, 10, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultLeftThighFarDL, "Link_Boots26", linkBoots.changedCvar, 10, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultHeadNearDL, "Link_Boots27", linkBoots.changedCvar, 20, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultHeadFarDL, "Link_Boots28", linkBoots.changedCvar, 20, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots5", linkBoots.changedCvar, 53, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots6", linkBoots.changedCvar, 69, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots7", linkBoots.changedCvar, 52, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots8", linkBoots.changedCvar, 61, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildLeftShinNearDL, "Link_Boots9", linkBoots.changedCvar, 53, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftShinNearDL, "Link_Boots10", linkBoots.changedCvar, 69, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildLeftShinFarDL, "Link_Boots11", linkBoots.changedCvar, 52, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftShinFarDL, "Link_Boots12", linkBoots.changedCvar, 61, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightFootNearDL, "Link_Boots13", linkBoots.changedCvar, 30, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightFootFarDL, "Link_Boots14", linkBoots.changedCvar, 30, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftFootNearDL, "Link_Boots15", linkBoots.changedCvar, 30, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftFootFarDL, "Link_Boots16", linkBoots.changedCvar, 30, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftThighNearDL, "Link_Boots17", linkBoots.changedCvar, 10, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildLeftThighFarDL, "Link_Boots18", linkBoots.changedCvar, 10, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Boots19", linkBoots.changedCvar, 20, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHeadFarDL, "Link_Boots20", linkBoots.changedCvar, 20, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Boots21", linkBoots.changedCvar, 57, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Boots22", linkBoots.changedCvar, 52, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftLegNearDL, "Link_Boots23", linkBoots.changedCvar, 57, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Boots24", linkBoots.changedCvar, 52, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftThighNearDL, "Link_Boots25", linkBoots.changedCvar, 10, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultLeftThighFarDL, "Link_Boots26", linkBoots.changedCvar, 10, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHeadNearDL, "Link_Boots27", linkBoots.changedCvar, 20, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHeadFarDL, "Link_Boots28", linkBoots.changedCvar, 20, gsSPGrayscale(false)); } } static CosmeticOption& mirrorShieldBody = cosmeticOptions.at("MirrorShield.Body"); if (manualChange || CVarGetInteger(mirrorShieldBody.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {mirrorShieldBody.defaultColor.x, mirrorShieldBody.defaultColor.y, mirrorShieldBody.defaultColor.z, mirrorShieldBody.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(mirrorShieldBody.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(mirrorShieldBody.cvar, mirrorShieldBody.defaultColor); PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Body1", mirrorShieldBody.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Body2", mirrorShieldBody.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "MirrorShield_Body3", mirrorShieldBody.changedCvar, 28, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -599,8 +679,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& mirrorShieldMirror = cosmeticOptions.at("MirrorShield.Mirror"); if (manualChange || CVarGetInteger(mirrorShieldMirror.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {mirrorShieldMirror.defaultColor.x, mirrorShieldMirror.defaultColor.y, mirrorShieldMirror.defaultColor.z, mirrorShieldMirror.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(mirrorShieldMirror.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(mirrorShieldMirror.cvar, mirrorShieldMirror.defaultColor); PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Mirror1", mirrorShieldMirror.changedCvar, 47, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Mirror2", mirrorShieldMirror.changedCvar, 48, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "MirrorShield_Mirror3", mirrorShieldMirror.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -612,8 +691,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& mirrorShieldEmblem = cosmeticOptions.at("MirrorShield.Emblem"); if (manualChange || CVarGetInteger(mirrorShieldEmblem.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {mirrorShieldEmblem.defaultColor.x, mirrorShieldEmblem.defaultColor.y, mirrorShieldEmblem.defaultColor.z, mirrorShieldEmblem.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(mirrorShieldEmblem.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(mirrorShieldEmblem.cvar, mirrorShieldEmblem.defaultColor); PATCH_GFX(gGiMirrorShieldSymbolDL, "MirrorShield_Emblem1", mirrorShieldEmblem.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 140)); PATCH_GFX(gGiMirrorShieldSymbolDL, "MirrorShield_Emblem2", mirrorShieldEmblem.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "MirrorShield_Emblem3", mirrorShieldEmblem.changedCvar, 165, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -626,58 +704,57 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& swordsKokiriBlade = cosmeticOptions.at("Swords.KokiriBlade"); if (manualChange || CVarGetInteger(swordsKokiriBlade.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {swordsKokiriBlade.defaultColor.x, swordsKokiriBlade.defaultColor.y, swordsKokiriBlade.defaultColor.z, swordsKokiriBlade.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(swordsKokiriBlade.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(swordsKokiriBlade.cvar, swordsKokiriBlade.defaultColor); PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriBlade1", swordsKokiriBlade.changedCvar, 79, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriBlade2", swordsKokiriBlade.changedCvar, 75, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriBlade3", swordsKokiriBlade.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriBlade4", swordsKokiriBlade.changedCvar, 6, gsDPSetEnvColor(color.r / 4, color.g / 4, color.b / 4, 255)); } - // static CosmeticOption& swordsKokiriHilt = cosmeticOptions.at("Swords.KokiriHilt"); - // if (manualChange || CVarGetInteger(swordsKokiriHilt.rainbowCvar, 0)) { - // static Color_RGBA8 defaultColor = {swordsKokiriHilt.defaultColor.x, swordsKokiriHilt.defaultColor.y, swordsKokiriHilt.defaultColor.z, swordsKokiriHilt.defaultColor.w}; - // Color_RGBA8 color = CVarGetColor(swordsKokiriHilt.cvar, defaultColor); - // PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt1", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt2", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt3", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt4", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt5", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt6", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt7", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt8", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt9", swordsKokiriHilt.changedCvar, 64, gsDPSetPrimColor(0, 0, MAX(color.r - 50, 0), MAX(color.g - 50, 0), MAX(color.b - 50, 0), 255)); - // PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt10", swordsKokiriHilt.changedCvar, 66, gsDPSetEnvColor(MAX(color.r - 50, 0) / 3, MAX(color.g - 50, 0) / 3, MAX(color.b - 50, 0) / 3, 255)); - // PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt11", swordsKokiriHilt.changedCvar, 162, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - // PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt12", swordsKokiriHilt.changedCvar, 164, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + /* + static CosmeticOption& swordsKokiriHilt = cosmeticOptions.at("Swords.KokiriHilt"); + if (manualChange || CVarGetInteger(swordsKokiriHilt.rainbowCvar, 0)) { + Color_RGBA8 color = CVarGetColor(swordsKokiriHilt.cvar, swordsKokiriHilt.defaultColor); + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt1", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt2", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt3", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt4", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt5", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt6", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt7", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt8", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt9", swordsKokiriHilt.changedCvar, 64, gsDPSetPrimColor(0, 0, MAX(color.r - 50, 0), MAX(color.g - 50, 0), MAX(color.b - 50, 0), 255)); + PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt10", swordsKokiriHilt.changedCvar, 66, gsDPSetEnvColor(MAX(color.r - 50, 0) / 3, MAX(color.g - 50, 0) / 3, MAX(color.b - 50, 0) / 3, 255)); + PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt11", swordsKokiriHilt.changedCvar, 162, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt12", swordsKokiriHilt.changedCvar, 164, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - // if (manualChange) { - // PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt13", swordsKokiriHilt.changedCvar, 108, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt14", swordsKokiriHilt.changedCvar, 134, gsSPGrayscale(false)); - // PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt15", swordsKokiriHilt.changedCvar, 106, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt16", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false)); - // PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt17", swordsKokiriHilt.changedCvar, 100, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt18", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false)); - // PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt19", swordsKokiriHilt.changedCvar, 128, gsSPEndDisplayList()); - // PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt20", swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt21", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false)); - // PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt22", swordsKokiriHilt.changedCvar, 120, gsSPEndDisplayList()); - // PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt23", swordsKokiriHilt.changedCvar, 166, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt24", swordsKokiriHilt.changedCvar, 192, gsSPGrayscale(false)); - // PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt25", swordsKokiriHilt.changedCvar, 194, gsSPEndDisplayList()); - // PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt26", swordsKokiriHilt.changedCvar, 156, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt27", swordsKokiriHilt.changedCvar, 176, gsSPGrayscale(false)); - // PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt28", swordsKokiriHilt.changedCvar, 178, gsSPEndDisplayList()); - // PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt29", swordsKokiriHilt.changedCvar, 162, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt30", swordsKokiriHilt.changedCvar, 188, gsSPGrayscale(false)); - // PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt31", swordsKokiriHilt.changedCvar, 190, gsSPEndDisplayList()); - // PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt32", swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt33", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false)); - // } - // } + if (manualChange) { + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt13", swordsKokiriHilt.changedCvar, 108, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt14", swordsKokiriHilt.changedCvar, 134, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt15", swordsKokiriHilt.changedCvar, 106, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt16", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt17", swordsKokiriHilt.changedCvar, 100, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt18", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt19", swordsKokiriHilt.changedCvar, 128, gsSPEndDisplayList()); + PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt20", swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt21", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt22", swordsKokiriHilt.changedCvar, 120, gsSPEndDisplayList()); + PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt23", swordsKokiriHilt.changedCvar, 166, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt24", swordsKokiriHilt.changedCvar, 192, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt25", swordsKokiriHilt.changedCvar, 194, gsSPEndDisplayList()); + PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt26", swordsKokiriHilt.changedCvar, 156, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt27", swordsKokiriHilt.changedCvar, 176, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt28", swordsKokiriHilt.changedCvar, 178, gsSPEndDisplayList()); + PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt29", swordsKokiriHilt.changedCvar, 162, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt30", swordsKokiriHilt.changedCvar, 188, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt31", swordsKokiriHilt.changedCvar, 190, gsSPEndDisplayList()); + PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt32", swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt33", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false)); + } + } + */ static CosmeticOption& swordsMasterBlade = cosmeticOptions.at("Swords.MasterBlade"); if (manualChange || CVarGetInteger(swordsMasterBlade.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {swordsMasterBlade.defaultColor.x, swordsMasterBlade.defaultColor.y, swordsMasterBlade.defaultColor.z, swordsMasterBlade.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(swordsMasterBlade.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(swordsMasterBlade.cvar, swordsMasterBlade.defaultColor); PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterBlade1", swordsMasterBlade.changedCvar, 60, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterBlade2", swordsMasterBlade.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterBlade3", swordsMasterBlade.changedCvar, 13, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -685,113 +762,109 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterBlade5", swordsMasterBlade.changedCvar, 13, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterBlade6", swordsMasterBlade.changedCvar, 14, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } - // static CosmeticOption& swordsMasterHilt = cosmeticOptions.at("Swords.MasterHilt"); - // if (manualChange || CVarGetInteger(swordsMasterHilt.rainbowCvar, 0)) { - // static Color_RGBA8 defaultColor = {swordsMasterHilt.defaultColor.x, swordsMasterHilt.defaultColor.y, swordsMasterHilt.defaultColor.z, swordsMasterHilt.defaultColor.w}; - // Color_RGBA8 color = CVarGetColor(swordsMasterHilt.cvar, defaultColor); - // PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt1", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt2", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt3", swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt4", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt5", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt6", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt7", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt8", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt9", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt10", swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + /* + static CosmeticOption& swordsMasterHilt = cosmeticOptions.at("Swords.MasterHilt"); + if (manualChange || CVarGetInteger(swordsMasterHilt.rainbowCvar, 0)) { + Color_RGBA8 color = CVarGetColor(swordsMasterHilt.cvar, swordsMasterHilt.defaultColor); + PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt1", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt2", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt3", swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt4", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt5", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt6", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt7", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt8", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt9", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt10", swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // if (manualChange) { - // PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt11", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt12", swordsMasterHilt.changedCvar, 64, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt13", swordsMasterHilt.changedCvar, 106, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt14", swordsMasterHilt.changedCvar, 120, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt15", swordsMasterHilt.changedCvar, 104, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt16", swordsMasterHilt.changedCvar, 182, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt17", swordsMasterHilt.changedCvar, 184, gsSPEndDisplayList()); - // PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt18", swordsMasterHilt.changedCvar, 80, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt19", swordsMasterHilt.changedCvar, 94, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt20", swordsMasterHilt.changedCvar, 162, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt21", swordsMasterHilt.changedCvar, 180, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt22", swordsMasterHilt.changedCvar, 154, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt23", swordsMasterHilt.changedCvar, 232, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt24", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt25", swordsMasterHilt.changedCvar, 130, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt26", swordsMasterHilt.changedCvar, 172, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt27", swordsMasterHilt.changedCvar, 186, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt28", swordsMasterHilt.changedCvar, 220, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt29", swordsMasterHilt.changedCvar, 298, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt30", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt31", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt32", swordsMasterHilt.changedCvar, 86, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt33", swordsMasterHilt.changedCvar, 208, gsSPGrayscale(false)); - // PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt34", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true)); - // PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt35", swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false)); - // PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt36", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList()); - // PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt37", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true)); - // PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt38", swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false)); - // PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt39", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList()); - // } - // } + if (manualChange) { + PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt11", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt12", swordsMasterHilt.changedCvar, 64, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt13", swordsMasterHilt.changedCvar, 106, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt14", swordsMasterHilt.changedCvar, 120, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt15", swordsMasterHilt.changedCvar, 104, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt16", swordsMasterHilt.changedCvar, 182, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt17", swordsMasterHilt.changedCvar, 184, gsSPEndDisplayList()); + PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt18", swordsMasterHilt.changedCvar, 80, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt19", swordsMasterHilt.changedCvar, 94, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt20", swordsMasterHilt.changedCvar, 162, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt21", swordsMasterHilt.changedCvar, 180, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt22", swordsMasterHilt.changedCvar, 154, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt23", swordsMasterHilt.changedCvar, 232, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt24", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt25", swordsMasterHilt.changedCvar, 130, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt26", swordsMasterHilt.changedCvar, 172, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt27", swordsMasterHilt.changedCvar, 186, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt28", swordsMasterHilt.changedCvar, 220, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt29", swordsMasterHilt.changedCvar, 298, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt30", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt31", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt32", swordsMasterHilt.changedCvar, 86, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt33", swordsMasterHilt.changedCvar, 208, gsSPGrayscale(false)); + PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt34", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true)); + PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt35", swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false)); + PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt36", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList()); + PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt37", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true)); + PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt38", swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false)); + PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt39", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList()); + } + } + */ static CosmeticOption& swordsBiggoronBlade = cosmeticOptions.at("Swords.BiggoronBlade"); if (manualChange || CVarGetInteger(swordsBiggoronBlade.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {swordsBiggoronBlade.defaultColor.x, swordsBiggoronBlade.defaultColor.y, swordsBiggoronBlade.defaultColor.z, swordsBiggoronBlade.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(swordsBiggoronBlade.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(swordsBiggoronBlade.cvar, swordsBiggoronBlade.defaultColor); PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronBlade1", swordsBiggoronBlade.changedCvar, 108, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronBlade2", swordsBiggoronBlade.changedCvar, 63, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronBlade3", swordsBiggoronBlade.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronBlade4", swordsBiggoronBlade.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); } - // static CosmeticOption& swordsBiggoronHilt = cosmeticOptions.at("Swords.BiggoronHilt"); - // if (manualChange || CVarGetInteger(swordsBiggoronHilt.rainbowCvar, 0)) { - // static Color_RGBA8 defaultColor = {swordsBiggoronHilt.defaultColor.x, swordsBiggoronHilt.defaultColor.y, swordsBiggoronHilt.defaultColor.z, swordsBiggoronHilt.defaultColor.w}; - // Color_RGBA8 color = CVarGetColor(swordsBiggoronHilt.cvar, defaultColor); - // PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt1", swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt2", swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt3", swordsBiggoronHilt.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - // PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt4", swordsBiggoronHilt.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - // PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt5", swordsBiggoronHilt.changedCvar, 154, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - // PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt6", swordsBiggoronHilt.changedCvar, 156, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - - // if (manualChange) { - // PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt7", swordsBiggoronHilt.changedCvar, 278, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt8", swordsBiggoronHilt.changedCvar, 332, gsSPGrayscale(false)); - // PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt9", swordsBiggoronHilt.changedCvar, 334, gsSPEndDisplayList()); - // PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt10", swordsBiggoronHilt.changedCvar, 38, gsSPGrayscale(true)); - // PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt11", swordsBiggoronHilt.changedCvar, 118, gsSPGrayscale(false)); - // } - // } + /* + static CosmeticOption& swordsBiggoronHilt = cosmeticOptions.at("Swords.BiggoronHilt"); + if (manualChange || CVarGetInteger(swordsBiggoronHilt.rainbowCvar, 0)) { + Color_RGBA8 color = CVarGetColor(swordsBiggoronHilt.cvar, swordsBiggoronHilt.defaultColor); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt1", swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt2", swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt3", swordsBiggoronHilt.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt4", swordsBiggoronHilt.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt5", swordsBiggoronHilt.changedCvar, 154, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt6", swordsBiggoronHilt.changedCvar, 156, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + if (manualChange) { + PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt7", swordsBiggoronHilt.changedCvar, 278, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt8", swordsBiggoronHilt.changedCvar, 332, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt9", swordsBiggoronHilt.changedCvar, 334, gsSPEndDisplayList()); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt10", swordsBiggoronHilt.changedCvar, 38, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt11", swordsBiggoronHilt.changedCvar, 118, gsSPGrayscale(false)); + } + } + */ static CosmeticOption& glovesGoronBracelet = cosmeticOptions.at("Gloves.GoronBracelet"); if (manualChange || CVarGetInteger(glovesGoronBracelet.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {glovesGoronBracelet.defaultColor.x, glovesGoronBracelet.defaultColor.y, glovesGoronBracelet.defaultColor.z, glovesGoronBracelet.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(glovesGoronBracelet.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(glovesGoronBracelet.cvar, glovesGoronBracelet.defaultColor); PATCH_GFX(gGiGoronBraceletDL, "Gloves_GoronBracelet1", glovesGoronBracelet.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiGoronBraceletDL, "Gloves_GoronBracelet2", glovesGoronBracelet.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet3", glovesGoronBracelet.changedCvar, 3, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet4", glovesGoronBracelet.changedCvar, 11, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet5", glovesGoronBracelet.changedCvar, 39, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet4", glovesGoronBracelet.changedCvar, 11, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet5", glovesGoronBracelet.changedCvar, 39, gsSPGrayscale(false)); } } static CosmeticOption& glovesSilverGauntlets = cosmeticOptions.at("Gloves.SilverGauntlets"); if (manualChange || CVarGetInteger(glovesSilverGauntlets.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {glovesSilverGauntlets.defaultColor.x, glovesSilverGauntlets.defaultColor.y, glovesSilverGauntlets.defaultColor.z, glovesSilverGauntlets.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(glovesSilverGauntlets.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(glovesSilverGauntlets.cvar, glovesSilverGauntlets.defaultColor); PATCH_GFX(gGiSilverGauntletsColorDL, "Gloves_SilverGauntlets1", glovesSilverGauntlets.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiSilverGauntletsColorDL, "Gloves_SilverGauntlets2", glovesSilverGauntlets.changedCvar, 4, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); } static CosmeticOption& glovesGoldenGauntlets = cosmeticOptions.at("Gloves.GoldenGauntlets"); if (manualChange || CVarGetInteger(glovesGoldenGauntlets.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {glovesGoldenGauntlets.defaultColor.x, glovesGoldenGauntlets.defaultColor.y, glovesGoldenGauntlets.defaultColor.z, glovesGoldenGauntlets.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(glovesGoldenGauntlets.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(glovesGoldenGauntlets.cvar, glovesGoldenGauntlets.defaultColor); PATCH_GFX(gGiGoldenGauntletsColorDL, "Gloves_GoldenGauntlets1", glovesGoldenGauntlets.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiGoldenGauntletsColorDL, "Gloves_GoldenGauntlets2", glovesGoldenGauntlets.changedCvar, 4, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); } static CosmeticOption& glovesGauntletsGem = cosmeticOptions.at("Gloves.GauntletsGem"); if (manualChange || CVarGetInteger(glovesGauntletsGem.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {glovesGauntletsGem.defaultColor.x, glovesGauntletsGem.defaultColor.y, glovesGauntletsGem.defaultColor.z, glovesGauntletsGem.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(glovesGauntletsGem.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(glovesGauntletsGem.cvar, glovesGauntletsGem.defaultColor); PATCH_GFX(gGiGauntletsDL, "Gloves_GauntletsGem1", glovesGauntletsGem.changedCvar, 84, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiGauntletsDL, "Gloves_GauntletsGem2", glovesGauntletsGem.changedCvar, 85, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkAdultLeftGauntletPlate2DL, "Gloves_GauntletsGem3", glovesGauntletsGem.changedCvar, 42, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -802,8 +875,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& equipmentBoomerangBody = cosmeticOptions.at("Equipment.BoomerangBody"); if (manualChange || CVarGetInteger(equipmentBoomerangBody.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentBoomerangBody.defaultColor.x, equipmentBoomerangBody.defaultColor.y, equipmentBoomerangBody.defaultColor.z, equipmentBoomerangBody.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentBoomerangBody.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentBoomerangBody.cvar, equipmentBoomerangBody.defaultColor); PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangBody1", equipmentBoomerangBody.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangBody2", equipmentBoomerangBody.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkChildLeftFistAndBoomerangNearDL, "Equipment_BoomerangBody3", equipmentBoomerangBody.changedCvar, 34, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -812,8 +884,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& equipmentBoomerangGem = cosmeticOptions.at("Equipment.BoomerangGem"); if (manualChange || CVarGetInteger(equipmentBoomerangGem.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentBoomerangGem.defaultColor.x, equipmentBoomerangGem.defaultColor.y, equipmentBoomerangGem.defaultColor.z, equipmentBoomerangGem.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentBoomerangGem.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentBoomerangGem.cvar, equipmentBoomerangGem.defaultColor); PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangGem1", equipmentBoomerangGem.changedCvar, 84, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangGem2", equipmentBoomerangGem.changedCvar, 85, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkChildLeftFistAndBoomerangNearDL, "Equipment_BoomerangGem3", equipmentBoomerangGem.changedCvar, 16, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -821,44 +892,42 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { // There appears to be no gem rendered on the far LOD variant, not sure if this is an SOH bug or what. // PATCH_GFX(gLinkChildLeftFistAndBoomerangFarDL, "Equipment_BoomerangGem5", equipmentBoomerangGem.changedCvar, 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } + /* + static CosmeticOption& equipmentSlingshotBody = cosmeticOptions.at("Equipment.SlingshotBody"); + if (manualChange || CVarGetInteger(equipmentSlingshotBody.rainbowCvar, 0)) { + Color_RGBA8 color = CVarGetColor(equipmentSlingshotBody.cvar, equipmentSlingshotBody.defaultColor); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody1", equipmentSlingshotBody.changedCvar, 10, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), MAX(color.b - 100, 0), 255)); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody2", equipmentSlingshotBody.changedCvar, 12, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, MAX(color.b - 100, 0) / 3, 255)); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody3", equipmentSlingshotBody.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody4", equipmentSlingshotBody.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody5", equipmentSlingshotBody.changedCvar, 128, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), MAX(color.b - 100, 0), 255)); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody6", equipmentSlingshotBody.changedCvar, 130, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, MAX(color.b - 100, 0) / 3, 255)); + PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody7", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody8", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody9", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // static CosmeticOption& equipmentSlingshotBody = cosmeticOptions.at("Equipment.SlingshotBody"); - // if (manualChange || CVarGetInteger(equipmentSlingshotBody.rainbowCvar, 0)) { - // static Color_RGBA8 defaultColor = {equipmentSlingshotBody.defaultColor.x, equipmentSlingshotBody.defaultColor.y, equipmentSlingshotBody.defaultColor.z, equipmentSlingshotBody.defaultColor.w}; - // Color_RGBA8 color = CVarGetColor(equipmentSlingshotBody.cvar, defaultColor); - // PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody1", equipmentSlingshotBody.changedCvar, 10, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), MAX(color.b - 100, 0), 255)); - // PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody2", equipmentSlingshotBody.changedCvar, 12, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, MAX(color.b - 100, 0) / 3, 255)); - // PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody3", equipmentSlingshotBody.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - // PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody4", equipmentSlingshotBody.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - // PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody5", equipmentSlingshotBody.changedCvar, 128, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), MAX(color.b - 100, 0), 255)); - // PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody6", equipmentSlingshotBody.changedCvar, 130, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, MAX(color.b - 100, 0) / 3, 255)); - // PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody7", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody8", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody9", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - - // if (manualChange) { - // PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody10",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody11",equipmentSlingshotBody.changedCvar, 74, gsSPGrayscale(false)); - // PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody12",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody13",equipmentSlingshotBody.changedCvar, 66, gsSPGrayscale(false)); - // PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody14",equipmentSlingshotBody.changedCvar, 96, gsSPGrayscale(true)); - // PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody15",equipmentSlingshotBody.changedCvar, 136, gsSPGrayscale(false)); - // PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody16",equipmentSlingshotBody.changedCvar, 138, gsSPEndDisplayList()); - // } - // } + if (manualChange) { + PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody10",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody11",equipmentSlingshotBody.changedCvar, 74, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody12",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody13",equipmentSlingshotBody.changedCvar, 66, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody14",equipmentSlingshotBody.changedCvar, 96, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody15",equipmentSlingshotBody.changedCvar, 136, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody16",equipmentSlingshotBody.changedCvar, 138, gsSPEndDisplayList()); + } + } + */ static CosmeticOption& equipmentSlingshotString = cosmeticOptions.at("Equipment.SlingshotString"); if (manualChange || CVarGetInteger(equipmentSlingshotString.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentSlingshotString.defaultColor.x, equipmentSlingshotString.defaultColor.y, equipmentSlingshotString.defaultColor.z, equipmentSlingshotString.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentSlingshotString.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentSlingshotString.cvar, equipmentSlingshotString.defaultColor); PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotString1",equipmentSlingshotString.changedCvar, 75, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotString2",equipmentSlingshotString.changedCvar, 76, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gLinkChildSlinghotStringDL, "Equipment_SlingshotString3",equipmentSlingshotString.changedCvar, 9, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildSlingshotStringDL, "Equipment_SlingshotString3",equipmentSlingshotString.changedCvar, 9, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentBowTips = cosmeticOptions.at("Equipment.BowTips"); if (manualChange || CVarGetInteger(equipmentBowTips.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentBowTips.defaultColor.x, equipmentBowTips.defaultColor.y, equipmentBowTips.defaultColor.z, equipmentBowTips.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentBowTips.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentBowTips.cvar, equipmentBowTips.defaultColor); PATCH_GFX(gGiBowDL, "Equipment_BowTips1", equipmentBowTips.changedCvar, 86, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBowDL, "Equipment_BowTips2", equipmentBowTips.changedCvar, 87, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkAdultRightHandHoldingBowFirstPersonDL, "Equipment_BowTips3", equipmentBowTips.changedCvar, 34, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -867,16 +936,14 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& equipmentBowString = cosmeticOptions.at("Equipment.BowString"); if (manualChange || CVarGetInteger(equipmentBowString.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentBowString.defaultColor.x, equipmentBowString.defaultColor.y, equipmentBowString.defaultColor.z, equipmentBowString.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentBowString.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentBowString.cvar, equipmentBowString.defaultColor); PATCH_GFX(gGiBowDL, "Equipment_BowString1", equipmentBowString.changedCvar, 105, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBowDL, "Equipment_BowString2", equipmentBowString.changedCvar, 106, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkAdultBowStringDL, "Equipment_BowString3", equipmentBowString.changedCvar, 9, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentBowBody = cosmeticOptions.at("Equipment.BowBody"); if (manualChange || CVarGetInteger(equipmentBowBody.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentBowBody.defaultColor.x, equipmentBowBody.defaultColor.y, equipmentBowBody.defaultColor.z, equipmentBowBody.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentBowBody.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentBowBody.cvar, equipmentBowBody.defaultColor); PATCH_GFX(gGiBowDL, "Equipment_BowBody1", equipmentBowBody.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBowDL, "Equipment_BowBody2", equipmentBowBody.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkAdultRightHandHoldingBowFirstPersonDL, "Equipment_BowBody3", equipmentBowBody.changedCvar, 42, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -885,8 +952,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& equipmentBowHandle = cosmeticOptions.at("Equipment.BowHandle"); if (manualChange || CVarGetInteger(equipmentBowHandle.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentBowHandle.defaultColor.x, equipmentBowHandle.defaultColor.y, equipmentBowHandle.defaultColor.z, equipmentBowHandle.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentBowHandle.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentBowHandle.cvar, equipmentBowHandle.defaultColor); PATCH_GFX(gGiBowDL, "Equipment_BowHandle1", equipmentBowHandle.changedCvar, 51, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBowDL, "Equipment_BowHandle2", equipmentBowHandle.changedCvar, 52, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gLinkAdultRightHandHoldingBowFirstPersonDL, "Equipment_BowHandle3", equipmentBowHandle.changedCvar, 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -896,8 +962,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& equipmentHammerHead = cosmeticOptions.at("Equipment.HammerHead"); if (manualChange || CVarGetInteger(equipmentHammerHead.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentHammerHead.defaultColor.x, equipmentHammerHead.defaultColor.y, equipmentHammerHead.defaultColor.z, equipmentHammerHead.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentHammerHead.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentHammerHead.cvar, equipmentHammerHead.defaultColor); PATCH_GFX(gGiHammerDL, "Equipment_HammerHead1", equipmentHammerHead.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiHammerDL, "Equipment_HammerHead2", equipmentHammerHead.changedCvar, 6, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); PATCH_GFX(gGiHammerDL, "Equipment_HammerHead3", equipmentHammerHead.changedCvar, 68, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -907,18 +972,22 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& equipmentHammerHandle = cosmeticOptions.at("Equipment.HammerHandle"); if (manualChange || CVarGetInteger(equipmentHammerHandle.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentHammerHandle.defaultColor.x, equipmentHammerHandle.defaultColor.y, equipmentHammerHandle.defaultColor.z, equipmentHammerHandle.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentHammerHandle.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentHammerHandle.cvar, equipmentHammerHandle.defaultColor); PATCH_GFX(gGiHammerDL, "Equipment_HammerHandle1", equipmentHammerHandle.changedCvar, 84, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiHammerDL, "Equipment_HammerHandle2", equipmentHammerHandle.changedCvar, 85, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); PATCH_GFX(gLinkAdultLeftHandHoldingHammerNearDL, "Equipment_HammerHandle5", equipmentHammerHandle.changedCvar, 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultLeftHandHoldingHammerFarDL, "Equipment_HammerHandle6", equipmentHammerHandle.changedCvar, 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } + + static CosmeticOption& equipmentHookshotChain = cosmeticOptions.at("Equipment.HookshotChain"); + if (manualChange || CVarGetInteger(equipmentHookshotChain.rainbowCvar, 0)) { + Color_RGBA8 color = CVarGetColor(equipmentHookshotChain.cvar, equipmentHookshotChain.defaultColor); + PATCH_GFX(gLinkAdultHookshotChainDL, "Equipment_HookshotChain1", equipmentHookshotChain.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + } static CosmeticOption& equipmentChuFace = cosmeticOptions.at("Equipment.ChuFace"); if (manualChange || CVarGetInteger(equipmentChuFace.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentChuFace.defaultColor.x, equipmentChuFace.defaultColor.y, equipmentChuFace.defaultColor.z, equipmentChuFace.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentChuFace.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentChuFace.cvar, equipmentChuFace.defaultColor); PATCH_GFX(gGiBombchuDL, "Equipment_ChuFace1", equipmentChuFace.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBombchuDL, "Equipment_ChuFace2", equipmentChuFace.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gBombchuDL, "Equipment_ChuFace3", equipmentChuFace.changedCvar, 2, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); @@ -930,8 +999,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& equipmentChuBody = cosmeticOptions.at("Equipment.ChuBody"); if (manualChange || CVarGetInteger(equipmentChuBody.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentChuBody.defaultColor.x, equipmentChuBody.defaultColor.y, equipmentChuBody.defaultColor.z, equipmentChuBody.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentChuBody.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(equipmentChuBody.cvar, equipmentChuBody.defaultColor); PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody1", equipmentChuBody.changedCvar, 39, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody2", equipmentChuBody.changedCvar, 40, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody3", equipmentChuBody.changedCvar, 60, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -941,18 +1009,17 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& equipmentBunnyHood = cosmeticOptions.at("Equipment.BunnyHood"); if (manualChange || CVarGetInteger(equipmentBunnyHood.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {equipmentBunnyHood.defaultColor.x, equipmentBunnyHood.defaultColor.y, equipmentBunnyHood.defaultColor.z, equipmentBunnyHood.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(equipmentBunnyHood.cvar, defaultColor); - PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood1", equipmentBunnyHood.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood2", equipmentBunnyHood.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood3", equipmentBunnyHood.changedCvar, 83, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood4", equipmentBunnyHood.changedCvar, 84, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkChildBunnyHoodDL, "Equipment_BunnyHood5", equipmentBunnyHood.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + Color_RGBA8 color = CVarGetColor(equipmentBunnyHood.cvar, equipmentBunnyHood.defaultColor); + PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood1", equipmentBunnyHood.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood2", equipmentBunnyHood.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood3", equipmentBunnyHood.changedCvar, 83, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood4", equipmentBunnyHood.changedCvar, 84, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkChildBunnyHoodDL, "Equipment_BunnyHood5", equipmentBunnyHood.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkChildBunnyHoodDL, "Equipment_BunnyHood6", equipmentBunnyHood.changedCvar, 13, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildBunnyHoodDL, "Equipment_BunnyHood6", equipmentBunnyHood.changedCvar, 13, gsSPGrayscale(true)); if (CVarGetInteger(equipmentBunnyHood.changedCvar, 0)) { - ResourceMgr_PatchGfxByName(gLinkChildBunnyHoodDL, "Equipment_BunnyHood7", 125, gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); + ResourceMgr_PatchGfxByName(gLinkChildBunnyHoodDL, "Equipment_BunnyHood7", 125, gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); } else { ResourceMgr_UnpatchGfxByName(gLinkChildBunnyHoodDL, "Equipment_BunnyHood7"); } @@ -961,8 +1028,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& consumableGreenRupee = cosmeticOptions.at("Consumable.GreenRupee"); if (manualChange || CVarGetInteger(consumableGreenRupee.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {consumableGreenRupee.defaultColor.x, consumableGreenRupee.defaultColor.y, consumableGreenRupee.defaultColor.z, consumableGreenRupee.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(consumableGreenRupee.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(consumableGreenRupee.cvar, consumableGreenRupee.defaultColor); PATCH_GFX(gGiGreenRupeeInnerColorDL, "Consumable_GreenRupee1", consumableGreenRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiGreenRupeeInnerColorDL, "Consumable_GreenRupee2", consumableGreenRupee.changedCvar, 4, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); PATCH_GFX(gGiGreenRupeeOuterColorDL, "Consumable_GreenRupee3", consumableGreenRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); @@ -981,8 +1047,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& consumableBlueRupee = cosmeticOptions.at("Consumable.BlueRupee"); if (manualChange || CVarGetInteger(consumableBlueRupee.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {consumableBlueRupee.defaultColor.x, consumableBlueRupee.defaultColor.y, consumableBlueRupee.defaultColor.z, consumableBlueRupee.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(consumableBlueRupee.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(consumableBlueRupee.cvar, consumableBlueRupee.defaultColor); PATCH_GFX(gGiBlueRupeeInnerColorDL, "Consumable_BlueRupee1", consumableBlueRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiBlueRupeeInnerColorDL, "Consumable_BlueRupee2", consumableBlueRupee.changedCvar, 4, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); PATCH_GFX(gGiBlueRupeeOuterColorDL, "Consumable_BlueRupee3", consumableBlueRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); @@ -990,8 +1055,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& consumableRedRupee = cosmeticOptions.at("Consumable.RedRupee"); if (manualChange || CVarGetInteger(consumableRedRupee.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {consumableRedRupee.defaultColor.x, consumableRedRupee.defaultColor.y, consumableRedRupee.defaultColor.z, consumableRedRupee.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(consumableRedRupee.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(consumableRedRupee.cvar, consumableRedRupee.defaultColor); PATCH_GFX(gGiRedRupeeInnerColorDL, "Consumable_RedRupee1", consumableRedRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiRedRupeeInnerColorDL, "Consumable_RedRupee2", consumableRedRupee.changedCvar, 4, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); PATCH_GFX(gGiRedRupeeOuterColorDL, "Consumable_RedRupee3", consumableRedRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); @@ -999,8 +1063,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& consumablePurpleRupee = cosmeticOptions.at("Consumable.PurpleRupee"); if (manualChange || CVarGetInteger(consumablePurpleRupee.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {consumablePurpleRupee.defaultColor.x, consumablePurpleRupee.defaultColor.y, consumablePurpleRupee.defaultColor.z, consumablePurpleRupee.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(consumablePurpleRupee.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(consumablePurpleRupee.cvar, consumablePurpleRupee.defaultColor); PATCH_GFX(gGiPurpleRupeeInnerColorDL, "Consumable_PurpleRupee1", consumablePurpleRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiPurpleRupeeInnerColorDL, "Consumable_PurpleRupee2", consumablePurpleRupee.changedCvar, 4, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); PATCH_GFX(gGiPurpleRupeeOuterColorDL, "Consumable_PurpleRupee3", consumablePurpleRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); @@ -1008,8 +1071,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& consumableGoldRupee = cosmeticOptions.at("Consumable.GoldRupee"); if (manualChange || CVarGetInteger(consumableGoldRupee.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {consumableGoldRupee.defaultColor.x, consumableGoldRupee.defaultColor.y, consumableGoldRupee.defaultColor.z, consumableGoldRupee.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(consumableGoldRupee.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(consumableGoldRupee.cvar, consumableGoldRupee.defaultColor); PATCH_GFX(gGiGoldRupeeInnerColorDL, "Consumable_GoldRupee1", consumableGoldRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiGoldRupeeInnerColorDL, "Consumable_GoldRupee2", consumableGoldRupee.changedCvar, 4, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); PATCH_GFX(gGiGoldRupeeOuterColorDL, "Consumable_GoldRupee3", consumableGoldRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); @@ -1018,12 +1080,13 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& consumableHearts = cosmeticOptions.at("Consumable.Hearts"); if (manualChange || CVarGetInteger(consumableHearts.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {consumableHearts.defaultColor.x, consumableHearts.defaultColor.y, consumableHearts.defaultColor.z, consumableHearts.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(consumableHearts.cvar, defaultColor); - // PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts1", consumableHearts.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - // PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts2", consumableHearts.changedCvar, 26, gsSPGrayscale(true)); - // PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts3", consumableHearts.changedCvar, 72, gsSPGrayscale(false)); - // PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts4", consumableHearts.changedCvar, 74, gsSPEndDisplayList()); + Color_RGBA8 color = CVarGetColor(consumableHearts.cvar, consumableHearts.defaultColor); + /* + PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts1", consumableHearts.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts2", consumableHearts.changedCvar, 26, gsSPGrayscale(true)); + PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts3", consumableHearts.changedCvar, 72, gsSPGrayscale(false)); + PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts4", consumableHearts.changedCvar, 74, gsSPEndDisplayList()); + */ PATCH_GFX(gGiHeartPieceDL, "Consumable_Hearts5", consumableHearts.changedCvar, 2, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiHeartPieceDL, "Consumable_Hearts6", consumableHearts.changedCvar, 6, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); PATCH_GFX(gGiHeartContainerDL, "Consumable_Hearts7", consumableHearts.changedCvar, 2, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -1033,8 +1096,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } static CosmeticOption& consumableMagic = cosmeticOptions.at("Consumable.Magic"); if (manualChange || CVarGetInteger(consumableMagic.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {consumableMagic.defaultColor.x, consumableMagic.defaultColor.y, consumableMagic.defaultColor.z, consumableMagic.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(consumableMagic.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(consumableMagic.cvar, consumableMagic.defaultColor); PATCH_GFX(gGiMagicJarSmallDL, "Consumable_Magic1", consumableMagic.changedCvar, 31, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gGiMagicJarSmallDL, "Consumable_Magic2", consumableMagic.changedCvar, 32, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); PATCH_GFX(gGiMagicJarLargeDL, "Consumable_Magic3", consumableMagic.changedCvar, 31, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -1045,8 +1107,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& npcGoldenSkulltula = cosmeticOptions.at("NPC.GoldenSkulltula"); if (manualChange || CVarGetInteger(npcGoldenSkulltula.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {npcGoldenSkulltula.defaultColor.x, npcGoldenSkulltula.defaultColor.y, npcGoldenSkulltula.defaultColor.z, npcGoldenSkulltula.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(npcGoldenSkulltula.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(npcGoldenSkulltula.cvar, npcGoldenSkulltula.defaultColor); PATCH_GFX(gSkulltulaTokenDL, "NPC_GoldenSkulltula1", npcGoldenSkulltula.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); PATCH_GFX(gSkulltulaTokenDL, "NPC_GoldenSkulltula2", npcGoldenSkulltula.changedCvar, 6, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); PATCH_GFX(gSkulltulaTokenFlameDL, "NPC_GoldenSkulltula3", npcGoldenSkulltula.changedCvar, 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); @@ -1061,8 +1122,7 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& npcGerudo = cosmeticOptions.at("NPC.Gerudo"); if (manualChange || CVarGetInteger(npcGerudo.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {npcGerudo.defaultColor.x, npcGerudo.defaultColor.y, npcGerudo.defaultColor.z, npcGerudo.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(npcGerudo.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(npcGerudo.cvar, npcGerudo.defaultColor); PATCH_GFX(gGerudoPurpleTorsoDL, "NPC_Gerudo1", npcGerudo.changedCvar, 139, gsDPSetEnvColor( color.r, color.g, color.b, 255)); PATCH_GFX(gGerudoPurpleRightThighDL, "NPC_Gerudo2", npcGerudo.changedCvar, 11, gsDPSetEnvColor(color.r, color.g, color.b, 255)); PATCH_GFX(gGerudoPurpleLeftThighDL, "NPC_Gerudo3", npcGerudo.changedCvar, 11, gsDPSetEnvColor(color.r, color.g, color.b, 255)); @@ -1075,36 +1135,31 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& npcMetalTrap = cosmeticOptions.at("NPC.MetalTrap"); if (manualChange || CVarGetInteger(npcMetalTrap.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {npcMetalTrap.defaultColor.x, npcMetalTrap.defaultColor.y, npcMetalTrap.defaultColor.z, npcMetalTrap.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(npcMetalTrap.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(npcMetalTrap.cvar, npcMetalTrap.defaultColor); PATCH_GFX(gSlidingBladeTrapDL, "NPC_MetalTrap1", npcMetalTrap.changedCvar, 59, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& n64LogoRed = cosmeticOptions.at("Title.N64LogoRed"); if (manualChange || CVarGetInteger(n64LogoRed.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {n64LogoRed.defaultColor.x, n64LogoRed.defaultColor.y, n64LogoRed.defaultColor.z, n64LogoRed.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(n64LogoRed.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(n64LogoRed.cvar, n64LogoRed.defaultColor); PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoRed1", n64LogoRed.changedCvar, 17, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoRed2", n64LogoRed.changedCvar, 18, gsDPSetEnvColor(color.r, color.g, color.b, 128)); } static CosmeticOption& n64LogoBlue = cosmeticOptions.at("Title.N64LogoBlue"); if (manualChange || CVarGetInteger(n64LogoBlue.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {n64LogoBlue.defaultColor.x, n64LogoBlue.defaultColor.y, n64LogoBlue.defaultColor.z, n64LogoBlue.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(n64LogoBlue.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(n64LogoBlue.cvar, n64LogoBlue.defaultColor); PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoBlue1", n64LogoBlue.changedCvar, 29, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoBlue2", n64LogoBlue.changedCvar, 30, gsDPSetEnvColor(color.r, color.g, color.b, 128)); } static CosmeticOption& n64LogoGreen = cosmeticOptions.at("Title.N64LogoGreen"); if (manualChange || CVarGetInteger(n64LogoGreen.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {n64LogoGreen.defaultColor.x, n64LogoGreen.defaultColor.y, n64LogoGreen.defaultColor.z, n64LogoGreen.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(n64LogoGreen.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(n64LogoGreen.cvar, n64LogoGreen.defaultColor); PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoGreen1", n64LogoGreen.changedCvar, 56, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoGreen2", n64LogoGreen.changedCvar, 57, gsDPSetEnvColor(color.r, color.g, color.b, 128)); } static CosmeticOption& n64LogoYellow = cosmeticOptions.at("Title.N64LogoYellow"); if (manualChange || CVarGetInteger(n64LogoYellow.rainbowCvar, 0)) { - static Color_RGBA8 defaultColor = {n64LogoYellow.defaultColor.x, n64LogoYellow.defaultColor.y, n64LogoYellow.defaultColor.z, n64LogoYellow.defaultColor.w}; - Color_RGBA8 color = CVarGetColor(n64LogoYellow.cvar, defaultColor); + Color_RGBA8 color = CVarGetColor(n64LogoYellow.cvar, n64LogoYellow.defaultColor); PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoYellow1", n64LogoYellow.changedCvar, 81, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoYellow2", n64LogoYellow.changedCvar, 82, gsDPSetEnvColor(color.r, color.g, color.b, 128)); } @@ -1120,6 +1175,15 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } } +extern "C" Color_RGBA8 CosmeticsEditor_GetDefaultValue(const char* id) { + return Color_RGBA8 { + (uint8_t)(cosmeticOptions[id].defaultColor.r * 255.0f), + (uint8_t)(cosmeticOptions[id].defaultColor.g * 255.0f), + (uint8_t)(cosmeticOptions[id].defaultColor.b * 255.0f), + (uint8_t)(cosmeticOptions[id].defaultColor.a * 255.0f) + }; +} + void Table_InitHeader(bool has_header = true) { if (has_header) { ImGui::TableHeadersRow(); @@ -1128,14 +1192,16 @@ void Table_InitHeader(bool has_header = true) { ImGui::TableNextColumn(); ImGui::AlignTextToFramePadding(); //This is to adjust Vertical pos of item in a cell to be normlized. ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 2); - ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x-60); + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x - 60); } + void DrawUseMarginsSlider(const std::string ElementName, const std::string CvarName){ std::string CvarLabel = CvarName + ".UseMargins"; std::string Label = ElementName + " use margins"; UIWidgets::EnhancementCheckbox(Label.c_str(), CvarLabel.c_str()); UIWidgets::Tooltip("Using this allow you move the element with General margins sliders"); } + void DrawPositionsRadioBoxes(const std::string CvarName, bool NoAnchorEnabled = true){ std::string CvarLabel = CvarName + ".PosType"; UIWidgets::EnhancementRadioButton("Original position", CvarLabel.c_str(), 0); @@ -1151,22 +1217,25 @@ void DrawPositionsRadioBoxes(const std::string CvarName, bool NoAnchorEnabled = UIWidgets::EnhancementRadioButton("Hidden", CvarLabel.c_str(), 4); UIWidgets::Tooltip("This will make your elements hidden"); } + void DrawPositionSlider(const std::string CvarName, int MinY, int MaxY, int MinX, int MaxX){ std::string PosXCvar = CvarName + ".PosX"; std::string PosYCvar = CvarName + ".PosY"; - std::string InvisibleLabelX = "##"+PosXCvar; - std::string InvisibleLabelY = "##"+PosYCvar; + std::string InvisibleLabelX = "##" + PosXCvar; + std::string InvisibleLabelY = "##" + PosYCvar; UIWidgets::EnhancementSliderInt("Up <-> Down : %d", InvisibleLabelY.c_str(), PosYCvar.c_str(), MinY, MaxY, "", 0); UIWidgets::Tooltip("This slider is used to move Up and Down your elements."); UIWidgets::EnhancementSliderInt("Left <-> Right : %d", InvisibleLabelX.c_str(), PosXCvar.c_str(), MinX, MaxX, "", 0); UIWidgets::Tooltip("This slider is used to move Left and Right your elements."); } -void DrawScaleSlider(const std::string CvarName,float DefaultValue){ - std::string InvisibleLabel = "##"+CvarName; + +void DrawScaleSlider(const std::string CvarName, float DefaultValue){ + std::string InvisibleLabel = "##" + CvarName; std::string CvarLabel = CvarName + ".Scale"; //Disabled for now. feature not done and several fixes needed to be merged. //UIWidgets::EnhancementSliderFloat("Scale : %dx", InvisibleLabel.c_str(), CvarLabel.c_str(), 0.1f, 3.0f,"",DefaultValue,true); } + void Draw_Table_Dropdown(const char* Header_Title, const char* Table_ID, const char* Column_Title, const char* Slider_Title, const char* Slider_ID, int MinY, int MaxY, int MinX, int MaxX, float Default_Value) { if (ImGui::CollapsingHeader(Header_Title)) { if (ImGui::BeginTable(Table_ID, 1, FlagsTable)) { @@ -1181,6 +1250,7 @@ void Draw_Table_Dropdown(const char* Header_Title, const char* Table_ID, const c } } } + void C_Button_Dropdown(const char* Header_Title, const char* Table_ID, const char* Column_Title, const char* Slider_Title, const char* Slider_ID, const char* Int_Type, float Slider_Scale_Value) { if (ImGui::CollapsingHeader(Header_Title)) { if (ImGui::BeginTable(Table_ID, 1, FlagsTable)) { @@ -1189,29 +1259,43 @@ void C_Button_Dropdown(const char* Header_Title, const char* Table_ID, const cha DrawUseMarginsSlider(Slider_Title, Slider_ID); DrawPositionsRadioBoxes(Slider_ID); s16 Min_X_CU = 0; - s16 Max_X_CU = ImGui::GetWindowViewport()->Size.x/2; - if(CVarGetInteger(Int_Type,0) == 2){ + s16 Max_X_CU = static_cast(ImGui::GetWindowViewport()->Size.x / 2); + if(CVarGetInteger(Int_Type, 0) == 2){ Max_X_CU = 294; - } else if(CVarGetInteger(Int_Type,0) == 3){ - Max_X_CU = ImGui::GetWindowViewport()->Size.x/2; - } else if(CVarGetInteger(Int_Type,0) == 4){ - Min_X_CU = (ImGui::GetWindowViewport()->Size.x/2)*-1; + } else if(CVarGetInteger(Int_Type, 0) == 3){ + Max_X_CU = static_cast(ImGui::GetWindowViewport()->Size.x / 2); + } else if(CVarGetInteger(Int_Type, 0) == 4){ + Min_X_CU = static_cast(ImGui::GetWindowViewport()->Size.x / 2) * -1; } - DrawPositionSlider(Slider_ID, 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_CU, Max_X_CU); + DrawPositionSlider(Slider_ID, 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), Min_X_CU, Max_X_CU); DrawScaleSlider(Slider_ID, Slider_Scale_Value); ImGui::NewLine(); ImGui::EndTable(); } + std::shared_ptr controller = Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(0); + for (auto [id, mapping] : controller->GetButton(BTN_DDOWN)->GetAllButtonMappings()) { + controller->GetButton(BTN_CUSTOM_OCARINA_NOTE_F4)->AddButtonMapping(mapping); + } + for (auto [id, mapping] : controller->GetButton(BTN_DRIGHT)->GetAllButtonMappings()) { + controller->GetButton(BTN_CUSTOM_OCARINA_NOTE_A4)->AddButtonMapping(mapping); + } + for (auto [id, mapping] : controller->GetButton(BTN_DLEFT)->GetAllButtonMappings()) { + controller->GetButton(BTN_CUSTOM_OCARINA_NOTE_B4)->AddButtonMapping(mapping); + } + for (auto [id, mapping] : controller->GetButton(BTN_DUP)->GetAllButtonMappings()) { + controller->GetButton(BTN_CUSTOM_OCARINA_NOTE_D5)->AddButtonMapping(mapping); + } } } + void Draw_Placements(){ if (ImGui::BeginTable("tableMargins", 1, FlagsTable)) { ImGui::TableSetupColumn("General margins settings", FlagsCell, TablesCellsWidth); Table_InitHeader(); - UIWidgets::EnhancementSliderInt("Top : %dx", "##UIMARGINT", CVAR_COSMETIC("HUD.Margin.T"), (ImGui::GetWindowViewport()->Size.y/2)*-1, 25, "", 0); - UIWidgets::EnhancementSliderInt("Left: %dx", "##UIMARGINL", CVAR_COSMETIC("HUD.Margin.L"), -25, ImGui::GetWindowViewport()->Size.x, "", 0); - UIWidgets::EnhancementSliderInt("Right: %dx", "##UIMARGINR", CVAR_COSMETIC("HUD.Margin.R"), (ImGui::GetWindowViewport()->Size.x)*-1, 25, "", 0); - UIWidgets::EnhancementSliderInt("Bottom: %dx", "##UIMARGINB", CVAR_COSMETIC("HUD.Margin.B"), (ImGui::GetWindowViewport()->Size.y/2)*-1, 25, "", 0); + UIWidgets::EnhancementSliderInt("Top : %dx", "##UIMARGINT", CVAR_COSMETIC("HUD.Margin.T"), static_cast(ImGui::GetWindowViewport()->Size.y / 2) * -1, 25, "", 0); + UIWidgets::EnhancementSliderInt("Left: %dx", "##UIMARGINL", CVAR_COSMETIC("HUD.Margin.L"), -25, static_cast(ImGui::GetWindowViewport()->Size.x), "", 0); + UIWidgets::EnhancementSliderInt("Right: %dx", "##UIMARGINR", CVAR_COSMETIC("HUD.Margin.R"), static_cast(ImGui::GetWindowViewport()->Size.x) * -1, 25, "", 0); + UIWidgets::EnhancementSliderInt("Bottom: %dx", "##UIMARGINB", CVAR_COSMETIC("HUD.Margin.B"), static_cast(ImGui::GetWindowViewport()->Size.y / 2) * -1, 25, "", 0); SetMarginAll("All margins on",true); UIWidgets::Tooltip("Set most of the elements to use margins\nSome elements with default position will not be affected\nElements without Anchor or Hidden will not be turned on"); ImGui::SameLine(); @@ -1229,8 +1313,8 @@ void Draw_Placements(){ Table_InitHeader(false); DrawUseMarginsSlider("Hearts counts", CVAR_COSMETIC("HUD.Hearts")); DrawPositionsRadioBoxes(CVAR_COSMETIC("HUD.HeartsCount")); - DrawPositionSlider(CVAR_COSMETIC("HUD.HeartsCount"),-22,ImGui::GetWindowViewport()->Size.y,-125,ImGui::GetWindowViewport()->Size.x); - DrawScaleSlider(CVAR_COSMETIC("HUD.HeartsCount"),0.7f); + DrawPositionSlider(CVAR_COSMETIC("HUD.HeartsCount"), -22, static_cast(ImGui::GetWindowViewport()->Size.y), -125, static_cast(ImGui::GetWindowViewport()->Size.x)); + DrawScaleSlider(CVAR_COSMETIC("HUD.HeartsCount"), 0.7f); UIWidgets::EnhancementSliderInt("Heart line length : %d", "##HeartLineLength", CVAR_COSMETIC("HUD.Hearts.LineLength"), 0, 20, "", 10); UIWidgets::Tooltip("This will set the length of a row of hearts. Set to 0 for unlimited length."); ImGui::NewLine(); @@ -1245,34 +1329,34 @@ void Draw_Placements(){ DrawPositionsRadioBoxes(CVAR_COSMETIC("HUD.MagicBar")); UIWidgets::EnhancementRadioButton("Anchor to life bar", CVAR_COSMETIC("HUD.MagicBar.PosType"), 5); UIWidgets::Tooltip("This will make your elements follow the bottom of the life meter"); - DrawPositionSlider(CVAR_COSMETIC("HUD.MagicBar"), 0, ImGui::GetWindowViewport()->Size.y/2, -5, ImGui::GetWindowViewport()->Size.x/2); - DrawScaleSlider(CVAR_COSMETIC("HUD.MagicBar"),1.0f); + DrawPositionSlider(CVAR_COSMETIC("HUD.MagicBar"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -5, static_cast(ImGui::GetWindowViewport()->Size.x / 2)); + DrawScaleSlider(CVAR_COSMETIC("HUD.MagicBar"), 1.0f); ImGui::NewLine(); ImGui::EndTable(); } } - if (CVarGetInteger(CVAR_ENHANCEMENT("VisualAgony"),0) && ImGui::CollapsingHeader("Visual stone of agony position")) { + if (CVarGetInteger(CVAR_ENHANCEMENT("VisualAgony"), 0) && ImGui::CollapsingHeader("Visual stone of agony position")) { if (ImGui::BeginTable("tabledvisualstoneofagony", 1, FlagsTable)) { ImGui::TableSetupColumn("Visual stone of agony settings", FlagsCell, TablesCellsWidth); Table_InitHeader(false); DrawUseMarginsSlider("Visual stone of agony", CVAR_COSMETIC("HUD.VisualSoA")); DrawPositionsRadioBoxes(CVAR_COSMETIC("HUD.VisualSoA")); s16 Min_X_VSOA = 0; - s16 Max_X_VSOA = ImGui::GetWindowViewport()->Size.x/2; - if(CVarGetInteger(CVAR_COSMETIC("HUD.VisualSoA.PosType"),0) == 2){ + s16 Max_X_VSOA = static_cast(ImGui::GetWindowViewport()->Size.x / 2); + if(CVarGetInteger(CVAR_COSMETIC("HUD.VisualSoA.PosType"), 0) == 2){ Max_X_VSOA = 290; - } else if(CVarGetInteger(CVAR_COSMETIC("HUD.VisualSoA.PosType"),0) == 4){ - Min_X_VSOA = (ImGui::GetWindowViewport()->Size.x/2)*-1; + } else if(CVarGetInteger(CVAR_COSMETIC("HUD.VisualSoA.PosType"), 0) == 4){ + Min_X_VSOA = static_cast(ImGui::GetWindowViewport()->Size.x / 2) * -1; } - DrawPositionSlider(CVAR_COSMETIC("HUD.VisualSoA"), 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_VSOA, Max_X_VSOA); - DrawScaleSlider(CVAR_COSMETIC("HUD.VisualSoA"),1.0f); + DrawPositionSlider(CVAR_COSMETIC("HUD.VisualSoA"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), Min_X_VSOA, Max_X_VSOA); + DrawScaleSlider(CVAR_COSMETIC("HUD.VisualSoA"), 1.0f); ImGui::NewLine(); ImGui::EndTable(); } } - Draw_Table_Dropdown("B Button position", "tablebbtn", "B Button settings", "B Button", CVAR_COSMETIC("HUD.BButton"), 0, ImGui::GetWindowViewport()->Size.y/4+50, -1, ImGui::GetWindowViewport()->Size.x-50, 0.95f); - Draw_Table_Dropdown("A Button position", "tableabtn", "A Button settings", "A Button", CVAR_COSMETIC("HUD.AButton"), -10, ImGui::GetWindowViewport()->Size.y/4+50, -20, ImGui::GetWindowViewport()->Size.x-50, 0.95f); - Draw_Table_Dropdown("Start Button position", "tablestartbtn", "Start Button settings", "Start Button", CVAR_COSMETIC("HUD.StartButton"), 0, ImGui::GetWindowViewport()->Size.y/2, 0, ImGui::GetWindowViewport()->Size.x/2+70, 0.75f); + Draw_Table_Dropdown("B Button position", "tablebbtn", "B Button settings", "B Button", CVAR_COSMETIC("HUD.BButton"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 4) + 50, -1, static_cast(ImGui::GetWindowViewport()->Size.x) - 50, 0.95f); + Draw_Table_Dropdown("A Button position", "tableabtn", "A Button settings", "A Button", CVAR_COSMETIC("HUD.AButton"), -10, static_cast(ImGui::GetWindowViewport()->Size.y / 4) + 50, -20, static_cast(ImGui::GetWindowViewport()->Size.x) - 50, 0.95f); + Draw_Table_Dropdown("Start Button position", "tablestartbtn", "Start Button settings", "Start Button", CVAR_COSMETIC("HUD.StartButton"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), 0, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 70, 0.75f); C_Button_Dropdown("C Button Up position", "tablecubtn", "C Button Up settings", "C Button Up", CVAR_COSMETIC("HUD.CUpButton"), CVAR_COSMETIC("HUD.CUpButton.PosType"), 0.5f); C_Button_Dropdown("C Button Down position", "tablecdbtn", "C Button Down settings", "C Button Down", CVAR_COSMETIC("HUD.CDownButton"), CVAR_COSMETIC("HUD.CDownButton.PosType"), 0.87f); C_Button_Dropdown("C Button Left position", "tableclbtn", "C Button Left settings", "C Button Left", CVAR_COSMETIC("HUD.CLeftButton"), CVAR_COSMETIC("HUD.CLeftButton.PosType"), 0.87f); @@ -1284,27 +1368,36 @@ void Draw_Placements(){ DrawUseMarginsSlider("DPad items", CVAR_COSMETIC("HUD.Dpad")); DrawPositionsRadioBoxes(CVAR_COSMETIC("HUD.Dpad")); s16 Min_X_Dpad = 0; - s16 Max_X_Dpad = ImGui::GetWindowViewport()->Size.x/2; - if(CVarGetInteger(CVAR_COSMETIC("HUD.Dpad.PosType"),0) == 2){ + s16 Max_X_Dpad = static_cast(ImGui::GetWindowViewport()->Size.x / 2); + if(CVarGetInteger(CVAR_COSMETIC("HUD.Dpad.PosType"), 0) == 2){ Max_X_Dpad = 290; - } else if(CVarGetInteger(CVAR_COSMETIC("HUD.Dpad.PosType"),0) == 4){ - Min_X_Dpad = (ImGui::GetWindowViewport()->Size.x/2)*-1; + } else if(CVarGetInteger(CVAR_COSMETIC("HUD.Dpad.PosType"), 0) == 4){ + Min_X_Dpad = static_cast(ImGui::GetWindowViewport()->Size.x / 2) * -1; } - DrawPositionSlider(CVAR_COSMETIC("HUD.Dpad"), 0, ImGui::GetWindowViewport()->Size.y/2, Min_X_Dpad, Max_X_Dpad); - DrawScaleSlider(CVAR_COSMETIC("HUD.Dpad"),1.0f); + DrawPositionSlider(CVAR_COSMETIC("HUD.Dpad"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), Min_X_Dpad, Max_X_Dpad); + DrawScaleSlider(CVAR_COSMETIC("HUD.Dpad"), 1.0f); ImGui::NewLine(); ImGui::EndTable(); } } - Draw_Table_Dropdown("Minimaps position", "tableminimapspos", "minimaps settings", "Minimap", CVAR_COSMETIC("HUD.Minimap"), (ImGui::GetWindowViewport()->Size.y/3)*-1, ImGui::GetWindowViewport()->Size.y/3, ImGui::GetWindowViewport()->Size.x*-1, ImGui::GetWindowViewport()->Size.x/2, 1.0f); - Draw_Table_Dropdown("Small Keys counter position", "tablesmolekeys", "Small Keys counter settings", "Small Keys counter", CVAR_COSMETIC("HUD.SmallKey"), 0, ImGui::GetWindowViewport()->Size.y/3, -1, ImGui::GetWindowViewport()->Size.x/2, 1.0f); - Draw_Table_Dropdown("Rupee counter position", "tablerupeecount", "Rupee counter settings", "Rupee counter", CVAR_COSMETIC("HUD.Rupees"), -2, ImGui::GetWindowViewport()->Size.y/3, -3, ImGui::GetWindowViewport()->Size.x/2, 1.0f); - Draw_Table_Dropdown("Carrots position", "tableCarrots", "Carrots settings", "Carrots", CVAR_COSMETIC("HUD.Carrots"), 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2+25, 1.0f); - Draw_Table_Dropdown("Timers position", "tabletimers", "Timers settings", "Timers", CVAR_COSMETIC("HUD.Timers"), 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2-50, 1.0f); - Draw_Table_Dropdown("Archery Scores position", "tablearchery", "Archery Scores settings", "Archery scores", CVAR_COSMETIC("HUD.ArcheryScore"), 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2-50, 1.0f); - Draw_Table_Dropdown("Title cards (Maps) position", "tabletcmaps", "Titlecard maps settings", "Title cards (overworld)", CVAR_COSMETIC("HUD.TitleCard.Map"), 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2+10, 1.0f); - Draw_Table_Dropdown("Title cards (Bosses) position", "tabletcbosses", "Title cards (Bosses) settings", "Title cards (Bosses)", CVAR_COSMETIC("HUD.TitleCard.Boss"), 0, ImGui::GetWindowViewport()->Size.y/2, -50, ImGui::GetWindowViewport()->Size.x/2+10, 1.0f); - Draw_Table_Dropdown("In-game Gameplay Timer position", "tablegameplaytimer", "In-game Gameplay Timer settings", "In-game Gameplay Timer", CVAR_COSMETIC("HUD.IGT"), 0, ImGui::GetWindowViewport()->Size.y / 2, -50, ImGui::GetWindowViewport()->Size.x / 2 + 10, 1.0f); + Draw_Table_Dropdown("Minimaps position", "tableminimapspos", "minimaps settings", "Minimap", CVAR_COSMETIC("HUD.Minimap"), + static_cast(ImGui::GetWindowViewport()->Size.y / 3) * -1, static_cast(ImGui::GetWindowViewport()->Size.y / 3), static_cast(ImGui::GetWindowViewport()->Size.x) * -1, static_cast(ImGui::GetWindowViewport()->Size.x / 2), 1.0f); + Draw_Table_Dropdown("Small Keys counter position", "tablesmolekeys", "Small Keys counter settings", "Small Keys counter", CVAR_COSMETIC("HUD.SmallKey"), + 0, static_cast(ImGui::GetWindowViewport()->Size.y / 3), -1, static_cast(ImGui::GetWindowViewport()->Size.x / 2), 1.0f); + Draw_Table_Dropdown("Rupee counter position", "tablerupeecount", "Rupee counter settings", "Rupee counter", CVAR_COSMETIC("HUD.Rupees"), + -2, static_cast(ImGui::GetWindowViewport()->Size.y / 3), -3, static_cast(ImGui::GetWindowViewport()->Size.x / 2), 1.0f); + Draw_Table_Dropdown("Carrots position", "tableCarrots", "Carrots settings", "Carrots", CVAR_COSMETIC("HUD.Carrots"), + 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 25, 1.0f); + Draw_Table_Dropdown("Timers position", "tabletimers", "Timers settings", "Timers", CVAR_COSMETIC("HUD.Timers"), + 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) - 50, 1.0f); + Draw_Table_Dropdown("Archery Scores position", "tablearchery", "Archery Scores settings", "Archery scores", CVAR_COSMETIC("HUD.ArcheryScore"), + 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) - 50, 1.0f); + Draw_Table_Dropdown("Title cards (Maps) position", "tabletcmaps", "Titlecard maps settings", "Title cards (overworld)", CVAR_COSMETIC("HUD.TitleCard.Map"), + 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 10, 1.0f); + Draw_Table_Dropdown("Title cards (Bosses) position", "tabletcbosses", "Title cards (Bosses) settings", "Title cards (Bosses)", CVAR_COSMETIC("HUD.TitleCard.Boss"), + 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 10, 1.0f); + Draw_Table_Dropdown("In-game Gameplay Timer position", "tablegameplaytimer", "In-game Gameplay Timer settings", "In-game Gameplay Timer", CVAR_COSMETIC("HUD.IGT"), + 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 10, 1.0f); if (ImGui::CollapsingHeader("Enemy Health Bar position")) { if (ImGui::BeginTable("enemyhealthbar", 1, FlagsTable)) { ImGui::TableSetupColumn("Enemy Health Bar settings", FlagsCell, TablesCellsWidth); @@ -1316,7 +1409,7 @@ void Draw_Placements(){ UIWidgets::Tooltip("This will make your elements follow the top edge of your game window"); UIWidgets::EnhancementRadioButton("Anchor to the bottom", posTypeCVar.c_str(), ENEMYHEALTH_ANCHOR_BOTTOM); UIWidgets::Tooltip("This will make your elements follow the bottom edge of your game window"); - DrawPositionSlider(CVAR_COSMETIC("HUD.EnemyHealthBar."), -SCREEN_HEIGHT, SCREEN_HEIGHT, -ImGui::GetWindowViewport()->Size.x / 2, ImGui::GetWindowViewport()->Size.x / 2); + DrawPositionSlider(CVAR_COSMETIC("HUD.EnemyHealthBar."), -SCREEN_HEIGHT, SCREEN_HEIGHT, -static_cast(ImGui::GetWindowViewport()->Size.x / 2), static_cast(ImGui::GetWindowViewport()->Size.x / 2)); if (UIWidgets::EnhancementSliderInt("Health Bar Width: %d", "##EnemyHealthBarWidth", CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Value"), 32, 128, "", 64)) { CVarSetInteger(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Changed"), 1); } @@ -1325,35 +1418,37 @@ void Draw_Placements(){ if (ImGui::Button("Reset##EnemyHealthBarWidth")) { CVarClear(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Value")); CVarClear(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Changed")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::NewLine(); ImGui::EndTable(); } } } + void Reset_Option_Single(const char* Button_Title, const char* name) { ImGui::SameLine(); if (ImGui::Button(Button_Title)) { CVarClear(name); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } + void Reset_Option_Double(const char* Button_Title, const char* name) { ImGui::SameLine(); if (ImGui::Button(Button_Title)) { CVarClear((std::string(name) + ".Value").c_str()); CVarClear((std::string(name) + ".Changed").c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } + void DrawSillyTab() { ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); - if (CVarGetInteger(CVAR_GENERAL("LetItSnow"), 0)) { - if (UIWidgets::EnhancementCheckbox("Let It Snow", CVAR_GENERAL("LetItSnow"))) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - } + if (UIWidgets::EnhancementCheckbox("Let It Snow", CVAR_GENERAL("LetItSnow"))) { + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } + UIWidgets::Tooltip("Makes snow fall, changes chest texture colors to red and green, etc, for December holidays.\nWill reset on restart outside of December 23-25."); if (UIWidgets::EnhancementSliderFloat("Link Body Scale: %.3fx", "##Link_BodyScale", CVAR_COSMETIC("Link.BodyScale.Value"), 0.001f, 0.025f, "", 0.01f, true)) { CVarSetInteger(CVAR_COSMETIC("Link.BodyScale.Changed"), 1); } @@ -1361,7 +1456,7 @@ void DrawSillyTab() { if (ImGui::Button("Reset##Link_BodyScale")) { CVarClear(CVAR_COSMETIC("Link.BodyScale.Value")); CVarClear(CVAR_COSMETIC("Link.BodyScale.Changed")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); if (gPlayState != nullptr) { static Player* player = GET_PLAYER(gPlayState); player->actor.scale.x = 0.01f; @@ -1381,7 +1476,7 @@ void DrawSillyTab() { Reset_Option_Single("Reset##BunnyHood_EarLength", CVAR_COSMETIC("BunnyHood.EarLength")); UIWidgets::EnhancementSliderFloat("Bunny Hood Spread: %f", "##BunnyHood_EarSpread", CVAR_COSMETIC("BunnyHood.EarSpread"), -300.0f, 500.0f, "", 0.0f, false); Reset_Option_Single("Reset##BunnyHood_EarSpread", CVAR_COSMETIC("BunnyHood.EarSpread")); - UIWidgets::EnhancementSliderFloat("Goron Neck Length: %f", "##Goron_NeckLength", CVAR_COSMETIC("Goron.NeckLength"), 0.0f, 1000.0f, "", 0.0f, false); + UIWidgets::EnhancementSliderFloat("Goron Neck Length: %f", "##Goron_NeckLength", CVAR_COSMETIC("Goron.NeckLength"), 0.0f, 5000.0f, "", 0.0f, false); Reset_Option_Single("Reset##Goron_NeckLength", CVAR_COSMETIC("Goron.NeckLength")); UIWidgets::EnhancementCheckbox("Unfix Goron Spin", CVAR_COSMETIC("UnfixGoronSpin")); UIWidgets::EnhancementSliderFloat("Fairies Size: %f", "##Fairies_Size", CVAR_COSMETIC("Fairies.Size"), 0.25f, 5.0f, "", 1.0f, false); @@ -1401,15 +1496,15 @@ void DrawSillyTab() { // allows you create and use multiple shades of the same color. void CopyMultipliedColor(CosmeticOption& cosmeticOptionSrc, CosmeticOption& cosmeticOptionTarget, float amount = 0.75f) { Color_RGBA8 newColor; - newColor.r = MIN((cosmeticOptionSrc.currentColor.x * 255.0) * amount, 255); - newColor.g = MIN((cosmeticOptionSrc.currentColor.y * 255.0) * amount, 255); - newColor.b = MIN((cosmeticOptionSrc.currentColor.z * 255.0) * amount, 255); + newColor.r = static_cast(MIN((cosmeticOptionSrc.currentColor.x * 255.0f) * amount, 255)); + newColor.g = static_cast(MIN((cosmeticOptionSrc.currentColor.y * 255.0f) * amount, 255)); + newColor.b = static_cast(MIN((cosmeticOptionSrc.currentColor.z * 255.0f) * amount, 255)); newColor.a = 255; - cosmeticOptionTarget.currentColor.x = newColor.r / 255.0; - cosmeticOptionTarget.currentColor.y = newColor.g / 255.0; - cosmeticOptionTarget.currentColor.z = newColor.b / 255.0; - cosmeticOptionTarget.currentColor.w = newColor.a / 255.0; + cosmeticOptionTarget.currentColor.x = newColor.r / 255.0f; + cosmeticOptionTarget.currentColor.y = newColor.g / 255.0f; + cosmeticOptionTarget.currentColor.z = newColor.b / 255.0f; + cosmeticOptionTarget.currentColor.w = newColor.a / 255.0f; CVarSetColor(cosmeticOptionTarget.cvar, newColor); CVarSetInteger((cosmeticOptionTarget.rainbowCvar), 0); @@ -1515,33 +1610,34 @@ void ApplySideEffects(CosmeticOption& cosmeticOption) { } void RandomizeColor(CosmeticOption& cosmeticOption) { + ImVec4 randomColor = GetRandomValue(); Color_RGBA8 newColor; - newColor.r = Random(0, 255); - newColor.g = Random(0, 255); - newColor.b = Random(0, 255); + newColor.r = static_cast(randomColor.x * 255.0f); + newColor.g = static_cast(randomColor.y * 255.0f); + newColor.b = static_cast(randomColor.z * 255.0f); newColor.a = 255; // For alpha supported options, retain the last set alpha instead of overwriting if (cosmeticOption.supportsAlpha) { - newColor.a = cosmeticOption.currentColor.w * 255; + newColor.a = static_cast(cosmeticOption.currentColor.w * 255.0f); } - cosmeticOption.currentColor.x = newColor.r / 255.0; - cosmeticOption.currentColor.y = newColor.g / 255.0; - cosmeticOption.currentColor.z = newColor.b / 255.0; - cosmeticOption.currentColor.w = newColor.a / 255.0; + cosmeticOption.currentColor.x = newColor.r / 255.0f; + cosmeticOption.currentColor.y = newColor.g / 255.0f; + cosmeticOption.currentColor.z = newColor.b / 255.0f; + cosmeticOption.currentColor.w = newColor.a / 255.0f; CVarSetColor(cosmeticOption.cvar, newColor); - CVarSetInteger((cosmeticOption.rainbowCvar), 0); - CVarSetInteger((cosmeticOption.changedCvar), 1); + CVarSetInteger(cosmeticOption.rainbowCvar, 0); + CVarSetInteger(cosmeticOption.changedCvar, 1); ApplySideEffects(cosmeticOption); } void ResetColor(CosmeticOption& cosmeticOption) { - Color_RGBA8 defaultColor = {cosmeticOption.defaultColor.x, cosmeticOption.defaultColor.y, cosmeticOption.defaultColor.z, cosmeticOption.defaultColor.w}; - cosmeticOption.currentColor.x = defaultColor.r / 255.0; - cosmeticOption.currentColor.y = defaultColor.g / 255.0; - cosmeticOption.currentColor.z = defaultColor.b / 255.0; - cosmeticOption.currentColor.w = defaultColor.a / 255.0; + Color_RGBA8 defaultColor = {cosmeticOption.defaultColor.r, cosmeticOption.defaultColor.g, cosmeticOption.defaultColor.b, cosmeticOption.defaultColor.a}; + cosmeticOption.currentColor.x = defaultColor.r / 255.0f; + cosmeticOption.currentColor.y = defaultColor.g / 255.0f; + cosmeticOption.currentColor.z = defaultColor.b / 255.0f; + cosmeticOption.currentColor.w = defaultColor.a / 255.0f; CVarClear(cosmeticOption.changedCvar); CVarClear(cosmeticOption.rainbowCvar); @@ -1605,25 +1701,26 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { } if (colorChanged) { Color_RGBA8 color; - color.r = cosmeticOption.currentColor.x * 255.0; - color.g = cosmeticOption.currentColor.y * 255.0; - color.b = cosmeticOption.currentColor.z * 255.0; - color.a = cosmeticOption.currentColor.w * 255.0; + color.r = static_cast(cosmeticOption.currentColor.x * 255.0f); + color.g = static_cast(cosmeticOption.currentColor.y * 255.0f); + color.b = static_cast(cosmeticOption.currentColor.z * 255.0f); + color.a = static_cast(cosmeticOption.currentColor.w * 255.0f); CVarSetColor(cosmeticOption.cvar, color); CVarSetInteger((cosmeticOption.rainbowCvar), 0); CVarSetInteger((cosmeticOption.changedCvar), 1); ApplySideEffects(cosmeticOption); ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); ImGui::Text("%s", cosmeticOption.label.c_str()); - ImGui::SameLine((ImGui::CalcTextSize("Mirror Shield Mirror").x * 1.0f) + 60.0f); + //the longest option name + ImGui::SameLine((ImGui::CalcTextSize("Message Light Blue (None No Shadow) Color").x * 1.0f) + 60.0f); if (ImGui::Button(("Random##" + cosmeticOption.label).c_str())) { RandomizeColor(cosmeticOption); ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (cosmeticOption.supportsRainbow) { ImGui::SameLine(); @@ -1633,21 +1730,21 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { CVarSetInteger((cosmeticOption.changedCvar), 1); ApplySideEffects(cosmeticOption); ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } ImGui::SameLine(); bool isLocked = (bool)CVarGetInteger((cosmeticOption.lockedCvar), 0); if (ImGui::Checkbox(("Locked##" + cosmeticOption.label).c_str(), &isLocked)) { CVarSetInteger((cosmeticOption.lockedCvar), isLocked); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (CVarGetInteger((cosmeticOption.changedCvar), 0)) { ImGui::SameLine(); if (ImGui::Button(("Reset##" + cosmeticOption.label).c_str())) { ResetColor(cosmeticOption); ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } } @@ -1655,7 +1752,8 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { void DrawCosmeticGroup(CosmeticGroup cosmeticGroup) { std::string label = groupLabels.at(cosmeticGroup); ImGui::Text("%s", label.c_str()); - ImGui::SameLine((ImGui::CalcTextSize("Mirror Shield Mirror").x * 1.0f) + 60.0f); + // the longest option name + ImGui::SameLine((ImGui::CalcTextSize("Message Light Blue (None No Shadow) Color").x * 1.0f) + 60.0f); if (ImGui::Button(("Random##" + label).c_str())) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (cosmeticOption.group == cosmeticGroup && (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) && !CVarGetInteger(cosmeticOption.lockedCvar, 0)) { @@ -1663,7 +1761,7 @@ void DrawCosmeticGroup(CosmeticGroup cosmeticGroup) { } } ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); if (ImGui::Button(("Reset##" + label).c_str())) { @@ -1673,7 +1771,7 @@ void DrawCosmeticGroup(CosmeticGroup cosmeticGroup) { } } ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } for (auto& [id, cosmeticOption] : cosmeticOptions) { if (cosmeticOption.group == cosmeticGroup && (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0))) { @@ -1703,7 +1801,7 @@ void CosmeticsEditorWindow::DrawElement() { CVarSetInteger(cosmeticOption.lockedCvar, 1); } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); if (ImGui::Button("Unlock All Advanced", ImVec2(ImGui::GetContentRegionAvail().x, 30.0f))) { @@ -1712,7 +1810,7 @@ void CosmeticsEditorWindow::DrawElement() { CVarSetInteger(cosmeticOption.lockedCvar, 0); } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } UIWidgets::EnhancementCheckbox("Sync Rainbow colors", CVAR_COSMETIC("RainbowSync")); @@ -1731,7 +1829,7 @@ void CosmeticsEditorWindow::DrawElement() { } } ApplyOrResetCustomGfxPatches(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (ImGui::Button("Lock All", ImVec2(ImGui::GetContentRegionAvail().x / 2, 30.0f))) { @@ -1740,7 +1838,7 @@ void CosmeticsEditorWindow::DrawElement() { CVarSetInteger(cosmeticOption.lockedCvar, 1); } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); if (ImGui::Button("Unlock All", ImVec2(ImGui::GetContentRegionAvail().x, 30.0f))) { @@ -1749,7 +1847,37 @@ void CosmeticsEditorWindow::DrawElement() { CVarSetInteger(cosmeticOption.lockedCvar, 0); } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + } + + if (ImGui::Button("Rainbow All", ImVec2(ImGui::GetContentRegionAvail().x / 2, 30.0f))) { + for (auto& [id, cosmeticOption] : cosmeticOptions) { + if ( + !CVarGetInteger(cosmeticOption.lockedCvar, 0) && + ( + !cosmeticOption.advancedOption || + CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0) + ) + ) { + CVarSetInteger(cosmeticOption.rainbowCvar, 1); + } + } + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + } + ImGui::SameLine(); + if (ImGui::Button("Un-Rainbow All", ImVec2(ImGui::GetContentRegionAvail().x, 30.0f))) { + for (auto& [id, cosmeticOption] : cosmeticOptions) { + if ( + !CVarGetInteger(cosmeticOption.lockedCvar, 0) && + ( + !cosmeticOption.advancedOption || + CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0) + ) + ) { + CVarSetInteger(cosmeticOption.rainbowCvar, 0); + } + } + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (ImGui::BeginTabBar("CosmeticsContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) { @@ -1763,7 +1891,7 @@ void CosmeticsEditorWindow::DrawElement() { ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Effects")) { - // DrawCosmeticGroup(COSMETICS_GROUP_MAGIC); // Cosmetics TODO: Implement magic effect colors + DrawCosmeticGroup(COSMETICS_GROUP_MAGIC); DrawCosmeticGroup(COSMETICS_GROUP_ARROWS); DrawCosmeticGroup(COSMETICS_GROUP_SPIN_ATTACK); DrawCosmeticGroup(COSMETICS_GROUP_TRAILS); @@ -1774,7 +1902,7 @@ void CosmeticsEditorWindow::DrawElement() { if (ImGui::Button("Reset##Trails_Duration")) { CVarClear(CVAR_COSMETIC("Trails.Duration.Value")); CVarClear(CVAR_COSMETIC("Trails.Duration.Changed")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::EndTabItem(); } @@ -1804,6 +1932,13 @@ void CosmeticsEditorWindow::DrawElement() { DrawCosmeticGroup(COSMETICS_GROUP_KALEIDO); ImGui::EndTabItem(); } + + if (CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) { + if (ImGui::BeginTabItem("Message")) { + DrawCosmeticGroup(COSMETICS_GROUP_MESSAGE); + ImGui::EndTabItem(); + } + } ImGui::EndTabBar(); } } @@ -1831,15 +1966,15 @@ void Cosmetics_RegisterOnSceneInitHook() { void CosmeticsEditorWindow::InitElement() { // Convert the `current color` into the format that the ImGui color picker expects for (auto& [id, cosmeticOption] : cosmeticOptions) { - Color_RGBA8 defaultColor = {cosmeticOption.defaultColor.x, cosmeticOption.defaultColor.y, cosmeticOption.defaultColor.z, cosmeticOption.defaultColor.w}; + Color_RGBA8 defaultColor = {cosmeticOption.defaultColor.r, cosmeticOption.defaultColor.g, cosmeticOption.defaultColor.b, cosmeticOption.defaultColor.a}; Color_RGBA8 cvarColor = CVarGetColor(cosmeticOption.cvar, defaultColor); - cosmeticOption.currentColor.x = cvarColor.r / 255.0; - cosmeticOption.currentColor.y = cvarColor.g / 255.0; - cosmeticOption.currentColor.z = cvarColor.b / 255.0; - cosmeticOption.currentColor.w = cvarColor.a / 255.0; + cosmeticOption.currentColor.x = cvarColor.r / 255.0f; + cosmeticOption.currentColor.y = cvarColor.g / 255.0f; + cosmeticOption.currentColor.z = cvarColor.b / 255.0f; + cosmeticOption.currentColor.w = cvarColor.a / 255.0f; } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); ApplyAuthenticGfxPatches(); @@ -1856,7 +1991,7 @@ void CosmeticsEditor_RandomizeAll() { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); } @@ -1869,7 +2004,7 @@ void CosmeticsEditor_RandomizeGroup(CosmeticGroup group) { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); } @@ -1880,7 +2015,7 @@ void CosmeticsEditor_ResetAll() { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); } @@ -1891,6 +2026,6 @@ void CosmeticsEditor_ResetGroup(CosmeticGroup group) { } } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); } diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h index 88f60c76c..55dba5780 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h @@ -1,13 +1,6 @@ #pragma once #include -#define PATCH_GFX(path, name, cvar, index, instruction) \ - if (CVarGetInteger(cvar, 0)) { \ - ResourceMgr_PatchGfxByName(path, name, index, instruction); \ - } else { \ - ResourceMgr_UnpatchGfxByName(path, name); \ - } - // Not to be confused with tabs, groups are 1:1 with the boxes shown in the UI, grouping them allows us to reset/randomize // every item in a group at once. If you are looking for tabs they are rendered manually in ImGui in `DrawCosmeticsEditor` typedef enum { @@ -28,9 +21,19 @@ typedef enum { COSMETICS_GROUP_TRAILS, COSMETICS_GROUP_NAVI, COSMETICS_GROUP_IVAN, + COSMETICS_GROUP_MESSAGE, COSMETICS_GROUP_MAX } CosmeticGroup; +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + Color_RGBA8 CosmeticsEditor_GetDefaultValue(const char* id); + +#ifdef __cplusplus +} + typedef struct { const std::string Name; const std::string ToolTip; @@ -46,8 +49,7 @@ static float TablesCellsWidth = 300.0f; static ImGuiTableColumnFlags FlagsTable = ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV; static ImGuiTableColumnFlags FlagsCell = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort; -void InitCosmeticsEditor();//Init the menu itself -ImVec4 GetRandomValue(int MaximumPossible); +ImVec4 GetRandomValue(); void CosmeticsEditor_RandomizeAll(); void CosmeticsEditor_RandomizeGroup(CosmeticGroup group); void CosmeticsEditor_ResetAll(); @@ -61,4 +63,5 @@ class CosmeticsEditorWindow : public Ship::GuiWindow { void InitElement() override; void DrawElement() override; void UpdateElement() override {}; -}; \ No newline at end of file +}; +#endif //__cplusplus \ No newline at end of file diff --git a/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp b/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp index 6b74769c1..75f6bd35d 100644 --- a/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp +++ b/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp @@ -1,6 +1,8 @@ #include #include #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" +#include "soh/ResourceManagerHelpers.h" extern "C" { #include @@ -9,11 +11,6 @@ extern "C" { #include "objects/object_gi_soldout/object_gi_soldout.h" #include "objects/object_ik/object_ik.h" #include "objects/object_link_child/object_link_child.h" - -uint32_t ResourceMgr_GameHasMasterQuest(); -uint32_t ResourceMgr_GameHasOriginal(); -void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction); -void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName); } typedef struct { diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp index c24b83fb6..4d4d27b3f 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp @@ -20,6 +20,10 @@ static const std::unordered_map percentColors = { { "w { "b", QM_BLUE }, { "c", QM_LBLUE }, { "p", QM_PINK }, { "y", QM_YELLOW }, { "B", QM_BLACK } }; +static const std::unordered_map colorToPercent = { { QM_WHITE, "%w" }, { QM_RED, "%r"}, { QM_GREEN, "%g" }, + { QM_BLUE, "%b" }, { QM_LBLUE, "%c"}, { QM_PINK, "%p" }, + { QM_YELLOW, "%y" }, { QM_BLACK, "%B" } }; + static const std::unordered_map altarIcons = { { "0", ITEM_KOKIRI_EMERALD }, { "1", ITEM_GORON_RUBY }, @@ -147,6 +151,8 @@ void CustomMessage::ProcessMessageFormat(std::string& str, MessageFormat format) CleanString(str); } else if (format == MF_AUTO_FORMAT){ AutoFormatString(str); + }else if (format == MF_ENCODE){ + EncodeColors(str); } } @@ -281,6 +287,12 @@ void CustomMessage::Clean() { } } +void CustomMessage::Encode() { + for (std::string& str : messages) { + EncodeColors(str); + } +} + 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]); @@ -330,6 +342,15 @@ static size_t NextLineLength(const std::string* textStr, const size_t lastNewlin nextPosJump = 1; // Assume worst case for player name 12 * 8 (widest character * longest name length) totalPixelWidth += 96; + } else if (textStr->at(currentPos) == '\x05') { + // Skip colour control characters. + nextPosJump = 2; + } else if (textStr->at(currentPos) == '\x1E') { + //For the high score char, we have to take the next Char, then use that to get a worst case scenario. + if (textStr->at(currentPos+1) == '\x01'){ + totalPixelWidth += 28; + } + nextPosJump = 2; } else { // Some characters only one byte while others are two bytes // So check both possibilities when checking for a character @@ -355,6 +376,65 @@ static size_t NextLineLength(const std::string* textStr, const size_t lastNewlin } } +size_t CustomMessage::FindNEWLINE(std::string& str, size_t lastNewline) const { + size_t newLine = str.find(NEWLINE()[0], lastNewline); + bool done; + + // Bail out early + if (newLine == std::string::npos) { + return newLine; + } + + do { + done = true; + if (newLine != 0) { + switch (str[newLine - 1]) { + case '\x05': // COLOR + case '\x06': // SHIFT + case '\x07': // TEXTID + case '\x0C': // BOX_BREAK_DELAYED + case '\x0E': // FADE + case '\x11': // FADE2 + case '\x12': // SFX + case '\x13': // ITEM_ICON + case '\x14': // TEXT_SPEED + case '\x15': // BACKGROUND + case '\x1E': // POINTS/HIGH_SCORE + done = false; + break; + default: + break; + } + if (newLine > 1) { + switch (str[newLine - 2]) { + case '\x07': // TEXTID + case '\x11': // FADE2 + case '\x12': // SFX + case '\x15': // BACKGROUND + done = false; + break; + default: + break; + } + if (newLine > 2) { + if (str[newLine - 3] == '\x15') { // BACKGROUND + done = false; + } + } + } + } + if (!done) { + newLine = str.find(NEWLINE()[0], newLine + 1); + if (newLine == std::string::npos) { + // if we reach the end of the string, quit now to save a loop + done = true; + } + } + } while (!done); + + return newLine; +} + void CustomMessage::AutoFormatString(std::string& str) const { ReplaceAltarIcons(str); ReplaceColors(str); @@ -369,7 +449,7 @@ void CustomMessage::AutoFormatString(std::string& str) const { 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); + size_t newLine = FindNEWLINE(str, lastNewline); if (carrot < waitForInput){ waitForInput = carrot; } @@ -506,7 +586,23 @@ const char* Interface_ReplaceSpecialCharacters(char text[]) { return textChar; } +void CustomMessage::EncodeColors(std::string& str) const { + for (std::string color: colors) { + if (const size_t firstHashtag = str.find('#'); firstHashtag != std::string::npos) { + str.replace(firstHashtag, 1, colorToPercent.at(color)); + if (const size_t secondHashtag = str.find('#', firstHashtag + 1); secondHashtag != std::string::npos) { + str.replace(secondHashtag, 1, "%w"); + } else { + SPDLOG_DEBUG("non-matching hashtags in string: \"%s\"", str); + } + } + } + // Remove any remaining '#' characters. + std::erase(str, '#'); +} + void CustomMessage::ReplaceColors(std::string& str) const { + EncodeColors(str); for (const auto& colorPair : percentColors) { std::string textToReplace = "%"; textToReplace += colorPair.first; @@ -516,18 +612,6 @@ void CustomMessage::ReplaceColors(std::string& str) const { 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, '#'); } void CustomMessage::ReplaceAltarIcons(std::string& str) const { @@ -619,6 +703,8 @@ CustomMessage CustomMessageManager::RetrieveMessage(std::string tableID, uint16_ message.AutoFormat(); } else if (format == MF_CLEAN){ message.Clean(); + } else if (format == MF_ENCODE){ + message.Encode(); } return message; diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.h b/soh/soh/Enhancements/custom-message/CustomMessageManager.h index 31455aa40..e8a969064 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.h @@ -26,7 +26,8 @@ typedef enum { MF_FORMATTED, MF_CLEAN, MF_RAW, - MF_AUTO_FORMAT + MF_AUTO_FORMAT, + MF_ENCODE, } MessageFormat; /** @@ -108,6 +109,11 @@ class CustomMessage { */ void ReplaceSpecialCharacters(std::string& str) const; + /** + * @brief Replaces hashtags with stored colors. + */ + void EncodeColors(std::string& str) const; + /** * @brief Replaces our color variable strings with the OoT control codes. */ @@ -160,6 +166,11 @@ class CustomMessage { */ void Clean(); + /** + * @brief Replaces variable characters with fixed ones to store the sata in string form + */ + void Encode(); + /** * @brief Replaces various symbols with the control codes necessary to * display them in OoT's textboxes for a single string @@ -167,6 +178,12 @@ class CustomMessage { */ void FormatString(std::string& str) const; + /** + * @brief finds NEWLINEs in a string, while filtering + * /x01's that are used as opperands + */ + size_t FindNEWLINE(std::string& str, size_t lastNewline) const; + /** * @brief formats the string specifically to fit in OoT's * textboxes, and use it's formatting. @@ -280,7 +297,7 @@ class MessageNotFoundException : public std::exception { : messageTableId(std::move(messageTableId_)), textId(textId_) { } virtual const char* what() const noexcept { - char* message; + static char message[500]; sprintf(message, "Message from table %s with textId %u was not found", messageTableId.c_str(), textId); return message; } diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index f1f3ac76b..f2e7733a2 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -6,6 +6,7 @@ #include #include #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" #include #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/cosmetics/CosmeticsEditor.h" @@ -518,6 +519,8 @@ static bool SaveStateHandler(std::shared_ptr Console, const std:: case SaveStateReturn::FAIL_WRONG_GAMESTATE: ERROR_MESSAGE("[SOH] Can not save a state outside of \"GamePlay\""); return 1; + default: + return 1; } } @@ -538,6 +541,8 @@ static bool LoadStateHandler(std::shared_ptr Console, const std:: case SaveStateReturn::FAIL_WRONG_GAMESTATE: ERROR_MESSAGE("[SOH] Can not load a state outside of \"GamePlay\""); return 1; + default: + return 1; } } @@ -1307,6 +1312,7 @@ static constexpr std::array, COSMETICS_GRO {"trials", COSMETICS_GROUP_TRAILS}, {"navi", COSMETICS_GROUP_NAVI}, {"ivan", COSMETICS_GROUP_IVAN}, + {"message", COSMETICS_GROUP_MESSAGE}, }}; static bool CosmeticsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { @@ -1590,5 +1596,5 @@ void DebugConsole_Init(void) { {"group_name", Ship::ArgumentType::TEXT, true}, }}); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } diff --git a/soh/soh/Enhancements/debugger/MessageViewer.cpp b/soh/soh/Enhancements/debugger/MessageViewer.cpp index 5b23c1876..7ae34b4a8 100644 --- a/soh/soh/Enhancements/debugger/MessageViewer.cpp +++ b/soh/soh/Enhancements/debugger/MessageViewer.cpp @@ -6,6 +6,7 @@ #include "../custom-message/CustomMessageManager.h" #include "functions.h" #include "macros.h" +#include "soh/cvar_prefixes.h" #include "message_data_static.h" #include "variables.h" #include "soh/util.h" diff --git a/soh/soh/Enhancements/debugger/actorViewer.cpp b/soh/soh/Enhancements/debugger/actorViewer.cpp index bea2d5b87..c6ac49a74 100644 --- a/soh/soh/Enhancements/debugger/actorViewer.cpp +++ b/soh/soh/Enhancements/debugger/actorViewer.cpp @@ -13,6 +13,7 @@ #include #include #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" extern "C" { #include @@ -1174,7 +1175,7 @@ void ActorViewerWindow::DrawElement() { Actor_Spawn(&gPlayState->actorCtx, gPlayState, newActor.id, newActor.pos.x, newActor.pos.y, newActor.pos.z, newActor.rot.x, newActor.rot.y, newActor.rot.z, newActor.params, 0); } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } @@ -1187,7 +1188,7 @@ void ActorViewerWindow::DrawElement() { newActor.pos.y, newActor.pos.z, newActor.rot.x, newActor.rot.y, newActor.rot.z, newActor.params); } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } } diff --git a/soh/soh/Enhancements/debugger/colViewer.cpp b/soh/soh/Enhancements/debugger/colViewer.cpp index 8ce5f8b50..2cba03f5b 100644 --- a/soh/soh/Enhancements/debugger/colViewer.cpp +++ b/soh/soh/Enhancements/debugger/colViewer.cpp @@ -8,12 +8,14 @@ #include #include #include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" extern "C" { #include #include "variables.h" #include "functions.h" #include "macros.h" +#include "soh/cvar_prefixes.h" extern PlayState* gPlayState; } @@ -60,7 +62,7 @@ void ColViewerWindow::DrawElement() { UIWidgets::LabeledRightAlignedEnhancementCombobox("Col Check", CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), ColRenderSettingNames, COLVIEW_DISABLED); UIWidgets::LabeledRightAlignedEnhancementCombobox("Waterbox", CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), ColRenderSettingNames, COLVIEW_DISABLED); - UIWidgets::EnhancementCheckbox("Apply as decal", CVAR_DEVELOPER_TOOLS("ColViewer.Decal")); + UIWidgets::EnhancementCheckbox("Apply as decal", CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), false, "", UIWidgets::CheckboxGraphics::Cross, true); UIWidgets::InsertHelpHoverText("Applies the collision as a decal display. This can be useful if there is z-fighting occuring " "with the scene geometry, but can cause other artifacts."); UIWidgets::EnhancementCheckbox("Shaded", CVAR_DEVELOPER_TOOLS("ColViewer.Shaded")); @@ -276,11 +278,6 @@ void CreateSphereData() { sphereGfx.push_back(gsSPEndDisplayList()); } -void ColViewerWindow::InitElement() { - CreateCylinderData(); - CreateSphereData(); -} - // Initializes the display list for a ColRenderSetting void InitGfx(std::vector& gfx, ColRenderSetting setting) { uint32_t rm; @@ -302,7 +299,7 @@ void InitGfx(std::vector& gfx, ColRenderSetting setting) { alpha = 0xFF; } - if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), 0) != 0) { + if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), 1) != 0) { rm |= ZMODE_DEC; } else if (setting == ColRenderSetting::Transparent) { rm |= ZMODE_XLU; @@ -689,3 +686,10 @@ extern "C" void DrawColViewer() { CLOSE_DISPS(gPlayState->state.gfxCtx); } + +void ColViewerWindow::InitElement() { + CreateCylinderData(); + CreateSphereData(); + + GameInteractor::Instance->RegisterGameHook(DrawColViewer); +} diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index a5126d32e..807c269d3 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -18,6 +18,7 @@ extern "C" { #include "variables.h" #include "functions.h" #include "macros.h" +#include "soh/cvar_prefixes.h" #include "soh/Enhancements/randomizer/adult_trade_shuffle.h" extern PlayState* gPlayState; @@ -1206,7 +1207,7 @@ void DrawQuestStatusTab() { ImGui::SameLine(); DrawQuestItemButton(QUEST_GERUDO_CARD); - for (const SongMapEntry& entry : songMapping) { + for (const auto& [quest, entry] : songMapping) { if ((entry.id != QUEST_SONG_MINUET) && (entry.id != QUEST_SONG_LULLABY)) { ImGui::SameLine(); } diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 30e4473c1..8eb939ec8 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -348,7 +348,7 @@ const std::vector flagTables = { { 0x24, "Market Crowd Text Randomizer" }, { 0x30, "Entered the Market" }, } }, - { "Randomizer Inf Flags", RANDOMIZER_INF, 16, { + { "Randomizer Inf Flags", RANDOMIZER_INF, (RAND_INF_MAX + 15) / 16, { { RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" }, { RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" }, @@ -511,6 +511,548 @@ const std::vector flagTables = { { 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_KF_LINKS_HOUSE_POT, "RAND_INF_KF_LINKS_HOUSE_POT" }, + { RAND_INF_KF_TWINS_HOUSE_POT_1, "RAND_INF_KF_TWINS_HOUSE_POT_1" }, + { RAND_INF_KF_TWINS_HOUSE_POT_2, "RAND_INF_KF_TWINS_HOUSE_POT_2" }, + { RAND_INF_KF_BROTHERS_HOUSE_POT_1, "RAND_INF_KF_BROTHERS_HOUSE_POT_1" }, + { RAND_INF_KF_BROTHERS_HOUSE_POT_2, "RAND_INF_KF_BROTHERS_HOUSE_POT_2" }, + { RAND_INF_GF_BREAK_ROOM_POT_1, "RAND_INF_GF_BREAK_ROOM_POT_1" }, + { RAND_INF_GF_BREAK_ROOM_POT_2, "RAND_INF_GF_BREAK_ROOM_POT_2" }, + { RAND_INF_GF_KITCHEN_POT_1, "RAND_INF_GF_KITCHEN_POT_1" }, + { RAND_INF_GF_KITCHEN_POT_2, "RAND_INF_GF_KITCHEN_POT_2" }, + { RAND_INF_GF_NORTH_F1_CARPENTER_POT_1, "RAND_INF_GF_NORTH_F1_CARPENTER_POT_1" }, + { RAND_INF_GF_NORTH_F1_CARPENTER_POT_2, "RAND_INF_GF_NORTH_F1_CARPENTER_POT_2" }, + { RAND_INF_GF_NORTH_F1_CARPENTER_POT_3, "RAND_INF_GF_NORTH_F1_CARPENTER_POT_3" }, + { RAND_INF_GF_NORTH_F2_CARPENTER_POT_1, "RAND_INF_GF_NORTH_F2_CARPENTER_POT_1" }, + { RAND_INF_GF_NORTH_F2_CARPENTER_POT_2, "RAND_INF_GF_NORTH_F2_CARPENTER_POT_2" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1, "RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2, "RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3, "RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4" }, + { RAND_INF_WASTELAND_NEAR_GS_POT_1, "RAND_INF_WASTELAND_NEAR_GS_POT_1" }, + { RAND_INF_WASTELAND_NEAR_GS_POT_2, "RAND_INF_WASTELAND_NEAR_GS_POT_2" }, + { RAND_INF_WASTELAND_NEAR_GS_POT_3, "RAND_INF_WASTELAND_NEAR_GS_POT_3" }, + { RAND_INF_WASTELAND_NEAR_GS_POT_4, "RAND_INF_WASTELAND_NEAR_GS_POT_4" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11" }, + { RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1, "RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1" }, + { RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2, "RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2" }, + { RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3, "RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3" }, + { RAND_INF_KAK_NEAR_POTION_SHOP_POT_1, "RAND_INF_KAK_NEAR_POTION_SHOP_POT_1" }, + { RAND_INF_KAK_NEAR_POTION_SHOP_POT_2, "RAND_INF_KAK_NEAR_POTION_SHOP_POT_2" }, + { RAND_INF_KAK_NEAR_POTION_SHOP_POT_3, "RAND_INF_KAK_NEAR_POTION_SHOP_POT_3" }, + { RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1, "RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1" }, + { RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2, "RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2" }, + { RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3, "RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3" }, + { RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1, "RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1" }, + { RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2, "RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2" }, + { RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3, "RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3" }, + { RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1, "RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1" }, + { RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2, "RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_1, "RAND_INF_GY_DAMPES_GRAVE_POT_1" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_2, "RAND_INF_GY_DAMPES_GRAVE_POT_2" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_3, "RAND_INF_GY_DAMPES_GRAVE_POT_3" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_4, "RAND_INF_GY_DAMPES_GRAVE_POT_4" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_5, "RAND_INF_GY_DAMPES_GRAVE_POT_5" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_6, "RAND_INF_GY_DAMPES_GRAVE_POT_6" }, + { RAND_INF_GC_LOWER_STAIRCASE_POT_1, "RAND_INF_GC_LOWER_STAIRCASE_POT_1" }, + { RAND_INF_GC_LOWER_STAIRCASE_POT_2, "RAND_INF_GC_LOWER_STAIRCASE_POT_2" }, + { RAND_INF_GC_UPPER_STAIRCASE_POT_1, "RAND_INF_GC_UPPER_STAIRCASE_POT_1" }, + { RAND_INF_GC_UPPER_STAIRCASE_POT_2, "RAND_INF_GC_UPPER_STAIRCASE_POT_2" }, + { RAND_INF_GC_UPPER_STAIRCASE_POT_3, "RAND_INF_GC_UPPER_STAIRCASE_POT_3" }, + { RAND_INF_GC_MEDIGORON_POT_1, "RAND_INF_GC_MEDIGORON_POT_1" }, + { RAND_INF_GC_DARUNIA_POT_1, "RAND_INF_GC_DARUNIA_POT_1" }, + { RAND_INF_GC_DARUNIA_POT_2, "RAND_INF_GC_DARUNIA_POT_2" }, + { RAND_INF_GC_DARUNIA_POT_3, "RAND_INF_GC_DARUNIA_POT_3" }, + { RAND_INF_DMC_NEAR_GC_POT_1, "RAND_INF_DMC_NEAR_GC_POT_1" }, + { RAND_INF_DMC_NEAR_GC_POT_2, "RAND_INF_DMC_NEAR_GC_POT_2" }, + { RAND_INF_DMC_NEAR_GC_POT_3, "RAND_INF_DMC_NEAR_GC_POT_3" }, + { RAND_INF_DMC_NEAR_GC_POT_4, "RAND_INF_DMC_NEAR_GC_POT_4" }, + { RAND_INF_ZD_NEAR_SHOP_POT_1, "RAND_INF_ZD_NEAR_SHOP_POT_1" }, + { RAND_INF_ZD_NEAR_SHOP_POT_2, "RAND_INF_ZD_NEAR_SHOP_POT_2" }, + { RAND_INF_ZD_NEAR_SHOP_POT_3, "RAND_INF_ZD_NEAR_SHOP_POT_3" }, + { RAND_INF_ZD_NEAR_SHOP_POT_4, "RAND_INF_ZD_NEAR_SHOP_POT_4" }, + { RAND_INF_ZD_NEAR_SHOP_POT_5, "RAND_INF_ZD_NEAR_SHOP_POT_5" }, + { RAND_INF_ZF_HIDDEN_CAVE_POT_1, "RAND_INF_ZF_HIDDEN_CAVE_POT_1" }, + { RAND_INF_ZF_HIDDEN_CAVE_POT_2, "RAND_INF_ZF_HIDDEN_CAVE_POT_2" }, + { RAND_INF_ZF_HIDDEN_CAVE_POT_3, "RAND_INF_ZF_HIDDEN_CAVE_POT_3" }, + { RAND_INF_ZF_NEAR_JABU_POT_1, "RAND_INF_ZF_NEAR_JABU_POT_1" }, + { RAND_INF_ZF_NEAR_JABU_POT_2, "RAND_INF_ZF_NEAR_JABU_POT_2" }, + { RAND_INF_ZF_NEAR_JABU_POT_3, "RAND_INF_ZF_NEAR_JABU_POT_3" }, + { RAND_INF_ZF_NEAR_JABU_POT_4, "RAND_INF_ZF_NEAR_JABU_POT_4" }, + { RAND_INF_LLR_FRONT_POT_1, "RAND_INF_LLR_FRONT_POT_1" }, + { RAND_INF_LLR_FRONT_POT_2, "RAND_INF_LLR_FRONT_POT_2" }, + { RAND_INF_LLR_FRONT_POT_3, "RAND_INF_LLR_FRONT_POT_3" }, + { RAND_INF_LLR_FRONT_POT_4, "RAND_INF_LLR_FRONT_POT_4" }, + { RAND_INF_LLR_RAIN_SHED_POT_1, "RAND_INF_LLR_RAIN_SHED_POT_1" }, + { RAND_INF_LLR_RAIN_SHED_POT_2, "RAND_INF_LLR_RAIN_SHED_POT_2" }, + { RAND_INF_LLR_RAIN_SHED_POT_3, "RAND_INF_LLR_RAIN_SHED_POT_3" }, + { RAND_INF_LLR_TALONS_HOUSE_POT_1, "RAND_INF_LLR_TALONS_HOUSE_POT_1" }, + { RAND_INF_LLR_TALONS_HOUSE_POT_2, "RAND_INF_LLR_TALONS_HOUSE_POT_2" }, + { RAND_INF_LLR_TALONS_HOUSE_POT_3, "RAND_INF_LLR_TALONS_HOUSE_POT_3" }, + { RAND_INF_HF_COW_GROTTO_POT_1, "RAND_INF_HF_COW_GROTTO_POT_1" }, + { RAND_INF_HF_COW_GROTTO_POT_2, "RAND_INF_HF_COW_GROTTO_POT_2" }, + { RAND_INF_HC_STORMS_GROTTO_POT_1, "RAND_INF_HC_STORMS_GROTTO_POT_1" }, + { RAND_INF_HC_STORMS_GROTTO_POT_2, "RAND_INF_HC_STORMS_GROTTO_POT_2" }, + { RAND_INF_HC_STORMS_GROTTO_POT_3, "RAND_INF_HC_STORMS_GROTTO_POT_3" }, + { RAND_INF_HC_STORMS_GROTTO_POT_4, "RAND_INF_HC_STORMS_GROTTO_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6" }, + { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1, "RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2, "RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_BLADE_POT_1, "RAND_INF_DODONGOS_CAVERN_BLADE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_BLADE_POT_2, "RAND_INF_DODONGOS_CAVERN_BLADE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, "RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, "RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4" }, + { RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, "RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, "RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, "RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6" }, + { RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1, "RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2, "RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3, "RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3" }, + { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3" }, + { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4" }, + { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_1, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_1" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_2, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_2" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_3, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_3" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_4, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_4" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_5, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_5" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_6, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_6" }, + { RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1" }, + { RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2" }, + { RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1, "RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1" }, + { RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2, "RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2" }, + { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1" }, + { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2" }, + { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3" }, + { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4" }, + { RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1, "RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1" }, + { RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2, "RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2" }, + { RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3, "RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3" }, + { RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1, "RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1" }, + { RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2, "RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2" }, + { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1" }, + { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2" }, + { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3" }, + { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4" }, + { RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1, "RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1" }, + { RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2, "RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2" }, + { RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3, "RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4" }, + { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1" }, + { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2" }, + { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1" }, + { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2" }, + { RAND_INF_WATER_TEMPLE_TORCH_POT_1, "RAND_INF_WATER_TEMPLE_TORCH_POT_1" }, + { RAND_INF_WATER_TEMPLE_TORCH_POT_2, "RAND_INF_WATER_TEMPLE_TORCH_POT_2" }, + { RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1, "RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1" }, + { RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2, "RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2" }, + { RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3, "RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3" }, + { RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1, "RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1" }, + { RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2, "RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2" }, + { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1" }, + { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2" }, + { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3" }, + { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4" }, + { RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, "RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1" }, + { RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, "RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2" }, + { RAND_INF_WATER_TEMPLE_RIVER_POT_1, "RAND_INF_WATER_TEMPLE_RIVER_POT_1" }, + { RAND_INF_WATER_TEMPLE_RIVER_POT_2, "RAND_INF_WATER_TEMPLE_RIVER_POT_2" }, + { RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1, "RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1" }, + { RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2, "RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2" }, + { RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1, "RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1" }, + { RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2, "RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, "RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3" }, + { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4" }, + { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5" }, + { RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1, "RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2, "RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3" }, + { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1, "RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2, "RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, "RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1, "RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2, "RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1, "RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2, "RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, "RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, "RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, "RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6" }, + { RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, "RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1" }, + { RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3, "RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4" }, + { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, "RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1" }, + { RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12" }, + { RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3" }, + { RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT, "RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT" }, + { RAND_INF_ICE_CAVERN_HALL_POT_1, "RAND_INF_ICE_CAVERN_HALL_POT_1" }, + { RAND_INF_ICE_CAVERN_HALL_POT_2, "RAND_INF_ICE_CAVERN_HALL_POT_2" }, + { RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1, "RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1" }, + { RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2, "RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2" }, + { RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3, "RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3" }, + { RAND_INF_ICE_CAVERN_NEAR_END_POT_1, "RAND_INF_ICE_CAVERN_NEAR_END_POT_1" }, + { RAND_INF_ICE_CAVERN_NEAR_END_POT_2, "RAND_INF_ICE_CAVERN_NEAR_END_POT_2" }, + { RAND_INF_ICE_CAVERN_FROZEN_POT_1, "RAND_INF_ICE_CAVERN_FROZEN_POT_1" }, + + { RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3" }, + { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4" }, + { RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3" }, + { RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3" }, + { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3" }, + { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4" }, + { RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4" }, + { RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, "RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT" }, + { RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3" }, + { RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3" }, + { RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3" }, + { RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8" }, + { RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT, "RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT" }, + { RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, "RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1" }, + { RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, "RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2" }, + { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1" }, + { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2" }, + { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3" }, + { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4" }, + { RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, "RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1" }, + { RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, "RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2" }, + { RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1, "RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1" }, + { RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2, "RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3" }, + { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4" }, + { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5" }, + { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3" }, + { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3" }, + { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4" }, + { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5" }, + { RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, "RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, "RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1, "RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2, "RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, "RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, "RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, "RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, "RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, "RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, "RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, "RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4" }, + { RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT, "RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT" }, + { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1" }, + { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2" }, + { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1" }, + { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2" }, + { RAND_INF_CAUGHT_LOACH, "RAND_INF_CAUGHT_LOACH" }, { RAND_INF_CAN_SWIM, "RAND_INF_CAN_SWIM" }, @@ -621,6 +1163,394 @@ const std::vector flagTables = { { 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" }, + + { RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE, "RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE" }, + { RAND_INF_KF_NORTH_GRASS_WEST_RUPEE, "RAND_INF_KF_NORTH_GRASS_WEST_RUPEE" }, + { RAND_INF_KF_NORTH_GRASS_EAST_RUPEE, "RAND_INF_KF_NORTH_GRASS_EAST_RUPEE" }, + { RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE, "RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE" }, + { RAND_INF_KF_SARIAS_TOP_LEFT_HEART, "RAND_INF_KF_SARIAS_TOP_LEFT_HEART" }, + { RAND_INF_KF_SARIAS_TOP_RIGHT_HEART, "RAND_INF_KF_SARIAS_TOP_RIGHT_HEART" }, + { RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART, "RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART" }, + { RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART, "RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART" }, + { RAND_INF_KF_BEAN_RUPEE_1, "RAND_INF_KF_BEAN_RUPEE_1" }, + { RAND_INF_KF_BEAN_RUPEE_2, "RAND_INF_KF_BEAN_RUPEE_2" }, + { RAND_INF_KF_BEAN_RUPEE_3, "RAND_INF_KF_BEAN_RUPEE_3" }, + { RAND_INF_KF_BEAN_RUPEE_4, "RAND_INF_KF_BEAN_RUPEE_4" }, + { RAND_INF_KF_BEAN_RUPEE_5, "RAND_INF_KF_BEAN_RUPEE_5" }, + { RAND_INF_KF_BEAN_RUPEE_6, "RAND_INF_KF_BEAN_RUPEE_6" }, + { RAND_INF_KF_BEAN_RED_RUPEE, "RAND_INF_KF_BEAN_RED_RUPEE" }, + { RAND_INF_LW_SHORTCUT_RUPEE_1, "RAND_INF_LW_SHORTCUT_RUPEE_1" }, + { RAND_INF_LW_SHORTCUT_RUPEE_2, "RAND_INF_LW_SHORTCUT_RUPEE_2" }, + { RAND_INF_LW_SHORTCUT_RUPEE_3, "RAND_INF_LW_SHORTCUT_RUPEE_3" }, + { RAND_INF_LW_SHORTCUT_RUPEE_4, "RAND_INF_LW_SHORTCUT_RUPEE_4" }, + { RAND_INF_LW_SHORTCUT_RUPEE_5, "RAND_INF_LW_SHORTCUT_RUPEE_5" }, + { RAND_INF_LW_SHORTCUT_RUPEE_6, "RAND_INF_LW_SHORTCUT_RUPEE_6" }, + { RAND_INF_LW_SHORTCUT_RUPEE_7, "RAND_INF_LW_SHORTCUT_RUPEE_7" }, + { RAND_INF_LW_SHORTCUT_RUPEE_8, "RAND_INF_LW_SHORTCUT_RUPEE_8" }, + { RAND_INF_LH_FRONT_RUPEE, "RAND_INF_LH_FRONT_RUPEE" }, + { RAND_INF_LH_MIDDLE_RUPEE, "RAND_INF_LH_MIDDLE_RUPEE" }, + { RAND_INF_LH_BACK_RUPEE, "RAND_INF_LH_BACK_RUPEE" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE" }, + { RAND_INF_DMT_BLUE_RUPEE, "RAND_INF_DMT_BLUE_RUPEE" }, + { RAND_INF_DMT_COW_GROTTO_LEFT_HEART, "RAND_INF_DMT_COW_GROTTO_LEFT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, "RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, "RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_RIGHT_HEART, "RAND_INF_DMT_COW_GROTTO_RIGHT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_1, "RAND_INF_DMT_COW_GROTTO_RUPEE_1" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_2, "RAND_INF_DMT_COW_GROTTO_RUPEE_2" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_3, "RAND_INF_DMT_COW_GROTTO_RUPEE_3" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_4, "RAND_INF_DMT_COW_GROTTO_RUPEE_4" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_5, "RAND_INF_DMT_COW_GROTTO_RUPEE_5" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_6, "RAND_INF_DMT_COW_GROTTO_RUPEE_6" }, + { RAND_INF_DMT_COW_GROTTO_RED_RUPEE, "RAND_INF_DMT_COW_GROTTO_RED_RUPEE" }, + { RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE, "RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE, "RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE, "RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE" }, + { RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART, "RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART" }, + { RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART, "RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART" }, + { RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART" }, + { RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART" }, + { RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART" }, + { RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART, "RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART" }, + { RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, "RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART" }, + { RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, "RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART" }, + { RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, "RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART" }, + { RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART, "RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART" }, + { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART" }, + { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART" }, + { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_1, "RAND_INF_WATER_TEMPLE_RIVER_HEART_1" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_2, "RAND_INF_WATER_TEMPLE_RIVER_HEART_2" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_3, "RAND_INF_WATER_TEMPLE_RIVER_HEART_3" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_4, "RAND_INF_WATER_TEMPLE_RIVER_HEART_4" }, + { RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, "RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, "RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART" }, + { RAND_INF_ICE_CAVERN_LOBBY_RUPEE, "RAND_INF_ICE_CAVERN_LOBBY_RUPEE" }, + { RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART" }, + { RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART" }, + { RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART" }, + { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1" }, + { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2" }, + { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3" }, + { RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART" }, + { RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, "RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART" }, + { RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, "RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3" }, + { RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART" }, + { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART" }, + { RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART, "RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART" }, + { RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART, "RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART" }, + { RAND_INF_DEKU_TREE_MQ_LOBBY_HEART, "RAND_INF_DEKU_TREE_MQ_LOBBY_HEART" }, + { RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, "RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART" }, + { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART" }, + { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART" }, + { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART" }, + { RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, "RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, "RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, "RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART" }, + { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART" }, + { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART" }, + { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART" }, + { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART" }, + { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART" }, + + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_1, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_1" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_2, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_2" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_3, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_3" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_4, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_4" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_5, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_5" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_6, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_6" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_7, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_7" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_8, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_8" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_1, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_1" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_2, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_2" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_3, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_3" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_4, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_4" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_5, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_5" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_6, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_6" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_7, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_7" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_8, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_8" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_1, "RAND_INF_COLOSSUS_OASIS_FAIRY_1" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_2, "RAND_INF_COLOSSUS_OASIS_FAIRY_2" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_3, "RAND_INF_COLOSSUS_OASIS_FAIRY_3" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_4, "RAND_INF_COLOSSUS_OASIS_FAIRY_4" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_5, "RAND_INF_COLOSSUS_OASIS_FAIRY_5" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_6, "RAND_INF_COLOSSUS_OASIS_FAIRY_6" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_7, "RAND_INF_COLOSSUS_OASIS_FAIRY_7" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_8, "RAND_INF_COLOSSUS_OASIS_FAIRY_8" }, + + { RAND_INF_ZR_BEAN_SPROUT_FAIRY_1, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_ZR_BEAN_SPROUT_FAIRY_2, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_ZR_BEAN_SPROUT_FAIRY_3, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_KF_BEAN_SPROUT_FAIRY_1, "RAND_INF_KF_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_KF_BEAN_SPROUT_FAIRY_2, "RAND_INF_KF_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_KF_BEAN_SPROUT_FAIRY_3, "RAND_INF_KF_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3" }, + { RAND_INF_LH_BEAN_SPROUT_FAIRY_1, "RAND_INF_LH_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_LH_BEAN_SPROUT_FAIRY_2, "RAND_INF_LH_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_LH_BEAN_SPROUT_FAIRY_3, "RAND_INF_LH_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_GV_BEAN_SPROUT_FAIRY_1, "RAND_INF_GV_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_GV_BEAN_SPROUT_FAIRY_2, "RAND_INF_GV_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_GV_BEAN_SPROUT_FAIRY_3, "RAND_INF_GV_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_DMC_BEAN_SPROUT_FAIRY_1, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_DMC_BEAN_SPROUT_FAIRY_2, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_DMC_BEAN_SPROUT_FAIRY_3, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_DMT_BEAN_SPROUT_FAIRY_1, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_DMT_BEAN_SPROUT_FAIRY_2, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_DMT_BEAN_SPROUT_FAIRY_3, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_3" }, + + { RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY" }, + { RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY" }, + { RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY" }, + { RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY" }, + { RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DMC_GOSSIP_STONE_FAIRY, "RAND_INF_DMC_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DMT_GOSSIP_STONE_FAIRY, "RAND_INF_DMT_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY, "RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY" }, + { RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, "RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, "RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_GV_GOSSIP_STONE_FAIRY, "RAND_INF_GV_GOSSIP_STONE_FAIRY" }, + { RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY, "RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY" }, + { RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY, "RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY" }, + { RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY, "RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY" }, + { RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY, "RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, "RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, "RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY" }, + { RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, "RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY" }, + { RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_KF_GOSSIP_STONE_FAIRY, "RAND_INF_KF_GOSSIP_STONE_FAIRY" }, + { RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY, "RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY" }, + { RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, "RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY" }, + { RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, "RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY" }, + { RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_LW_GOSSIP_STONE_FAIRY, "RAND_INF_LW_GOSSIP_STONE_FAIRY" }, + { RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY" }, + { RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY" }, + { RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY" }, + { RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZD_GOSSIP_STONE_FAIRY, "RAND_INF_ZD_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY, "RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY, "RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + + { RAND_INF_LH_ISLAND_SUN_FAIRY, "RAND_INF_LH_ISLAND_SUN_FAIRY" }, + { RAND_INF_HF_POND_STORMS_FAIRY, "RAND_INF_HF_POND_STORMS_FAIRY" }, + { RAND_INF_DMT_FLAG_SUN_FAIRY, "RAND_INF_DMT_FLAG_SUN_FAIRY" }, + { RAND_INF_LW_SHORTCUT_STORMS_FAIRY, "RAND_INF_LW_SHORTCUT_STORMS_FAIRY" }, + { RAND_INF_GF_KITCHEN_SUN_FAIRY, "RAND_INF_GF_KITCHEN_SUN_FAIRY" }, + { RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY" }, + { RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, "RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY" }, + { RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, "RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY" }, + { RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, "RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY" }, + { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY" }, + { RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, "RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY" }, + { RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, "RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY" }, + { RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY" }, + { RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY" }, + { RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY" }, } }, }; diff --git a/soh/soh/Enhancements/debugger/dlViewer.cpp b/soh/soh/Enhancements/debugger/dlViewer.cpp index 42b005a8c..fdfc8be1c 100644 --- a/soh/soh/Enhancements/debugger/dlViewer.cpp +++ b/soh/soh/Enhancements/debugger/dlViewer.cpp @@ -120,9 +120,9 @@ void DLViewerWindow::DrawElement() { } try { - auto res = std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource(activeDisplayList)); + auto res = std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource(activeDisplayList)); - if (res->GetInitData()->Type != static_cast(LUS::ResourceType::DisplayList)) { + if (res->GetInitData()->Type != static_cast(Fast::ResourceType::DisplayList)) { ImGui::Text("Resource type is not a Display List. Please choose another."); return; } diff --git a/soh/soh/Enhancements/debugger/hookDebugger.cpp b/soh/soh/Enhancements/debugger/hookDebugger.cpp index b31ddc396..8ee9b3391 100644 --- a/soh/soh/Enhancements/debugger/hookDebugger.cpp +++ b/soh/soh/Enhancements/debugger/hookDebugger.cpp @@ -4,14 +4,14 @@ #include #include -static std::unordered_map> hookData; +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) { + if ((*hookData[hookName]).size() == 0) { ImGui::TextColored(grey, "No hooks found"); return; } @@ -27,7 +27,7 @@ void DrawHookRegisteringInfos(const char* hookName) { //ImGui::TableSetupColumn("Stub"); ImGui::TableSetupColumn("Number of Calls"); ImGui::TableHeadersRow(); - for (auto& [id, hookInfo] : hookData[hookName]) { + for (auto& [id, hookInfo] : (*hookData[hookName])) { ImGui::TableNextRow(); ImGui::TableNextColumn(); @@ -100,12 +100,10 @@ void HookDebuggerWindow::DrawElement() { } } -void HookDebuggerWindow::UpdateElement() { - hookData.clear(); - +void HookDebuggerWindow::InitElement() { #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 index 90e6886b5..ae6f5113f 100644 --- a/soh/soh/Enhancements/debugger/hookDebugger.h +++ b/soh/soh/Enhancements/debugger/hookDebugger.h @@ -4,7 +4,7 @@ class HookDebuggerWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; - void InitElement() override {}; + void InitElement() override; void DrawElement() override; - void UpdateElement() override; + void UpdateElement() override {}; }; diff --git a/soh/soh/Enhancements/debugger/valueViewer.cpp b/soh/soh/Enhancements/debugger/valueViewer.cpp index c03be8ee1..a58512ea3 100644 --- a/soh/soh/Enhancements/debugger/valueViewer.cpp +++ b/soh/soh/Enhancements/debugger/valueViewer.cpp @@ -7,6 +7,7 @@ extern "C" { #include "variables.h" #include "functions.h" #include "macros.h" +#include "soh/cvar_prefixes.h" extern PlayState* gPlayState; void GfxPrint_SetColor(GfxPrint* printer, u32 r, u32 g, u32 b, u32 a); void GfxPrint_SetPos(GfxPrint* printer, s32 x, s32 y); diff --git a/soh/soh/Enhancements/enemyrandomizer.cpp b/soh/soh/Enhancements/enemyrandomizer.cpp index e0f82062c..89aab7e00 100644 --- a/soh/soh/Enhancements/enemyrandomizer.cpp +++ b/soh/soh/Enhancements/enemyrandomizer.cpp @@ -6,13 +6,13 @@ #include "soh/Enhancements/enhancementTypes.h" #include "variables.h" #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" +#include "soh/ResourceManagerHelpers.h" extern "C" { #include } -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"), diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h index ebc1b6fac..5e28024b6 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h @@ -217,7 +217,7 @@ namespace GameInteractionEffect { void _Apply() override; }; - class PressRandomButton: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + class PressRandomButton: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { GameInteractionEffectQueryResult CanBeApplied() override; void _Apply() override; }; diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index 6fa2c07c5..ea9c61914 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -54,13 +54,13 @@ typedef enum { } GIColors; typedef enum { - /* */ GI_TP_DEST_LINKSHOUSE = ENTR_LINKS_HOUSE_0, - /* */ GI_TP_DEST_MINUET = ENTR_SACRED_FOREST_MEADOW_2, - /* */ GI_TP_DEST_BOLERO = ENTR_DEATH_MOUNTAIN_CRATER_4, - /* */ GI_TP_DEST_SERENADE = ENTR_LAKE_HYLIA_8, - /* */ GI_TP_DEST_REQUIEM = ENTR_DESERT_COLOSSUS_5, - /* */ GI_TP_DEST_NOCTURNE = ENTR_GRAVEYARD_7, - /* */ GI_TP_DEST_PRELUDE = ENTR_TEMPLE_OF_TIME_7, + /* */ GI_TP_DEST_LINKSHOUSE = ENTR_LINKS_HOUSE_CHILD_SPAWN, + /* */ GI_TP_DEST_MINUET = ENTR_SACRED_FOREST_MEADOW_WARP_PAD, + /* */ GI_TP_DEST_BOLERO = ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, + /* */ GI_TP_DEST_SERENADE = ENTR_LAKE_HYLIA_WARP_PAD, + /* */ GI_TP_DEST_REQUIEM = ENTR_DESERT_COLOSSUS_WARP_PAD, + /* */ GI_TP_DEST_NOCTURNE = ENTR_GRAVEYARD_WARP_PAD, + /* */ GI_TP_DEST_PRELUDE = ENTR_TEMPLE_OF_TIME_WARP_PAD, } GITeleportDestinations; typedef enum { @@ -76,6 +76,7 @@ typedef enum { VB_MIDO_SPAWN, // Opt: *EnMd // Vanilla condition: EnMd->interactInfo.talkState == NPC_TALK_STATE_ACTION + // Note: When overriding this, ensure you're not in the intro cutscene as Mido's path has not been loaded VB_MOVE_MIDO_IN_KOKIRI_FOREST, // Opt: *EnMd // Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) @@ -117,7 +118,7 @@ typedef enum { /* Vanilla Condition: ``` LINK_IS_ADULT && - gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 && + gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) && Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) && Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) && @@ -126,6 +127,7 @@ typedef enum { */ VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, // Opt: *EnGo2 + VB_GORON_LINK_BE_SCARED, // 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) @@ -194,6 +196,9 @@ typedef enum { // Opt: *EnKz // Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED) VB_KING_ZORA_BE_MOVED, + // Opt: *EnKz, + // Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) + VB_KING_ZORA_TUNIC_CHECK, // Vanilla condition: gSaveState.bgsFlag VB_BIGGORON_CONSIDER_TRADE_COMPLETE, // Vanilla condition: gSaveState.bgsFlag @@ -244,6 +249,11 @@ typedef enum { ``` */ VB_DRAW_AMMO_COUNT, + // Opt: *ObjTsubo + VB_POT_SETUP_DRAW, + VB_POT_DROP_ITEM, + // Opt: *ActorDoorShutter + VB_LOCK_BOSS_DOOR, // Vanilla condition: true VB_HAVE_OCARINA_NOTE_D4, // Vanilla condition: true @@ -280,16 +290,26 @@ typedef enum { VB_SPAWN_BLUE_WARP, // Vanilla condition: this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF VB_BLUE_WARP_APPLY_ENTRANCE_AND_CUTSCENE, + // Vanilla condition: SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2 + // Opt: int (original next entrance index) + VB_SET_VOIDOUT_FROM_SURFACE, // 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, + // Opt: *EnFr + // Vanilla condition: this->reward == GI_NONE + VB_FROGS_GO_TO_IDLE, /*** Play Cutscenes ***/ VB_PLAY_TRANSITION_CS, + VB_PLAY_GORON_FREE_CS, + VB_PLAY_FIRE_ARROW_CS, + // Vanilla condition: INV_CONTENT(ITEM_ARROW_FIRE) == ITEM_NONE + VB_SPAWN_FIRE_ARROW, // Opt: *EventChkInf flag VB_PLAY_ENTRANCE_CS, // Opt: *cutsceneId @@ -305,6 +325,8 @@ typedef enum { // Vanilla condition: !EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL VB_PLAY_PULL_MASTER_SWORD_CS, VB_PLAY_DROP_FISH_FOR_JABU_CS, + // Opt: *EnKz + VB_PLAY_MWEEP_CS, // Vanilla condition: player->getItemId == GI_GAUNTLETS_SILVER VB_PLAY_NABOORU_CAPTURED_CS, VB_PLAY_ZELDAS_LULLABY_CS, @@ -338,9 +360,24 @@ typedef enum { VB_SHOULD_GIVE_VANILLA_FISHING_PRIZE, VB_GIVE_RANDO_FISHING_PRIZE, VB_PLAY_THROW_ANIMATION, + VB_INFLICT_VOID_DAMAGE, + // Vanilla condition: Close enough & various cutscene checks + // Opt: *EnRu1 + VB_PLAY_CHILD_RUTO_INTRO, + // Vanilla condition: !INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE && in the big okto room + // Opt: *EnRu1 + VB_RUTO_WANT_TO_BE_TOSSED_TO_SAPPHIRE, + // Vanilla condition: Landed on the platform in the big okto room + // Opt: *EnRu1 + VB_RUTO_RUN_TO_SAPPHIRE, + // Vanilla condition: !Flags_GetInfTable(INFTABLE_145) + // Opt: *EnRu1 + VB_RUTO_BE_CONSIDERED_NOT_KIDNAPPED, + /*** Give Items ***/ + VB_FREEZE_ON_SKULL_TOKEN, // Opt: *EnBox VB_GIVE_ITEM_FROM_CHEST, // Opt: ItemID @@ -349,7 +386,6 @@ typedef enum { VB_GIVE_ITEM_FROM_ITEM_00, // Opt: *EnSi VB_GIVE_ITEM_SKULL_TOKEN, - VB_FREEZE_ON_SKULL_TOKEN, // Opt: *EnCow VB_GIVE_ITEM_FROM_COW, // Opt: *EnDns @@ -362,9 +398,6 @@ typedef enum { 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: *EnGb @@ -378,8 +411,6 @@ typedef enum { 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 @@ -448,13 +479,13 @@ typedef enum { // Opt: *EnToryo VB_TRADE_SAW, // Opt: *EnKz, - VB_TRADE_PRESCRIPTION, + VB_ADULT_KING_ZORA_ITEM_GIVE, // Opt: *EnMk VB_TRADE_FROG, VB_TRADE_TIMER_ODD_MUSHROOM, - VB_TRADE_TIMER_EYEDROPS, VB_TRADE_TIMER_FROG, + VB_TRADE_TIMER_EYEDROPS, // Opt: *EnNiwLady VB_ANJU_SET_OBTAINED_TRADE_ITEM, @@ -479,6 +510,15 @@ typedef enum { // Vanilla condition: Actor is ACTOR_EN_ELF, ACTOR_EN_FISH, ACTOR_EN_ICE_HONO, or ACTOR_EN_INSECT // Opt: *Actor VB_BOTTLE_ACTOR, + + /*** Shuffle Fairies ***/ + // Opt: *EnElf + VB_SPAWN_FOUNTAIN_FAIRIES, + VB_FAIRY_HEAL, + // Opt: *ObjBean + VB_SPAWN_BEAN_STALK_FAIRIES, + // Opt: *EnGs + VB_SPAWN_GOSSIP_STONE_FAIRY, } GIVanillaBehavior; #ifdef __cplusplus @@ -561,15 +601,43 @@ struct HookInfo { #define GET_CURRENT_REGISTERING_INFO(type) HookRegisteringInfo{} #endif -#define REGISTER_VB_SHOULD(flag, body) \ +#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); \ + flag, [](GIVanillaBehavior _, bool* should, va_list _originalArgs) { \ + va_list args; \ + va_copy(args, _originalArgs); \ + body; \ + va_end(args); \ }) +#define COND_HOOK(hookType, condition, body) \ + { \ + static HOOK_ID hookId = 0; \ + GameInteractor::Instance->UnregisterGameHook(hookId); \ + hookId = 0; \ + if (condition) { \ + hookId = GameInteractor::Instance->RegisterGameHook(body); \ + } \ + } +#define COND_ID_HOOK(hookType, id, condition, body) \ + { \ + static HOOK_ID hookId = 0; \ + GameInteractor::Instance->UnregisterGameHookForID(hookId); \ + hookId = 0; \ + if (condition) { \ + hookId = GameInteractor::Instance->RegisterGameHookForID(id, body); \ + } \ + } +#define COND_VB_SHOULD(id, condition, body) \ + { \ + static HOOK_ID hookId = 0; \ + GameInteractor::Instance->UnregisterGameHookForID(hookId); \ + hookId = 0; \ + if (condition) { \ + hookId = REGISTER_VB_SHOULD(id, body); \ + } \ + } + class GameInteractor { public: static GameInteractor* Instance; @@ -625,8 +693,8 @@ public: inline static std::vector hooksForFilter; }; - template std::unordered_map GetHookData() { - return RegisteredGameHooks::hookData; + template std::unordered_map* GetHookData() { + return &RegisteredGameHooks::hookData; } // General Hooks diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 3438d269d..cb238539f 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -1,3 +1,5 @@ +#pragma once + #include "GameInteractor.h" #include diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp index fb428d1ae..bb04e72b8 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp @@ -8,6 +8,7 @@ extern "C" { #include "variables.h" #include "macros.h" +#include "soh/cvar_prefixes.h" #include "functions.h" extern PlayState* gPlayState; } @@ -341,7 +342,7 @@ void GameInteractor::RawAction::UpdateActor(void* refActor) { } void GameInteractor::RawAction::TeleportPlayer(int32_t nextEntrance) { - Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); gPlayState->nextEntranceIndex = nextEntrance; gPlayState->transitionTrigger = TRANS_TRIGGER_START; gPlayState->transitionType = TRANS_TYPE_FADE_BLACK; @@ -476,7 +477,7 @@ void GameInteractor::RawAction::SetCosmeticsColor(uint8_t cosmeticCategory, uint break; } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ApplyOrResetCustomGfxPatches(); } diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 82a4b3b6e..3f7691741 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -1,11 +1,10 @@ -extern "C" { #include "gameplaystats.h" -} #include "gameplaystatswindow.h" #include "soh/SaveManager.h" #include "functions.h" #include "macros.h" +#include "soh/cvar_prefixes.h" #include "../UIWidgets.hpp" #include "soh/util.h" diff --git a/soh/soh/Enhancements/gameplaystats.h b/soh/soh/Enhancements/gameplaystats.h index 528da33f9..9d41f2560 100644 --- a/soh/soh/Enhancements/gameplaystats.h +++ b/soh/soh/Enhancements/gameplaystats.h @@ -1,5 +1,17 @@ #pragma once +#include "soh/cvar_prefixes.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + uint64_t GetUnixTimestamp(void); + char* GameplayStats_GetCurrentTime(); +#ifdef __cplusplus +}; +#endif + // When using RTA timing // get the diff since the save was created, // unless the game is complete in which we use the defeated ganon timestamp @@ -17,7 +29,6 @@ gSaveContext.sohStats.sceneTimer) void InitStatTracker(); -char* GameplayStats_GetCurrentTime(); typedef enum { // 0x00 to 0x9B (0 to 155) used for getting items, diff --git a/soh/soh/Enhancements/item-tables/ItemTableTypes.h b/soh/soh/Enhancements/item-tables/ItemTableTypes.h index 44ceb2143..d9d742717 100644 --- a/soh/soh/Enhancements/item-tables/ItemTableTypes.h +++ b/soh/soh/Enhancements/item-tables/ItemTableTypes.h @@ -30,13 +30,13 @@ typedef enum GetItemCategory { } GetItemCategory; #define GET_ITEM(itemId, objectId, drawId, textId, field, chestAnim, itemCategory, modIndex, getItemId) \ - { itemId, field, (int16_t)((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, itemId, modIndex, NULL } #define GET_ITEM_CUSTOM_TABLE(itemId, objectId, drawId, textId, field, chestAnim, itemCategory, modIndex, tableId, getItemId) \ - { itemId, field, (int16_t)((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, itemId, modIndex, NULL } #define GET_ITEM_NONE \ - { ITEM_NONE, 0, 0, 0, 0, 0, 0, 0, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, NULL } + { ITEM_NONE, 0, 0, 0, 0, 0, 0, 0, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, ITEM_NONE, 0, NULL } typedef struct PlayState PlayState; typedef struct GetItemEntry GetItemEntry; diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp index 6d66a0578..36cf9d0a2 100644 --- a/soh/soh/Enhancements/kaleido.cpp +++ b/soh/soh/Enhancements/kaleido.cpp @@ -125,8 +125,8 @@ namespace Rando { 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)); + ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).GetContextOptionIndex() + 1, + ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).GetContextOptionIndex() + 1)); yOffset += 18; } if (ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS)) { @@ -191,37 +191,41 @@ namespace Rando { // 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)) && + if (((pauseCtx->unk_1E4 == 0) || (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; + if (!((pauseCtx->state != 6) || ((pauseCtx->stickRelX == 0) && (pauseCtx->stickRelY == 0)))) { + 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; + } } - } 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, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + } 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, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } - 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); - } + } else if (pauseCtx->cursorSpecialPos != 0 && pauseCtx->state == 7) { + pauseCtx->cursorSpecialPos = 0; } } int yOffset = 2; @@ -230,7 +234,7 @@ namespace Rando { if (shouldScroll) { entry->SetYOffset(yOffset); yOffset += 18; - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } Matrix_Push(); entry->Draw(play, &mEntryDl); diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index 3e3f0b7e7..60463bd81 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -3,6 +3,10 @@ #include "game-interactor/GameInteractor.h" #include "tts/tts.h" #include "soh/OTRGlobals.h" +#include "soh/SaveManager.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/resource/type/Skeleton.h" +#include "soh/Enhancements/boss-rush/BossRushTypes.h" #include "soh/Enhancements/boss-rush/BossRush.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/randomizer/3drando/random.hpp" @@ -33,15 +37,18 @@ #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 "src/overlays/actors/ovl_En_Elf/z_en_elf.h" #include "objects/object_link_boy/object_link_boy.h" #include "objects/object_link_child/object_link_child.h" #include "objects/object_custom_equip/object_custom_equip.h" +#include "soh_assets.h" #include "kaleido.h" extern "C" { #include #include "align_asset_macro.h" #include "macros.h" +#include "soh/cvar_prefixes.h" #include "functions.h" #include "variables.h" #include "functions.h" @@ -55,7 +62,6 @@ uint8_t ResourceMgr_FileExists(const char* resName); extern SaveContext gSaveContext; extern PlayState* gPlayState; extern void Overlay_DisplayText(float duration, const char* text); -uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum); } // GreyScaleEndDlist @@ -68,15 +74,6 @@ static const ALIGN_ASSET(2) char tokinoma_room_0DL_007A70[] = dtokinoma_room_0DL #define dtokinoma_room_0DL_007FD0 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007FD0" static const ALIGN_ASSET(2) char tokinoma_room_0DL_007FD0[] = dtokinoma_room_0DL_007FD0; -// TODO: When there's more uses of something like this, create a new GI::RawAction? -void ReloadSceneTogglingLinkAge() { - gPlayState->nextEntranceIndex = gSaveContext.entranceIndex; - gPlayState->transitionTrigger = TRANS_TRIGGER_START; - gPlayState->transitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); // Fade Out - gSaveContext.nextTransitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); - gPlayState->linkAgeOnLoad ^= 1; // toggle linkAgeOnLoad -} - void RegisterInfiniteMoney() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; @@ -156,21 +153,6 @@ void RegisterInfiniteNayrusLove() { }); } -void RegisterMoonJumpOnL() { - GameInteractor::Instance->RegisterGameHook([]() { - if (!GameInteractor::IsSaveLoaded(true)) return; - - if (CVarGetInteger(CVAR_CHEAT("MoonJumpOnL"), 0) != 0) { - Player* player = GET_PLAYER(gPlayState); - - if (CHECK_BTN_ANY(gPlayState->state.input[0].cur.button, BTN_L)) { - player->actor.velocity.y = 6.34375f; - } - } - }); -} - - void RegisterInfiniteISG() { GameInteractor::Instance->RegisterGameHook([]() { if (!GameInteractor::IsSaveLoaded(true)) return; @@ -223,42 +205,43 @@ void RegisterFreezeTime() { } /// Switches Link's age and respawns him at the last entrance he entered. -void RegisterSwitchAge() { - GameInteractor::Instance->RegisterGameHook([]() { - static bool warped = false; +void SwitchAge() { + if (gPlayState == NULL) return; - if (!GameInteractor::IsSaveLoaded(true)) { - CVarClear(CVAR_GENERAL("SwitchAge")); - warped = false; - return; + Player* player = GET_PLAYER(gPlayState); + + // Hyrule Castle: Very likely to fall through floor, so we force a specific entrance + if (gPlayState->sceneNum == SCENE_HYRULE_CASTLE || gPlayState->sceneNum == SCENE_OUTSIDE_GANONS_CASTLE) { + gPlayState->nextEntranceIndex = ENTR_CASTLE_GROUNDS_SOUTH_EXIT; + } else { + gSaveContext.respawnFlag = 1; + gPlayState->nextEntranceIndex = gSaveContext.entranceIndex; + + // Preserve the player's position and orientation + gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = gPlayState->nextEntranceIndex; + gSaveContext.respawn[RESPAWN_MODE_DOWN].roomIndex = gPlayState->roomCtx.curRoom.num; + gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = player->actor.world.pos; + gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = player->actor.shape.rot.y; + + if (gPlayState->roomCtx.curRoom.behaviorType2 < 4) { + gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0DFF; + } else { + // Scenes with static backgrounds use a special camera we need to preserve + Camera* camera = GET_ACTIVE_CAM(gPlayState); + s16 camId = camera->camDataIdx; + gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0D00 | camId; } + } - static Vec3f playerPos; - static int16_t playerYaw; - static RoomContext* roomCtx; - static s32 roomNum; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_INSTANT; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK_FAST; + gPlayState->linkAgeOnLoad ^= 1; - if (CVarGetInteger(CVAR_GENERAL("SwitchAge"), 0) && !warped) { - playerPos = GET_PLAYER(gPlayState)->actor.world.pos; - playerYaw = GET_PLAYER(gPlayState)->actor.shape.rot.y; - roomCtx = &gPlayState->roomCtx; - roomNum = roomCtx->curRoom.num; - ReloadSceneTogglingLinkAge(); - warped = true; - } - - if (warped && gPlayState->transitionTrigger != TRANS_TRIGGER_START && - gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT) { - GET_PLAYER(gPlayState)->actor.shape.rot.y = playerYaw; - GET_PLAYER(gPlayState)->actor.world.pos = playerPos; - if (roomNum != roomCtx->curRoom.num) { - func_8009728C(gPlayState, roomCtx, roomNum); //load original room - //func_800973FC(gPlayState, &gPlayState->roomCtx); // commit to room load? - func_80097534(gPlayState, roomCtx); // load map for new room (unloading the previous room) - } - warped = false; - CVarClear(CVAR_GENERAL("SwitchAge")); - } + static HOOK_ID hookId = 0; + hookId = REGISTER_VB_SHOULD(VB_INFLICT_VOID_DAMAGE, { + *should = false; + GameInteractor::Instance->UnregisterGameHookForID(hookId); }); } @@ -266,8 +249,7 @@ void RegisterSwitchAge() { void RegisterOcarinaTimeTravel() { GameInteractor::Instance->RegisterGameHook([]() { - if (!GameInteractor::IsSaveLoaded(true)) { - CVarClear(CVAR_ENHANCEMENT("TimeTravel")); + if (!GameInteractor::IsSaveLoaded(true) || !CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0)) { return; } @@ -277,22 +259,15 @@ void RegisterOcarinaTimeTravel() { Actor* nearbyOcarinaSpot = Actor_FindNearby(gPlayState, player, ACTOR_EN_OKARINA_TAG, ACTORCAT_PROP, 120.0f); Actor* nearbyDoorOfTime = Actor_FindNearby(gPlayState, player, ACTOR_DOOR_TOKI, ACTORCAT_BG, 500.0f); Actor* nearbyFrogs = Actor_FindNearby(gPlayState, player, ACTOR_EN_FR, ACTORCAT_NPC, 300.0f); - uint8_t hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER); - uint8_t hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME); - // If TimeTravel + Player have the Ocarina of Time + Have Master Sword + is in proper range + Actor* nearbyGossipStone = Actor_FindNearby(gPlayState, player, ACTOR_EN_GS, ACTORCAT_NPC, 300.0f); + bool justPlayedSoT = gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME; + bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime && !nearbyFrogs && !nearbyGossipStone; + bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME); + bool doesntNeedOcarinaOfTime = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2; + bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER); // TODO: Once Swordless Adult is fixed: Remove the Master Sword check - if (((CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 1 && hasOcarinaOfTime) || CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2) && hasMasterSword && - gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME && !nearbyTimeBlockEmpty && !nearbyTimeBlock && - !nearbyOcarinaSpot && !nearbyFrogs) { - - if (IS_RANDO) { - CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1); - } else if (!IS_RANDO && !nearbyDoorOfTime) { - // This check is made for when Link is learning the Song Of Time in a vanilla save file that load a - // Temple of Time scene where the only object present is the Door of Time - CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1); - } - ReloadSceneTogglingLinkAge(); + if (justPlayedSoT && notNearAnySource && (hasOcarinaOfTime || doesntNeedOcarinaOfTime) && hasMasterSword) { + SwitchAge(); } }); } @@ -471,7 +446,7 @@ void RegisterPermanentHeartLoss() { void RegisterDeleteFileOnDeath() { GameInteractor::Instance->RegisterGameHook([]() { - if (!CVarGetInteger(CVAR_ENHANCEMENT("DeleteFileOnDeath"), 0) || !GameInteractor::IsSaveLoaded() || &gPlayState->gameOverCtx == NULL || &gPlayState->pauseCtx == NULL) return; + if (!CVarGetInteger(CVAR_ENHANCEMENT("DeleteFileOnDeath"), 0) || !GameInteractor::IsSaveLoaded() || gPlayState == NULL) return; if (gPlayState->gameOverCtx.state == GAMEOVER_DEATH_MENU && gPlayState->pauseCtx.state == 9) { SaveManager::Instance->DeleteZeldaFile(gSaveContext.fileNum); @@ -1023,6 +998,42 @@ void RegisterResetNaviTimer() { }); } +void RegisterBrokenGiantsKnifeFix() { + GameInteractor::Instance->RegisterGameHook([](GetItemEntry itemEntry) { + if (itemEntry.itemId != ITEM_SWORD_BGS) { + return; + } + + int32_t bypassEquipmentChecks = 0; + + if (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("FixBrokenGiantsKnife"), 0)) { + // Flag wasn't reset because Kokiri or Master Sword was missing, so we need to + // bypass those checks + bypassEquipmentChecks |= (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER); + } else { + // If enhancement is off, flag should be handled exclusively by vanilla behaviour + return; + } + + int32_t allSwordsInEquipment = bypassEquipmentChecks | ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD); + int32_t allSwordFlags = (1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) | + (1 << EQUIP_INV_SWORD_BIGGORON) | (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE); + + if (allSwordsInEquipment != allSwordFlags) { + return; + } + + gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE); + + if (gSaveContext.equips.buttonItems[0] == ITEM_SWORD_KNIFE) { + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; + if (gPlayState != NULL) { + Interface_LoadItemIcon1(gPlayState, 0); + } + } + }); +} + //this map is used for enemies that can be uniquely identified by their id //and that are always counted //enemies that can't be uniquely identified by their id @@ -1284,6 +1295,9 @@ std::vector getEnabledAddTraps () { std::vector enabledAddTraps; for (int i = 0; i < ADD_TRAP_MAX; i++) { if (CVarGetInteger(altTrapTypeCvars[i], 0)) { + if (gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE && (i == ADD_VOID_TRAP || i == ADD_TELEPORT_TRAP)) { + continue; // don't add void or teleport if you're holding the fishing pole, as this causes issues + } enabledAddTraps.push_back(static_cast(i)); } } @@ -1317,7 +1331,7 @@ void RegisterAltTrapTypes() { eventTimer = 3; break; case ADD_SPEED_TRAP: - Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); GameInteractor::State::RunSpeedModifier = -2; statusTimer = 200; Overlay_DisplayText(10, "Speed Decreased!"); @@ -1326,8 +1340,8 @@ void RegisterAltTrapTypes() { eventTimer = 3; break; case ADD_VOID_TRAP: - Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - eventTimer = 3; + Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + eventTimer = 3; break; case ADD_AMMO_TRAP: eventTimer = 3; @@ -1339,6 +1353,8 @@ void RegisterAltTrapTypes() { case ADD_TELEPORT_TRAP: eventTimer = 3; break; + default: + break; } }); GameInteractor::Instance->RegisterGameHook([]() { @@ -1364,9 +1380,9 @@ void RegisterAltTrapTypes() { AMMO(ITEM_BOW) = AMMO(ITEM_BOW) * 0.5; AMMO(ITEM_BOMB) = AMMO(ITEM_BOMB) * 0.5; AMMO(ITEM_BOMBCHU) = AMMO(ITEM_BOMBCHU) * 0.5; - Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); break; - case ADD_TELEPORT_TRAP: + case ADD_TELEPORT_TRAP: { int entrance; int index = 1 + rand() % 10; switch (index) { @@ -1394,6 +1410,9 @@ void RegisterAltTrapTypes() { } GameInteractor::RawAction::TeleportPlayer(entrance); break; + } + default: + break; } } statusTimer--; @@ -1639,6 +1658,54 @@ void RegisterRandomizerCompasses() { }); } +void RegisterCustomSkeletons() { + static int8_t previousTunic = -1; + + GameInteractor::Instance->RegisterGameHook([]() { + + if (!GameInteractor::IsSaveLoaded() || gPlayState == NULL) { + return; + } + + if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) != previousTunic) { + SOH::SkeletonPatcher::UpdateCustomSkeletons(); + } + previousTunic = CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC); + }); + + GameInteractor::Instance->RegisterGameHook([]() { + if (!GameInteractor::IsSaveLoaded() || gPlayState == NULL) { + return; + } + + SOH::SkeletonPatcher::UpdateCustomSkeletons(); + }); +} + +#define FAIRY_FLAG_BIG (1 << 9) + + +void RegisterFairyCustomization() { + REGISTER_VB_SHOULD(VB_FAIRY_HEAL, { + EnElf* enElf = va_arg(args, EnElf*); + // Don't trigger if fairy is shuffled + if (!IS_RANDO || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FAIRIES) || enElf->sohFairyIdentity.randomizerInf == RAND_INF_MAX) { + if (CVarGetInteger(CVAR_ENHANCEMENT("FairyEffect"), 0) && !(enElf->fairyFlags & FAIRY_FLAG_BIG)) + { + if (CVarGetInteger(CVAR_ENHANCEMENT("FairyPercentRestore"), 0)) + { + Health_ChangeBy(gPlayState, (gSaveContext.healthCapacity * CVarGetInteger(CVAR_ENHANCEMENT("FairyHealth"), 100) / 100 + 15) / 16 * 16); + } + else + { + Health_ChangeBy(gPlayState, CVarGetInteger(CVAR_ENHANCEMENT("FairyHealth"), 8) * 16); + } + *should = false; + } + } + }); +} + void InitMods() { BossRush_RegisterHooks(); RandomizerRegisterHooks(); @@ -1651,12 +1718,10 @@ void InitMods() { RegisterInfiniteAmmo(); RegisterInfiniteMagic(); RegisterInfiniteNayrusLove(); - RegisterMoonJumpOnL(); RegisterInfiniteISG(); RegisterEzQPA(); RegisterUnrestrictedItems(); RegisterFreezeTime(); - RegisterSwitchAge(); RegisterOcarinaTimeTravel(); RegisterAutoSave(); RegisterDaytimeGoldSkultullas(); @@ -1670,6 +1735,7 @@ void InitMods() { RegisterMenuPathFix(); RegisterMirrorModeHandler(); RegisterResetNaviTimer(); + RegisterBrokenGiantsKnifeFix(); RegisterEnemyDefeatCounts(); RegisterBossDefeatTimestamps(); RegisterAltTrapTypes(); @@ -1684,4 +1750,6 @@ void InitMods() { RegisterPatchCustomEquipmentDlistsHandler(); RegisterPauseMenuHooks(); RandoKaleido_RegisterHooks(); + RegisterFairyCustomization(); + RegisterCustomSkeletons(); } diff --git a/soh/soh/Enhancements/mods.h b/soh/soh/Enhancements/mods.h index d14ef28f1..b84ecdd41 100644 --- a/soh/soh/Enhancements/mods.h +++ b/soh/soh/Enhancements/mods.h @@ -18,6 +18,7 @@ void UpdateHyperBossesState(); void InitMods(); void UpdatePatchHand(); void UpdatePatchCustomEquipmentDlists(); +void SwitchAge(); #ifdef __cplusplus } diff --git a/soh/soh/Enhancements/nametag.cpp b/soh/soh/Enhancements/nametag.cpp index 2adc3fffb..c2d72eae0 100644 --- a/soh/soh/Enhancements/nametag.cpp +++ b/soh/soh/Enhancements/nametag.cpp @@ -10,6 +10,7 @@ extern "C" { #include "z64.h" #include "macros.h" +#include "soh/cvar_prefixes.h" #include "functions.h" #include "variables.h" #include "textures/message_static/message_static.h" @@ -201,7 +202,7 @@ extern "C" void NameTag_RegisterForActorWithOptions(Actor* actor, const char* te processedText.erase(std::remove_if(processedText.begin(), processedText.end(), [](const char& c) { // 172 is max supported texture for the in-game font system, // and filter anything less than a space but not the newline or nul characters - return c > 172 || (c < ' ' && c != '\n' && c != '\0'); + return (unsigned char)c > 172 || (c < ' ' && c != '\n' && c != '\0'); }), processedText.end()); int16_t numChar = processedText.length(); @@ -213,7 +214,7 @@ extern "C" void NameTag_RegisterForActorWithOptions(Actor* actor, const char* te Vtx* vertices = (Vtx*)calloc(sizeof(Vtx[4]), numChar + 1); // Set all the char vtx first to get the total size for the textbox - for (size_t i = 0; i < numChar; i++) { + for (int16_t i = 0; i < numChar; i++) { if (processedText[i] == '\n') { offsetX = 0; numLines++; diff --git a/soh/soh/Enhancements/pausewarp.c b/soh/soh/Enhancements/pausewarp.c index 5538e7ad4..b87952232 100644 --- a/soh/soh/Enhancements/pausewarp.c +++ b/soh/soh/Enhancements/pausewarp.c @@ -22,12 +22,12 @@ static const int ocarinaSongMap[] = { }; static const int entranceIndexMap[] = { - ENTR_SACRED_FOREST_MEADOW_2, // Minuet - ENTR_DEATH_MOUNTAIN_CRATER_4, // Bolero - ENTR_LAKE_HYLIA_8, // Serenade - ENTR_DESERT_COLOSSUS_5, // Requiem - ENTR_GRAVEYARD_7, // Nocturne - ENTR_TEMPLE_OF_TIME_7 // Prelude + ENTR_SACRED_FOREST_MEADOW_WARP_PAD, // Minuet + ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, // Bolero + ENTR_LAKE_HYLIA_WARP_PAD, // Serenade + ENTR_DESERT_COLOSSUS_WARP_PAD, // Requiem + ENTR_GRAVEYARD_WARP_PAD, // Nocturne + ENTR_TEMPLE_OF_TIME_WARP_PAD // Prelude }; static const int songAudioMap[] = { diff --git a/soh/soh/Enhancements/presets.cpp b/soh/soh/Enhancements/presets.cpp index 0a2582c4a..a823844f6 100644 --- a/soh/soh/Enhancements/presets.cpp +++ b/soh/soh/Enhancements/presets.cpp @@ -73,7 +73,10 @@ void DrawPresetSelector(PresetType presetTypeId) { if (selectedPresetId != 0) { applyPreset(selectedPresetDef.entries); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + if (presetTypeId == PRESET_TYPE_RANDOMIZER){ + Rando::Context::GetInstance()->GetSettings()->ReloadOptions(); + } } ImGui::PopStyleVar(1); } diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h index f88dfaf8c..1bc4550f5 100644 --- a/soh/soh/Enhancements/presets.h +++ b/soh/soh/Enhancements/presets.h @@ -8,6 +8,7 @@ #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" enum PresetEntryType { PRESET_ENTRY_TYPE_S32, @@ -241,6 +242,8 @@ const std::vector enhancementsCvars = { CVAR_ENHANCEMENT("AuthenticLogo"), CVAR_ENHANCEMENT("PauseLiveLinkRotationSpeed"), CVAR_ENHANCEMENT("BowReticle"), + CVAR_ENHANCEMENT("BoomerangFirstPerson"), + CVAR_ENHANCEMENT("BoomerangReticle"), CVAR_ENHANCEMENT("FixTexturesOOB"), CVAR_ENHANCEMENT("IvanCoopModeEnabled"), CVAR_ENHANCEMENT("EnemySpawnsOverWaterboxes"), @@ -303,6 +306,7 @@ const std::vector enhancementsCvars = { CVAR_ENHANCEMENT("TimeSavers.SkipChildStealth"), CVAR_ENHANCEMENT("TimeSavers.SkipTowerEscape"), CVAR_ENHANCEMENT("TimeSavers.SkipForcedDialog"), + CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), CVAR_ENHANCEMENT("SlowTextSpeed"), }; @@ -353,8 +357,6 @@ const std::vector cheatCvars = { CVAR_DEVELOPER_TOOLS("SaveFileID"), CVAR_CHEAT("EnableBetaQuest"), CVAR_DEVELOPER_TOOLS("BetterDebugWarpScreen"), - CVAR_GENERAL("SwitchAge"), - CVAR_GENERAL("SwitchTimeline"), CVAR_CHEAT("NoRedeadFreeze"), CVAR_CHEAT("NoKeeseGuayTarget"), CVAR_CHEAT("BombTimerMultiplier"), @@ -378,6 +380,12 @@ const std::vector cheatCvars = { }; const std::vector randomizerCvars = { + CVAR_RANDOMIZER_ENHANCEMENT("MatchKeyColors"), + CVAR_RANDOMIZER_ENHANCEMENT("QuestItemFanfares"), + CVAR_RANDOMIZER_ENHANCEMENT("RandoRelevantNavi"), + CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), + CVAR_RANDOMIZER_ENHANCEMENT("RandomizeRupeeNames"), + CVAR_RANDOMIZER_SETTING("100GSHint"), CVAR_RANDOMIZER_SETTING("10GSHint"), CVAR_RANDOMIZER_SETTING("20GSHint"), CVAR_RANDOMIZER_SETTING("30GSHint"), @@ -386,10 +394,13 @@ const std::vector randomizerCvars = { CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), CVAR_RANDOMIZER_SETTING("AltarHint"), CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), + CVAR_RANDOMIZER_SETTING("BigPoesHint"), + CVAR_RANDOMIZER_SETTING("BiggoronHint"), CVAR_RANDOMIZER_SETTING("BlueFireArrows"), CVAR_RANDOMIZER_SETTING("BombchusInLogic"), CVAR_RANDOMIZER_SETTING("BossKeysanity"), CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), + CVAR_RANDOMIZER_SETTING("ChickensHint"), CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), CVAR_RANDOMIZER_SETTING("CuccosToReturn"), CVAR_RANDOMIZER_SETTING("DampeHint"), @@ -398,24 +409,27 @@ const std::vector randomizerCvars = { CVAR_RANDOMIZER_SETTING("DungeonCount"), CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), CVAR_RANDOMIZER_SETTING("EnableGlitchCutscenes"), - CVAR_RANDOMIZER_SETTING("EnabledGlitches"), - CVAR_RANDOMIZER_SETTING("EnabledTricks"), - 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("FishsanityPondCount"), + CVAR_RANDOMIZER_SETTING("ClosedForest"), + CVAR_RANDOMIZER_SETTING("FrogsHint"), + CVAR_RANDOMIZER_SETTING("FullWallets"), CVAR_RANDOMIZER_SETTING("GanonTrial"), CVAR_RANDOMIZER_SETTING("GanonTrialCount"), - CVAR_RANDOMIZER_SETTING("GerudoFortress"), + CVAR_RANDOMIZER_SETTING("GanondorfHint"), + CVAR_RANDOMIZER_SETTING("FortressCarpenters"), CVAR_RANDOMIZER_SETTING("GerudoKeys"), CVAR_RANDOMIZER_SETTING("GossipStoneHints"), + CVAR_RANDOMIZER_SETTING("GregHint"), CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), + CVAR_RANDOMIZER_SETTING("HBAHint"), CVAR_RANDOMIZER_SETTING("HintClarity"), CVAR_RANDOMIZER_SETTING("HintDistribution"), CVAR_RANDOMIZER_SETTING("IceTraps"), + CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), + CVAR_RANDOMIZER_SETTING("InfiniteUpgrades"), CVAR_RANDOMIZER_SETTING("ItemPool"), CVAR_RANDOMIZER_SETTING("KakarikoGate"), CVAR_RANDOMIZER_SETTING("Keysanity"), @@ -425,36 +439,81 @@ 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("LoachHint"), CVAR_RANDOMIZER_SETTING("LogicRules"), + CVAR_RANDOMIZER_SETTING("MQDungeonCount"), + CVAR_RANDOMIZER_SETTING("MQDungeons"), + CVAR_RANDOMIZER_SETTING("MQDungeonsBottomOfTheWell"), + CVAR_RANDOMIZER_SETTING("MQDungeonsDekuTree"), + CVAR_RANDOMIZER_SETTING("MQDungeonsDodongosCavern"), + CVAR_RANDOMIZER_SETTING("MQDungeonsFireTemple"), + CVAR_RANDOMIZER_SETTING("MQDungeonsForestTemple"), + CVAR_RANDOMIZER_SETTING("MQDungeonsGTG"), + CVAR_RANDOMIZER_SETTING("MQDungeonsGanonsCastle"), + CVAR_RANDOMIZER_SETTING("MQDungeonsIceCavern"), + CVAR_RANDOMIZER_SETTING("MQDungeonsJabuJabu"), + CVAR_RANDOMIZER_SETTING("MQDungeonsSelection"), + CVAR_RANDOMIZER_SETTING("MQDungeonsShadowTemple"), + CVAR_RANDOMIZER_SETTING("MQDungeonsSpiritTemple"), + CVAR_RANDOMIZER_SETTING("MQDungeonsWaterTemple"), + CVAR_RANDOMIZER_SETTING("MalonHint"), + CVAR_RANDOMIZER_SETTING("MaskShopHint"), CVAR_RANDOMIZER_SETTING("MedallionCount"), + CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"), + CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"), + CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"), + CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), + CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"), + CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"), + CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"), + CVAR_RANDOMIZER_SETTING("MerchantPrices"), + CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), + CVAR_RANDOMIZER_SETTING("MerchantText"), + CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), + CVAR_RANDOMIZER_SETTING("MixBosses"), CVAR_RANDOMIZER_SETTING("MixDungeons"), - CVAR_RANDOMIZER_SETTING("MixedEntrances"), CVAR_RANDOMIZER_SETTING("MixGrottos"), CVAR_RANDOMIZER_SETTING("MixInteriors"), CVAR_RANDOMIZER_SETTING("MixOverworld"), - CVAR_RANDOMIZER_SETTING("MQDungeonCount"), - CVAR_RANDOMIZER_SETTING("MQDungeons"), + CVAR_RANDOMIZER_SETTING("MixedEntrances"), + CVAR_RANDOMIZER_SETTING("OoTHint"), CVAR_RANDOMIZER_SETTING("RainbowBridge"), CVAR_RANDOMIZER_SETTING("RewardCount"), + CVAR_RANDOMIZER_SETTING("SariaHint"), CVAR_RANDOMIZER_SETTING("ScrubText"), + CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"), + CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"), + CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), + CVAR_RANDOMIZER_SETTING("ScrubsGiantWalletWeight"), + CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"), + CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"), + CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"), + CVAR_RANDOMIZER_SETTING("ScrubsPrices"), + CVAR_RANDOMIZER_SETTING("ScrubsPricesAffordable"), + CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"), + CVAR_RANDOMIZER_SETTING("SheikLAHint"), CVAR_RANDOMIZER_SETTING("Shopsanity"), + CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"), + CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"), CVAR_RANDOMIZER_SETTING("ShopsanityCount"), - CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"), + CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), + CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"), 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("ShopsanityPrices"), CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), + CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), + CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), + CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), + CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), + CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"), CVAR_RANDOMIZER_SETTING("ShuffleCows"), + CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), + CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), @@ -467,54 +526,42 @@ const std::vector randomizerCvars = { CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsBottomOfTheWell"), CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsFireTemple"), CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsForestTemple"), + CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGTG"), CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGanonsCastle"), CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), - CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGTG"), CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsShadowTemple"), CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsSpiritTemple"), CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsWaterTemple"), CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), + CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), 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("ShuffleOcarinaButtons"), 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("ShuffleSwim"), CVAR_RANDOMIZER_SETTING("ShuffleTokens"), CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"), CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), + CVAR_RANDOMIZER_SETTING("SkeletonKey"), CVAR_RANDOMIZER_SETTING("SkipChildStealth"), CVAR_RANDOMIZER_SETTING("SkipChildZelda"), CVAR_RANDOMIZER_SETTING("SkipEponaRace"), CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), - CVAR_RANDOMIZER_SETTING("SkipTowerEscape"), + CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), CVAR_RANDOMIZER_SETTING("StartingAge"), - CVAR_RANDOMIZER_SETTING("StartingConsumables"), CVAR_RANDOMIZER_SETTING("StartingBoleroOfFire"), + CVAR_RANDOMIZER_SETTING("StartingConsumables"), CVAR_RANDOMIZER_SETTING("StartingDekuShield"), CVAR_RANDOMIZER_SETTING("StartingEponasSong"), + CVAR_RANDOMIZER_SETTING("StartingHearts"), CVAR_RANDOMIZER_SETTING("StartingKokiriSword"), CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), + CVAR_RANDOMIZER_SETTING("StartingMasterSword"), CVAR_RANDOMIZER_SETTING("StartingMinuetOfForest"), CVAR_RANDOMIZER_SETTING("StartingNocturneOfShadow"), CVAR_RANDOMIZER_SETTING("StartingOcarina"), @@ -530,21 +577,11 @@ const std::vector randomizerCvars = { CVAR_RANDOMIZER_SETTING("StoneCount"), CVAR_RANDOMIZER_SETTING("SunlightArrows"), CVAR_RANDOMIZER_SETTING("TokenCount"), + CVAR_RANDOMIZER_SETTING("TriforceHunt"), + CVAR_RANDOMIZER_SETTING("TriforceHuntRequiredPieces"), + CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), CVAR_RANDOMIZER_SETTING("WarpSongText"), CVAR_RANDOMIZER_SETTING("ZorasFountain"), - CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), - CVAR_RANDOMIZER_SETTING("GregHint"), - CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), - CVAR_RANDOMIZER_SETTING("TriforceHuntTotalPieces"), - CVAR_RANDOMIZER_SETTING("TriforceHuntRequiredPieces"), - CVAR_RANDOMIZER_SETTING("TriforceHunt"), - CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), - CVAR_RANDOMIZER_SETTING("SariaHint"), - CVAR_RANDOMIZER_ENHANCEMENT("RandomizeRupeeNames"), - CVAR_RANDOMIZER_SETTING("FrogsHint"), - CVAR_RANDOMIZER_SETTING("OoTHint"), - CVAR_RANDOMIZER_ENHANCEMENT("RandoRelevantNavi"), - CVAR_RANDOMIZER_ENHANCEMENT("QuestItemFanfares"), }; const std::vector vanillaPlusPresetEntries = { @@ -990,10 +1027,10 @@ const std::vector spockRacePresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), 1), PRESET_ENTRY_CPP_STRING(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), FormatLocations( { RC_MARKET_10_BIG_POES, RC_KAK_40_GOLD_SKULLTULA_REWARD, RC_KAK_50_GOLD_SKULLTULA_REWARD, RC_ZR_FROGS_OCARINA_GAME })), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_OFF), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FullWallets"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SKIP), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_FAST), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_FAST), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GregHint"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), RO_KAK_GATE_OPEN), @@ -1075,10 +1112,10 @@ const std::vector spockRaceNoLogicPresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), 1), PRESET_ENTRY_CPP_STRING(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), FormatLocations( { RC_MARKET_10_BIG_POES, RC_KAK_40_GOLD_SKULLTULA_REWARD, RC_KAK_50_GOLD_SKULLTULA_REWARD, RC_ZR_FROGS_OCARINA_GAME })), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_OFF), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FullWallets"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SKIP), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_FAST), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_FAST), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_ANYWHERE), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GregHint"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GsExpectSunsSong"), 0), @@ -1125,9 +1162,9 @@ const std::vector s6PresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 4), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_OPEN), PRESET_ENTRY_CPP_STRING(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), FormatLocations({ RC_DEKU_THEATER_MASK_OF_TRUTH })), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_CLOSED_DEKU), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_DEKU_ONLY), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SKIP), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_FAST), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_FAST), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IceTraps"), RO_ICE_TRAPS_OFF), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), RO_KAK_GATE_OPEN), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MedallionCount"), 6), @@ -1142,12 +1179,13 @@ const std::vector s6PresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipTowerEscape"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), RO_WATERFALL_CLOSED), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingAge"), RO_AGE_RANDOM), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingConsumables"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingDekuShield"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_STARTWITH), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingOcarina"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), 0), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), RO_ZF_CLOSED), }; const std::vector hellModePresetEntries = { @@ -1163,7 +1201,7 @@ const std::vector hellModePresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_OPEN), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableGlitchCutscenes"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_OPEN), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_OFF), 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("GerudoKeys"), RO_GERUDO_KEYS_ANYWHERE), @@ -1202,18 +1240,20 @@ const std::vector hellModePresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipTowerEscape"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), RO_WATERFALL_OPEN), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingAge"), RO_AGE_RANDOM), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_ANYWHERE), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), 2), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), RO_ZF_OPEN), }; const std::vector BenchmarkPresetEntries = { - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_CLOSED_DEKU), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_DEKU_ONLY), 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("SleepingWaterfall"), RO_WATERFALL_CLOSED), 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("FortressCarpenters"), RO_GF_CARPENTERS_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), diff --git a/soh/soh/Enhancements/randomizer/3drando/category.hpp b/soh/soh/Enhancements/randomizer/3drando/category.hpp deleted file mode 100644 index fc230b435..000000000 --- a/soh/soh/Enhancements/randomizer/3drando/category.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -enum class OptionCategory { - Setting, - Toggle, -}; \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp b/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp index 64b75b670..179987dcc 100644 --- a/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp @@ -29,7 +29,7 @@ constexpr std::array EnglishDungeonNames = { "Bottom of the Well", "Ice Cavern", "Ganon's Tower", - "Gerudo Training Grounds", + "Gerudo Training Ground", "Gerudo Fortress", "Ganon's Castle", }; diff --git a/soh/soh/Enhancements/randomizer/3drando/entrance.cpp b/soh/soh/Enhancements/randomizer/3drando/entrance.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 5bfa5aea1..e7a6ce38b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -238,10 +238,10 @@ static int GetMaxGSCount() { int maxBridge = 0; int maxLACS = 0; if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) { - maxBridge = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Value(); + maxBridge = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).GetContextOptionIndex(); } if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) { - maxLACS = ctx->GetOption(RSK_LACS_TOKEN_COUNT).Value(); + maxLACS = ctx->GetOption(RSK_LACS_TOKEN_COUNT).GetContextOptionIndex(); } maxBridge = std::max(maxBridge, maxLACS); //Get the max amount of GS which could be useful from token reward locations @@ -266,7 +266,7 @@ static int GetMaxGSCount() { 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) - ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Value(); + return std::max(maxUseful, maxBridge) - ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).GetContextOptionIndex(); } std::string GetShopItemBaseName(std::string itemName) { @@ -617,8 +617,8 @@ void LookForExternalArea(Region* currentRegion, std::set &alreadyChecke //if this entrance does not pass areas, only process it if we are in low priority mode if ((LowPriorityMode || entrance->DoesSpreadAreas()) && !alreadyChecked.contains(entrance->GetParentRegion())){ std::set otherAreas = entrance->GetParentRegion()->GetAllAreas(); - alreadyChecked.insert(entrance->GetParentRegion()); if (otherAreas.size() == 0) { + alreadyChecked.insert(entrance->GetParentRegion()); LookForExternalArea(entrance->GetParentRegion(), alreadyChecked, areas, LowPriorityMode); //If we find a valid area we should add it. //If it's Links Pocket or RA_NONE, do not propagate those, they are not real areas. @@ -715,7 +715,7 @@ static void CalculateWotH() { //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 && + if (itemLoc->IsHintable() && itemLoc->GetFirstArea() > RA_LINKS_POCKET && !(IsBeatableWithout(ctx->playthroughLocations[i][j], true))) { itemLoc->SetWothCandidate(); } @@ -856,11 +856,6 @@ static void AssumedFill(const std::vector& items, const std::vect SPDLOG_DEBUG(Rando::StaticData::RetrieveItem(item).GetName().GetEnglish()); SPDLOG_DEBUG(". TRYING AGAIN...\n"); -#ifdef ENABLE_DEBUG - Regions::DumpWorldGraph(Rando::StaticData::RetrieveItem(item).GetName().GetEnglish()); - PlacementLog_Write(); -#endif - // reset any locations that got an item for (RandomizerCheck loc : attemptedLocations) { ctx->GetItemLocation(loc)->SetPlacedItem(RG_NONE); diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index 1b2870ed6..49d090a26 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -918,7 +918,7 @@ void StaticData::HintTable_Init() { /*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]]#.", + hintTextTable[RHT_GERUDO_FORTRESS_TO_GERUDO_TRAINING_GROUND_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]]#. @@ -1101,7 +1101,7 @@ void StaticData::HintTable_Init() { /*french*/ "le #Laboratoire du Lac#")); // /*spanish*/el laboratorio del lago - hintTextTable[RHT_LH_FISHING_HOLE] = HintText(CustomMessage("the #Fishing Pond#", + hintTextTable[RHT_LH_FISHING_POND] = HintText(CustomMessage("the #Fishing Pond#", /*german*/ "der #Angelteich#", /*french*/ "l'#Étang#")); // /*spanish*/el estanque @@ -1177,7 +1177,7 @@ void StaticData::HintTable_Init() { // /*spanish*/la tienda de pociones de la abuela hintTextTable[RHT_GRAVEYARD_DAMPES_HOUSE] = HintText(CustomMessage("Dampé's Hut", - /*german*/ "der #Hut von Boris#", + /*german*/ "die #Hütte von Boris#", /*french*/ "la #Cabane du Fossoyeur#")); // /*spanish*/la cabaña de Dampé @@ -1277,12 +1277,12 @@ void StaticData::HintTable_Init() { // /*spanish*/la #tumba de la Canción del Sol# hintTextTable[RHT_GRAVEYARD_COMPOSERS_GRAVE] = HintText(CustomMessage("the #Composers' Grave#", - /*german*/ "das Königsgrab", + /*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", + /*german*/ "das #Grab von Boris#", /*french*/ "la #Tombe d'Igor#")); // /*spanish*/la #tumba de Dampé# @@ -2253,6 +2253,118 @@ void StaticData::HintTable_Init() { /*german*/ "", /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + hintTextTable[RHT_JUNK_CREW_1] = HintText(CustomMessage("They say that %gGanondorf's Mom%w is going out with %ySqueak%w!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_2] = HintText(CustomMessage("They say that %gProxySaw%w is still fixing %yCaladius's Bugs%w...", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_3] = HintText(CustomMessage("They say that %gItsHeckinPat%w is still just %yEyeballing it%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_4] = HintText(CustomMessage("They say that %gCaladius%w is working on %yV2%w of something.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_5] = HintText(CustomMessage("They say that %gdice%w is a funny name for a %ytaco%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_6] = HintText(CustomMessage("They say %g2Ship Rando%w is still blocked by %yV3%w...", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_7] = HintText(CustomMessage("They say if you click your heels and say %gframebuffer%w 3 times, %yArchez%w appears!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_8] = HintText(CustomMessage("They say %gVB%w stands for %yVirtual Bananas%w... Probably.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_9] = HintText(CustomMessage("They say %gZeru%w is still routing his %yHundo%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_10] = HintText(CustomMessage("They say %gRaccoonCloud%w is still looking for his %yHover Boots%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_11] = HintText(CustomMessage("They say %gItsHeckinPat%w foreclosed on his %yHut%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_12] = HintText(CustomMessage("They say %gRaccoonCloud%w is part of the %yInner Circle%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_13] = HintText(CustomMessage("They say %gMoonlitxShadows%w is the %rleader%w of the %yDork Army%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_14] = HintText(CustomMessage("They say %gGanondorf%w hates the %yInternet%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_15] = HintText(CustomMessage("They say %gMido's House%w hoards %yTrash%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_16] = HintText(CustomMessage("They say %gSweettalking Ganondorf%w rewards %yHis Heart%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_17] = HintText(CustomMessage("They say %gaMannus%w said %yGo To Bed%w!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_18] = HintText(CustomMessage("They say %gCaladius%w is a %yPinhead%w!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_19] = HintText(CustomMessage("They say %gRaccoonCloud%w loves the %yIce Cavern%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_20] = HintText(CustomMessage("They say %gNo One%w should forget %yHover Scrub%w!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_21] = HintText(CustomMessage("They say %gMoonlitxShadows%w likes to %ySlide%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_23] = HintText(CustomMessage("They say that %gBackwalking%w should be %rBanned%w!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_24] = HintText(CustomMessage("They say that %gGorons%w should always have %yLong Necks%w!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_25] = HintText(CustomMessage("They say that %gCaladius%w has a %ytendency to lose his shirt%w!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_26] = HintText(CustomMessage("They say that if your %rSkip keeps Failing%w, you're probably an %yESS Off%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_27] = HintText(CustomMessage("They say that %gLogic%w is just a %ySuggestion%w.", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_28] = HintText(CustomMessage("They say there's %gAlways Logic%w in %yNo Logic%w...", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + + hintTextTable[RHT_JUNK_CREW_29] = HintText(CustomMessage("They said that %rFredomato%w has just %yone more push up%w to do!", + /*german*/ "", + /*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR)); + /*-------------------------- | DUNGEON HINT TEXT | ---------------------------*/ @@ -2358,7 +2470,7 @@ void StaticData::HintTable_Init() { /*french*/ "la prison d'une ombre")}); // /*spanish*/la prisión de las sombras - hintTextTable[RHT_GERUDO_TRAINING_GROUND] = HintText(CustomMessage("Gerudo Training Grounds", + hintTextTable[RHT_GERUDO_TRAINING_GROUND] = HintText(CustomMessage("Gerudo Training Ground", /*german*/ "Gerudo-Trainingsgelände", /*french*/ "le Gymnase Gerudo"), // /*spanish*/el Centro de Instrucción Gerudo @@ -2381,86 +2493,95 @@ void StaticData::HintTable_Init() { /*-------------------------- | BOSS HINT TEXT | ---------------------------*/ - - 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 +//RANDOTODO check the beginning and end on the french translations + hintTextTable[RHT_QUEEN_GOHMA] = HintText(CustomMessage("They say that #Queen Gohma# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Königin Gohma# #[[1]]# hielte.", + /*french*/ "Selon moi, la #Reine Gohma# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/la #Reina Goma# porta #[[1]]#. {}, - {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 + {CustomMessage("They say that the #Parasitic Armored Arachnid# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #gepanzerte parasitäre Spinne# #[[1]]# hielte.", + /*french*/ "Selon moi, le #monstre insectoïde géant# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/el #arácnido parasitario acorazado# porta #[[1]]#. - 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 + hintTextTable[RHT_KING_DODONGO] = HintText(CustomMessage("They say that #King Dodongo# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #König Dodongo# #[[1]]# hielte.", + /*french*/ "Selon moi, le #Roi Dodongo# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/el #Rey Dodongo# porta #[[1]]#. {}, - {CustomMessage("the #Infernal Dinosaur# holds", - /*german*/ "der #infernalische Dinosaurier# hält", - /*french*/ "le #dinosaure infernal# possède")}); - // /*spanish*/el #dinosaurio infernal# porta + {CustomMessage("They say that the #Infernal Dinosaur# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #infernalische Dinosaurier# #[[1]]# hielte.", + /*french*/ "Selon moi, le #dinosaure infernal# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/el #dinosaurio infernal# porta #[[1]]#. - hintTextTable[RHT_BARINADE] = HintText(CustomMessage("#Barinade# holds", - /*german*/ "#Barinade# hält", - /*french*/ "#Barinade# possède"), - // /*spanish*/#Barinade# porta + hintTextTable[RHT_BARINADE] = HintText(CustomMessage("They say that #Barinade# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Barinade# #[[1]]# hielte.", + /*french*/ "Selon moi, #Barinade# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#Barinade# porta #[[1]]#. {}, - {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 + {CustomMessage("They say that the #Bio-Electric Anemone# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #bioelektrische Anemone# #[[1]]# hielte.", + /*french*/ "Selon moi, l'#anémone bioélectrique# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/la #anémona bioeléctrica# porta #[[1]]#. - hintTextTable[RHT_PHANTOM_GANON] = HintText(CustomMessage("#Phantom Ganon# holds", - /*german*/ "#Phantom-Ganon# hält", - /*french*/ "#Ganon Spectral# possède"), - // /*spanish*/#Ganon Fantasma# porta + hintTextTable[RHT_PHANTOM_GANON] = HintText(CustomMessage("They say that #Phantom Ganon# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Phantom-Ganon# #[[1]]# hielte.", + /*french*/ "Selon moi, #Ganon Spectral# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#Ganon Fantasma# porta #[[1]]#. {}, - {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 + {CustomMessage("They say that the #Evil Spirit from Beyond# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #böse Geist aus dem Jenseits# #[[1]]# hielte.", + /*french*/ "Selon moi, l'#esprit maléfique de l'au-delà# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/el #espíritu maligno de ultratumba# porta #[[1]]#. - hintTextTable[RHT_VOLVAGIA] = HintText(CustomMessage("#Volvagia# holds", - /*german*/ "#Volvagia# hält", - /*french*/ "#Volvagia# possède"), - // /*spanish*/#Volvagia# porta + hintTextTable[RHT_VOLVAGIA] = HintText(CustomMessage("They say that #Volvagia# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Volvagia# #[[1]]# hielte.", + /*french*/ "Selon moi, #Volvagia# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#Volvagia# porta #[[1]]#. {}, - {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 + {CustomMessage("They say that the #Subterranean Lava Dragon# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #subterrane Lavadrache# #[[1]]# hielte.", + /*french*/ "Selon moi, le #dragon des profondeurs# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/el #dragón de lava subterráneo# porta #[[1]]#. - hintTextTable[RHT_MORPHA] = HintText(CustomMessage("#Morpha# holds", - /*german*/ "#Morpha# hält", - /*french*/ "#Morpha# possède"), - // /*spanish*/#Morpha# porta + hintTextTable[RHT_MORPHA] = HintText(CustomMessage("They say that #Morpha# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Morpha# #[[1]]# hielte.", + /*french*/ "Selon moi, #Morpha# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#Morpha# porta #[[1]]#. {}, - {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 + {CustomMessage("They say that the #Giant Aquatic Amoeba# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #gigantische aquatische Amöbe# #[[1]]# hielte.", + /*french*/ "Selon moi, l'#amibe aquatique géante# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/la #ameba acuática gigante# porta #[[1]]#. - hintTextTable[RHT_BONGO_BONGO] = HintText(CustomMessage("#Bongo Bongo# holds", - /*german*/ "#Bongo Bongo# hält", - /*french*/ "#Bongo Bongo# possède"), - // /*spanish*/#Bongo Bongo# porta + hintTextTable[RHT_BONGO_BONGO] = HintText(CustomMessage("They say that #Bongo Bongo# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Bongo Bongo# #[[1]]# hielte.", + /*french*/ "Selon moi, #Bongo Bongo# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#Bongo Bongo# porta #[[1]]#. {}, - {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 + {CustomMessage("They say that the #Phantom Shadow Beast# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß das #Phantomschattenbiest# #[[1]]# hielte.", + /*french*/ "Selon moi, le #monstre de l'ombre# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/la #alimaña oscura espectral# porta #[[1]]#. - hintTextTable[RHT_TWINROVA] = HintText(CustomMessage("#Twinrova# holds", - /*german*/ "#Twinrova# hält", - /*french*/ "#Twinrova# possède"), - // /*spanish*/#Birova# porta + hintTextTable[RHT_TWINROVA] = HintText(CustomMessage("They say that #Twinrova# holds #[[1]]#.", + /*german*/ "Man erzählt sich, daß #Twinrova# #[[1]]# hielte.", + /*french*/ "Selon moi, #Twinrova# possède #[[1]]#.", {QM_RED, QM_GREEN}), + // /*spanish*/#Birova# porta #[[1]]#. {}, - {CustomMessage("the #Sorceress Sisters# hold", - /*german*/ "die #Hexenschwestern# halten", - /*french*/ "#les sorcières jumelles# possède")}); - // /*spanish*/las #hermanas hechiceras# portan + {CustomMessage("They say that the #Sorceress Sisters# hold #[[1]]#.", + /*german*/ "Man erzählt sich, daß die #Hexenschwestern# #[[1]]# hielten.", + /*french*/ "Selon moi, #les sorcières jumelles# possède #[[1]]#.", {QM_RED, QM_GREEN})}); + // /*spanish*/las #hermanas hechiceras# portan #[[1]]#. + + hintTextTable[RHT_GIFT_FROM_RAURU] = HintText(CustomMessage("They say that the #Sage of Light# gifts @ #[[1]]#.", + /*german*/ "Man erzählt sich, daß der #Weise des Lichts# #[[1]]# schenke.", + /*french*/ "Selon moi, #le Sage de la Lumière# donne #[[1]]#.", {QM_RED, QM_GREEN}), + {}, + {CustomMessage("They say that #a former owl# gifts @ #[[1]]#.", + /*german*/ "Man erzählt sich, daß #eine einstige Eule# #[[1]]# schenke.", + /*french*/ "Selon moi, #un ancien hibou# donne #[[1]]#.", {QM_RED, QM_GREEN})}); + /*-------------------------- | BRIDGE HINT TEXT | ---------------------------*/ @@ -2665,7 +2786,7 @@ void StaticData::HintTable_Init() { | ALTAR TEXT | ---------------------------*/ - hintTextTable[RHT_CHILD_ALTAR_STONES] = HintText(CustomMessage("3 Spiritual Stone's found in Hyrule...^$0#[[1]]#...^$1#[[2]]#...^$2#[[3]]#...^", + hintTextTable[RHT_CHILD_ALTAR_STONES] = HintText(CustomMessage("3 Spiritual Stones 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})); @@ -2781,7 +2902,7 @@ void StaticData::HintTable_Init() { {QM_RED, QM_GREEN, QM_GREEN})); 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", + "Prove yourself to be a horsemaster by scoring 1500 points to win my #[[1]]#!\x0B", {QM_RED, QM_GREEN})); 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#!^" 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 20e646307..0dbd94adf 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 @@ -117,6 +117,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*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]]#. + hintTextTable[RHT_DEKU_TREE_HEART] = HintText(CustomMessage("They say that a #heart in the Deku Tree# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | DODONGOS CAVERN | ---------------------------*/ @@ -275,6 +279,23 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The /*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_POT_DODONGOS_CAVERN] = HintText(CustomMessage("They say that a #pot in Dodongo's Cavern# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DODONGOS_CAVERN_HEART] = HintText(CustomMessage("They say that a #heart in Dodongo's Cavern# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone in Dodongo's Cavern# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone in Dodongo's Cavern# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + /*-------------------------- | JABU JABUS BELLY | ---------------------------*/ @@ -421,6 +442,20 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The /*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]]#. + + hintTextTable[RHT_POT_JABU_JABUS_BELLY] = HintText(CustomMessage("They say that a #pot in Jabu Jabu's Belly# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + + hintTextTable[RHT_JABU_JABU_RUPEE] = HintText(CustomMessage("They say that #underwater in Jabu-Jabu's Belly# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_JABU_JABU_HEART] = HintText(CustomMessage("They say that near a #central lift in Jabu-Jabu's Belly# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | FOREST TEMPLE | ---------------------------*/ @@ -638,11 +673,19 @@ hintTextTable[RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = HintText(CustomMessage("The /*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]]#.", + 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]]#. - + + hintTextTable[RHT_POT_FOREST_TEMPLE] = HintText(CustomMessage("They say that a #pot in Forest Temple# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_FOREST_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Forest Temple# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | FIRE TEMPLE | ---------------------------*/ @@ -831,6 +874,22 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa /*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]]#. + hintTextTable[RHT_POT_FIRE_TEMPLE] = HintText(CustomMessage("They say that a #pot in Fire Temple# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_FIRE_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Fire Temple# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun in a hot arena# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun behind a knight's throne in a volcano# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | WATER TEMPLE | ---------------------------*/ @@ -958,6 +1017,30 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa /*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_POT_WATER_TEMPLE] = HintText(CustomMessage("They say that a #pot in Water Temple# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WATER_TEMPLE_HEART] = HintText(CustomMessage("They say that in a #river in the Water Temple# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WATER_TEMPLE_HEART] = HintText(CustomMessage("They say that in a #river in the Water Temple# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun atop a small pillar before a duel with one's shadow# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY] = HintText(CustomMessage("They say that #calling the rain before a duel with one's shadow# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun before a duel with one's shadow# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | SPIRIT TEMPLE | ---------------------------*/ @@ -1191,6 +1274,18 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa /*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]]#. + hintTextTable[RHT_POT_SPIRIT_TEMPLE] = HintText(CustomMessage("They say that a #pot in Spirit Temple# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SPIRIT_TEMPLE_HEART] = HintText(CustomMessage("They say that on a #small platform# in the Spirit Temple lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SPIRIT_TEMPLE_MQ_HEART] = HintText(CustomMessage("They say that guarded by a #ring of flame# in the Spirit Temple is #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | SHADOW TEMPLE | ---------------------------*/ @@ -1434,6 +1529,26 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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]]#. + hintTextTable[RHT_POT_SHADOW_TEMPLE] = HintText(CustomMessage("They say that a #pot in Shadow Temple# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SHADOW_TEMPLE_HEART] = HintText(CustomMessage("They say that a #heart in the Shadow Temple# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY] = HintText(CustomMessage("They say that an #calling the rain for a sentry guarding a house of the dead# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY] = HintText(CustomMessage("They say that an #calling the rain on a platform suspended above a bottomless pit# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY] = HintText(CustomMessage("They say that an #calling the sun near an invisible chest guarded by the dead# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!.", {QM_RED, QM_GREEN})); + /*-------------------------- | BOTTOM OF THE WELL | ---------------------------*/ @@ -1552,6 +1667,31 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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_POT_BOTTOM_OF_THE_WELL] = HintText(CustomMessage("They say that a #pot in Bottom of the Well# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_HEART] = HintText(CustomMessage("They say that a #heart within the well# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_RUPEE] = HintText(CustomMessage("They say that a #hidden path through the floor# the well# leads to #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY] = HintText(CustomMessage("They say that an #calling the sun a dead end# within the well reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY] = HintText(CustomMessage("They say that an #calling the sun in an empty cell# within the well reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!.", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY] = HintText(CustomMessage("They say that an #calling the sun a dead end# within the well reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!.", {QM_RED, QM_GREEN})); + + /*-------------------------- | ICE CAVERN | ---------------------------*/ @@ -1625,30 +1765,47 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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]]#. + hintTextTable[RHT_POT_ICE_CAVERN] = HintText(CustomMessage("They say that a #pot in Ice Cavern# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", { QM_RED, QM_GREEN })); + + hintTextTable[RHT_ICE_CAVERN_HEART] = HintText(CustomMessage("They say that atop on a #frozen pillar# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ICE_CAVERN_RUPEE] = HintText(CustomMessage("They say that a #rupee in a frozen cavern# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ICE_CAVERN_ENTRANCE_STORMS_FAIRY] = HintText(CustomMessage("They say that #calling the rain near the entrance to a frozen cave# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + // /*spanish*/ Según dicen, una #Skulltula tras un ardiente hielo# otorga #[[1]]#. + /*-------------------------- - | GERUDO TRAINING GROUNDS | + | Gerudo Training Ground | ---------------------------*/ - hintTextTable[RHT_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST] = HintText(CustomMessage("They say that a #blinded eye in the Gerudo Training Grounds# drops #[[1]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST] = HintText(CustomMessage("They say that a #blinded eye in the Gerudo Training Ground# 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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST] = HintText(CustomMessage("They say that a #blinded eye in the Gerudo Training Ground# 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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_STALFOS_CHEST] = HintText(CustomMessage("They say that #soldiers walking on shifting sands# in the Gerudo Training Ground 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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_BEAMOS_CHEST] = HintText(CustomMessage("They say that #reptilian warriors# in the Gerudo Training Ground 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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth# in the Gerudo Training Ground 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]]#. @@ -1668,17 +1825,17 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST] = HintText(CustomMessage("They say that the #Song of Time# in the Gerudo Training Ground 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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST] = HintText(CustomMessage("They say that the #Song of Time# in the Gerudo Training Ground 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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST] = HintText(CustomMessage("They say that #fiery foes# in the Gerudo Training Ground 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]]#. @@ -1723,7 +1880,11 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY] = HintText(CustomMessage("They say that #calling the rain near the entrance to the Gerudo Training Grounds# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GERUDO_TRAINING_GROUND_FREESTANDING_KEY] = HintText(CustomMessage("They say that the #Song of Time# in the Gerudo Training Ground 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]]#. @@ -1738,7 +1899,7 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST] = HintText(CustomMessage("They say that #soldiers walking on shifting sands# in the Gerudo Training Ground 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]]#. @@ -1758,12 +1919,12 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST] = HintText(CustomMessage("They say that #fiery foes# in the Gerudo Training Ground 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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST] = HintText(CustomMessage("They say that #reptilian warriors# in the Gerudo Training Ground 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]]#. @@ -1793,7 +1954,7 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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]]#.", + hintTextTable[RHT_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST] = HintText(CustomMessage("They say that the #Eye of Truth# in the Gerudo Training Ground 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]]#. @@ -1803,6 +1964,10 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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_GROUNDS_HEART] = HintText(CustomMessage("They say that a watching a #trial with Dinalfos# is #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + /*-------------------------- | GANONS CASTLE | ---------------------------*/ @@ -1886,6 +2051,14 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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_SPIRIT_TRIAL_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun for a sentry in the test of the sands# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GANONS_CASTLE_SCRUBS_FAIRY] = HintText(CustomMessage("They say that within a #sanctuary before the final trial# rests #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + 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})); @@ -1995,5 +2168,14 @@ hintTextTable[RHT_SHADOW_TEMPLE_MAP_CHEST] = HintText(CustomMessage("They say th /*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_POT_GANONS_CASTLE] = HintText(CustomMessage("They say that a #pot in Ganon's Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GANONS_CASTLE_HEART] = HintText(CustomMessage("They say that a #heart in Ganon's Castle# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + } } 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 a467c18b5..cdbbb5329 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 @@ -1490,5 +1490,450 @@ void StaticData::HintTable_Init_Exclude_Overworld() { /*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]]#. + + hintTextTable[RHT_POT_KOKIRI_FOREST] = HintText(CustomMessage("They say that a #pot in Kokiri Forest# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_GERUDO_FORTRESS] = HintText(CustomMessage("They say that a #pot in Gerudo Fortress# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_WASTELAND] = HintText(CustomMessage("They say that a #pot in Haunted Wasteland# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_MARKET] = HintText(CustomMessage("They say that a #pot in Market# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_KAKARIKO] = HintText(CustomMessage("They say that a #pot in Kakariko Village# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_GRAVEYARD] = HintText(CustomMessage("They say that a #pot in Graveyard# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_GORON_CITY] = HintText(CustomMessage("They say that a #pot in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_DEATH_MOUNTAIN_CRATER] = HintText(CustomMessage("They say that a #pot in Death Mountain Crater# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_ZORAS_DOMAIN] = HintText(CustomMessage("They say that a #pot in Zora's Domain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_ZORAS_FOUNTAIN] = HintText(CustomMessage("They say that a #pot in Zora's Fountain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_LON_LON_RANCH] = HintText(CustomMessage("They say that a #pot in Lon Lon Ranch# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_HYRULE_FIELD] = HintText(CustomMessage("They say that a #pot in Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_POT_HYRULE_CASTLE] = HintText(CustomMessage("They say that a #pot in Hyrule Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_KOKIRI_FOREST_RUPEE] = HintText(CustomMessage("They say that a rupee in a #tranquil forest# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_KOKIRI_FOREST_HEART] = HintText(CustomMessage("They say that a heart in a #tranquil forest# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_SARIAS_HOUSE_HEART] = HintText(CustomMessage("They say that a heart in a #dear friend's home# hides #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_LOST_WOODS_RUPEE] = HintText(CustomMessage("They say that under a #boulder in the woods# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_LOST_WOODS_SHORTCUT_RUPEE] = HintText(CustomMessage("They say that in a #pool of water in the woods# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_LAKE_HYLIA_RUPEE] = HintText(CustomMessage("They say that just off the #coast of a lake# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_LABORATORY_RUPEE] = HintText(CustomMessage("They say that at the #bottom of a tank# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_DAMPES_GRAVE_RUPEE] = HintText(CustomMessage("They say that within a #quick-footed spirit's grave# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_GERUDO_VALLEY_GROTTO_RUPEE] = HintText(CustomMessage("They say that an Octarok in an #underground spring# guards #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_DEATH_MOUNTAIN_TRAIL_RUPEE] = HintText(CustomMessage("They say that beneath a boulder on a #mountain's cliffside# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART] = HintText(CustomMessage("They say that accompanying a #cow in a small cave# is #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE] = HintText(CustomMessage("They say that accompanying a #cow in a small cave# is #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_DEATH_MOUNTAIN_CRATER_RUPEE] = HintText(CustomMessage("They say that on a #small platform suspended above lava# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_ZORAS_RIVER_WATERFALL_RUPEE] = HintText(CustomMessage("They say that beneath a #waterfall feeding a narrow river# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + hintTextTable[RHT_ZORAS_FOUNTAIN_RUPEE] = HintText(CustomMessage("They say that at the bottom of a #partially-frozen spring# lies #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + // /*spanish*/ + + hintTextTable[RHT_SFM_FAIRY_GROTTO_FAIRY] = HintText(CustomMessage("They say that within #a fountain beneath a forest meadow# rests #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_FAIRY_GROTTO_FAIRY] = HintText(CustomMessage("They say that within #a fountain beneath a river# rests #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HF_FAIRY_GROTTO_FAIRY] = HintText(CustomMessage("They say that within #a fountain beneath a a few trees bordering a wide field# rests #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZD_FAIRY_GROTTO_FAIRY] = HintText(CustomMessage("They say that within #a fountain beneath the home of the Zoras# rests #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GF_FAIRY_GROTTO_FAIRY] = HintText(CustomMessage("They say that within #a fountain beneath the home of thieves# rests #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY] = HintText(CustomMessage("They say that within #a fountain behind a wall within a grave# rests #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_COLOSSUS_OASIS_FAIRY] = HintText(CustomMessage("They say that #restoring water to a dried oasis# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout on the riverside# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KF_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout near a forest shop# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout near the entrance to the forest# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout above a sylvan theatre# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LH_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout on the lakeside# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GV_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout on the side of a canyon# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_COLOSSUS_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout near a temple of the sand# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GRAVEYARD_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout within a graveyard# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMC_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout within a volcano# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMT_BEAN_SPROUT_FAIRY] = HintText(CustomMessage("They say that #watering a young sprout on the moutainside# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_TOT_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone in the ouskirts of the market# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_TOT_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone in the ouskirts of the market# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMC_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within a volcano# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMC_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within a volcano# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMT_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone on a mountain cliff face# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMT_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone on a mountain cliff face# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_COLOSSUS_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near the temple of the sane# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_COLOSSUS_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near the temple of the sane# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GV_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near a canyon waterfall# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GV_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near a canyon waterfall# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GC_MAZE_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone behind a maze of rock# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GC_MAZE_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone behind a maze of rock# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near a blacksmith# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near a blacksmith# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GRAVEYARD_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking the graveyard# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking the graveyard# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HC_MALON_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking the path to the castle# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HC_MALON_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking the path to the castle# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near a secret path to the castle# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near a secret path to the castle# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath the castle# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath the castle# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone near an ancient tree# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone near an ancient tree# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KF_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking a forest village# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KF_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking a forest village# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath a forest village# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath a forest village# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LH_LAB_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking the river feeding a lake# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LH_LAB_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking the river feeding a lake# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone at the back of a lake# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone at the back of a lake# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone at the back of a lake# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone at the back of a lake# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LW_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within a perplexing wood# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LW_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within a perplexing wood# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SFM_MAZE_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overlooking a forest maze# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overlooking a forest maze# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SFM_SARIA_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone watching a hiding place in the woods# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone watching a hiding place in the woods# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZD_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone listening to an aquatic king# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZD_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone listening to an aquatic king# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone in the ouskirts of a deap fountain# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone in the ouskirts of a deap fountain# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZF_JABU_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone watching a guardian of the sea# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZF_JABU_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone watching a guardian of the sea# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone overwatching a river# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone overwatching a river# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath a waterfall# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath a waterfall# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone hiding near a cow# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone hiding near a cow# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath the entrance to the market# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath the entrance to the market# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath trees guarded by a Peahat# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath trees guarded by a Peahat# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath a village at the base of a mountain# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath a village at the base of a mountain# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within a plateau by a river# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within a plateau by a river# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath an escape from the forest# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath an escape from the forest# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone beneath the entrance to a village within a mountain# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone beneath the entrance to a village within a mountain# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY] = HintText(CustomMessage("They say that #playing a tune for an odd stone within the side of a crater# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within the side of a crater# reveals #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + } } 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 60464746c..cd33fd441 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 @@ -1302,7 +1302,7 @@ void StaticData::HintTable_Init_Item() { 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"), + hintTextTable[RHT_GERUDO_TRAINING_GROUND_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é") @@ -1437,7 +1437,7 @@ void StaticData::HintTable_Init_Item() { 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"), + hintTextTable[RHT_GERUDO_TRAINING_GROUND_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") diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index fa86a863b..941f0924b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -113,8 +113,8 @@ StaticHintInfo::StaticHintInfo(HintType _type, std::vectorGetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES)) { - stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Value(); + stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).GetContextOptionIndex(); } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { - stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Value() - 6; + stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).GetContextOptionIndex() - 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; + stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).GetContextOptionIndex() - 6; } 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() }); + stones = std::max({ stones, ctx->GetOption(RSK_LACS_STONE_COUNT).GetContextOptionIndex() }); } 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 )}); + stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).GetContextOptionIndex() - 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 )}); + stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).GetContextOptionIndex() - 6 )}); } return stones; } @@ -242,18 +242,18 @@ 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(); + medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).GetContextOptionIndex(); } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { - medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Value() - 3; + medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).GetContextOptionIndex() - 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; + medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).GetContextOptionIndex() - 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() }); + medallions = std::max({ medallions, ctx->GetOption(RSK_LACS_MEDALLION_COUNT).GetContextOptionIndex() }); } 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 )}); + medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).GetContextOptionIndex() - 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 )}); + medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).GetContextOptionIndex() - 3 )}); } return medallions; } @@ -262,10 +262,10 @@ 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(); + tokens = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).GetContextOptionIndex(); } 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() }); + tokens = std::max({ tokens, ctx->GetOption(RSK_LACS_TOKEN_COUNT).GetContextOptionIndex() }); } return tokens; } @@ -273,7 +273,7 @@ uint8_t TokensRequiredBySettings() { 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); + return ctx->GetOption(RSK_BIG_POE_COUNT).GetContextOptionIndex() >= 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(); @@ -411,7 +411,7 @@ static bool CreateHint(RandomizerCheck location, uint8_t copies, HintType type, return false; } RandomizerCheck gossipStone = RandomElement(gossipStoneLocations); - RandomizerArea area = RandomElementFromSet(ctx->GetItemLocation(location)->GetAreas()); + RandomizerArea area = ctx->GetItemLocation(location)->GetRandomArea(); //Set that hints are accesible ctx->GetItemLocation(location)->SetHintAccesible(); @@ -483,7 +483,7 @@ static void CreateTrialHints(uint8_t copies) { AddGossipStoneHintCopies(copies, HINT_TYPE_HINT_KEY, "Trial", {RHT_ZERO_TRIALS}); } else { 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 + if (ctx->GetOption(RSK_TRIAL_COUNT).GetContextOptionIndex() >= 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();}); @@ -501,10 +501,7 @@ void CreateWarpSongTexts() { auto warpSongEntrances = GetShuffleableEntrances(EntranceType::WarpSong, false); for (auto entrance : warpSongEntrances) { //RANDOTODO make random - RandomizerArea destination = RA_NONE; - if (!entrance->GetConnectedRegion()->GetAllAreas().empty()){ - destination = *entrance->GetConnectedRegion()->GetAllAreas().begin(); - } + RandomizerArea destination = entrance->GetConnectedRegion()->GetFirstArea(); 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})); @@ -614,7 +611,7 @@ uint8_t PlaceHints(std::vector& selectedHints, std::vectorGetOption(RSK_HINT_DISTRIBUTION).Value()]; + const HintSetting& hintSetting = hintSettingTable[ctx->GetOption(RSK_HINT_DISTRIBUTION).GetContextOptionIndex()]; std::vector distTable = hintSetting.distTable; // Apply impa's song exclusions when zelda is skipped @@ -710,7 +707,7 @@ void CreateChildAltarHint() { } std::vector stoneAreas = {}; for (auto loc : stoneLocs){ - stoneAreas.push_back(RandomElementFromSet(ctx->GetItemLocation(loc)->GetAreas())); + stoneAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); } ctx->AddHint(RH_ALTAR_CHILD, Hint(RH_ALTAR_CHILD, HINT_TYPE_ALTAR_CHILD, {}, stoneLocs, stoneAreas)); } @@ -732,7 +729,7 @@ void CreateAdultAltarHint() { } std::vector medallionAreas = {}; for (auto loc : medallionLocs){ - medallionAreas.push_back(RandomElementFromSet(ctx->GetItemLocation(loc)->GetAreas())); + medallionAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); } ctx->AddHint(RH_ALTAR_ADULT, Hint(RH_ALTAR_ADULT, HINT_TYPE_ALTAR_ADULT, {}, medallionLocs, medallionAreas)); } @@ -748,13 +745,23 @@ void CreateStaticHintFromData(RandomizerHint hint, StaticHintInfo staticData){ std::vector locations = {}; if (staticData.targetItems.size() > 0){ locations = FindItemsAndMarkHinted(staticData.targetItems, staticData.hintChecks); - } - for(auto check: staticData.targetChecks){ - ctx->GetItemLocation(check)->SetHintAccesible(); + } else { + for(auto check: staticData.targetChecks){ + locations.push_back(check); + } } std::vector areas = {}; for (auto loc : locations){ - areas.push_back(RandomElementFromSet(ctx->GetItemLocation(loc)->GetAreas())); + ctx->GetItemLocation(loc)->SetHintAccesible(); + if (ctx->GetItemLocation(loc)->GetAreas().empty()){ + //If we get to here then it means a location got through with no area assignment, which means something went wrong elsewhere. + SPDLOG_DEBUG("Attempted to hint location with no areas: "); + SPDLOG_DEBUG(Rando::StaticData::GetLocation(loc)->GetName()); + //assert(false); + areas.push_back(RA_NONE); + } else { + areas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); + } } //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)); @@ -769,7 +776,7 @@ void CreateStaticItemHint(RandomizerHint hintKey, std::vector locations = FindItemsAndMarkHinted(items, hintChecks); std::vector areas = {}; for (auto loc : locations){ - areas.push_back(RandomElementFromSet(ctx->GetItemLocation(loc)->GetAreas())); + areas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); } ctx->AddHint(hintKey, Hint(hintKey, HINT_TYPE_AREA, hintTextKeys, locations, areas, {}, yourPocket)); } diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.hpp b/soh/soh/Enhancements/randomizer/3drando/hints.hpp index d111c78ca..9199c6c81 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.hpp @@ -69,6 +69,8 @@ struct StaticHintInfo{ std::vector _hintChecks = {}, bool _yourPocket = false, int _num = 0); }; +RandomizerHintTextKey GetRandomJunkHint(); extern void CreateAllHints(); extern void CreateWarpSongTexts(); -void CreateStaticHints(); \ No newline at end of file +void CreateStaticHints(); +RandomizerHintTextKey GetRandomJunkHint(); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 52f6359c5..6f908de22 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -535,8 +535,6 @@ static void PlaceVanillaDekuScrubItems(bool junkOneTimeScrubs) { 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() { @@ -624,6 +622,114 @@ static void PlaceVanillaOverworldFish() { } } +static void PlaceVanillaFairies() { + auto ctx = Rando::Context::GetInstance(); + for (auto rc : Rando::StaticData::GetOverworldFairyLocations()) { + ctx->PlaceItemInLocation(rc, GetJunkItem(), false, true); + } + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) { + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, GetJunkItem(), false, true); + } else { + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_1, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_2, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_3, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_4, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_5, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_6, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_7, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, GetJunkItem(), false, true); + } + if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) { + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, GetJunkItem(), false, true); + } else { + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, GetJunkItem(), false, true); + } + if (ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsMQ()) { + ctx->PlaceItemInLocation(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, GetJunkItem(), false, true); + } + if (ctx->GetDungeon(Rando::WATER_TEMPLE)->IsMQ()) { + ctx->PlaceItemInLocation(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, GetJunkItem(), false, true); + } + if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsMQ()) { + ctx->PlaceItemInLocation(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, GetJunkItem(), false, true); + } else { + ctx->PlaceItemInLocation(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, GetJunkItem(), false, true); + } + if (ctx->GetDungeon(Rando::SHADOW_TEMPLE)->IsMQ()) { + ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, GetJunkItem(), false, true); + } else { + ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, GetJunkItem(), false, true); + } + if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsMQ()) { + ctx->PlaceItemInLocation(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, GetJunkItem(), false, true); + ctx->PlaceItemInLocation(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, GetJunkItem(), false, true); + } else { + ctx->PlaceItemInLocation(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, GetJunkItem(), false, true); + } + if (ctx->GetDungeon(Rando::ICE_CAVERN)->IsVanilla()) { + ctx->PlaceItemInLocation(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, GetJunkItem(), false, true); + } + if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsVanilla()) { + ctx->PlaceItemInLocation(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, GetJunkItem(), false, true); + } + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla()) { + ctx->PlaceItemInLocation(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, GetJunkItem(), false, true); + } +} + +static void PlaceItemsForType(RandomizerCheckType rctype, bool overworldActive, bool dungeonActive, bool placeVanilla) { + for (RandomizerCheck rc : ctx->GetLocations(ctx->allLocations, rctype)) { + auto loc = Rando::StaticData::GetLocation(rc); + + // If item is in the overworld and shuffled, add its item to the pool + if (loc->IsOverworld()) { + if (overworldActive) { + AddItemToMainPool(loc->GetVanillaItem()); + } else if (placeVanilla) { + ctx->PlaceItemInLocation(rc, loc->GetVanillaItem(), false, true); + } + } else { + if (dungeonActive) { + // If the same in MQ and vanilla, add. + RandomizerCheckQuest currentQuest = loc->GetQuest(); + if (currentQuest == RCQUEST_BOTH) { + AddItemToMainPool(loc->GetVanillaItem()); + } else { + // Check if current item's dungeon is vanilla or MQ, and only add if quest corresponds to it. + SceneID itemScene = loc->GetScene(); + + if (itemScene >= SCENE_DEKU_TREE && itemScene <= SCENE_GERUDO_TRAINING_GROUND) { + bool isMQ = ctx->GetDungeon(itemScene)->IsMQ(); + + if ((isMQ && currentQuest == RCQUEST_MQ) || (!isMQ && currentQuest == RCQUEST_VANILLA)) { + AddItemToMainPool(loc->GetVanillaItem()); + } + } + } + } else if (placeVanilla) { + ctx->PlaceItemInLocation(rc, loc->GetVanillaItem(), false, true); + } + } + } +} + static void SetScarceItemPool() { ReplaceMaxItem(RG_PROGRESSIVE_BOMBCHUS, 3); ReplaceMaxItem(RG_BOMBCHU_5, 1); @@ -631,8 +737,8 @@ static void SetScarceItemPool() { 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_STICK_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG) ? 2 : 1); + ReplaceMaxItem(RG_PROGRESSIVE_NUT_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG) ? 2 : 1); ReplaceMaxItem(RG_PROGRESSIVE_BOW, 2); ReplaceMaxItem(RG_PROGRESSIVE_SLINGSHOT, 2); ReplaceMaxItem(RG_PROGRESSIVE_BOMB_BAG, 2); @@ -648,14 +754,14 @@ static void SetMinimalItemPool() { 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_STICK_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG) ? 1 : 0); + ReplaceMaxItem(RG_PROGRESSIVE_NUT_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG) ? 1 : 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(RG_HEART_CONTAINER, (ctx->GetOption(RSK_STARTING_HEARTS).Value() == 18)? 1 : 0); + ReplaceMaxItem(RG_HEART_CONTAINER, (ctx->GetOption(RSK_STARTING_HEARTS).GetContextOptionIndex() == 18)? 1 : 0); } void GenerateItemPool() { @@ -679,16 +785,16 @@ void GenerateItemPool() { RG_FIRE_ARROWS, RG_ICE_ARROWS, RG_LIGHT_ARROWS, - RG_DOUBLE_DEFENSE, //Double defense + RG_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 + RG_PROGRESSIVE_HOOKSHOT, + RG_PROGRESSIVE_STRENGTH, + RG_PROGRESSIVE_BOMB_BAG, + RG_PROGRESSIVE_BOW, + RG_PROGRESSIVE_SLINGSHOT, + RG_PROGRESSIVE_WALLET, + RG_PROGRESSIVE_SCALE, + RG_PROGRESSIVE_MAGIC_METER, }; //Check song shuffle and dungeon reward shuffle just for ice traps if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_ANYWHERE)) { @@ -721,7 +827,7 @@ void GenerateItemPool() { 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)); + AddItemToMainPool(RG_TRIFORCE_PIECE, (ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).GetContextOptionIndex() + 1)); ctx->PlaceItemInLocation(RC_TRIFORCE_COMPLETED, RG_TRIFORCE); // Win condition ctx->PlaceItemInLocation(RC_GANON, GetJunkItem(), false, true); } else { @@ -742,7 +848,7 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { AddItemToMainPool(RG_MASTER_SWORD); - ctx->possibleIceTrapModels.push_back(RG_MASTER_SWORD); //Master Sword without the GI enum + ctx->possibleIceTrapModels.push_back(RG_MASTER_SWORD); } else { if (!ctx->GetOption(RSK_STARTING_MASTER_SWORD)) { ctx->PlaceItemInLocation(RC_TOT_MASTER_SWORD, RG_MASTER_SWORD, false, true); @@ -761,7 +867,7 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { AddItemToPool(PendingJunkPool, RG_PROGRESSIVE_OCARINA); } - ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_OCARINA); //Progressive ocarina + ctx->possibleIceTrapModels.push_back(RG_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); @@ -780,7 +886,6 @@ void GenerateItemPool() { 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); @@ -817,11 +922,20 @@ void GenerateItemPool() { PlaceVanillaCowMilk(); } + // Shuffle Pots + bool overworldPotsActive = ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL); + bool dungeonPotsActive = ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_DUNGEONS) || + ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL); + if (overworldPotsActive || dungeonPotsActive) { + PlaceItemsForType(RCTYPE_POT, overworldPotsActive, dungeonPotsActive, false); + } + 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(); + uint8_t pondCt = ctx->GetOption(RSK_FISHSANITY_POND_COUNT).GetContextOptionIndex(); for (uint8_t i = 0; i < pondCt; i++) { AddItemToMainPool(GetJunkItem()); } @@ -874,7 +988,7 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { AddItemToPool(PendingJunkPool, RG_MAGIC_BEAN_PACK); } - ctx->possibleIceTrapModels.push_back(RG_MAGIC_BEAN_PACK); //Magic bean pack + ctx->possibleIceTrapModels.push_back(RG_MAGIC_BEAN_PACK); } else { ctx->PlaceItemInLocation(RC_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, false, true); } @@ -1018,7 +1132,7 @@ void GenerateItemPool() { //Ice Traps AddItemToMainPool(RG_ICE_TRAP); - if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUNDS)->IsVanilla()) { + if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsVanilla()) { AddItemToMainPool(RG_ICE_TRAP); } if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla()) { @@ -1026,13 +1140,13 @@ void GenerateItemPool() { } //Gerudo Fortress - if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN)) { + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE)) { 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)) { + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_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); @@ -1050,14 +1164,14 @@ void GenerateItemPool() { } } 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)) { + if (ctx->GetOption(RSK_KEYRINGS_GERUDO_FORTRESS) && ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL)) { AddItemToPool(PendingJunkPool, RG_GERUDO_FORTRESS_KEY_RING); } else { AddItemToPool(PendingJunkPool, RG_GERUDO_FORTRESS_SMALL_KEY); } } } else { - if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST)) { + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_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); @@ -1071,7 +1185,7 @@ void GenerateItemPool() { } //Gerudo Membership Card - if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_OPEN)) { + if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_CARPENTERS_FREE)) { AddItemToMainPool(RG_GERUDO_MEMBERSHIP_CARD); ctx->possibleIceTrapModels.push_back(RG_GERUDO_MEMBERSHIP_CARD); } else if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { @@ -1137,10 +1251,10 @@ void GenerateItemPool() { } else { AddItemToPool(PendingJunkPool, RG_SHADOW_TEMPLE_SMALL_KEY); } - if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUNDS)->HasKeyRing()) { - AddItemToPool(PendingJunkPool, RG_GERUDO_TRAINING_GROUNDS_KEY_RING); + if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_GERUDO_TRAINING_GROUND_KEY_RING); } else { - AddItemToPool(PendingJunkPool, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY); + AddItemToPool(PendingJunkPool, RG_GERUDO_TRAINING_GROUND_SMALL_KEY); } if (ctx->GetDungeon(Rando::GANONS_CASTLE)->HasKeyRing()) { AddItemToPool(PendingJunkPool, RG_GANONS_CASTLE_KEY_RING); @@ -1175,6 +1289,27 @@ void GenerateItemPool() { AddItemsToPool(ItemPool, shopsanityRupees); //Shopsanity gets extra large rupees } + // Shuffle Fairies + if (ctx->GetOption(RSK_SHUFFLE_FAIRIES)) { + for (auto rc : Rando::StaticData::GetOverworldFairyLocations()) { + AddItemToMainPool(GetJunkItem()); + } + // 8 extra for Ganon's Castle + 2 Dodongo's Cavern Gossip Stone + 3 Shadow Temple + int extra = 13; + extra += ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla() ? 0 : 2; + extra += ctx->GetDungeon(Rando::WATER_TEMPLE)->IsVanilla() ? 0 : 3; + extra += ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsVanilla() ? 2 : 1; + extra += ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() ? 1 : 2; + extra += ctx->GetDungeon(Rando::ICE_CAVERN)->IsVanilla() ? 1 : 0; + extra += ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsVanilla() ? 1 : 0; + extra += ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla() ? 1 : 0; + for (int i = 0; i < extra; i++) { + AddItemToMainPool(GetJunkItem()); + } + } else { + PlaceVanillaFairies(); + } + //Scrubsanity if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) { //Deku Tree @@ -1207,7 +1342,7 @@ void GenerateItemPool() { //Overworld Scrubs AddItemsToPool(ItemPool, dekuScrubItems); - //I'm not sure what this is for, but it was in ootr so I copied it + //Scrubs which sell seeds or arrows sell it based on age, this randomly assigns them for (uint8_t i = 0; i < 7; i++) { if (Random(0, 3)) { AddItemToMainPool(RG_ARROWS_30); @@ -1219,6 +1354,16 @@ void GenerateItemPool() { PlaceVanillaDekuScrubItems(ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF)); } + // RANDOTODO: Don't add freestanding locations to the seed at all in the first place so this check + // can be put back in place, and not place the vanilla items in PlaceItemsForType. + bool overworldFreeStandingActive = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_ALL); + bool dungeonFreeStandingActive = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_DUNGEONS) || + ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_ALL); + //if (overworldFreeStandingActive || dungeonFreeStandingActive) { + PlaceItemsForType(RCTYPE_FREESTANDING, overworldFreeStandingActive, dungeonFreeStandingActive, true); + //} + AddItemsToPool(ItemPool, alwaysItems); AddItemsToPool(ItemPool, dungeonRewards); @@ -1259,7 +1404,7 @@ void GenerateItemPool() { if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla()) { AddItemsToPool(ItemPool, BW_Vanilla); } - if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUNDS)->IsMQ()) { + if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsMQ()) { AddItemsToPool(ItemPool, GTG_MQ); } else { AddItemsToPool(ItemPool, GTG_Vanilla); @@ -1328,10 +1473,8 @@ void GenerateItemPool() { 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) { - AddItemToMainPool(dungeon->GetSmallKey(), dungeon->GetSmallKeyCount()); - } + } else if (dungeon->GetSmallKeyCount() > 0) { + AddItemToMainPool(dungeon->GetSmallKey(), dungeon->GetSmallKeyCount()); } } } @@ -1348,7 +1491,7 @@ void GenerateItemPool() { 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)) { + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).GetContextOptionIndex() >= 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); @@ -1373,7 +1516,7 @@ void GenerateItemPool() { 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 + ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_GORONSWORD); } else { ctx->possibleIceTrapModels.push_back(RG_BIGGORON_SWORD); } diff --git a/soh/soh/Enhancements/randomizer/3drando/keys.hpp b/soh/soh/Enhancements/randomizer/3drando/keys.hpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp index c1c3391e2..725844f10 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.cpp @@ -211,6 +211,14 @@ bool Here(const RandomizerRegion region, ConditionFn condition) { return areaTable[region].Here(condition); } +bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) { + return areaTable[region].MQSpiritShared(condition, false, anyAge); +} + +bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) { + return areaTable[region].MQSpiritShared(condition, true, anyAge); +} + bool CanPlantBean(const RandomizerRegion region) { return areaTable[region].CanPlantBeanCheck(); } @@ -249,14 +257,17 @@ void RegionTable_Init() { areaTable.fill(Region("Invalid Region", "Invalid Region", {}, NO_DAY_NIGHT_CYCLE, {}, {}, {})); //name, scene, hint text, events, locations, exits - areaTable[RR_ROOT] = Region("Root", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ROOT] = Region("Root", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->KakarikoVillageGateOpen, {[]{return ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}}), + }, { //Locations LOCATION(RC_LINKS_POCKET, true), - LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Value();), + LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).GetContextOptionIndex() + 1;), LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)), }, { //Exits - Entrance(RR_ROOT_EXITS, {[]{return true;}}) + Entrance(RR_ROOT_EXITS, {[]{return true;}}), }); areaTable[RR_ROOT_EXITS] = Region("Root Exits", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -345,13 +356,6 @@ void RegionTable_Init() { exit.GetConnectedRegion()->entrances.push_front(&exit); } } - /* - //Events -}, { - //Locations -}, { - //Exits -*/ } void ReplaceFirstInString(std::string& s, std::string const& toReplace, std::string const& replaceWith) { @@ -387,7 +391,7 @@ void ReplaceAllInString(std::string& s, std::string const& toReplace, std::strin std::string CleanCheckConditionString(std::string condition) { ReplaceAllInString(condition, "logic->", ""); ReplaceAllInString(condition, "ctx->", ""); - ReplaceAllInString(condition, ".Value()", ""); + ReplaceAllInString(condition, ".GetContextOptionIndex()", ""); ReplaceAllInString(condition, "GetSaveContext()->", ""); return condition; } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp index 3961418c6..27817d568 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access.hpp @@ -18,54 +18,54 @@ extern std::shared_ptr logic; class EventAccess { public: - explicit EventAccess(bool* event_, std::vector conditions_met_) - : event(event_) { - conditions_met.resize(2); - for (size_t i = 0; i < conditions_met_.size(); i++) { - conditions_met[i] = conditions_met_[i]; - } + explicit EventAccess(bool* event_, std::vector conditions_met_) + : event(event_) { + conditions_met.resize(2); + for (size_t i = 0; i < conditions_met_.size(); i++) { + conditions_met[i] = conditions_met_[i]; } + } - bool ConditionsMet() const { - 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 (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { - return conditions_met[0](); - } else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) { - if (conditions_met[0]()) { - return true; - } else if (conditions_met[1] != NULL) { - return conditions_met[1](); - } - } - return false; + bool ConditionsMet() const { + 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 (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { + return conditions_met[0](); + } else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) { + if (conditions_met[0]()) { + return true; + } else if (conditions_met[1] != NULL) { + return conditions_met[1](); + } } + return false; + } - bool CheckConditionAtAgeTime(bool& age, bool& time) { + 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; + time = true; + age = true; - return ConditionsMet(); - } + return ConditionsMet(); + } - void EventOccurred() { - *event = true; - } + void EventOccurred() { + *event = true; + } - bool GetEvent() const { - return *event; - } + bool GetEvent() const { + return *event; + } private: - bool* event; - std::vector conditions_met; + bool* event; + std::vector conditions_met; }; std::string CleanCheckConditionString(std::string condition); @@ -76,49 +76,49 @@ std::string CleanCheckConditionString(std::string condition); class LocationAccess { public: - 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_) + : 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]; - } + 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]; } + } - bool GetConditionsMet() const { - 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 (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { - return conditions_met[0](); - } else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) { - if (conditions_met[0]()) { - return true; - } else if (conditions_met[1] != NULL) { - return conditions_met[1](); - } - } - return false; + bool GetConditionsMet() const { + 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 (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { + return conditions_met[0](); + } else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) { + if (conditions_met[0]()) { + return true; + } else if (conditions_met[1] != NULL) { + return conditions_met[1](); + } } + return false; + } - bool CheckConditionAtAgeTime(bool& age, bool& time) const; + bool CheckConditionAtAgeTime(bool& age, bool& time) const; - bool ConditionsMet() const; + bool ConditionsMet() const; - RandomizerCheck GetLocation() const { - return location; - } + RandomizerCheck GetLocation() const { + return location; + } - std::string GetConditionStr() const { - return condition_str; - } + std::string GetConditionStr() const { + return condition_str; + } protected: RandomizerCheck location; @@ -138,118 +138,199 @@ namespace Rando { class Region { public: - Region(); - Region(std::string regionName_, std::string scene_, std::set areas, + Region(); + Region(std::string regionName_, std::string scene_, std::set areas, bool timePass_, std::vector events_, std::vector locations_, std::list exits_); - ~Region(); + ~Region(); - std::string regionName; - std::string scene; - std::set areas; - bool timePass; - std::vector events; - std::vector locations; - 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 - //worry about a vector potentially reallocating itself and invalidating all our - //entrance pointers. + std::string regionName; + std::string scene; + std::set areas; + bool timePass; + std::vector events; + std::vector locations; + 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 + //worry about a vector potentially reallocating itself and invalidating all our + //entrance pointers. - bool childDay = false; - bool childNight = false; - bool adultDay = false; - bool adultNight = false; - bool addedToPool = false;; + bool childDay = false; + bool childNight = false; + bool adultDay = false; + bool adultNight = false; + bool addedToPool = false;; - void ApplyTimePass(); + void ApplyTimePass(); - bool UpdateEvents(); + bool UpdateEvents(); - void AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition); + void AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition); - void RemoveExit(Rando::Entrance* exitToRemove); + void RemoveExit(Rando::Entrance* exitToRemove); - void SetAsPrimary(RandomizerRegion exitToBePrimary); + void SetAsPrimary(RandomizerRegion exitToBePrimary); - Rando::Entrance* GetExit(RandomizerRegion exit); + Rando::Entrance* GetExit(RandomizerRegion exit); - bool Child() const { - return childDay || childNight; + bool Child() const { + return childDay || childNight; + } + + bool Adult() const { + return adultDay || adultNight; + } + + bool BothAgesCheck() const { + return Child() && Adult(); + } + + bool HasAccess() const { + return Child() || Adult(); + } + + bool AllAccess() const { + return childDay && childNight && adultDay && adultNight; + } + + //Check to see if an exit can be access as both ages at both times of day + bool CheckAllAccess(RandomizerRegion exitKey); + + std::set GetAllAreas() const{ + return areas; + } + +RandomizerArea GetFirstArea() const{ + if (areas.empty()){ + assert(false); + return RA_NONE; + } else { + return *areas.begin(); } + } - bool Adult() const { - return adultDay || adultNight; - } + void ReplaceAreas(std::set newAreas) { + areas = newAreas; + } - bool BothAgesCheck() const { - return Child() && Adult(); - } + //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 Here(ConditionFn condition) { - bool HasAccess() const { - return Child() || Adult(); - } + //store current age variables + bool pastAdult = logic->IsAdult; + bool pastChild = logic->IsChild; - bool AllAccess() const { - return childDay && childNight && adultDay && adultNight; - } + //set age access as this areas ages + logic->IsChild = Child(); + logic->IsAdult = Adult(); - //Check to see if an exit can be access as both ages at both times of day - bool CheckAllAccess(RandomizerRegion exitKey); + //heck condition as well as having at least child or adult access + bool hereVal = condition() && (logic->IsAdult || logic->IsChild); - std::set GetAllAreas() const{ - return areas; - } + //set back age variables + logic->IsChild = pastChild; + logic->IsAdult = pastAdult; - void ReplaceAreas(std::set newAreas) { - areas = newAreas; - } + return hereVal; + } - //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 Here(ConditionFn condition) { + bool CanPlantBeanCheck() const; + bool AllAccountedFor() const; + void ResetVariables(); + + void printAgeTimeAccess() const { + auto message = "Child Day: " + std::to_string(childDay) + "\t" + "Child Night: " + std::to_string(childNight) + "\t" + "Adult Day: " + std::to_string(adultDay) + "\t" + "Adult Night: " + std::to_string(adultNight); + } + +/*This logic covers checks that exist in the shared areas of MQ spirit from a glitchless standpoint. + This room has Quantum logic that I am currently handling with this function, however this is NOT suitable for glitch logic as it relies on specific ages + In this chunk there are 3 possibilities for passing a check, but first I have to talk about parallel universes. + + In MQ Spirit key logic, we mostly care about 2 possibilities for how the player can spend keys, creating 2 Parralel universes + In the first universe, the player did not enter spirit as adult until after climbing as child, thus child spends keys linearly, only needing 2 to reach statue room. + In the second universe, the player went in as adult, possibly out of logic, and started wasting the keys to lock child out. + These Universes converge when the player has 7 keys (meaning adult can no longer lock child out) and adult is known to be able to reach Statue room. This creates "Certain Access", which is tracked seperatly for each age. + Child Certain Access is simple, if we have 7 keys and child access, it's Certain Access. + Adult Certain Access is also simple, adult is not key locked, so if they make it to a location, it's Certain Access. + Things get complicated when we handle the overlap of the 2 universes, + though an important detail is that if we have Certain Access as either age, we don't need to checked the overlap because overlap logic is strictly stricter than either Certain Access. + + In order to track the first universe, the logic allows technical child access with the minimum number of keys, and then checks in this function for if we have 7 keys to determine if that is Certain or not. + This is for technical reasons, as areas with no access at all will simply not be checked. + Normally we would need to do similar shenanigans to track the second universe, however adult must have go through statue room to waste keys, + so can go back there and get new keys for Child to use if they do, and the navigation logic for shared MQ spirit from Statue Room is very simple for Adult. + Additionally, we don't need to know if adult can actually reach spirit temple or climb to statue room, because if the player can't do that, then universe 2 can't happen anyway, + and if the player does so out of logic, they can do it again, as the only consumable used sets a permanent flag. + + The Adult Navigation logic is as such: + - Broken Wall room is 6 key locked, because if the player tries to spend 6 keys in a way that would block adults access, they would have to give child access instead. + - The child side hammer switch for the time travelling chest is 7 key locked for adult + - Reaching gauntlets hand is 7 key locked + - Going back into big block room is complex, but the only check there is child only so not a concern + - Everything else is possible with basic adult movement, or is impossible for child to reach glitchlessly + Anything 7 key locked does not need to be checked as shared, as all child access is Certain and because of this workaround we don't need to fake Adult access, meaning that is also Certain. + All of this combined means that when checking if adult can reach a location in universe 2, we only have to ask if it is a 6 key locked location or not. + + Knowing all of this this, we can confirm things are logical in 3 different ways: + - If we have Adult Access, we know it is Certain Access, so they can get checks alone. + - If we have 7 keys, child has Certain Access as we know they cannot be locked out, so can get checks alone, otherwise we check the logical overlap + - If Child and Adult can get the check (ignoring actual adult access to the location), and the location is either not 6 key locked or we have 6 keys, we can get the check with the overlap*/ + bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false) { + //if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if adult is here it's also Certain Access + if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)){ + if (anyAge){ + return Here(condition); + } + return condition(); + //else, if we are here as adult, we have Certain Access from that and don't need special handling for checking adult + } else if (Adult() && logic->IsAdult){ + return condition(); + //if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and meet the adult universe's access condition + //We only need to do it as child, as only child access matters for this check, as adult access is assumed based on keys + } else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) { + bool result = false; //store current age variables bool pastAdult = logic->IsAdult; bool pastChild = logic->IsChild; - //set age access as this areas ages - logic->IsChild = Child(); - logic->IsAdult = Adult(); - - //heck condition as well as having at least child or adult access - bool hereVal = condition() && (logic->IsAdult || logic->IsChild); - + //First check if the check is possible as child + logic->IsChild = true; + logic->IsAdult = false; + result = condition(); + //If so, check again as adult. both have to be true for result to be true + if (result) { + logic->IsChild = false; + logic->IsAdult = true; + result = condition(); + } + //set back age variables logic->IsChild = pastChild; logic->IsAdult = pastAdult; - - return hereVal; - } - - bool CanPlantBeanCheck() const; - bool AllAccountedFor() const; - - void ResetVariables(); - - void printAgeTimeAccess() const { - auto message = "Child Day: " + std::to_string(childDay) + "\t" - "Child Night: " + std::to_string(childNight) + "\t" - "Adult Day: " + std::to_string(adultDay) + "\t" - "Adult Night: " + std::to_string(adultNight); + return result; } + return false; + } }; extern std::array areaTable; extern std::vector grottoEvents; -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 Here(const RandomizerRegion region, ConditionFn condition); //RANDOTODO make a less stupid way to check own at either age than self referencing with this +bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false); +bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false); bool CanPlantBean(const RandomizerRegion region); bool BothAges(const RandomizerRegion region); bool ChildCanAccess(const RandomizerRegion region); 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 671abda83..7f309c206 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 @@ -13,7 +13,7 @@ void RegionTable_Init_BottomOfTheWell() { //Technically involves an fake wall, but passing it lensless is intended in vanilla and it is well telegraphed Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, {[]{return ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() && logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}}), 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;}}), + Entrance(RR_KAK_WELL, {[]{return true;}}), }); /*-------------------------- @@ -31,6 +31,9 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, (logic->HasItem(RG_BRONZE_SCALE) || logic->LoweredWaterInsideBotw) && logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE)), LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->LoweredWaterInsideBotw), LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->LoweredWaterInsideBotw), + LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, (logic->CanBreakPots() && logic->LoweredWaterInsideBotw) || logic->CanUse(RG_BOOMERANG)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}}), @@ -62,8 +65,13 @@ void RegionTable_Init_BottomOfTheWell() { Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM, {[]{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}}), }); -//this area has pots and can be reached without lens in logic from basement, but that could require silver rupees if they are shuffled. - areaTable[RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM] = Region("Bottom of the Well Southwest Room", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, {}, { +//this area can be reached without lens in logic from basement, but that could require silver rupees if they are shuffled. + areaTable[RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM] = Region("Bottom of the Well Southwest Room", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, logic->CanBreakPots()), + }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, {[]{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}}), }); @@ -72,6 +80,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM] = Region("Bottom of the Well Keese-Beamos Room", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_CHEST, ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH)), + LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, logic->CanBreakPots() && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, {[]{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH));}}), @@ -83,7 +92,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_LIKE_LIKE_CAGE] = Region("Bottom of the Well Like-Like Cage", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_BOTTOM_OF_THE_WELL_LIKE_LIKE_CHEST, true), - LOCATION(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM, {[]{return true;}}), @@ -96,8 +105,8 @@ void RegionTable_Init_BottomOfTheWell() { EventAccess(&logic->DekuBabaNuts, {[]{return logic->CanGetDekuBabaNuts();}}), }, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT)), - LOCATION(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT)), + LOCATION(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, {[]{return logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}}), @@ -105,7 +114,9 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM] = Region("Bottom of the Well Coffin Room", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, {[]{return logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE);}}), @@ -123,7 +134,20 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT] = Region("Bottom of the Well Basement", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->BlastOrSmash()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->BlastOrSmash()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, {[]{return logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}}), @@ -135,14 +159,20 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT_USEFUL_BOMB_FLOWERS] = Region("Bottom of the Well Basement Useful Bomb Flowers", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations //Assumes RR_BOTTOM_OF_THE_WELL_BASEMENT access - LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MAP_CHEST, logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, {[]{return logic->CanDetonateUprightBombFlower();}}), }); -//Relevant when freestanding shuffle is added - areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM] = Region("Bottom of the Well Basement Platform", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM] = Region("Bottom of the Well Basement Platform", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, true), + }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, {[]{return true;}}), }); @@ -160,7 +190,13 @@ void RegionTable_Init_BottomOfTheWell() { //You have to throw the pot from further back to hit the switch from the front instead of the top, trying to hit the "fingers" directly //This unintuitiveness means it should be a trick. ZL is needed to get a clear path to carry the pot EventAccess(&logic->LoweredWaterInsideBotw, {[]{return logic->CanJumpslash() || logic->CanUseProjectile();}}), - }, {}, { + }, { + //Locations + //Implies CanBreakPots() + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, logic->HasExplosives()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()), + }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return logic->IsChild;}}), Entrance(RR_BOTTOM_OF_THE_WELL_MQ_WEST_ROOM_SWITCH, {[]{return Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}}), @@ -183,7 +219,9 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM] = Region("Bottom of the Well MQ Coffin Room", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}}), @@ -209,7 +247,7 @@ void RegionTable_Init_BottomOfTheWell() { areaTable[RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE] = Region("Bottom of the Well MQ Middle", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_MAP_CHEST, true), //This location technically involves an invisible platform, but it's intended to do lensless in vanilla and is clearly signposted by pots. LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_FREESTANDING_KEY, true), //The enemies in this room are invisible and crowd around the player, being awkward to deal with blind unless you already know how. @@ -219,18 +257,29 @@ void RegionTable_Init_BottomOfTheWell() { //Also you get cheap shotted on entry sometimes. //An MQ lens trick is recommended here, and a review of this room for OHKO logic what that is added is advised. //In the meantime I assume damage taken or the easy answer (nuts) - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->OpenedWestRoomMQBotw && (logic->TakeDamage() || logic->CanUse(RG_NUTS)) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->OpenedWestRoomMQBotw && (logic->TakeDamage() || logic->CanUse(RG_NUTS)) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, logic->CanBreakPots()), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits //If a relevant trick causes you to be able to warp into here without going through PERIMETER, a new eventAccess will be needed for lowering the gates with ZL Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SWITCH_PLATFORM, {[]{return logic->OpenedMiddleHoleMQBotw;}}), - Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT, {[]{return true;}}), + Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT, {[]{return true;}}), }); areaTable[RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT] = Region("Bottom of the Well MQ Basement", "Bottom of the Well", {RA_BOTTOM_OF_THE_WELL}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - //behind invisible big skulltulas, but with navi spotting it's easy to avoid them, or at worst, take your way through as they do not block the path - LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + //behind invisible big skulltulas, but with navi spotting it's easy to avoid them, or at worst, tank your way through as they do not block the path + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, true), + LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_castle_town.cpp index 22d7303dc..2e9178d6f 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 @@ -38,10 +38,18 @@ void RegionTable_Init_CastleTown() { EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), }, { //Locations - 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), + LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)), + LOCATION(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)), + LOCATION(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)), + LOCATION(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() || (logic->CanUse(RG_SUNS_SONG) && logic->IsAdult)), + LOCATION(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + 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(RR_THE_MARKET, {[]{return true;}}), @@ -66,7 +74,7 @@ void RegionTable_Init_CastleTown() { }, { //Locations LOCATION(RC_TOT_MASTER_SWORD, logic->IsAdult), - LOCATION(RC_GIFT_FROM_SAGES, logic->IsAdult), + LOCATION(RC_GIFT_FROM_RAURU, logic->IsAdult), LOCATION(RC_SHEIK_AT_TEMPLE, logic->HasItem(RG_FOREST_MEDALLION) && logic->IsAdult), }, { //Exits @@ -89,14 +97,18 @@ void RegionTable_Init_CastleTown() { EventAccess(&logic->BugRock, {[]{return true;}}), }, { //Locations - 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), + LOCATION(RC_HC_MALON_EGG, true), + LOCATION(RC_HC_GS_TREE, logic->IsChild && logic->CanAttack()), + LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_HC_MALON_GOSSIP_STONE, true), + LOCATION(RC_HC_ROCK_WALL_GOSSIP_STONE, true), }, { //Exits Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), - Entrance(RR_HC_GARDEN, {[]{return logic->CanUse(RG_WEIRD_EGG) || !ctx->GetOption(RSK_SHUFFLE_WEIRD_EGG);}}), + Entrance(RR_HC_GARDEN, {[]{return logic->CanUse(RG_WEIRD_EGG) || !ctx->GetOption(RSK_SHUFFLE_WEIRD_EGG) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}}), Entrance(RR_HC_GREAT_FAIRY_FOUNTAIN, {[]{return logic->BlastOrSmash();}}), Entrance(RR_HC_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); @@ -120,15 +132,30 @@ void RegionTable_Init_CastleTown() { Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), }); - areaTable[RR_HC_STORMS_GROTTO] = Region("HC Storms Grotto", "HC Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_HC_STORMS_GROTTO] = Region("HC Storms Grotto", "HC Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_HC_GS_STORMS_GROTTO, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_HC_STORMS_GS)), + }, { + //Exits + Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), + Entrance(RR_HC_STORMS_GROTTO_BEHIND_WALLS, {[]{return logic->CanBreakMudWalls();}}), + }); + + areaTable[RR_HC_STORMS_GROTTO_BEHIND_WALLS] = Region("HC Storms Grotto Behind Walls", "HC Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->NutPot, {[]{return logic->NutPot || logic->BlastOrSmash();}}), - EventAccess(&logic->GossipStoneFairy, {[]{return logic->CanBreakMudWalls() && logic->CallGossipFairy();}}), - EventAccess(&logic->WanderingBugs, {[]{return logic->WanderingBugs || logic->BlastOrSmash();}}), + EventAccess(&logic->NutPot, {[]{return true;}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), + EventAccess(&logic->WanderingBugs, {[]{return true;}}), }, { //Locations - 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()), + LOCATION(RC_HC_GS_STORMS_GROTTO, logic->HookshotOrBoomerang()), + LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_HC_STORMS_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_HC_STORMS_GROTTO_POT_1, logic->CanBreakPots()), + LOCATION(RC_HC_STORMS_GROTTO_POT_2, logic->CanBreakPots()), + LOCATION(RC_HC_STORMS_GROTTO_POT_3, logic->CanBreakPots()), + LOCATION(RC_HC_STORMS_GROTTO_POT_4, logic->CanBreakPots()), }, { //Exits Entrance(RR_CASTLE_GROUNDS, {[]{return true;}}), @@ -172,8 +199,63 @@ void RegionTable_Init_CastleTown() { EventAccess(&logic->CanEmptyBigPoes, {[]{return logic->IsAdult;}}), }, { //Locations - LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && logic->BigPoeKill), - LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), + LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && logic->BigPoeKill), + LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_3, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_4, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_5, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_6, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_7, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_8, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_9, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_10, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_11, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_12, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_13, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_14, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_15, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_16, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_17, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_18, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_19, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_20, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_21, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_22, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_23, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_24, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_25, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_26, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_27, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_28, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_29, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_30, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_31, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_32, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_33, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_34, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_35, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_36, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_37, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_38, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_39, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_40, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_41, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_42, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_43, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_44, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_1, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_2, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_3, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_4, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_5, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_6, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_7, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_8, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_9, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_10, logic->IsAdult && logic->CanBreakPots()), + LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_11, logic->IsAdult && logic->CanBreakPots()), }, { //Exits Entrance(RR_MARKET_ENTRANCE, {[]{return true;}}), @@ -242,7 +324,7 @@ void RegionTable_Init_CastleTown() { areaTable[RR_MARKET_TREASURE_CHEST_GAME] = Region("Market Treasure Chest Game", "Market Treasure Chest Game", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_GREG_HINT, true), + LOCATION(RC_GREG_HINT, logic->HasItem(RG_CHILD_WALLET)), LOCATION(RC_MARKET_TREASURE_CHEST_GAME_REWARD, logic->HasItem(RG_CHILD_WALLET) && ((logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)))), LOCATION(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))), @@ -282,7 +364,12 @@ void RegionTable_Init_CastleTown() { Entrance(RR_MARKET_BACK_ALLEY, {[]{return true;}}), }); - areaTable[RR_MARKET_MAN_IN_GREEN_HOUSE] = Region("Market Man in Green House", "Market Man in Green House", {}, 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, {}, { + // Locations + LOCATION(RC_MK_BACK_ALLEY_HOUSE_POT_1, logic->CanBreakPots()), + LOCATION(RC_MK_BACK_ALLEY_HOUSE_POT_2, logic->CanBreakPots()), + LOCATION(RC_MK_BACK_ALLEY_HOUSE_POT_3, logic->CanBreakPots()), + }, { //Exits Entrance(RR_MARKET_BACK_ALLEY, {[]{return true;}}), }); diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_death_mountain.cpp index e914230fb..9d443937d 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 @@ -6,7 +6,7 @@ using namespace Rando; void RegionTable_Init_DeathMountain() { areaTable[RR_DEATH_MOUNTAIN_TRAIL] = Region("Death Mountain", "Death Mountain", {RA_DEATH_MOUNTAIN_TRAIL}, DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET)));}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET));}}), }, { //Locations LOCATION(RC_DMT_CHEST, logic->BlastOrSmash() || (ctx->GetTrickOption(RT_DMT_BOMBABLE) && logic->IsChild && logic->HasItem(RG_GORONS_BRACELET))), @@ -14,6 +14,12 @@ void RegionTable_Init_DeathMountain() { LOCATION(RC_DMT_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_DMT_SOIL_GS) && (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_BOOMERANG)))), LOCATION(RC_DMT_GS_NEAR_KAK, logic->BlastOrSmash()), LOCATION(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, logic->IsAdult && logic->AtNight && (logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_DMT_HOOKSHOT_LOWER_GS) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_DMT_BEAN_LOWER_GS) && CanPlantBean(RR_DEATH_MOUNTAIN_TRAIL)) || (ctx->GetTrickOption(RT_DMT_HOVERS_LOWER_GS) && logic->CanUse(RG_HOVER_BOOTS)) || ctx->GetTrickOption(RT_DMT_JS_LOWER_GS)) && logic->CanGetNightTimeGS()), + LOCATION(RC_DMT_BLUE_RUPEE, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_DMT_RED_RUPEE, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), }, { //Exits Entrance(RR_KAK_BEHIND_GATE, {[]{return true;}}), @@ -29,11 +35,13 @@ void RegionTable_Init_DeathMountain() { EventAccess(&logic->BugRock, {[]{return logic->BugRock || logic->IsChild;}}), }, { //Locations - 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), + 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_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_DMT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMT_GOSSIP_STONE, true), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), @@ -50,8 +58,19 @@ void RegionTable_Init_DeathMountain() { areaTable[RR_DMT_COW_GROTTO] = Region("DMT Cow Grotto", "DMT Cow Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DMT_COW_GROTTO_COW, logic->CanUse(RG_EPONAS_SONG)), - LOCATION(RC_DMT_COW_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMT_COW_GROTTO_COW, logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_DMT_COW_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMT_COW_GROTTO_LEFT_HEART, true), + LOCATION(RC_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, true), + LOCATION(RC_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, true), + LOCATION(RC_DMT_COW_GROTTO_RIGHT_HEART, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_1, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_2, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_3, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_4, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_5, true), + LOCATION(RC_DMT_COW_GROTTO_RUPEE_6, true), + LOCATION(RC_DMT_COW_GROTTO_RED_RUPEE, true), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_SUMMIT, {[]{return true;}}), @@ -60,11 +79,13 @@ void RegionTable_Init_DeathMountain() { areaTable[RR_DMT_STORMS_GROTTO] = Region("DMT Storms Grotto", "DMT Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LOCATION(RC_DMT_STORMS_GROTTO_CHEST, true), - LOCATION(RC_DMT_STORMS_GROTTO_FISH, logic->HasBottle()), - LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), - LOCATION(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMT_STORMS_GROTTO_CHEST, true), + LOCATION(RC_DMT_STORMS_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + 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(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), @@ -89,26 +110,45 @@ void RegionTable_Init_DeathMountain() { EventAccess(&logic->StopGCRollingGoronAsAdult, {[]{return logic->StopGCRollingGoronAsAdult || (logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && logic->CanUse(RG_DINS_FIRE))));}}), }, { //Locations - LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (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)), + 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->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET))), + LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CallGossipFairyExceptSuns()), + LOCATION(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_LOWER_STAIRCASE_POT_1, logic->CanBreakPots()), + LOCATION(RC_GC_LOWER_STAIRCASE_POT_2, logic->CanBreakPots()), + LOCATION(RC_GC_UPPER_STAIRCASE_POT_1, logic->CanBreakPots()), + LOCATION(RC_GC_UPPER_STAIRCASE_POT_2, logic->CanBreakPots()), + LOCATION(RC_GC_UPPER_STAIRCASE_POT_3, logic->CanBreakPots()), }, { //Exits Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), + Entrance(RR_GC_MEDIGORON, {[]{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}}), Entrance(RR_GC_WOODS_WARP, {[]{return logic->GCWoodsWarpOpen;}}), Entrance(RR_GC_SHOP, {[]{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire || logic->CanUse(RG_FAIRY_BOW)));}}), Entrance(RR_GC_DARUNIAS_CHAMBER, {[]{return (logic->IsAdult && logic->StopGCRollingGoronAsAdult) || (logic->IsChild && logic->GCDaruniasDoorOpenChild);}}), Entrance(RR_GC_GROTTO_PLATFORM, {[]{return logic->IsAdult && ((logic->CanUse(RG_SONG_OF_TIME) && ((logic->EffectiveHealth() > 2) || logic->CanUse(RG_GORON_TUNIC) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_NAYRUS_LOVE))) || (logic->EffectiveHealth() > 1 && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_HOOKSHOT)) || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_HOOKSHOT)) || (logic->EffectiveHealth() > 2 && logic->CanUse(RG_HOOKSHOT) && ctx->GetTrickOption(RT_GC_GROTTO)));}}), }); + areaTable[RR_GC_MEDIGORON] = Region("GC Medigoron", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE, true), + LOCATION(RC_GC_MEDIGORON_POT_1, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GORON_CITY, {[]{return true;}}), + }); + + areaTable[RR_GC_WOODS_WARP] = Region("GC Woods Warp", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->GCWoodsWarpOpen, {[]{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE));}}), @@ -123,7 +163,10 @@ void RegionTable_Init_DeathMountain() { EventAccess(&logic->GoronCityChildFire, {[]{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_STICKS));}}), }, { //Locations - LOCATION(RC_GC_DARUNIAS_JOY, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), + LOCATION(RC_GC_DARUNIAS_JOY, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), + LOCATION(RC_GC_DARUNIA_POT_1, logic->CanBreakPots()), + LOCATION(RC_GC_DARUNIA_POT_2, logic->CanBreakPots()), + LOCATION(RC_GC_DARUNIA_POT_3, logic->CanBreakPots()), }, { //Exits Entrance(RR_GORON_CITY, {[]{return true;}}), @@ -174,15 +217,18 @@ void RegionTable_Init_DeathMountain() { EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || (logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3));}}), }, { //Locations - LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer() >= 16 || logic->Hearts() >= 3), - LOCATION(RC_DMC_GS_CRATE, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->IsChild && logic->CanAttack()), - LOCATION(RC_DMC_GOSSIP_STONE, logic->HasExplosives() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer() >= 16 || logic->Hearts() >= 3), + LOCATION(RC_DMC_GS_CRATE, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->IsChild && logic->CanAttack()), + LOCATION(RC_DMC_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns() && logic->HasExplosives() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS) && logic->HasExplosives() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_GOSSIP_STONE, logic->HasExplosives() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3)), }, { //Exits Entrance(RR_DMC_UPPER_NEARBY, {[]{return true;}}), Entrance(RR_DMC_LADDER_AREA_NEARBY, {[]{return logic->FireTimer() >= 16 || logic->Hearts() >= 3;}}), Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return logic->IsAdult && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_DISTANT_SCARECROW) && ((logic->EffectiveHealth() > 2) || (logic->CanUse(RG_BOTTLE_WITH_FAIRY) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || logic->CanUse(RG_NAYRUS_LOVE));}}), Entrance(RR_DMC_LOWER_NEARBY, {[]{return false;}}), + Entrance(RR_DMC_DISTANT_PLATFORM, {[]{return (logic->FireTimer() >= 48 && logic->Hearts() >= 2) || logic->Hearts() >= 3;}}), }); areaTable[RR_DMC_LADDER_AREA_NEARBY] = Region("DMC Ladder Region Nearby", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, {}, { @@ -194,7 +240,13 @@ void RegionTable_Init_DeathMountain() { Entrance(RR_DMC_LOWER_NEARBY, {[]{return logic->Hearts() >= 3 && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DMC_BOULDER_JS) && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)) || (ctx->GetTrickOption(RT_DMC_BOULDER_SKIP) && logic->IsAdult));}}), }); - areaTable[RR_DMC_LOWER_NEARBY] = Region("DMC Lower Nearby", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DMC_LOWER_NEARBY] = Region("DMC Lower Nearby", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, {}, { + // Locations + LOCATION(RC_DMC_NEAR_GC_POT_1, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), + }, { //Exits Entrance(RR_DMC_LOWER_LOCAL, {[]{return logic->FireTimer() >= 48;}}), Entrance(RR_GC_DARUNIAS_CHAMBER, {[]{return true;}}), @@ -221,16 +273,28 @@ void RegionTable_Init_DeathMountain() { areaTable[RR_DMC_CENTRAL_LOCAL] = Region("DMC Central Local", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_DMC_CENTRAL_LOCAL) && logic->CanUse(RG_SONG_OF_STORMS));}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3);}}), }, { //Locations - LOCATION(RC_DMC_GS_BEAN_PATCH, (logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_DMC_GS_BEAN_PATCH, ( logic->FireTimer() >= 8 || logic->Hearts() >= 3) && logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_DMC_NEAR_PLATFORM_RED_RUPEE, logic->IsChild), + LOCATION(RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, logic->IsChild && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), }, { //Exits Entrance(RR_DMC_CENTRAL_NEARBY, {[]{return true;}}), Entrance(RR_DMC_LOWER_NEARBY, {[]{return (logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL)) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}}), Entrance(RR_DMC_UPPER_NEARBY, {[]{return logic->IsAdult && CanPlantBean(RR_DMC_CENTRAL_LOCAL);}}), Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return (logic->IsChild && logic->Hearts() >= 3 && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)) || (logic->IsAdult && logic->FireTimer() >= 24);}}), + Entrance(RR_DMC_DISTANT_PLATFORM, {[]{return logic->FireTimer() >= 48 && logic->CanUse(RG_DISTANT_SCARECROW);}}), }); areaTable[RR_DMC_GREAT_FAIRY_FOUNTAIN] = Region("DMC Great Fairy Fountain", "DMC Great Fairy Fountain", {}, NO_DAY_NIGHT_CYCLE, {}, { @@ -243,11 +307,13 @@ void RegionTable_Init_DeathMountain() { areaTable[RR_DMC_UPPER_GROTTO] = Region("DMC Upper Grotto", "DMC Upper Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LOCATION(RC_DMC_UPPER_GROTTO_CHEST, true), - LOCATION(RC_DMC_UPPER_GROTTO_FISH, logic->HasBottle()), - LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), - LOCATION(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), + LOCATION(RC_DMC_UPPER_GROTTO_CHEST, true), + LOCATION(RC_DMC_UPPER_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + 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(RR_DMC_UPPER_LOCAL, {[]{return true;}}), @@ -263,4 +329,18 @@ void RegionTable_Init_DeathMountain() { //Exits Entrance(RR_DMC_LOWER_LOCAL, {[]{return true;}}), }); + + areaTable[RR_DMC_DISTANT_PLATFORM] = Region("DMC Distant Platform", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_1, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_2, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_3, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_4, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_5, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_6, logic->IsAdult), + LOCATION(RC_DMC_DISTANT_PLATFORM_RED_RUPEE, logic->IsAdult), + }, { + //Exits + Entrance(RR_DMC_CENTRAL_LOCAL, {[]{return logic->FireTimer() >= 48 && logic->CanUse(RG_DISTANT_SCARECROW);}}), + }); } 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 1e98831bc..90bb9a0da 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 @@ -25,7 +25,9 @@ void RegionTable_Init_DekuTree() { EventAccess(&logic->DekuBabaNuts, {[]{return logic->CanGetDekuBabaNuts();}}), }, { //Locations - LOCATION(RC_DEKU_TREE_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_LOBBY_LOWER_HEART, true), + LOCATION(RC_DEKU_TREE_LOBBY_UPPER_HEART, logic->CanPassEnemy(RE_BIG_SKULLTULA)), }, { //Exits Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return true;}}), @@ -114,9 +116,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_BASEMENT_BACK_LOBBY] = Region("Deku Tree Basement Back Lobby", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->DekuBabaSticks, {[]{return logic->DekuBabaSticks || (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_BOOMERANG));}}), - EventAccess(&logic->DekuBabaNuts, {[]{return logic->DekuBabaNuts || (Here(RR_DEKU_TREE_BASEMENT_BACK_LOBBY, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);}) && - (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE)));}}), + EventAccess(&logic->DekuBabaSticks, {[]{return logic->CanKillEnemy(RE_WITHERED_DEKU_BABA);}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->CanGetDekuBabaNuts();}}), }, {}, { //Exits Entrance(RR_DEKU_TREE_BASEMENT_TORCH_ROOM, {[]{return true;}}), @@ -144,7 +145,12 @@ void RegionTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, {[]{return Here(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->HasFireSourceWithTorch() || (ctx->GetTrickOption(RT_DEKU_B1_BOW_WEBS) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));});}}), }); - areaTable[RR_DEKU_TREE_OUTSIDE_BOSS_ROOM] = Region("Deku Tree Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DEKU_TREE_OUTSIDE_BOSS_ROOM] = Region("Deku Tree Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + }, { //Exits 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();});}}), @@ -173,8 +179,9 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_2F] = Region("Deku Tree MQ 2F", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MQ_MAP_CHEST, true), - LOCATION(RC_DEKU_TREE_MQ_GS_LOBBY, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_DEKU_TREE_MQ_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_MQ_GS_LOBBY, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_DEKU_TREE_MQ_LOBBY_HEART, true), }, { //Exits Entrance(RR_DEKU_TREE_MQ_1F, {[]{return true;}}), @@ -193,6 +200,7 @@ void RegionTable_Init_DekuTree() { //Implies CanKillEnemy(RE_GOHMA_LARVA) LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_CHEST, logic->CanKillEnemy(RE_DEKU_BABA)), LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_BACK_CHEST, logic->HasFireSourceWithTorch() || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW))), + LOCATION(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, true), }, { //Exits Entrance(RR_DEKU_TREE_MQ_2F, {[]{return true;}}), @@ -201,7 +209,10 @@ void RegionTable_Init_DekuTree() { Entrance(RR_DEKU_TREE_MQ_BASEMENT, {[]{return true;}}), }); - areaTable[RR_DEKU_TREE_MQ_EYE_TARGET_ROOM] = Region("Deku Tree MQ Eye Target Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DEKU_TREE_MQ_EYE_TARGET_ROOM] = Region("Deku Tree MQ Eye Target Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DEKU_TREE_MQ_DEKU_BABA_HEART, true), + }, { //Exits Entrance(RR_DEKU_TREE_MQ_COMPASS_ROOM, {[]{return Here(RR_DEKU_TREE_MQ_EYE_TARGET_ROOM, []{return logic->CanHitEyeTargets();});}}), Entrance(RR_DEKU_TREE_MQ_2F, {[]{return true;}}), @@ -220,7 +231,8 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_PAST_BOULDER_VINES] = Region("Deku Tree MQ Past Boulder Vines", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT)), + LOCATION(RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, true), }, { //Exits Entrance(RR_DEKU_TREE_MQ_COMPASS_ROOM, {[]{return logic->BlastOrSmash();}}), @@ -277,7 +289,7 @@ void RegionTable_Init_DekuTree() { LOCATION(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, logic->CanUse(RG_SONG_OF_TIME) && logic->CanPassEnemy(RE_BIG_SKULLTULA)), }, { //Exits - Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHWEST_ROOM, {[]{return logic->MQDekuWaterRoomTorches && logic->CanPassEnemy(RE_BIG_SKULLTULA, logic->CanUse(RG_SONG_OF_TIME) ? ED_CLOSE : ED_HAMMER_JUMPSLASH);}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHWEST_ROOM, {[]{return logic->MQDekuWaterRoomTorches && logic->CanPassEnemy(RE_BIG_SKULLTULA, logic->CanUse(RG_SONG_OF_TIME) ? ED_CLOSE : ED_SHORT_JUMPSLASH);}}), Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, {[]{return ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield()) || logic->CanUse(RG_LONGSHOT) || logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)));}}), @@ -296,7 +308,7 @@ void RegionTable_Init_DekuTree() { EventAccess(&logic->DekuBabaNuts, {[]{return logic->CanGetDekuBabaNuts();}}) }, { //Locations - LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT))), + LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG))), }, { //Exits Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return logic->IsChild && Here(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}}), @@ -307,7 +319,7 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_MQ_BASEMENT_BACK_ROOM] = Region("Deku Tree MQ Basement Back Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT)), + LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), }, { //Exits Entrance(RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM, {[]{return true;}}), @@ -330,11 +342,14 @@ void RegionTable_Init_DekuTree() { }); areaTable[RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] = - Region("Deku Tree MQ Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, - { + Region("Deku Tree MQ Outside Boss Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, { + LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + }, { // Exits - Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return logic->HasItem(RG_BRONZE_SCALE);}}), - Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return Here(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return logic->CanReflectNuts();});}}), + Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, {[]{return Here(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return logic->CanReflectNuts();});}}), }); } 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 23f17cf21..92ddd3f8a 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 @@ -30,9 +30,11 @@ void RegionTable_Init_DodongosCavern() { EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}), }, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MAP_CHEST, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), - LOCATION(RC_DODONGOS_CAVERN_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);})), + 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_FAIRY, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CallGossipFairy()), + LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);}) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, Here(RR_DODONGOS_CAVERN_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);})), }, { //Exits Entrance(RR_DODONGOS_CAVERN_BEGINNING, {[]{return true;}}), @@ -52,7 +54,13 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_SE_CORRIDOR] = Region("Dodongos Cavern SE Corridor", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DC_SCARECROW_GS) && (logic->CanAttack()))), + LOCATION(RC_DODONGOS_CAVERN_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DC_SCARECROW_GS) && (logic->CanAttack()))), + LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_5, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_6, logic->CanBreakPots()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), @@ -75,7 +83,14 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_LOWER_LIZALFOS] = Region("Dodongos Cavern Lower Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_LOWER_LIZALFOS] = Region("Dodongos Cavern Lower Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LIZALFOS_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, true), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_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();});}}), @@ -83,7 +98,13 @@ void RegionTable_Init_DodongosCavern() { logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives();});}}), }); - areaTable[RR_DODONGOS_CAVERN_DODONGO_ROOM] = Region("Dodongos Cavern Dodongo Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_DODONGO_ROOM] = Region("Dodongos Cavern Dodongo Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_TORCH_ROOM_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_TORCH_ROOM_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_TORCH_ROOM_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_TORCH_ROOM_POT_4, logic->CanBreakPots()), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_LOBBY_SWITCH, {[]{return logic->HasFireSourceWithTorch();}}), Entrance(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), @@ -109,6 +130,10 @@ void RegionTable_Init_DodongosCavern() { //Locations LOCATION(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, Here(RR_DODONGOS_CAVERN_FAR_BRIDGE, []{return logic->HookshotOrBoomerang();}) || logic->CanUse(RG_LONGSHOT)), LOCATION(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, logic->IsAdult || logic->CanAttack() || (HasAccessTo(RR_DODONGOS_CAVERN_STAIRS_LOWER) && logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_DC_VINES_GS))), + LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_STAIRCASE_POT_4, logic->CanBreakPots()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_STAIRS_LOWER, {[]{return true;}}), @@ -132,11 +157,12 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER] = Region("Dodongos Cavern Bomb Room Lower", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, true), }, { //Exits 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));}}), + Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return (logic->IsAdult && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}}), }); areaTable[RR_DODONGOS_CAVERN_2F_SIDE_ROOM] = Region("Dodongos Cavern 2F Side Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { @@ -148,13 +174,22 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), }); - areaTable[RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM] = Region("Dodongos Cavern First Slingshot Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM] = Region("Dodongos Cavern First Slingshot Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_SINGLE_EYE_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_SINGLE_EYE_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_DC_SLINGSHOT_SKIP);}}), }); - areaTable[RR_DODONGOS_CAVERN_UPPER_LIZALFOS] = Region("Dodongos Cavern Upper Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_UPPER_LIZALFOS] = Region("Dodongos Cavern Upper Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, true), + LOCATION(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, true), + LOCATION(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, true), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_LOWER_LIZALFOS, []{return logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || @@ -163,7 +198,11 @@ void RegionTable_Init_DodongosCavern() { logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives();});}}), }); - areaTable[RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM] = Region("Dodongos Cavern Second Slingshot Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_SECOND_SLINGSHOT_ROOM] = Region("Dodongos Cavern Second Slingshot Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Location + LOCATION(RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_UPPER_LIZALFOS, {[]{return true;}}), Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || ctx->GetTrickOption(RT_DC_SLINGSHOT_SKIP);}}), @@ -172,6 +211,8 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER] = Region("Dodongos Cavern Bomb Room Upper", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_BLADE_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_BLADE_POT_2, logic->CanBreakPots()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, {[]{return true;}}), @@ -193,14 +234,18 @@ void RegionTable_Init_DodongosCavern() { EventAccess(&logic->FairyPot, {[]{return true;}}), }, {}, { //Exits - Entrance(RR_DODONGOS_CAVERN_LOBBY, {[]{return true;}}), - Entrance(RR_DODONGOS_CAVERN_BACK_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_BOSS_AREA, []{return logic->BlastOrSmash();});}}), + 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[RR_DODONGOS_CAVERN_BACK_ROOM] = Region("Dodongos Cavern Back Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_DODONGOS_CAVERN_GS_BACK_ROOM, logic->CanAttack()), + LOCATION(RC_DODONGOS_CAVERN_BACK_ROOM_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_BACK_ROOM_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_BACK_ROOM_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_BACK_ROOM_POT_4, logic->CanBreakPots()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, {[]{return true;}}), @@ -217,17 +262,14 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return Here(RR_DODONGOS_CAVERN_MQ_BEGINNING, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_LOBBY] = Region("Dodongos Cavern MQ Lobby", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { - //Events - EventAccess(&logic->GossipStoneFairy, {[]{return (Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || logic->HasItem(RG_GORONS_BRACELET)) && logic->CallGossipFairy();}}), - }, { + areaTable[RR_DODONGOS_CAVERN_MQ_LOBBY] = Region("Dodongos Cavern MQ Lobby", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->HasItem(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->HasItem(RG_GORONS_BRACELET);})), - }, { + LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, logic->CanBreakMudWalls() || logic->HasItem(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()), + }, { //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_GOSSIP_STONE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}}), Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}}), Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, {[]{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls();}) || @@ -238,6 +280,19 @@ void RegionTable_Init_DodongosCavern() { (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))));});}}), }); + areaTable[RR_DODONGOS_CAVERN_MQ_GOSSIP_STONE] = Region("Dodongos Cavern MQ Gossip Stone", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_GOSSIP_STONE, true), + LOCATION(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + }, { + //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return true;}}), +}); + 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);}}), @@ -253,7 +308,13 @@ void RegionTable_Init_DodongosCavern() { 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));}}), - }, {}, { + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, logic->CanBreakPots()), + }, { //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) || @@ -305,7 +366,11 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_LOWER] = Region("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ClearMQDCUpperLobbyRocks, {[]{return (((logic->IsAdult /*or bunny hood jump*/) && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_STICKS);}}), - }, {}, { + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, true), + }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return logic->TakeDamage();}}), Entrance(RR_DODONGOS_CAVERN_MQ_DODONGO_ROOM, {[]{return true;}}), @@ -315,7 +380,11 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, {[]{return logic->CanUse(RG_STICKS) && logic->HasItem(RG_GORONS_BRACELET);}}), //Implies access to RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM from here }); - areaTable[RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM] = Region("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM] = Region("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2, logic->CanBreakPots()), + }, { //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) @@ -332,7 +401,12 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS] = Region("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, logic->BlastOrSmash()), //Implied CanGetEnemyDrop(RE_GOLD_SKULLTULA) + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, logic->BlastOrSmash()), //Implied CanGetEnemyDrop(RE_GOLD_SKULLTULA) + LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, logic->BlastOrSmash()), }, { //Exits //Falling down gets you stuck with nothing there, not a useful exit for logic @@ -340,7 +414,11 @@ void RegionTable_Init_DodongosCavern() { Entrance(RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, {[]{return Here(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), }); - areaTable[RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM] = Region("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM] = Region("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, logic->CanBreakPots()), + }, { //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));}));}}), @@ -352,6 +430,8 @@ void RegionTable_Init_DodongosCavern() { }, { //Locations LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, true), + LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, logic->CanBreakPots()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, {[]{return logic->ClearMQDCUpperLobbyRocks;}}), @@ -362,15 +442,21 @@ void RegionTable_Init_DodongosCavern() { 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()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, logic->CanBreakPots()), }, { //Exits + Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, {[]{return true;}}), 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 - }, {}, { + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, true), + }, { //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);});}}), @@ -380,8 +466,12 @@ void RegionTable_Init_DodongosCavern() { //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 + logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true))), //Implies you can avoid/kill the enemies with what you use on the skull, if this assumption is broken, add //&& (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);}) || (logic->CanAvoidEnemy(RE_FIRE_KEESE) && logic->CanAvoidEnemy(RE_MAD_SCRUB))) + LOCATION(RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, logic->CanBreakPots()), }, { //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);});}}), @@ -391,14 +481,20 @@ void RegionTable_Init_DodongosCavern() { 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 + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG, true))), //Implies you can avoid/kill the enemies with what you use on the skull, if this assumption is broken, add //&& (Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanKillEnemy(RE_FIRE_KEESE) && logic->CanKillEnemy(RE_MAD_SCRUB);}) || (logic->CanAvoidEnemy(RE_FIRE_KEESE) && logic->CanAvoidEnemy(RE_MAD_SCRUB))) }, { //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, {}, {}, { + areaTable[RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH] = Region("Dodongos Cavern MQ Behind Mouth", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SW_POT, logic->CanBreakPots()), + }, { //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: @@ -410,6 +506,8 @@ void RegionTable_Init_DodongosCavern() { 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 + LOCATION(RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, logic->CanBreakPots()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, {[]{return logic->CanAttack();}}), @@ -423,9 +521,11 @@ void RegionTable_Init_DodongosCavern() { 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*/);})), + LOCATION(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) || logic->HasItem(RG_GORONS_BRACELET) || //even if you somehow warp to BACK_BEHIND_FIRE, if you can kill the skull at range, you can get to BEHIND_MOUTH + Here(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)) || + (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) /* || bunny jumps*/);})), + LOCATION(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT, logic->CanBreakPots()), }, { //Exits Entrance(RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE, {[]{return true;}}), 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 b0ece5e7b..a719e1187 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 @@ -35,6 +35,10 @@ void RegionTable_Init_FireTemple() { }, { //Locations LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, true), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), + LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, (logic->CanBreakPots() && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))), }, { //Exits Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return true;}}), @@ -62,8 +66,7 @@ void RegionTable_Init_FireTemple() { }, { //Exits Entrance(RR_FIRE_TEMPLE_LOOP_TILES, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, {[]{return Here(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || - logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG)));});}}), + Entrance(RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH, {[]{return Here(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return logic->CanKillEnemy(RE_FLARE_DANCER);});}}), }); areaTable[RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH] = Region("Fire Temple Loop Hammer Switch", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, { @@ -90,7 +93,12 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_LOOP_GORON_ROOM, {[]{return logic->FireLoopSwitch;}}), }); - areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM] = Region("Fire Temple Big Lava Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_BIG_LAVA_ROOM] = Region("Fire Temple Big Lava Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_POT_1, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_POT_2, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_POT_3, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 2);}}), Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM_NORTH_GORON, {[]{return true;}}), @@ -124,7 +132,12 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM] = Region("Fire Temple Fire Pillar Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_PILLAR_ROOM] = Region("Fire Temple Fire Pillar Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, logic->FireTimer() >= 56), + LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, logic->FireTimer() >= 56), + LOCATION(RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, logic->FireTimer() >= 56), + }, { //Exits Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}}), Entrance(RR_FIRE_TEMPLE_SHORTCUT_ROOM, {[]{return logic->FireTimer() >= 56 && logic->SmallKeys(RR_FIRE_TEMPLE, 4);}}), @@ -166,7 +179,12 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM] = Region("Fire Temple East Central Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM] = Region("Fire Temple East Central Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, true), + LOCATION(RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, true), + LOCATION(RC_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, true), + }, { //Exits Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, {[]{return logic->TakeDamage();}}), Entrance(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 5, 8);}}), @@ -174,7 +192,12 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_MAP_AREA, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW);}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_WALL_CHASE] = Region("Fire Temple Fire Wall Chase", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_WALL_CHASE] = Region("Fire Temple Fire Wall Chase", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, logic->FireTimer() >= 24 && (logic->IsAdult || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, logic->FireTimer() >= 24 && (logic->IsAdult || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, logic->FireTimer() >= 24), + }, { //Exits Entrance(RR_FIRE_TEMPLE_EAST_CENTRAL_ROOM, {[]{return logic->FireTimer() >= 24 && logic->SmallKeys(RR_FIRE_TEMPLE, 6, 8);}}), Entrance(RR_FIRE_TEMPLE_MAP_AREA, {[]{return logic->IsAdult;}}), @@ -226,7 +249,13 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_ROOM] = Region("Fire Temple Fire Maze Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_FIRE_MAZE_ROOM] = Region("Fire Temple Fire Maze Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + // Locations + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FIRE_TEMPLE_CORRIDOR, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, {[]{return logic->CanUse(RG_HOVER_BOOTS);}}), @@ -267,7 +296,13 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, {[]{return true;}}), }); - areaTable[RR_FIRE_TEMPLE_LATE_FIRE_MAZE] = Region("Fire Temple Late Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_LATE_FIRE_MAZE] = Region("Fire Temple Late Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + // Locations + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FIRE_TEMPLE_FIRE_MAZE_ROOM, {[]{return false;}}), Entrance(RR_FIRE_TEMPLE_WEST_CENTRAL_LOWER, {[]{return true;}}), @@ -276,10 +311,8 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_UPPER_FLARE_DANCER] = Region("Fire Temple Upper Flare Dancer", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return Here(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_HOOKSHOT) || (logic->HasExplosives() && ((logic->CanUse(RG_KOKIRI_SWORD)) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || - logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG)));});}}), - 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)));});}}), + Entrance(RR_FIRE_TEMPLE_LATE_FIRE_MAZE, {[]{return Here(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return logic->CanKillEnemy(RE_FLARE_DANCER);});}}), + Entrance(RR_FIRE_TEMPLE_WEST_CLIMB, {[]{return Here(RR_FIRE_TEMPLE_UPPER_FLARE_DANCER, []{return logic->CanKillEnemy(RE_FLARE_DANCER);});}}), }); areaTable[RR_FIRE_TEMPLE_WEST_CLIMB] = Region("Fire Temple West Climb", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -314,8 +347,12 @@ void RegionTable_Init_FireTemple() { | MASTER QUEST DUNGEON | ---------------------------*/ if (ctx->GetDungeon(FIRE_TEMPLE)->IsMQ()) { - //potentially dangerous temp flag on the first room's torches, should be made parament if possible - areaTable[RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER] = Region("Fire Temple MQ First Room Lower", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //potentially dangerous temp flag on the first room's torches, should be made permanent if possible + areaTable[RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER] = Region("Fire Temple MQ First Room Lower", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FIRE_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_SOUTH, {[]{return true;}}), @@ -339,7 +376,10 @@ void RegionTable_Init_FireTemple() { Entrance(RR_FIRE_TEMPLE_MQ_MAP_ROOM_CAGE, {[]{return logic->OpenedLowestGoronCage;}}), }); - areaTable[RR_FIRE_TEMPLE_MQ_STALFOS_ROOM] = Region("Fire Temple MQ Stalfos Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_STALFOS_ROOM] = Region("Fire Temple MQ Stalfos Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM, {[]{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}}), @@ -348,7 +388,18 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_IRON_KNUCKLE_ROOM] = Region("Fire Temple MQ Iron Knuckle Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), - }, {}, { + }, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_STALFOS_ROOM, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_MQ_LOWER_FLARE_DANCER, {[]{return Here(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_LOWER, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}}), @@ -383,39 +434,54 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple MQ Near Boss Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - //Child cannot make it to the north side torches without a hook without specifically bunny hood speed + hover boots - //The Damage logic here is for crossing to the north torches with hookshot, then using dins there before jumping down and running across the lava to get in dins range of the south torch - //Fairies cannot be used for this as it is time sensetive, and NL is only useful with sticks as it disables other magic while in use, so it's tunic or raw damage taking ability. - //testing tells me you take 3 ticks of lava damage, which is 12 internal damage or 3/4 of a heart at x1 damage multiplier, performing this run - //logic->EffectiveHealth() works in half hearts for whatever reason, meaning this needs a deeper refactor to be perfect, but it should be good enough for now - LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, //Using the south torch as the initial torch, or using FAs, we first have to sort the crate... - //If we don't go out of the way to break the box it's reasonable to do things in ~25 seconds, otherwise it takes about 40 - (logic->FireTimer() > (ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) ? 25 : 40) && - (ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) || logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS))) && - //then use FA's, or dins + bow as adult. Child can only do a torch shot from the north side upper torch so will be handled in the lower case to avoid RT_FIRE_MQ_NEAR_BOSS issues - (logic->CanUse(RG_FIRE_ARROWS) || (logic->IsAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)))) || - //If we're starting with the north torches, we need to get across first, and light them - //Pretty much all these methods take ~20-30 seconds - (logic->FireTimer() > 30 && - (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanUse(RG_DINS_FIRE) && - //then we need to either use a bow to shoot back across, or somehow get back to use dins again. Alternatively we can use Sticks as adult and NL - (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_GORON_TUNIC) || logic->EffectiveHealth() >= 2 || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_STICKS))))))) + //If we're using the south torch as the initial torch, or using FAs, we either have to cross to the north to remove the crate, or use a trick to ignore it + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->FireTimer() > 25 && ctx->GetTrickOption(RT_FIRE_MQ_NEAR_BOSS) && + (logic->CanUse(RG_FIRE_ARROWS) || (logic->IsAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)))) }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, {[]{return true;}}), + //Child cannot make it to the north side torches without a hook without specifically bunny hood speed + hover boots + Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM_NORTH, {[]{return logic->FireTimer() > 32 && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));}}), Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_FIRE_TEMPLE_BOSS_KEY) && logic->FireTimer() >= 15 && ((logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->IsAdult && logic->HitFireTemplePlatform) || (logic->HitFireTemplePlatform && logic->CanUse(RG_HOVER_BOOTS))) ;}}), }); + +//This room assumes tunic logic is handled on entry. +//Covers the upper section too, as all methods to reach this can climb up somehow + areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM_NORTH] = Region("Fire Temple MQ Near Boss Room North", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //If we have FAs, we can just remove the crate and use those to light the torches. + //otherwise, with Dins, we first light them with dins and then either use a bow shot or to cross back over to light the other torch + //Valid ways across are adult+hovers, bunny+hovers, longshot or running through the lava and then climbing back up as adult (child can't reach the ledge). + //The Damage logic here is for jumping down and running across the lava to get in dins range of the south torch + //Fairies cannot be used for this as it is time sensetive, and NL is only useful with sticks as it disables other magic while in use, so it's tunic or raw damage taking ability. + //testing tells me you take 3 ticks of lava damage, which is 12 internal damage or 3/4 of a heart at x1 damage multiplier, performing this run + //logic->EffectiveHealth() works in half hearts for whatever reason, meaning this needs a deeper refactor to be perfect, but it should be good enough for now + LOCATION(RC_FIRE_TEMPLE_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || + (logic->CanUse(RG_DINS_FIRE) && + (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_LONGSHOT) || + (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_GORON_TUNIC) || logic->EffectiveHealth() >= 2 || (logic->CanUse(RG_NAYRUS_LOVE) && logic->CanUse(RG_STICKS))))))), + LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, {[]{return true;}}), + }); areaTable[RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM] = Region("Fire Temple MQ Big Lava Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations //I'm currently assuming the oversight version of RT_FIRE_MQ_BK_CHEST for the fire timer logic - LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->FireTimer() >= 40 && logic->HasFireSource() && logic->HasExplosives() && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST))), + LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->FireTimer() >= 40 && logic->HasFireSource() && logic->HasExplosives() && + (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST)))), //implies CanGetEnemyDrop(RE_GOLD_SKULLTULA) LOCATION(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, logic->FireTimer() >= 20 && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, logic->FireTimer() >= 40 && + (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_FIRE_MQ_BLOCKED_CHEST) && ((logic->IsAdult && logic->CanBreakPots()) || logic->CanUse(RG_BOOMERANG))))), }, { //Exits // Fewer tunic requirements ends here @@ -429,14 +495,21 @@ void RegionTable_Init_FireTemple() { EventAccess(&logic->FairyPot, {[]{return logic->CanUse(RG_HOOKSHOT);}}), }, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, logic->HookshotOrBoomerang()), + LOCATION(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, logic->HookshotOrBoomerang()), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return true;}}), }); //This room assumes Goron Tunic until looser tunic requirements tricks are made - areaTable[RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM] = Region("Fire Temple MQ Elevator Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_ELEVATOR_ROOM] = Region("Fire Temple MQ Elevator Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, true), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, true), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, true), + }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_MQ_BIG_TORCH_ROOM, {[]{return true;}}), @@ -529,13 +602,22 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM] = Region("Fire Temple MQ Narrow Path Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), - }, {}, { + }, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_LOWER_MAZE, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, {[]{return logic->TakeDamage();}}), }); - areaTable[RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM] = Region("Fire Temple MQ High Torch Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM] = Region("Fire Temple MQ High Torch Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_UPPER_MAZE, {[]{return logic->SmallKeys(RR_FIRE_TEMPLE, 3);}}), Entrance(RR_FIRE_TEMPLE_MQ_NARROW_PATH_ROOM, {[]{return true;}}), @@ -546,15 +628,17 @@ void RegionTable_Init_FireTemple() { areaTable[RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE] = Region("Fire Temple MQ South Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, logic->HasExplosives()), + LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, logic->HasExplosives()), + LOCATION(RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT, logic->CanBreakPots()), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_DOOR, {[]{return logic->HitFireTemplePlatform;}}), Entrance(RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, {[]{return true;}}), Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS, {[]{return logic->IsAdult || logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS);}}), //Hover boots get there via the platforms - Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SIDE_ROOM, {[]{return (bool)ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}), - Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, {[]{return logic->OpenedFireMQFireMazeDoor;}}), + Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, {[]{return (bool)ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}), + Entrance(RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE, {[]{return logic->OpenedFireMQFireMazeDoor;}}), }); areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS] = Region("Fire Temple MQ Fire Maze Platforms", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, { @@ -562,27 +646,35 @@ void RegionTable_Init_FireTemple() { EventAccess(&logic->HitFireTemplePlatform, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), EventAccess(&logic->OpenedFireMQFireMazeDoor, {[]{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_HOOKSHOT);}}), }, {}, { - Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SIDE_ROOM, {[]{return logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS);}}), - //trick to get to RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE with hovers + taking damage is plausible + Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, {[]{return true;}}), + Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, {[]{return logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_HOVER_BOOTS);}}), + //trick to get to RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE with hovers + taking damage is plausible }); - areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SIDE_ROOM] = Region("Fire Temple MQ Side Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE] = Region("Fire Temple MQ North Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, logic->CanBreakPots()), }, { //Exits Entrance(RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, {[]{return logic->IsAdult || ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}), - Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, {[]{return (bool)ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}), + Entrance(RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE, {[]{return (bool)ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}), }); - areaTable[RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE] = Region("Fire Temple MQ North Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE] = Region("Fire Temple MQ West Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL, {[]{return true;}}), - Entrance(RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SIDE_ROOM, {[]{return (bool)ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}), + Entrance(RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, {[]{return (bool)ctx->GetTrickOption(RT_FIRE_MQ_FLAME_MAZE);}}), }); //this area exists for the pots in case we void warp to the top of fire somehow, because there's no way to get back the way we came - areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL] = Region("Fire Temple MQ Fire Maze Past Wall", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL] = Region("Fire Temple MQ Fire Maze Past Wall", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, logic->CanBreakPots()), + LOCATION(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, logic->CanUse(RG_BOOMERANG)), + }, { Entrance(RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER, {[]{return true;}}), }); 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 96fe9a978..31b8c382c 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 @@ -41,6 +41,12 @@ void RegionTable_Init_ForestTemple() { }, { //Locations LOCATION(RC_FOREST_TEMPLE_GS_LOBBY, logic->HookshotOrBoomerang()), + LOCATION(RC_FOREST_TEMPLE_LOBBY_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_LOBBY_POT_2, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_LOBBY_POT_3, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_LOBBY_POT_4, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_LOBBY_POT_5, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_LOBBY_POT_6, logic->CanBreakPots()), }, { //Exits Entrance(RR_FOREST_TEMPLE_SOUTH_CORRIDOR, {[]{return true;}}), @@ -65,6 +71,8 @@ void RegionTable_Init_ForestTemple() { }, { //Locations 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)), + LOCATION(RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, logic->CanBreakPots()), }, { //Exits Entrance(RR_FOREST_TEMPLE_NORTH_CORRIDOR, {[]{return true;}}), @@ -77,10 +85,12 @@ void RegionTable_Init_ForestTemple() { }, { //Locations LOCATION(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, logic->CanUse(RG_LONGSHOT) || Here(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, []{return logic->HookshotOrBoomerang();})), + LOCATION(RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), + LOCATION(RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), }, { //Exits Entrance(RR_FOREST_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_SONG_OF_TIME);}}), - Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return false;}}), + Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_UPPER, {[]{return ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS);}}), Entrance(RR_FOREST_TEMPLE_MAP_ROOM, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_SEWER, {[]{return logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_IRON_BOOTS) || HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER);}}), Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, {[]{return false;}}), @@ -90,7 +100,11 @@ void RegionTable_Init_ForestTemple() { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->CanGetDekuBabaSticks();}}), EventAccess(&logic->DekuBabaNuts, {[]{return logic->CanGetDekuBabaNuts();}}), - }, {}, { + }, { + //Locations + LOCATION(RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, true), + LOCATION(RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, true), + }, { //Exits Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_BELOW_BOSS_KEY_CHEST, {[]{return true;}}), @@ -136,7 +150,9 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_SEWER] = Region("Forest Temple Sewer", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER)), + LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER)), + LOCATION(RC_FOREST_TEMPLE_WELL_WEST_HEART, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)), + LOCATION(RC_FOREST_TEMPLE_WELL_EAST_HEART, HasAccessTo(RR_FOREST_TEMPLE_NE_OUTDOORS_UPPER) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)), }, { //Exits Entrance(RR_FOREST_TEMPLE_NW_OUTDOORS_LOWER, {[]{return true;}}), @@ -203,6 +219,10 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_UPPER_STALFOS] = Region("Forest Temple Upper Stalfos", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_BOW_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_4, logic->CanBreakPots()), }, { //Exits 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);}}), @@ -215,6 +235,9 @@ void RegionTable_Init_ForestTemple() { }, { //Locations LOCATION(RC_FOREST_TEMPLE_BLUE_POE_CHEST, logic->ForestTempleBeth), + LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_2, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_BLUE_POE_POT_3, logic->CanBreakPots()), }, { //Exits Entrance(RR_FOREST_TEMPLE_UPPER_STALFOS, {[]{return true;}}), @@ -233,7 +256,11 @@ void RegionTable_Init_ForestTemple() { Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, {[]{return true;}}), }); - areaTable[RR_FOREST_TEMPLE_FROZEN_EYE_ROOM] = Region("Forest Temple Frozen Eye Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_FOREST_TEMPLE_FROZEN_EYE_ROOM] = Region("Forest Temple Frozen Eye Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FOREST_TEMPLE_FROZEN_EYE_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_FROZEN_EYE_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FOREST_TEMPLE_NE_CORRIDOR_STRAIGHTENED, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 5);}}), Entrance(RR_FOREST_TEMPLE_NE_CORRIDOR_TWISTED, {[]{return logic->SmallKeys(RR_FOREST_TEMPLE, 5) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE));}}), @@ -251,7 +278,11 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_GREEN_POE_ROOM] = Region("Forest Temple Green Poe Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTempleAmy, {[]{return logic->ForestTempleAmy || logic->CanUse(RG_FAIRY_BOW);}}), - }, {}, { + }, { + //Locations + LOCATION(RC_FOREST_TEMPLE_GREEN_POE_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_GREEN_POE_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FOREST_TEMPLE_FALLING_ROOM, {[]{return true;}}), Entrance(RR_FOREST_TEMPLE_EAST_CORRIDOR, {[]{return logic->ForestTempleAmy;}}), @@ -280,7 +311,7 @@ void RegionTable_Init_ForestTemple() { if (ctx->GetDungeon(FOREST_TEMPLE)->IsMQ()) { areaTable[RR_FOREST_TEMPLE_MQ_LOBBY] = Region("Forest Temple MQ Lobby", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA, ED_HAMMER_JUMPSLASH, false) || logic->CanUse(RG_HOVER_BOOTS)), + LOCATION(RC_FOREST_TEMPLE_MQ_FIRST_ROOM_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA, ED_SHORT_JUMPSLASH, false) || logic->CanUse(RG_HOVER_BOOTS)), //Implies CanPassEnemy(RE_BIG_SKULLTULA) LOCATION(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, logic->HookshotOrBoomerang()), }, { @@ -292,7 +323,15 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_CENTRAL_AREA] = Region("Forest Temple MQ Central Region", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTempleMeg, {[]{return logic->ForestTempleJoelle && logic->ForestTempleBeth && logic->ForestTempleAmy && logic->CanKillEnemy(RE_MEG);}}), - }, {}, { + }, { + //Locations + LOCATION(RC_FOREST_TEMPLE_MQ_LOBBY_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_LOBBY_POT_2, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_LOBBY_POT_3, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_LOBBY_POT_4, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_LOBBY_POT_5, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_LOBBY_POT_6, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_WOLFOS_ROOM, {[]{return logic->IsChild || logic->CanUse(RG_SONG_OF_TIME);}}), Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return logic->CanHitEyeTargets();}}), @@ -309,6 +348,8 @@ void RegionTable_Init_ForestTemple() { }, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_CHEST, logic->ForestClearBelowBowChest), + LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, logic->CanBreakPots()), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return logic->ForestClearBelowBowChest && (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME));}}), @@ -317,13 +358,12 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_LOWER_BLOCK_PUZZLE] = Region("Forest Temple MQ Lower Block Puzzle", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //longshot is capable of hitting the switch, but some invisible collision makes the shot harder than you would think, so it may be trickworthy EventAccess(&logic->MQForestBlockRoomTargets, {[]{return (ctx->GetTrickOption(RT_FOREST_MQ_BLOCK_PUZZLE) && logic->CanUse(RG_BOMBCHU_5));}}), - //Trick (RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH not added to either n64 or oot3d rando as of yet, to enable in SoH needs uncommenting in randomizer_tricks.cpp) //It is barely possible to get this as child with master + hovers, but it's tight without bunny speed EventAccess(&logic->ForestCanTwistHallway, {[]{return (ctx->GetTrickOption(RT_FOREST_MQ_JS_HALLWAY_SWITCH) && logic->CanUse(RG_HOVER_BOOTS) && - (logic->IsAdult && logic->CanJumpslash()) || + (logic->IsAdult && logic->CanJumpslash()) || (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || (logic->MQForestBlockRoomTargets && logic->CanUse(RG_MASTER_SWORD)))) || - (ctx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || - (ctx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->CanUse(RG_HOOKSHOT));}}), + (ctx->GetTrickOption(RT_FOREST_MQ_RANG_HALLWAY_SWITCH) && logic->CanUse(RG_BOOMERANG)) || + (ctx->GetTrickOption(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH) && logic->CanUse(RG_HOOKSHOT));}}), }, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), @@ -382,7 +422,10 @@ void RegionTable_Init_ForestTemple() { EventAccess(&logic->ForestCanTwistHallway, {[]{return logic->CanHitSwitch();}}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, logic->CanKillEnemy(RE_REDEAD)), + LOCATION(RC_FOREST_TEMPLE_MQ_REDEAD_CHEST, logic->CanKillEnemy(RE_REDEAD)), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, true), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, true), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, true), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return true;}}), @@ -391,13 +434,21 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_NW_OUTDOORS] = Region("Forest Temple MQ NW Outdoors", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + //the well checks are considered from both areas instead of being a region because the draining is a temp flag and the skull (as well as the chest with hook glitch) has different breath timers from each side + LOCATION(RC_FOREST_TEMPLE_MQ_GS_WELL, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), + LOCATION(RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, logic->CanUse(RG_BOOMERANG) && ctx->GetTrickOption(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG)), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return (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)) && logic->WaterTimer() > 10;}}), + Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS, {[]{return (((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_FOREST_MQ_WELL_SWIM) && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16;}}), Entrance(RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, {[]{return logic->CanUse(RG_FIRE_ARROWS);}}), }); -//The well is included here because the eye target is a temp flag, making it unwieldy to use as an EventAccess to make it it's own room +//The well only coniders the eye target here because the eye target is a temp flag, making it unwieldy to use as an EventAccess or to make it it's own room areaTable[RR_FOREST_TEMPLE_MQ_NE_OUTDOORS] = Region("Forest Temple MQ NE Outdoors", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->DekuBabaSticks, {[]{return logic->CanGetDekuBabaSticks();}}), @@ -407,9 +458,13 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_MQ_WELL_CHEST, logic->CanHitEyeTargets()), LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), //implies logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) - LOCATION(RC_FOREST_TEMPLE_MQ_GS_WELL, logic->CanHitEyeTargets() || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_WELL, logic->CanHitEyeTargets() || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) || logic->CanHitEyeTargets()), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) || logic->CanHitEyeTargets()), + LOCATION(RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) || logic->CanHitEyeTargets()), }, { //Exits + Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return (((logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_LONGSHOT)) && logic->HasItem(RG_BRONZE_SCALE)) || logic->HasItem(RG_GOLDEN_SCALE)) && logic->WaterTimer() >= 16;}}), Entrance(RR_FOREST_TEMPLE_MQ_OUTDOORS_TOP_LEDGES, {[]{return logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && ((logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || logic->CanUse(RG_SONG_OF_TIME)));}}), Entrance(RR_FOREST_TEMPLE_MQ_NE_OUTDOORS_LEDGE, {[]{return logic->CanUse(RG_LONGSHOT);}}), }); @@ -418,9 +473,9 @@ void RegionTable_Init_ForestTemple() { //Locations LOCATION(RC_FOREST_TEMPLE_MQ_RAISED_ISLAND_COURTYARD_UPPER_CHEST, true), //Actually killing the skull from the doorframe with melee is annoying. Hammer swing hits low enough unaided, other swords need to crouch stab but the spot is precise based on range. kokiri sword doesn't reach at all for adult. - LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, ((logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_FOREST_DOORFRAME))) && logic->CanJumpslash() && - (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->HookshotOrBoomerang() || - (logic->CanStandingShield() && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD) || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD)))))), + LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, ((logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME)) || (logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_FOREST_DOORFRAME))) && logic->CanJumpslash() && + (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->HookshotOrBoomerang() || + (logic->CanStandingShield() && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD) || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD)))))), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_NW_OUTDOORS, {[]{return logic->HasFireSourceWithTorch();}}), @@ -457,7 +512,11 @@ void RegionTable_Init_ForestTemple() { EventAccess(&logic->ForestClearBelowBowChest, {[]{return logic->CanKillEnemy(RE_WOLFOS);}}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_BOW_CHEST, logic->ForestClearBelowBowChest && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3)), + LOCATION(RC_FOREST_TEMPLE_MQ_BOW_CHEST, logic->ForestClearBelowBowChest && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3)), + LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, logic->CanBreakPots()), }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_JOELLE_ROOM, {[]{return logic->ForestClearBelowBowChest && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3);}}), @@ -469,7 +528,10 @@ void RegionTable_Init_ForestTemple() { EventAccess(&logic->ForestTempleBeth, {[]{return logic->CanUse(RG_FAIRY_BOW);}}), }, { //Locations - LOCATION(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, logic->ForestTempleBeth), + LOCATION(RC_FOREST_TEMPLE_MQ_COMPASS_CHEST, logic->ForestTempleBeth), + LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, logic->CanBreakPots()), }, { //Exits //!QUANTUM LOGIC! @@ -500,7 +562,11 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_MQ_AMY_ROOM] = Region("Forest Temple MQ Amy Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTempleAmy, {[]{return logic->CanUse(RG_FAIRY_BOW);}}), - }, {}, { + }, { + //Locations + LOCATION(RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return logic->ForestTempleAmy;}}), Entrance(RR_FOREST_TEMPLE_MQ_FALLING_ROOM, {[]{return true;}}), @@ -515,8 +581,20 @@ void RegionTable_Init_ForestTemple() { LOCATION(RC_FOREST_TEMPLE_MQ_BASEMENT_CHEST, true), }, { //Exits - Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return logic->ForestTempleMeg;}}), - Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, {[]{return logic->ForestOpenBossCorridor;}}), + Entrance(RR_FOREST_TEMPLE_MQ_CENTRAL_AREA, {[]{return logic->ForestTempleMeg;}}), + Entrance(RR_FOREST_TEMPLE_MQ_BASEMENT_POT_ROOM, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->TakeDamage();}}), + Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, {[]{return logic->ForestOpenBossCorridor;}}), + }); + + areaTable[RR_FOREST_TEMPLE_MQ_BASEMENT_POT_ROOM] = Region("Forest Temple MQ Basement Pot Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_FOREST_TEMPLE_MQ_BASEMENT_POT_1, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_BASEMENT_POT_2, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_BASEMENT_POT_3, logic->CanBreakPots()), + LOCATION(RC_FOREST_TEMPLE_MQ_BASEMENT_POT_4, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_FOREST_TEMPLE_MQ_BASEMENT, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}}), }); areaTable[RR_FOREST_TEMPLE_MQ_BOSS_REGION] = Region("Forest Temple MQ Boss Region", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { 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 fc13129c1..83b9540aa 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 @@ -22,7 +22,7 @@ void RegionTable_Init_GanonsCastle() { 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), + LOCATION(RC_SHEIK_HINT_GC, true), }, { //Exits Entrance(RR_GANONS_CASTLE_ENTRYWAY, {[]{return true;}}), @@ -32,7 +32,7 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}), - Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && + Entrance(RR_GANONS_TOWER_FLOOR_1, {[]{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && (logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && (logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && (logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && @@ -50,6 +50,14 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku()), LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, logic->CanStunDeku()), LOCATION(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_1, true), + LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_2, true), + LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_3, true), + LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_4, true), + LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_5, true), + LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_6, true), + LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_7, true), + LOCATION(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, true), }, {}); areaTable[RR_GANONS_CASTLE_FOREST_TRIAL] = Region("Ganon's Castle Forest Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { @@ -58,22 +66,32 @@ void RegionTable_Init_GanonsCastle() { }, { //Locations LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanDamage()), + LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, logic->CanBreakPots() && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_DINS_FIRE))), + LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, logic->CanBreakPots() && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_DINS_FIRE))), }, {}); areaTable[RR_GANONS_CASTLE_FIRE_TRIAL] = Region("Ganon's Castle Fire Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FireTrialClear, {[]{return logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_LONGSHOT);}}), - }, {}, {}); + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, logic->CanBreakPots() && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, logic->CanBreakPots() && logic->CanUse(RG_GORON_TUNIC) && logic->CanUse(RG_GOLDEN_GAUNTLETS) && logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_GANONS_CASTLE_FIRE_TRIAL_HEART, logic->CanUse(RG_GORON_TUNIC)), + }, {}); areaTable[RR_GANONS_CASTLE_WATER_TRIAL] = Region("Ganon's Castle Water Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || logic->HasBottle();}}), - EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || logic->BlueFire();}}), + EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD));}}), EventAccess(&logic->WaterTrialClear, {[]{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_LIGHT_ARROWS);}}), }, { //Locations LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_LEFT_CHEST, true), LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_RIGHT_CHEST, true), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_1, logic->CanBreakPots() && logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_2, logic->CanBreakPots() && logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GANONS_CASTLE_WATER_TRIAL_POT_3, logic->CanBreakPots() && logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD)), }, {}); areaTable[RR_GANONS_CASTLE_SHADOW_TRIAL] = Region("Ganon's Castle Shadow Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { @@ -83,6 +101,13 @@ void RegionTable_Init_GanonsCastle() { //Locations LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_FRONT_CHEST, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild), LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_GOLDEN_GAUNTLETS_CHEST, logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_LONGSHOT) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_DINS_FIRE)))), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, logic->CanBreakPots() && 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))))))), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, logic->CanBreakPots() && 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))))))), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, (logic->CanUse(RG_FIRE_ARROWS) || (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) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, (logic->CanUse(RG_FIRE_ARROWS) || (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) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, (logic->CanUse(RG_FIRE_ARROWS) || (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) || logic->CanUse(RG_BOOMERANG))), }, {}); areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Region("Ganon's Castle Spirit Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { @@ -93,6 +118,10 @@ void RegionTable_Init_GanonsCastle() { //Locations LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanJumpslashExceptHammer()), LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, true), }, {}); areaTable[RR_GANONS_CASTLE_LIGHT_TRIAL] = Region("Ganon's Castle Light Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { @@ -108,15 +137,12 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, true), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH)), LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_GANONS_CASTLE, 1)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, logic->CanBreakPots() && logic->SmallKeys(RR_GANONS_CASTLE, 2)), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, logic->CanBreakPots() && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, logic->CanBreakPots() && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_GANONS_CASTLE, 2) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))), }, {}); - } - areaTable[RR_GANONS_CASTLE_TOWER] = Region("Ganon's Castle Tower", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GANONS_TOWER_BOSS_KEY_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GANONDORF_HINT, logic->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 | @@ -142,7 +168,7 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_CHAIRS_ROOM, {[]{return true;}}), Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_DINOLFOS_ROOM, {[]{return Here(RR_GANONS_CASTLE_MQ_MAIN, []{return logic->CanUse(RG_GOLDEN_GAUNTLETS);});}}), //RANDOTODO could we just set these events automatically based on the setting? - Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && + Entrance(RR_GANONS_TOWER_FLOOR_1, {[]{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) && (logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) && (logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) && (logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) && @@ -161,6 +187,14 @@ void RegionTable_Init_GanonsCastle() { LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, logic->CanStunDeku()), LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, logic->CanStunDeku()), LOCATION(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, logic->CanStunDeku()), + LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, true), + LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, true), + LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, true), + LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, true), + LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, true), + LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, true), + LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, true), + LOCATION(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, true), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_MAIN, {[]{return true;}}), @@ -190,7 +224,11 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_FOREST_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Forest Trial Final Room", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ForestTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS);}}), - }, {}, { + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_FOREST_TRIAL_BEAMOS_ROOM, {[]{return true;}}), }); @@ -207,7 +245,11 @@ void RegionTable_Init_GanonsCastle() { //Events EventAccess(&logic->FireTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS);}}), //There's no way back across the lava without glitches - }, {}, {}); + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, logic->CanBreakPots()), + }, {}); areaTable[RR_GANONS_CASTLE_MQ_WATER_TRIAL_GEYSER_ROOM] = Region("Ganon's Castle MQ Water Trial Geyser Room", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { //Events @@ -215,6 +257,7 @@ void RegionTable_Init_GanonsCastle() { }, { //Locations LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, logic->BlueFire()), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_MAIN, {[]{return true;}}), @@ -233,7 +276,8 @@ void RegionTable_Init_GanonsCastle() { EventAccess(&logic->WaterTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS);}}), }, { //Locations - LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, logic->BlueFire()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, logic->CanBreakPots()), }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_WATER_TRIAL_BLOCK_ROOM, {[]{return Here(RR_GANONS_CASTLE_MQ_WATER_TRIAL_FINAL_ROOM, []{return logic->BlueFire();});}}), @@ -298,7 +342,11 @@ void RegionTable_Init_GanonsCastle() { areaTable[RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Shadow Trial Final Room", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ShadowTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS);}}), - }, {}, { + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_FAR_SIDE, {[]{return (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}), }); @@ -337,7 +385,11 @@ void RegionTable_Init_GanonsCastle() { //Events EventAccess(&logic->SpiritTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS);}}), EventAccess(&logic->NutPot, {[]{return true;}}), - }, {}, { + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_AFTER_SWITCH, {[]{return true;}}), }); @@ -369,11 +421,93 @@ void RegionTable_Init_GanonsCastle() { Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_FRONT, {[]{return logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GANON_MQ_LIGHT_TRIAL);}}), Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM, {[]{return logic->SmallKeys(RR_GANONS_CASTLE, 3) && (ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanJumpslash() || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_BOOMERANG));}}), + }); areaTable[RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM] = Region("Ganon's Castle MQ Light Trial Final Room", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->LightTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS);}}), - }, {}, {}); + }, { + //Locations + LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, logic->CanBreakPots()), + }, {}); } + + /*-------------------------- + | TOWER AND ESCAPE | + ---------------------------*/ + areaTable[RR_GANONS_TOWER_FLOOR_1] = Region("Ganon's Tower Floor 1", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_GANONS_CASTLE_LOBBY, {[]{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}}), + Entrance(RR_GANONS_TOWER_FLOOR_2, {[]{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}}), + }); + + areaTable[RR_GANONS_TOWER_FLOOR_2] = Region("Ganon's Tower Floor 2", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GANONS_TOWER_BOSS_KEY_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)), + }, { + //Exits + Entrance(RR_GANONS_TOWER_FLOOR_1, {[]{return Here(RR_GANONS_TOWER_FLOOR_2, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}}), + Entrance(RR_GANONS_TOWER_FLOOR_3, {[]{return Here(RR_GANONS_TOWER_FLOOR_2, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}}), + }); + + areaTable[RR_GANONS_TOWER_FLOOR_3] = Region("Ganon's Tower Floor 3", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_GANONS_TOWER_FLOOR_2, {[]{return Here(RR_GANONS_TOWER_FLOOR_3, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE, ED_CLOSE, true, 2);});}}), + Entrance(RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, {[]{return Here(RR_GANONS_TOWER_FLOOR_3, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE, ED_CLOSE, true, 2);});}}), + }); + + areaTable[RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR] = Region("Ganon's Tower Before Ganondorf's Lair", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, { + // Locations + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_1, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_2, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_3, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_4, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_5, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_6, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_7, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_8, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_9, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_10, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_11, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_12, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_13, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_14, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_15, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_16, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_17, logic->CanBreakPots()), + LOCATION(RC_GANONS_CASTLE_GANONS_TOWER_POT_18, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GANONS_TOWER_FLOOR_3, {[]{return Here(RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, []{return true;});}}), + Entrance(RR_GANONS_TOWER_GANONDORF_LAIR, {[]{return Here(RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, []{return logic->HasItem(RG_GANONS_CASTLE_BOSS_KEY);});}}), + }); + + areaTable[RR_GANONS_TOWER_GANONDORF_LAIR] = Region("Ganondorf's Lair", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GANONDORF_HINT, logic->HasBossSoul(RG_GANON_SOUL)), + }, { + //Exits + Entrance(RR_GANONS_CASTLE_ESCAPE, {[]{return logic->CanKillEnemy(RE_GANONDORF);}}), + }); + + areaTable[RR_GANONS_CASTLE_ESCAPE] = Region("Ganon's Castle Escape", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //10 pots + //RANDOTODO hook potsanity pots up to escape. + }, { + //Exits + //temporary + Entrance(RR_GANONS_CASTLE_GANON_ARENA, {[]{return true;}}), + //real logic once we figure out how to deal with castle escape skip + //Entrance(RR_GANONS_CASTLE_GANON_ARENA, {[]{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}}), + }); + + areaTable[RR_GANONS_CASTLE_GANON_ARENA] = Region("Ganon's Arena", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GANON, logic->CanKillEnemy(RE_GANON)), + LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->SmallKeys(RR_GANONS_CASTLE, 2)), + LOCATION(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->SmallKeys(RR_GANONS_CASTLE, 2)), + }, {}); } diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_ground.cpp new file mode 100644 index 000000000..ba781b882 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_ground.cpp @@ -0,0 +1,340 @@ +#include "../location_access.hpp" +#include "../../entrance.h" +#include "../../dungeon.h" + +using namespace Rando; + +void RegionTable_Init_GerudoTrainingGrounds() { + /*-------------------------- + | VANILLA/MQ DECIDER | + ---------------------------*/ + areaTable[RR_GERUDO_TRAINING_GROUND_ENTRYWAY] = Region("Gerudo Training Ground Entryway", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_LOBBY, {[]{return ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsVanilla();}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, {[]{return ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsMQ();}}), + Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}), + }); + + /*-------------------------- + | VANILLA DUNGEON | + ---------------------------*/ + if (ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsVanilla()) { + areaTable[RR_GERUDO_TRAINING_GROUND_LOBBY] = Region("Gerudo Training Ground Lobby", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), + LOCATION(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, true), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUND_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_GROUND_LAVA_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUND_LOBBY, []{return (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HasExplosives();});}}), + Entrance(RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE, {[]{return true;}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE] = Region("Gerudo Training Ground Central Maze", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 3) && (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 4)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 6)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 7)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 9)), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT, {[]{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 9);}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT] = Region("Gerudo Training Ground Central Maze Right", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, true), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_HAMMER_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM, {[]{return true;}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_LAVA_ROOM] = Region("Gerudo Training Ground Lava Room", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT, {[]{return logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild;}}), + Entrance(RR_GERUDO_TRAINING_GROUND_HAMMER_ROOM, {[]{return logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_HOOKSHOT));}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_HAMMER_ROOM] = Region("Gerudo Training Ground Hammer Room", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, logic->CanAttack()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || (logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS))), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER, {[]{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_FAIRY_BOW);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_LAVA_ROOM, {[]{return true;}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER] = Region("Gerudo Training Ground Eye Statue Lower", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_HAMMER_ROOM, {[]{return true;}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_EYE_STATUE_UPPER] = Region("Gerudo Training Ground Eye Statue Upper", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, logic->CanUse(RG_FAIRY_BOW)), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER, {[]{return true;}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_ROOM] = Region("Gerudo Training Ground Heavy Block Room", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanJumpslashExceptHammer()), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_EYE_STATUE_UPPER, {[]{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)));}}), + Entrance(RR_GERUDO_TRAINING_GROUND_LIKE_LIKE_ROOM, {[]{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanUse(RG_SILVER_GAUNTLETS);}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_LIKE_LIKE_ROOM] = Region("Gerudo Training Ground Like Like Room", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanJumpslashExceptHammer()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanJumpslashExceptHammer()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, logic->CanJumpslashExceptHammer()), + LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->CanJumpslashExceptHammer()), + }, {}); + } + + /*--------------------------- + | MASTER QUEST DUNGEON | + ---------------------------*/ + if (ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsMQ()) { + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_LOBBY] = Region("Gerudo Training Ground MQ Lobby", "Gerudo Training Ground", {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_MAZE_PATH_FIRST_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_SECOND_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, logic->CanBreakPots()), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, logic->CanBreakPots()), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, logic->CanBreakPots()), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_HIDDEN_ROOM, {[]{return ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_FIRST_LOCK, {[]{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 1);}}), + //It's possible to use the torch in RR_GERUDO_TRAINING_GROUND_MQ_MAZE_HIDDEN_ROOM with flame storage to light these + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return logic->HasFireSource();});}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT));});}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_HIDDEN_ROOM] = Region("Gerudo Training Ground MQ Maze Hidden Room", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HIDDEN_CEILING_CHEST, true), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, {[]{return true;}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_FIRST_LOCK] = Region("Gerudo Training Ground MQ Maze First Lock", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_THIRD_CHEST, true), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, {[]{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 1);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_CENTER, {[]{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 3);}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_CENTER] = Region("Gerudo Training Ground MQ Center", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->MQGTGMazeSwitch, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), + }, {}, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_FIRST_LOCK, {[]{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 3);}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM] = Region("Gerudo Training Ground MQ Sand Room", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, logic->CanKillEnemy(RE_IRON_KNUCKLE)), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEFT_SIDE, {[]{return Here(RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_LEFT_SIDE] = Region("Gerudo Training Ground MQ Left Side", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUND_MQ_LEFT_SIDE, []{return logic->CanUse(RG_LONGSHOT) || + ctx->GetTrickOption(RT_GTG_MQ_WIHTOUT_HOOKSHOT) || + (ctx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanJumpslash() && logic->CanUse(RG_HOOKSHOT));});}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM] = Region("Gerudo Training Ground MQ Stalfos Room", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->BlueFireAccess, {[]{return true;}}), + }, { + //Locations + //implies logic->CanKillEnemy(RE_BIG_SKULLTULA) + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true)), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK, {[]{return Here(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}) && logic->CanUse(RG_SILVER_GAUNTLETS);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, {[]{return logic->IsAdult && Here(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}) && + (ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire() && + (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)));}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK] = Region("Gerudo Training Ground MQ Behind Block", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //implies logic->CanKillEnemy(RE_SPIKE) + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, logic->CanKillEnemy(RE_FREEZARD)), + }, {}); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE] = Region("Gerudo Training Ground MQ Statue Room Ledge", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, {[]{return true;}}), + //implies dropping down to hit the switch. Using swords, especially master, is a bit awkward, may be trick worthy, but is only relevant with other tricks + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, []{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG);});}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM, {[]{return true;}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM] = Region("Gerudo Training Ground MQ Magenta Fire Room", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, logic->MQGTGMazeSwitch),}, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, {[]{return true;}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM] = Region("Gerudo Training Ground MQ Statue ROom", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, {[]{return logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SLUG_ROOM, {[]{return true;}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SLUG_ROOM] = Region("Gerudo Training Ground MQ Torch Slug Room", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //implies logic->CanKillEnemy(RE_TORCH_SLUG) + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, logic->CanKillEnemy(RE_IRON_KNUCKLE)), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanHitSwitch(ED_BOMB_THROW)), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SLUG_ROOM, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_SWITCH_LEDGE, {[]{return Here(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SLUG_ROOM, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_SWITCH_LEDGE] = Region("Gerudo Training Ground MQ Switch Ledge", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->MQGTGRightSideSwitch, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), + EventAccess(&logic->GTGPlatformSilverRupees, {[]{return logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS);}}), + }, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, {[]{return logic->CanUse(RG_FIRE_ARROWS);}}), + //the fire bubble here is a jerk if you are aiming for the nearest hook platform, you have to aim to the right hand side with hook to dodge it + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, {[]{return logic->CanUse(RG_LONGSHOT) || (logic->GTGPlatformSilverRupees && logic->CanUse(RG_HOOKSHOT)) || + ((logic->CanUse(RG_FIRE_ARROWS) && logic->GTGPlatformSilverRupees) && logic->CanUse(RG_HOVER_BOOTS));}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, {[]{return logic->MQGTGRightSideSwitch && logic->CanUse(RG_LONGSHOT);}}), + }); + +//this region exists to place silver rupee items on later, normally it's all on fire and cannot be stood on without access from another area +//This covers the 2 platforms that can be jumped to directly from RR_GERUDO_TRAINING_GROUND_MQ_SWITCH_LEDGE +//the unshuffled rupee collection is handled by the event GTGPlatformSilverRupees + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS] = Region("Gerudo Training Ground MQ Ledge Side Platforms", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + //This is merely to extend this region's logic if you have hovers + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_FURTHEST_PLATFORM, {[]{return logic->CanUse(RG_HOVER_BOOTS);}}), + }); + +//this region exists to place silver rupee items on later, normally it's all on fire and cannot be stood on without access from another area +//This covers the platform that needs hover boots or the spawned targets to reach from any starting point other than RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT +//the unshuffled rupee collection is handled by the event GTGPlatformSilverRupees + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_FURTHEST_PLATFORM] = Region("Gerudo Training Ground MQ Furthest Platform", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + //This is merely to extend this region's logic if you have hovers + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, {[]{return logic->CanUse(RG_HOVER_BOOTS);}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH] = Region("Gerudo Training Ground MQ Platforms Unlit Torch", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->GTGPlatformSilverRupees, {[]{return logic->HasFireSource() && logic->CanUse(RG_HOVER_BOOTS);}}), + }, {}, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER, {[]{return logic->GTGPlatformSilverRupees;}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, {[]{return logic->HasFireSource() && logic->CanUse(RG_HOVER_BOOTS);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SIDE_PLATFORMS, {[]{return logic->HasFireSource() || logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, {[]{return logic->MQGTGRightSideSwitch && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->HasFireSource()));}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SIDE_PLATFORMS] = Region("Gerudo Training Ground Torch Side Platforms", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, { + //Events + //this torch shot is possible as child but tight and obtuse enough to be a trick + EventAccess(&logic->GTGPlatformSilverRupees, {[]{return ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)) && logic->CanUse(RG_HOVER_BOOTS);}}), + }, {}, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, {[]{return ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS)) && logic->CanUse(RG_HOVER_BOOTS);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, {[]{return (logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS) || + logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, {[]{return logic->MQGTGRightSideSwitch && ((logic->CanUse(RG_FAIRY_BOW) && logic->IsAdult) || logic->CanUse(RG_FIRE_ARROWS) || + logic->CanUse(RG_LONGSHOT));}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_ROOM, {[]{return true;}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER] = Region("Gerudo Training Ground MQ Underwater", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //it is possible to snipe the stingers with bow or sling before dropping in, or just get really lucky, and avoid needing to take damage, but that might be trick worthy + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, logic->HasFireSource() && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->TakeDamage()), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, {[]{return true;}}), + }); + + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT] = Region("Gerudo Training Ground MQ Maze Right", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->GTGPlatformSilverRupees, {[]{return logic->CanUse(RG_FIRE_ARROWS) && logic->CanUse(RG_HOVER_BOOTS);}}), + }, { + //Locations + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, true), + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, true), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, {[]{return true;}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, {[]{return logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, {[]{return logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_LONGSHOT) || (logic->GTGPlatformSilverRupees && logic->CanUse(RG_HOVER_BOOTS));}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, {[]{return logic->CanUse(RG_FIRE_ARROWS);}}), + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_FURTHEST_PLATFORM, {[]{return logic->CanUse(RG_FIRE_ARROWS);}}), + }); + + areaTable[RR_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_ROOM] = Region("Gerudo Training Ground MQ Dinolfos Room", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, { + //Events + //EventAccess(&WallFairy, {[]{return WallFairy || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}}), + }, { + //Locations + //implies logic->CanKillEnemy(RE_LIZALFOS and logic->CanKillEnemy(RE_DODONGO) + //is logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2, true) && logic->CanKillEnemy(RE_ARMOS, ED_CLOSE, true, 1, true) broken down to exclude sticks, as it take too many to clear the room + //Proper enemy kill room ammo logic is needed to handle this room + //some combinations may be impossible without taking damage, keep an eye out for issues here + LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || + ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)))), + }, { + //Exits + Entrance(RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SIDE_PLATFORMS, {[]{return Here(RR_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_ROOM, []{return logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_FAIRY_BOW) || + ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT)));});}}), + }); + + } +} 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 deleted file mode 100644 index 345d89136..000000000 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_gerudo_training_grounds.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include "../location_access.hpp" -#include "../../entrance.h" -#include "../../dungeon.h" - -using namespace Rando; - -void RegionTable_Init_GerudoTrainingGrounds() { - /*-------------------------- - | VANILLA/MQ DECIDER | - ---------------------------*/ - areaTable[RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY] = Region("Gerudo Training Grounds Entryway", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, {}, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_LOBBY, {[]{return 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 (ctx->GetDungeon(GERUDO_TRAINING_GROUNDS)->IsVanilla()) { - areaTable[RR_GERUDO_TRAINING_GROUNDS_LOBBY] = Region("Gerudo Training Grounds Lobby", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), - LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)), - LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return true;}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM, {[]{return (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (logic->CanUse(RG_HOOKSHOT) || ctx->GetTrickOption(RT_GTG_WITHOUT_HOOKSHOT));}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_LOBBY, []{return (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->HasExplosives();});}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE, {[]{return true;}}), - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE] = Region("Gerudo Training Grounds Central Maze", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 3) && (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(RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT, {[]{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 9);}}), - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT] = Region("Gerudo Training Grounds Central Maze Right", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, true), - LOCATION(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, true), - LOCATION(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, true), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT);}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return true;}}), - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM] = Region("Gerudo Training Grounds Lava Room", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT, {[]{return logic->CanUse(RG_SONG_OF_TIME) || logic->IsChild;}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_HOOKSHOT));}}), - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM] = Region("Gerudo Training Grounds Hammer Room", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, logic->CanAttack()), - LOCATION(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || (logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS))), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, {[]{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_FAIRY_BOW);}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, {[]{return true;}}), - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER] = Region("Gerudo Training Grounds Eye Statue Lower", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, {[]{return true;}}), - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER] = Region("Gerudo Training Grounds Eye Statue Upper", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, logic->CanUse(RG_FAIRY_BOW)), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, {[]{return true;}}), - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM] = Region("Gerudo Training Grounds Heavy Block Room", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, logic->CanJumpslashExceptHammer()), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER, {[]{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS)));}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM, {[]{return (ctx->GetTrickOption(RT_LENS_GTG) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanUse(RG_SILVER_GAUNTLETS);}}), - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM] = Region("Gerudo Training Grounds Like Like Room", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, logic->CanJumpslashExceptHammer()), - }, {}); - } - - /*--------------------------- - | MASTER QUEST DUNGEON | - ---------------------------*/ - 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(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[RR_GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE] = Region("Gerudo Training Grounds MQ Right Side", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, { - //Events - //EventAccess(&WallFairy, {[]{return WallFairy || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW));}}), - }, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return (logic->CanUse(RG_FAIRY_BOW) || (logic->CanUse(RG_LONGSHOT) && logic->HasFireSource())) && logic->CanUse(RG_HOVER_BOOTS) && logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD));}}), - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER] = Region("Gerudo Training Grounds MQ Underwater", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, logic->HasFireSource() && logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && logic->TakeDamage()), - }, {}); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE] = Region("Gerudo Training Grounds MQ Left Side", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->HasExplosives()), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM, {[]{return (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || ctx->GetTrickOption(RT_GTG_MQ_WIHTOUT_HOOKSHOT) || (ctx->GetTrickOption(RT_GTG_MQ_WITH_HOOKSHOT) && logic->IsAdult && logic->CanUse(RG_HOOKSHOT));}}), - //Trick: (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || LogicGtgMQWithoutHookshot || (LogicGtgMQWithHookshot && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM] = Region("Gerudo Training Grounds MQ Stalfos Room", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, { - //Events - EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || logic->HasBottle();}}), - }, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS, {[]{return logic->IsAdult && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && (ctx->GetTrickOption(RT_LENS_GTG_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_GTG_FAKE_WALL) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));}}), - //Trick: logic->IsAdult && (LogicLensGtgMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->BlueFire && (logic->CanUse(RG_SONG_OF_TIME) || (LogicGtgFakeWall && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS))) - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS] = Region("Gerudo Training Grounds MQ Back Areas", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->HasExplosives()), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, {[]{return logic->CanUse(RG_LONGSHOT);}}), - }); - - areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT] = Region("Gerudo Training Grounds MQ Central Maze Right", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, true), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_SIDE_CHEST, true), - LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, logic->SmallKeys(RR_GERUDO_TRAINING_GROUNDS, 3)), - }, { - //Exits - Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, {[]{return logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOOKSHOT) && logic->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 63e4c05d0..f662dd082 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 @@ -9,25 +9,30 @@ void RegionTable_Init_GerudoValley() { EventAccess(&logic->BugRock, {[]{return logic->BugRock || logic->IsChild;}}), }, { //Locations - LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), Entrance(RR_GV_UPPER_STREAM, {[]{return true;}}), Entrance(RR_GV_CRATE_LEDGE, {[]{return logic->IsChild || logic->CanUse(RG_LONGSHOT);}}), Entrance(RR_GV_GROTTO_LEDGE, {[]{return true;}}), - Entrance(RR_GV_FORTRESS_SIDE, {[]{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_GV_FORTRESS_SIDE, {[]{return (logic->IsAdult && (logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || logic->CarpenterRescue)) || (logic->IsChild && logic->CanUse(RG_HOOKSHOT));}}), }); areaTable[RR_GV_UPPER_STREAM] = Region("GV Upper Stream", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), - EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_GV_UPPER_STREAM) && logic->CanUse(RG_SONG_OF_STORMS));}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}}), }, { //Locations LOCATION(RC_GV_WATERFALL_FREESTANDING_POH, logic->IsChild || logic->HasItem(RG_BRONZE_SCALE)),//can use cucco as child LOCATION(RC_GV_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), LOCATION(RC_GV_COW, logic->IsChild && logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_GV_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GV_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GV_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GV_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_GV_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_GV_GOSSIP_STONE, true), }, { //Exits @@ -51,23 +56,24 @@ void RegionTable_Init_GerudoValley() { LOCATION(RC_GV_CRATE_FREESTANDING_POH, true), }, { //Exits + Entrance(RR_GV_UPPER_STREAM, {[]{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}}), Entrance(RR_GV_LOWER_STREAM, {[]{return true;}}), }); areaTable[RR_GV_FORTRESS_SIDE] = Region("GV Fortress Side", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {}, { - //Locations + //Locations 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()), + LOCATION(RC_GV_GS_BEHIND_TENT, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_GS_PILLAR, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), }, { //Exits 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_GERUDO_VALLEY, {[]{return logic->IsChild || logic->CanUse(RG_EPONA) || logic->CanUse(RG_LONGSHOT) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || 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;}}), + Entrance(RR_GV_CRATE_LEDGE, {[]{return ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives();}}), }); areaTable[RR_GV_CARPENTER_TENT] = Region("GV Carpenter Tent", "GV Carpenter Tent", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -75,7 +81,17 @@ void RegionTable_Init_GerudoValley() { Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), }); - areaTable[RR_GV_OCTOROK_GROTTO] = Region("GV Octorok Grotto", "GV Octorok Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_GV_OCTOROK_GROTTO] = Region("GV Octorok Grotto", "GV Octorok Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_GV_OCTOROK_GROTTO_RED_RUPEE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG)), + }, { //Exits Entrance(RR_GV_GROTTO_LEDGE, {[]{return true;}}), }); @@ -97,21 +113,39 @@ void RegionTable_Init_GerudoValley() { EventAccess(&logic->GtG_GateOpen, {[]{return logic->GtG_GateOpen || (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}}), }, { //Locations - LOCATION(RC_GF_CHEST, logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_GF_HBA_1000_POINTS, logic->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->CanJumpslashExceptHammer() || 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()), + 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->CanKillEnemy(RE_GERUDO_WARRIOR)), + LOCATION(RC_GF_NORTH_F2_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR) && (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->CanKillEnemy(RE_GERUDO_WARRIOR)), + LOCATION(RC_GF_SOUTH_F2_CARPENTER, logic->CanKillEnemy(RE_GERUDO_WARRIOR)), + 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->CanGetNightTimeGS()), + LOCATION(RC_GF_GS_TOP_FLOOR, logic->IsAdult && (logic->CanJumpslashExceptHammer() || 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()), + LOCATION(RC_GF_BREAK_ROOM_POT_1, logic->CanBreakPots()), + LOCATION(RC_GF_BREAK_ROOM_POT_2, logic->CanBreakPots()), + LOCATION(RC_GF_KITCHEN_POT_1, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakPots()), + LOCATION(RC_GF_KITCHEN_POT_2, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanBreakPots()), + LOCATION(RC_GF_NORTH_F1_CARPENTER_POT_1, logic->CanBreakPots()), + LOCATION(RC_GF_NORTH_F1_CARPENTER_POT_2, logic->CanBreakPots()), + LOCATION(RC_GF_NORTH_F1_CARPENTER_POT_3, logic->CanBreakPots()), + LOCATION(RC_GF_NORTH_F2_CARPENTER_POT_1, logic->CanBreakPots()), + LOCATION(RC_GF_NORTH_F2_CARPENTER_POT_2, logic->CanBreakPots()), + LOCATION(RC_GF_SOUTH_F1_CARPENTER_POT_1, logic->CanBreakPots()), + LOCATION(RC_GF_SOUTH_F1_CARPENTER_POT_2, logic->CanBreakPots()), + LOCATION(RC_GF_SOUTH_F1_CARPENTER_POT_3, logic->CanBreakPots()), + LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_1, logic->CanBreakPots()), + LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2, logic->CanBreakPots()), + LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3, logic->CanBreakPots()), + LOCATION(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_4, logic->CanBreakPots()), + //RANDOTODO doublecheck when GF isn't a blob + LOCATION(RC_GF_KITCHEN_SUN_FAIRY, (logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_SUNS_SONG)), }, { //Exits Entrance(RR_GV_FORTRESS_SIDE, {[]{return true;}}), Entrance(RR_GF_OUTSIDE_GATE, {[]{return logic->GF_GateOpen;}}), - Entrance(RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, {[]{return logic->GtG_GateOpen && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}}), + Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, {[]{return logic->GtG_GateOpen && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}}), Entrance(RR_GF_STORMS_GROTTO, {[]{return logic->IsAdult && logic->CanOpenStormsGrotto();}}), }); @@ -127,7 +161,17 @@ void RegionTable_Init_GerudoValley() { areaTable[RR_GF_STORMS_GROTTO] = Region("GF Storms Grotto", "GF Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FreeFairies, {[]{return true;}}), - }, {}, { + }, { + //Locations + LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_1, true), + LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_2, true), + LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_3, true), + LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_4, true), + LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_5, true), + LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_6, true), + LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_7, true), + LOCATION(RC_GF_FAIRY_GROTTO_FAIRY_8, true), + }, { //Exits Entrance(RR_GERUDO_FORTRESS, {[]{return true;}}), }); @@ -148,6 +192,10 @@ void RegionTable_Init_GerudoValley() { LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()), LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CanJumpslashExceptHammer() || logic->CanUse(RG_HOVER_BOOTS)), LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang()), + LOCATION(RC_WASTELAND_NEAR_GS_POT_1, logic->CanBreakPots()), + LOCATION(RC_WASTELAND_NEAR_GS_POT_2, logic->CanBreakPots()), + LOCATION(RC_WASTELAND_NEAR_GS_POT_3, logic->CanBreakPots()), + LOCATION(RC_WASTELAND_NEAR_GS_POT_4, logic->CanBreakPots()), }, { //Exits Entrance(RR_WASTELAND_NEAR_COLOSSUS, {[]{return ctx->GetTrickOption(RT_LENS_HW) || logic->CanUse(RG_LENS_OF_TRUTH);}}), @@ -166,20 +214,46 @@ void RegionTable_Init_GerudoValley() { EventAccess(&logic->BugRock, {[]{return true;}}), }, { //Locations - 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), + 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->CanGetNightTimeGS()), + LOCATION(RC_COLOSSUS_GS_HILL, logic->IsAdult && ((CanPlantBean(RR_DESERT_COLOSSUS) && logic->CanAttack()) || logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_COLOSSUS_GS) && logic->CanUse(RG_HOOKSHOT))) && logic->CanGetNightTimeGS()), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), }, { //Exits + //You can kinda get the fairies without entering the water, but it relies on them cooperating and leevers are jerks. should be a trick + Entrance(RR_DESERT_COLOSSUS_OASIS, {[]{return logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}), Entrance(RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives();}}), Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_WASTELAND_NEAR_COLOSSUS, {[]{return true;}}), Entrance(RR_COLOSSUS_GROTTO, {[]{return logic->CanUse(RG_SILVER_GAUNTLETS);}}), }); - areaTable[RR_DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY] = Region("Desert Colossus From Spirit Entryway", "Desert Colossus", {RA_DESERT_COLOSSUS}, NO_DAY_NIGHT_CYCLE, {}, { +//specifically the full oasis, after the fairies have spawned + areaTable[RR_DESERT_COLOSSUS_OASIS] = Region("Desert Colossus Oasis", "Desert Colossus", {RA_DESERT_COLOSSUS}, DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->FairyPond, {[]{return true;}}), + }, { + //Locations + LOCATION(RC_COLOSSUS_OASIS_FAIRY_1, true), + LOCATION(RC_COLOSSUS_OASIS_FAIRY_2, true), + LOCATION(RC_COLOSSUS_OASIS_FAIRY_3, true), + LOCATION(RC_COLOSSUS_OASIS_FAIRY_4, true), + LOCATION(RC_COLOSSUS_OASIS_FAIRY_5, true), + LOCATION(RC_COLOSSUS_OASIS_FAIRY_6, true), + LOCATION(RC_COLOSSUS_OASIS_FAIRY_7, true), + LOCATION(RC_COLOSSUS_OASIS_FAIRY_8, true), + }, { + //Exits + Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), + }); + + areaTable[RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE] = Region("Desert Colossus From Spirit Entryway", "Desert Colossus", {RA_DESERT_COLOSSUS}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SHEIK_AT_COLOSSUS, 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 7330aa77b..540cb0e34 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 @@ -9,8 +9,9 @@ void RegionTable_Init_HyruleField() { EventAccess(&logic->BigPoeKill, {[]{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_EPONA) && logic->HasBottle();}}), }, { //Locations - LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3), - LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3), + LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_SONG_FROM_OCARINA_OF_TIME, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_HF_POND_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits Entrance(RR_LW_BRIDGE, {[]{return true;}}), @@ -32,11 +33,13 @@ void RegionTable_Init_HyruleField() { areaTable[RR_HF_SOUTHEAST_GROTTO] = Region("HF Southeast Grotto", "HF Southeast Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, true), - LOCATION(RC_HF_SOUTHEAST_GROTTO_FISH, logic->HasBottle()), - LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), - LOCATION(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_CHEST, true), + LOCATION(RC_HF_SOUTHEAST_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + 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(RR_HYRULE_FIELD, {[]{return true;}}), @@ -44,11 +47,13 @@ void RegionTable_Init_HyruleField() { areaTable[RR_HF_OPEN_GROTTO] = Region("HF Open Grotto", "HF Open Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LOCATION(RC_HF_OPEN_GROTTO_CHEST, true), - LOCATION(RC_HF_OPEN_GROTTO_FISH, logic->HasBottle()), - LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), - LOCATION(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_OPEN_GROTTO_CHEST, true), + LOCATION(RC_HF_OPEN_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + 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(RR_HYRULE_FIELD, {[]{return true;}}), @@ -58,28 +63,45 @@ void RegionTable_Init_HyruleField() { //Locations LOCATION(RC_HF_DEKU_SCRUB_GROTTO, logic->CanStunDeku()), LOCATION(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_FENCE_GROTTO_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); - areaTable[RR_HF_COW_GROTTO] = Region("HF Cow Grotto", "HF Cow Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { + areaTable[RR_HF_COW_GROTTO] = Region("HF Cow Grotto", "HF Cow Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HF_COW_GROTTO_BEHIND_WEBS, {[]{return logic->HasFireSource();}}), + }); + + areaTable[RR_HF_COW_GROTTO_BEHIND_WEBS] = Region("HF Cow Grotto Behind Webs", "HF Cow Grotto", {}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->BugShrub, {[]{return logic->CanCutShrubs();}}), + EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), + }, { //Locations - LOCATION(RC_HF_GS_COW_GROTTO, logic->HasFireSource() && logic->HookshotOrBoomerang()), - LOCATION(RC_HF_COW_GROTTO_COW, logic->HasFireSource() && logic->CanUse(RG_EPONAS_SONG)), - LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE, logic->HasFireSource()), + LOCATION(RC_HF_GS_COW_GROTTO, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_HF_COW_GROTTO_COW, logic->CanUse(RG_EPONAS_SONG)), + LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_HF_COW_GROTTO_GOSSIP_STONE, true), + LOCATION(RC_HF_COW_GROTTO_POT_1, logic->CanBreakPots()), + LOCATION(RC_HF_COW_GROTTO_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_HYRULE_FIELD, {[]{return true;}}), + Entrance(RR_HF_COW_GROTTO, {[]{return true;}}), }); areaTable[RR_HF_NEAR_MARKET_GROTTO] = Region("HF Near Market Grotto", "HF Near Market Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LOCATION(RC_HF_NEAR_MARKET_GROTTO_CHEST, true), - LOCATION(RC_HF_NEAR_MARKET_GROTTO_FISH, logic->HasBottle()), - LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), - LOCATION(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_CHEST, true), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + 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(RR_HYRULE_FIELD, {[]{return true;}}), @@ -88,7 +110,17 @@ void RegionTable_Init_HyruleField() { areaTable[RR_HF_FAIRY_GROTTO] = Region("HF Fairy Grotto", "HF Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FreeFairies, {[]{return true;}}), - }, {}, { + }, { + //Locations + LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_1, true), + LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_2, true), + LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_3, true), + LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_4, true), + LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_5, true), + LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_6, true), + LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_7, true), + LOCATION(RC_HF_FAIRY_GROTTO_FAIRY_8, true), + }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), }); @@ -112,23 +144,37 @@ void RegionTable_Init_HyruleField() { areaTable[RR_LAKE_HYLIA] = Region("Lake Hylia", "Lake Hylia", {RA_LAKE_HYLIA}, DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), - EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_LAKE_HYLIA) && logic->CanUse(RG_SONG_OF_STORMS));}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && 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 - LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)), - LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->WaterTempleClear && logic->HasItem(RG_BRONZE_SCALE)) || logic->CanUse(RG_DISTANT_SCARECROW)) && logic->CanUse(RG_FAIRY_BOW)), - LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA))), - LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), - LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_RANG_OR_HOOKSHOT) || (ctx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslashExceptHammer())) && logic->AtNight && logic->CanGetNightTimeGS()), - LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) && logic->AtNight && logic->CanGetNightTimeGS() && logic->HasItem(RG_BRONZE_SCALE)), - 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), + LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)), + LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->WaterTempleClear && logic->HasItem(RG_BRONZE_SCALE)) || logic->CanUse(RG_DISTANT_SCARECROW)) && logic->CanUse(RG_FAIRY_BOW)), + LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA))), + LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + LOCATION(RC_LH_GS_LAB_WALL, logic->IsChild && (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || (ctx->GetTrickOption(RT_LH_LAB_WALL_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), + LOCATION(RC_LH_GS_SMALL_ISLAND, logic->IsChild && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA) && logic->CanGetNightTimeGS() && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_LH_GS_TREE, logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanGetNightTimeGS()), + LOCATION(RC_LH_FRONT_RUPEE, logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_LH_MIDDLE_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LH_BACK_RUPEE, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LH_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LH_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LH_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LH_LAB_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + //You can walk along the edge of the lake to get these without swimming, the fairy is created going backwards, which is convenient here, + LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LH_ISLAND_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && ((logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->WaterTempleClear)) || logic->CanUse(RG_DISTANT_SCARECROW))), + LOCATION(RC_LH_LAB_GOSSIP_STONE, true), + LOCATION(RC_LH_SOUTHEAST_GOSSIP_STONE, true), + LOCATION(RC_LH_SOUTHWEST_GOSSIP_STONE, true), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), @@ -143,7 +189,7 @@ void RegionTable_Init_HyruleField() { areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", "Lake Hylia", {RA_LAKE_HYLIA}, DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_LAKE_HYLIA, {[]{return logic->HasItem(RG_BRONZE_SCALE);}}), - Entrance(RR_LH_FISHING_HOLE, {[]{return true;}}), + Entrance(RR_LH_FISHING_POND, {[]{return true;}}), }); areaTable[RR_LH_OWL_FLIGHT] = Region("LH Owl Flight", "Lake Hylia", {RA_LAKE_HYLIA}, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -153,35 +199,37 @@ void RegionTable_Init_HyruleField() { areaTable[RR_LH_LAB] = Region("LH Lab", "LH Lab", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - 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)), + 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)), + LOCATION(RC_LH_LAB_FRONT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), + LOCATION(RC_LH_LAB_LEFT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), + LOCATION(RC_LH_LAB_RIGHT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), }, { //Exits Entrance(RR_LAKE_HYLIA, {[]{return true;}}), }); - // 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, {}, { + areaTable[RR_LH_FISHING_POND] = Region("LH Fishing Hole", "LH Fishing Hole", {}, DAY_NIGHT_CYCLE, {}, { //Locations 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_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)), @@ -225,9 +273,16 @@ void RegionTable_Init_HyruleField() { //Locations LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay), LOCATION(RC_LLR_GS_TREE, logic->IsChild), - LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->AtNight && logic->CanGetNightTimeGS()), - LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), - LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->AtNight && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_RAIN_SHED, logic->IsChild && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_HOUSE_WINDOW, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_GS_BACK_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_LLR_FRONT_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_FRONT_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_FRONT_POT_3, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_FRONT_POT_4, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_RAIN_SHED_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_RAIN_SHED_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_LLR_RAIN_SHED_POT_3, logic->IsChild && logic->CanBreakPots()), }, { //Exits Entrance(RR_HYRULE_FIELD, {[]{return true;}}), @@ -240,6 +295,9 @@ void RegionTable_Init_HyruleField() { areaTable[RR_LLR_TALONS_HOUSE] = Region("LLR Talons House", "LLR Talons House", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_LLR_TALONS_CHICKENS, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild && logic->AtDay && logic->HasItem(RG_ZELDAS_LETTER)), + LOCATION(RC_LLR_TALONS_HOUSE_POT_1, logic->CanBreakPots()), + LOCATION(RC_LLR_TALONS_HOUSE_POT_2, logic->CanBreakPots()), + LOCATION(RC_LLR_TALONS_HOUSE_POT_3, logic->CanBreakPots()), }, { //Exits Entrance(RR_LON_LON_RANCH, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_ice_cavern.cpp index 32ebd754f..e5f24ab55 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 @@ -19,7 +19,10 @@ void RegionTable_Init_IceCavern() { | VANILLA DUNGEON | ---------------------------*/ if (ctx->GetDungeon(ICE_CAVERN)->IsVanilla()) { - areaTable[RR_ICE_CAVERN_BEGINNING] = Region("Ice Cavern Beginning", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_ICE_CAVERN_BEGINNING] = Region("Ice Cavern Beginning", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + }, { //Exits Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return true;}}), Entrance(RR_ICE_CAVERN_MAIN, {[]{return Here(RR_ICE_CAVERN_BEGINNING, []{return (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE);});}}), @@ -38,6 +41,21 @@ void RegionTable_Init_IceCavern() { 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)))), + LOCATION(RC_ICE_CAVERN_HALL_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_HALL_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_SPINNING_BLADE_POT_3, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_NEAR_END_POT_1, logic->CanBreakPots() && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_NEAR_END_POT_2, logic->CanBreakPots() && logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_FROZEN_POT_1, logic->CanBreakPots() && logic->BlueFire() && logic->IsAdult), + LOCATION(RC_ICE_CAVERN_LOBBY_RUPEE, logic->BlueFire()), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, logic->IsAdult), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, logic->IsAdult), + LOCATION(RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, logic->IsAdult), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, logic->BlueFire() && (logic->CanUse(RG_SONG_OF_TIME) || logic->CanUse(RG_BOOMERANG))), }, {}); } @@ -45,40 +63,90 @@ void RegionTable_Init_IceCavern() { | MASTER QUEST DUNGEON | ---------------------------*/ 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, { + areaTable[RR_ICE_CAVERN_MQ_BEGINNING] = Region("Ice Cavern MQ Beginning", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_ICE_CAVERN_MQ_ENTRANCE_POT, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return true;}}), + //It is in logic to use a pot to hit the toggle switch here. + Entrance(RR_ICE_CAVERN_MQ_HUB, {[]{return true;}}), + }); + + areaTable[RR_ICE_CAVERN_MQ_HUB] = Region("Ice Cavern MQ Hub", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), - }, {}, { + }, { + //Locations + LOCATION(RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, logic->CanBreakPots()), + }, { //Exits - Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return true;}}), - Entrance(RR_ICE_CAVERN_MQ_MAP_ROOM, {[]{return logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_DINS_FIRE) || (logic->HasExplosives() && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_STICKS) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)));}}), - Entrance(RR_ICE_CAVERN_MQ_COMPASS_ROOM, {[]{return logic->IsAdult && logic->BlueFire();}}), - Entrance(RR_ICE_CAVERN_MQ_IRON_BOOTS_REGION, {[]{return logic->BlueFire();}}), + //the switch for the glass blocking the entrance is linked to the switch that controls the glass around the skulltulla in RR_ICE_CAVERN_MQ_SCARECROW_ROOM + //if you clear the ice, you can hit it with a pot from here. + Entrance(RR_ICE_CAVERN_BEGINNING, {[]{return logic->BlueFire();}}), + Entrance(RR_ICE_CAVERN_MQ_MAP_ROOM, {[]{return Here(RR_ICE_CAVERN_MQ_BEGINNING, []{return logic->CanKillEnemy(RE_WHITE_WOLFOS) && logic->CanKillEnemy(RE_FREEZARD);});}}), + Entrance(RR_ICE_CAVERN_MQ_COMPASS_ROOM, {[]{return logic->IsAdult && logic->BlueFire();}}), + Entrance(RR_ICE_CAVERN_MQ_SCARECROW_ROOM, {[]{return logic->BlueFire();}}), }); areaTable[RR_ICE_CAVERN_MQ_MAP_ROOM] = Region("Ice Cavern MQ Map Room", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BlueFireAccess, {[]{return logic->BlueFireAccess || (logic->HasBottle() && logic->CanJumpslashExceptHammer());}}), + //Child can fit between the stalagmites on the left hand side + EventAccess(&logic->BlueFireAccess, {[]{return logic->IsChild || logic->CanJumpslash() || logic->HasExplosives();}}), }, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && (logic->CanJumpslash() || logic->HasExplosives() || logic->CanUseProjectile())), + LOCATION(RC_ICE_CAVERN_MQ_MAP_CHEST, logic->BlueFire() && Here(RR_ICE_CAVERN_MQ_MAP_ROOM, []{return logic->CanHitSwitch();})), }, {}); - areaTable[RR_ICE_CAVERN_MQ_IRON_BOOTS_REGION] = Region("Ice Cavern MQ Iron Boots Region", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ICE_CAVERN_MQ_SCARECROW_ROOM] = Region("Ice Cavern MQ Scarecrow Room", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->IsAdult && (logic->CanJumpslash())), - LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->IsAdult && (logic->CanJumpslash())), - 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 - }, {}); + LOCATION(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, (logic->BlueFire() && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (logic->IsAdult && logic->CanHitSwitch(ED_LONG_JUMPSLASH))), + LOCATION(RC_ICE_CAVERN_MQ_GS_SCARECROW, logic->CanUse(RG_SCARECROW) || (logic->IsAdult && (logic->CanUse(RG_LONGSHOT) || ctx->GetTrickOption(RT_ICE_MQ_SCARECROW)))), + }, { + //Exits + Entrance(RR_ICE_CAVERN_MQ_HUB, {[]{return logic->BlueFire();}}), + //Assumes RR_ICE_CAVERN_MQ_HUB access for a pot if using blue fire + Entrance(RR_ICE_CAVERN_MQ_WEST_CORRIDOR, {[]{return logic->IsAdult && logic->BlueFire();}}), + }); - areaTable[RR_ICE_CAVERN_MQ_COMPASS_ROOM] = Region("Ice Cavern MQ Compass Room", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_ICE_CAVERN_MQ_WEST_CORRIDOR] = Region("Ice Cavern MQ West Corridor", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_ICE_CAVERN_MQ_SCARECROW_ROOM, {[]{return logic->BlueFire();}}), + Entrance(RR_ICE_CAVERN_MQ_STALFOS_ROOM, {[]{return true;}}), + }); + + areaTable[RR_ICE_CAVERN_MQ_STALFOS_ROOM] = Region("Ice Cavern MQ Stalfos Room", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_ICE_CAVERN_MQ_IRON_BOOTS_CHEST, logic->CanKillEnemy(RE_STALFOS)), + LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_STALFOS)), + }, { + //Exits + Entrance(RR_ICE_CAVERN_MQ_SCARECROW_ROOM, {[]{return logic->BlueFire() && Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}}), + Entrance(RR_ICE_CAVERN_MQ_BEGINNING, {[]{return logic->CanUse(RG_IRON_BOOTS) && Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}}), + }); + + areaTable[RR_ICE_CAVERN_MQ_COMPASS_ROOM] = Region("Ice Cavern MQ Compass Room", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->BlueFireAccess, {[]{return true;}}), + }, { //Locations LOCATION(RC_ICE_CAVERN_MQ_COMPASS_CHEST, true), + //It is possible for child with master, BGS or sticks, or adult with BGS, to hit this switch through the ice with a crouchstab, but it's precise and unintuitive for a trick 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 + //doing RT_ICE_MQ_RED_ICE_GS as child is untested, as I could not perform the trick reliably even as adult + LOCATION(RC_ICE_CAVERN_MQ_GS_RED_ICE, (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && logic->CanUse(RG_ICE_ARROWS)) || + (logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE) && (logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_ICE_MQ_RED_ICE_GS))) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA))), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_POT_1, logic->CanBreakPots()), + LOCATION(RC_ICE_CAVERN_MQ_COMPASS_POT_2, logic->CanBreakPots()), }, {}); } } 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 a80a7ba4a..73ad909c7 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 @@ -21,138 +21,148 @@ void RegionTable_Init_JabuJabusBelly() { if (ctx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla()) { areaTable[RR_JABU_JABUS_BELLY_BEGINNING] = Region("Jabu Jabus Belly Beginning", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return logic->CanUseProjectile();}}), + Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN, {[]{return logic->CanUseProjectile();}}), }); - areaTable[RR_JABU_JABUS_BELLY_LIFT_MIDDLE] = Region("Jabu Jabus Belly Lift Middle", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, { +//Combines Lift room middle and lower, 1F holes room, the forked corridor, and it's side rooms + areaTable[RR_JABU_JABUS_BELLY_MAIN] = Region("Jabu Jabus Belly Main", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->JabuRutoInB1, {[]{return true;}}), + EventAccess(&logic->JabuWestTentacle, {[]{return logic->JabuRutoIn1F && logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}}), + }, { + //Locations + LOCATION(RC_JABU_JABUS_BELLY_DEKU_SCRUB, logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || ctx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE) || logic->CanUse(RG_IRON_BOOTS)) && logic->CanStunDeku()), + //We can kill the Stingers with ruto + LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, logic->JabuRutoIn1F), + LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->JabuWestTentacle), + }, { //Exits Entrance(RR_JABU_JABUS_BELLY_BEGINNING, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_LIFT_LOWER, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, {[]{return HasAccessTo(RR_JABU_JABUS_BELLY_LIFT_UPPER) || (ctx->GetTrickOption(RT_JABU_BOSS_HOVER) && logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}}), - }); + Entrance(RR_JABU_JABUS_BELLY_B1_NORTH, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_COMPASS_ROOM, {[]{return logic->JabuWestTentacle;}}), + Entrance(RR_JABU_JABUS_BELLY_BLUE_TENTACLE, {[]{return logic->JabuWestTentacle;}}), + Entrance(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, {[]{return logic->JabuEastTentacle;}}), + Entrance(RR_JABU_JABUS_BELLY_BIGOCTO_LEDGE, {[]{return logic->JabuNorthTentacle;}}), + Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, {[]{return logic->LoweredJabuPath || (ctx->GetTrickOption(RT_JABU_BOSS_HOVER) && logic->CanUse(RG_HOVER_BOOTS));}}), + }); - areaTable[RR_JABU_JABUS_BELLY_MAIN_UPPER] = Region("Jabu Jabus Belly Main Upper", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, { - //Exits - Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), - 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[RR_JABU_JABUS_BELLY_MAIN_LOWER] = Region("Jabu Jabus Belly Main Lower", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { +//contains B1 of hole room (aside from the ledge leading to big octo), 2 octorock room and north water switch room + areaTable[RR_JABU_JABUS_BELLY_B1_NORTH] = Region("Jabu Jabus Belly B1 North", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->JabuRutoIn1F, {[]{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}}), + EventAccess(&logic->FairyPot, {[]{return logic->CanUse(RG_BOOMERANG) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_OCTOROK));}}), + }, { //Locations LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, logic->HookshotOrBoomerang()), LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, logic->HookshotOrBoomerang()), - }, { + LOCATION(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, logic->HookshotOrBoomerang()), + LOCATION(RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, (logic->CanBreakPots() && (logic->CanUse(RG_BOOMERANG) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_OCTOROK, ED_BOOMERANG, false))))), + LOCATION(RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, (logic->CanBreakPots() && (logic->CanUse(RG_BOOMERANG) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_OCTOROK, ED_BOOMERANG, false))))), + LOCATION(RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, (logic->CanBreakPots() && (logic->CanUse(RG_BOOMERANG) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_OCTOROK, ED_BOOMERANG, false))))), + LOCATION(RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, (logic->CanBreakPots() && (logic->CanUse(RG_BOOMERANG) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_OCTOROK, ED_BOOMERANG, false))))), + LOCATION(RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, (logic->CanBreakPots() && (logic->CanUse(RG_BOOMERANG) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_OCTOROK, ED_BOOMERANG, false))))), + }, { //Exits - 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;}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN, {[]{return true;}}), + //there's tricks for getting here with bunny-jumps or just side-hops + Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->HasItem(RG_HOVER_BOOTS);}}), + Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_SOUTH, {[]{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}}), }); - areaTable[RR_JABU_JABUS_BELLY_SHABOMB_CORRIDOR] = Region("Jabu Jabus Belly Shabomb Corridor", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE] = Region("Jabu Jabus Belly Water Switch Room Ledge", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, true), + //this is the logic for climbing back and forth to use the pots to kill the skull... + LOCATION(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, logic->HasItem(RG_BRONZE_SCALE) || + (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || + //or killing the skull before climbing to grab the token + logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)), + LOCATION(RC_JABU_JABUS_BELLY_BASEMENT_POT_1, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_BASEMENT_POT_2, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_BASEMENT_POT_3, logic->CanBreakPots()), }, { //Exits - 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();}}), + Entrance(RR_JABU_JABUS_BELLY_B1_NORTH, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_SOUTH, {[]{return true;}}), }); - areaTable[RR_JABU_JABUS_BELLY_LOWER_SIDE_ROOM] = Region("Jabu Jabus Belly Lower Side Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { - //Events - EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_HOVER_BOOTS));}}), - }, {}, { - //Exits - Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), - }); - - areaTable[RR_JABU_JABUS_BELLY_LIFT_LOWER] = Region("Jabu Jabus Belly Lift Lower", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_SOUTH] = Region("Jabu Jabus Belly Water Switch Room South", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_DEKU_SCRUB, logic->HasItem(RG_BRONZE_SCALE) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || ctx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE) || logic->CanUse(RG_IRON_BOOTS)) && logic->CanStunDeku()), + LOCATION(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, logic->HookshotOrBoomerang()), }, { //Exits - Entrance(RR_JABU_JABUS_BELLY_SHABOMB_CORRIDOR, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), - }); - - areaTable[RR_JABU_JABUS_BELLY_FORKED_CORRIDOR] = Region("Jabu Jabus Belly Forked Corridor", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, { - //Exits - Entrance(RR_JABU_JABUS_BELLY_MAIN_UPPER, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_BOOMERANG_ROOM, {[]{return true;}}), - 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[RR_JABU_JABUS_BELLY_BOOMERANG_ROOM] = Region("Jabu Jabus Belly Boomerang Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, true), - }, { - //Exits - Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), - }); - - areaTable[RR_JABU_JABUS_BELLY_MAP_ROOM] = Region("Jabu Jabus Belly Map Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_JABU_JABUS_BELLY_MAP_CHEST, logic->CanUse(RG_BOOMERANG)), - }, { - //Exits - Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_B1_NORTH, {[]{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}}), + Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->HasItem(RG_HOVER_BOOTS);}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN, {[]{return logic->CanUseProjectile();}}), }); areaTable[RR_JABU_JABUS_BELLY_COMPASS_ROOM] = Region("Jabu Jabus Belly Compass Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanAttack()), + //ruto could theoretically clear this room, but it's hard because of the timer and she doesn't appear with you when you respawn after failing, which would force a savewarp + LOCATION(RC_JABU_JABUS_BELLY_COMPASS_CHEST, logic->CanKillEnemy(RE_SHABOM)), }, { //Exits - Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN, {[]{return Here(RR_JABU_JABUS_BELLY_COMPASS_ROOM, []{return logic->CanKillEnemy(RE_SHABOM);});}}), }); - areaTable[RR_JABU_JABUS_BELLY_BLUE_TENTACLE] = Region("Jabu Jabus Belly Blue Tentacle", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_BLUE_TENTACLE] = Region("Jabu Jabus Belly Blue Tentacle", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + EventAccess(&logic->JabuEastTentacle, {[]{return logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}}), + }, {}, { //Exits - Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return Here(RR_JABU_JABUS_BELLY_BLUE_TENTACLE, []{return logic->CanUse(RG_BOOMERANG);});}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN, {[]{return logic->JabuEastTentacle;}}), }); - areaTable[RR_JABU_JABUS_BELLY_GREEN_TENTACLE] = Region("Jabu Jabus Belly Green Tentacle", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_GREEN_TENTACLE] = Region("Jabu Jabus Belly Green Tentacle", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + EventAccess(&logic->JabuNorthTentacle, {[]{return logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}}), + }, {}, { //Exits - Entrance(RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, {[]{return Here(RR_JABU_JABUS_BELLY_GREEN_TENTACLE, []{return logic->CanUse(RG_BOOMERANG);});}}), + //implied logic->CanKillEnemy(RE_BARI) + Entrance(RR_JABU_JABUS_BELLY_MAIN, {[]{return logic->JabuNorthTentacle;}}), }); - areaTable[RR_JABU_JABUS_BELLY_BIGOCTO_ROOM] = Region("Jabu Jabus Belly Bigocto Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_BIGOCTO_LEDGE] = Region("Jabu Jabus Belly Bigocto Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //Only adult can get the token without assistance + LOCATION(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)), + //You can get the LOWER skull token from here as aduly with hovers backwalk and a backflip, but it's trickworthy and not relevant unless you can beat tentacles without rang + }, { //Exits - Entrance(RR_JABU_JABUS_BELLY_MAIN_LOWER, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO, {[]{return Here(RR_JABU_JABUS_BELLY_BIGOCTO_ROOM, []{return (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_NUTS)) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_STICKS));});}}), + Entrance(RR_JABU_JABUS_BELLY_B1_NORTH, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO, {[]{return logic->JabuRutoIn1F && Here(RR_JABU_JABUS_BELLY_BIGOCTO_LEDGE, []{return logic->CanKillEnemy(RE_BIG_OCTO);});}}), }); areaTable[RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO] = Region("Jabu Jabus Belly Above Bigocto", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), EventAccess(&logic->NutPot, {[]{return true;}}), - }, {}, { + }, { + //Locations + LOCATION(RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, logic->CanBreakPots()), + }, { //Exits Entrance(RR_JABU_JABUS_BELLY_LIFT_UPPER, {[]{return logic->CanUse(RG_BOOMERANG);}}), }); - areaTable[RR_JABU_JABUS_BELLY_LIFT_UPPER] = Region("Jabu Jabus Belly Lift Upper", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_JABU_JABUS_BELLY_LIFT_UPPER] = Region("Jabu Jabus Belly Lift Upper", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->LoweredJabuPath, {[]{return true;}}), + }, {}, { //Exits - Entrance(RR_JABU_JABUS_BELLY_LIFT_MIDDLE, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_LIFT_LOWER, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN, {[]{return true;}}), }); areaTable[RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM] = Region("Jabu Jabus Belly Near Boss Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, logic->CanAttack()), + LOCATION(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW)), }, { //Exits - 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))));}}), + Entrance(RR_JABU_JABUS_BELLY_MAIN, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT))) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_EXPLOSIVES) && (logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_BOMB_BAG))));}}), }); } @@ -166,54 +176,165 @@ void RegionTable_Init_JabuJabusBelly() { }, { //Locations 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)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), }, { //Exits 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);});}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, {[]{return Here(RR_JABU_JABUS_BELLY_MQ_BEGINNING, []{return logic->CanUse(RG_FAIRY_SLINGSHOT);});}}), }); - areaTable[RR_JABU_JABUS_BELLY_MQ_MAIN] = Region("Jabu Jabus Belly MQ Main", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM] = Region("Jabu Jabus Belly MQ Lift Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->MQJabuLiftRoomCow, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT);}}), + }, { + //Locations + LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, true), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, logic->CanUse(RG_IRON_BOOTS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, logic->CanUse(RG_IRON_BOOTS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, logic->CanUse(RG_IRON_BOOTS)), + }, { + //Exits + Entrance(RR_JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_UNDERWATER_ALCOVE, {[]{return logic->HasItem(RG_SILVER_SCALE) || (logic->HasItem(RG_BRONZE_SCALE) && ((logic->IsChild || logic->CanUse(RG_IRON_BOOTS) || ctx->GetTrickOption(RT_JABU_ALCOVE_JUMP_DIVE))));}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, {[]{return logic->MQJabuHolesRoomDoor;}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM_EAST_LEDGE, {[]{return logic->LoweredJabuPath || logic->CanUse(RG_HOVER_BOOTS) || (logic->CanUse(RG_HOOKSHOT) && logic->MQJabuLiftRoomCow);}}), + //If opening RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM by lowering the geyser as 1 age is to let the other through is relevant, it needs an eventAccess + }); + + areaTable[RR_JABU_JABUS_BELLY_MQ_UNDERWATER_ALCOVE] = Region("Jabu Jabus Belly MQ Underwater Alcove", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->MQJabuHolesRoomDoor, {[]{return true;}}), + }, { + //Locations + LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, logic->CanHitSwitch(ED_HOOKSHOT, true) || (ctx->GetTrickOption(RT_JABU_MQ_RANG_JUMP) && logic->CanUse(RG_BOOMERANG) && logic->HasItem(RG_BRONZE_SCALE))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, logic->CanBreakPots()), + //Getting the ones closest to the ledge with rang may be a trick due to the awkward angle without blind shooting through the flesh + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, logic->HasItem(RG_GOLDEN_SCALE) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_BOOMERANG)), + }, { + //Exits + Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, {[]{return logic->HasItem(RG_BRONZE_SCALE);}}), + }); + + areaTable[RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM] = Region("Jabu Jabus Belly MQ Holes Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_LOWER_CHEST, true), - LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))) || ChildCanAccess(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_COMPASS_CHEST, (logic->IsChild || logic->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(RR_JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_MQ_DEPTHS, {[]{return logic->HasExplosives() && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanUse(RG_BOOMERANG);}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, {[]{return logic->CanUse(RG_BOOMERANG) && logic->HasExplosives() && Here(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->CanUse(RG_FAIRY_SLINGSHOT);});}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_INVISIBLE_KEESE_ROOM, {[]{return logic->JabuNorthTentacle;}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_PAST_OCTO, {[]{return logic->JabuWestTentacle && Here(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, []{return logic->CanKillEnemy(RE_BIG_OCTO);}) && logic->CanUse(RG_FAIRY_SLINGSHOT);}}), }); - areaTable[RR_JABU_JABUS_BELLY_MQ_DEPTHS] = Region("Jabu Jabus Belly MQ Depths", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM] = Region("Jabu Jabus Belly MQ Water Switch Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, true), - LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, logic->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);})), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_ROOM_SMALL_CHEST, true), + //Implies logic->CanKillEnemy(RE_LIKE_LIKE) && logic->CanKillEnemy(RE_STINGER). Without swim, jump from the song of time block to the vines. + LOCATION(RC_JABU_JABUS_BELLY_MQ_BOOMERANG_CHEST, logic->CanKillEnemy(RE_LIZALFOS)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, (logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)) || (ctx->GetTrickOption(RT_JABU_MQ_SOT_GS) && logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, {[]{return logic->CanUse(RG_STICKS) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_KOKIRI_SWORD));}}), + //without swim, jump from rang chest to the other side + Entrance(RR_JABU_JABUS_BELLY_MQ_BEGINNING, {[]{return Here(RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, {[]{return (logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE)) && Here(RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM, []{return logic->CanKillEnemy(RE_LIZALFOS);});}}), }); - 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, { + //Includes Like Like room + areaTable[RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR] = Region("Jabu Jabus Belly MQ Forked Corridor", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->JabuNorthTentacle, {[]{return Here(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, []{return logic->BlastOrSmash();}) && logic->CanUse(RG_BOOMERANG);}}), + }, { + //Locations + //Implies CanKillEnemy(RE_LIKE_LIKE) + LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_ROOM_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, {[]{return logic->CanUse(RG_BOOMERANG);}}), + //If some mode lets an age use sticks and not sling, and other use sling and not sticks, this needs changing + Entrance(RR_JABU_JABUS_BELLY_MQ_WEST_FORKED_ROOMS, {[]{return Here(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, []{return logic->CanUse(RG_BOOMERANG);}) && + (Here(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanUse(RG_STICKS);}) || + Here(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, []{return logic->HasFireSource();}));}}), + }); + + areaTable[RR_JABU_JABUS_BELLY_MQ_WEST_FORKED_ROOMS] = Region("Jabu Jabus Belly MQ West Forked Rooms", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->JabuWestTentacle, {[]{return logic->CanUse(RG_BOOMERANG);}}), + }, { + //Locations + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, Here(RR_JABU_JABUS_BELLY_MQ_WEST_FORKED_ROOMS, []{return logic->HasExplosives();}) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + }, { + //Exits + Entrance(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, {[]{return true;}}), + }); + + areaTable[RR_JABU_JABUS_BELLY_MQ_INVISIBLE_KEESE_ROOM] = Region("Jabu Jabus Belly MQ Invisible Keese Room", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, //firstly, we can just use FAs to clear the web and then longshot the skull + logic->CanUse(RG_FIRE_ARROWS) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_LONGSHOT) || + //Otherwise, we we have to cross the gap and kill the skull. + (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) && + //We can cheese the gap with hovers + ((logic->CanUse(RG_HOVER_BOOTS) || + //Otherwise we have to kill the enemies to raise the platform. This persists so we can do it as the other age. + Here(RR_JABU_JABUS_BELLY_MQ_INVISIBLE_KEESE_ROOM, []{return (ctx->GetTrickOption(RT_LENS_JABU_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && + logic->CanKillEnemy(RE_STINGER, ED_BOOMERANG, false, 2, false, true) && + //we can hit the keese farthest from the water with irons and hookshot, but we won't be able to see it while doing so + (logic->CanKillEnemy(RE_KEESE, ED_LONGSHOT, false) || (ctx->GetTrickOption(RT_LENS_JABU_MQ) && logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)));})) + //If we kill the enemies, we then need to cross the water using the platform. Note that adult cannot do so while swimming because MQ jank. + && ((logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && logic->CanUse(RG_IRON_BOOTS)))))), + }, { + //Exits + Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, {[]{return (logic->JabuNorthTentacle || logic->TakeDamage()) && logic->HasItem(RG_BRONZE_SCALE);}}), + }); + + areaTable[RR_JABU_JABUS_BELLY_MQ_PAST_OCTO] = Region("Jabu Jabus Belly MQ Past Octo", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { + //Events + //if a hover up to the path is added, this will want it's own room + EventAccess(&logic->LoweredJabuPath, {[]{return logic->CanUse(RG_BOOMERANG) && logic->CanUse(RG_FAIRY_SLINGSHOT);}}), + }, { + //Locations + LOCATION(RC_JABU_JABUS_BELLY_MQ_COW, logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_FAIRY_SLINGSHOT)), + }, { + //Exits + Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, {[]{return logic->CanUse(RG_BOOMERANG) && logic->CanUse(RG_FAIRY_SLINGSHOT);}}), + //you take both fall damage and tentacle damage, unless the tentacle is down. need better damage logic + Entrance(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, {[]{return logic->TakeDamage() && Here(RR_JABU_JABUS_BELLY_MQ_PAST_OCTO, []{return logic->CanKillEnemy(RE_BIG_OCTO);});}}), + }); + + areaTable[RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM_EAST_LEDGE] = Region("Jabu Jabus Belly MQ Lift Room East Ledge", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_JABU_JABUS_BELLY_MQ_SECOND_ROOM_UPPER_CHEST, logic->MQJabuLiftRoomCow), + }, { + //Exits + Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_EAST_ROOM, {[]{return logic->JabuNorthTentacle;}}), + }); + + areaTable[RR_JABU_JABUS_BELLY_MQ_EAST_ROOM] = Region("Jabu Jabus Belly MQ Boss Region", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_JABU_JABUS_BELLY_MQ_COW, logic->CanUse(RG_EPONAS_SONG)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_NEAR_BOSS_CHEST, logic->CanUse(RG_FAIRY_SLINGSHOT)), - LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, logic->CanUse(RG_BOOMERANG) || (ctx->GetTrickOption(RT_JABU_NEAR_BOSS_RANGED) && logic->CanUse(RG_HOOKSHOT))), + 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))), + LOCATION(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, logic->CanBreakPots()), }, { //Exits - Entrance(RR_JABU_JABUS_BELLY_MQ_MAIN, {[]{return true;}}), - Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return logic->CanUse(RG_FAIRY_SLINGSHOT);}}), + Entrance(RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM_EAST_LEDGE, {[]{return true;}}), + Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, {[]{return Here(RR_JABU_JABUS_BELLY_MQ_EAST_ROOM, []{return logic->CanUse(RG_FAIRY_SLINGSHOT);});}}), }); } @@ -225,7 +346,7 @@ void RegionTable_Init_JabuJabusBelly() { { // Exits 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_MQ_EAST_ROOM, { [] { return ctx->GetDungeon(JABU_JABUS_BELLY)->IsMQ(); } }), Entrance(RR_JABU_JABUS_BELLY_BOSS_ROOM, { [] { return true; } }), }); @@ -238,6 +359,12 @@ void RegionTable_Init_JabuJabusBelly() { }, { // Locations + LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_1, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_2, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_3, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_4, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_5, logic->CanBreakPots()), + LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_6, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_BARINADE_HEART, logic->JabuJabusBellyClear), LOCATION(RC_BARINADE, logic->JabuJabusBellyClear), }, @@ -246,4 +373,5 @@ void RegionTable_Init_JabuJabusBelly() { 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 a596b1808..8d1b2a35a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_kakariko.cpp @@ -7,35 +7,49 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAKARIKO_VILLAGE] = Region("Kakariko Village", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, { //Events 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)));}}), + //Open Gate setting is applies in RR_ROOT + EventAccess(&logic->KakarikoVillageGateOpen, {[]{return logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER);}}), }, { //Locations LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION)), LOCATION(RC_KAK_ANJU_AS_CHILD, logic->IsChild && logic->AtDay), LOCATION(RC_KAK_ANJU_AS_ADULT, logic->IsAdult && logic->AtDay), LOCATION(RC_KAK_TRADE_POCKET_CUCCO, logic->IsAdult && logic->AtDay && (logic->CanUse(RG_POCKET_EGG) && logic->WakeUpAdultTalon)), - LOCATION(RC_KAK_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->CanJumpslashExceptHammer())) && logic->AtNight && logic->CanGetNightTimeGS()), + //Can kill lower kak skulls with pots + LOCATION(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, logic->IsChild && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_SKULLTULA_HOUSE, logic->IsChild && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_GUARDS_HOUSE, logic->IsChild && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_TREE, logic->IsChild && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), + LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_KAK_NEAR_POTION_SHOP_POT_3, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_KAK_NEAR_IMPAS_HOUSE_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_KAK_NEAR_IMPAS_HOUSE_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_KAK_NEAR_IMPAS_HOUSE_POT_3, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_KAK_NEAR_GUARDS_HOUSE_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_KAK_NEAR_GUARDS_HOUSE_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_KAK_NEAR_GUARDS_HOUSE_POT_3, logic->IsChild && logic->CanBreakPots()), }, { //Exits - 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);}}), + 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_KAK_WELL, {[]{return logic->IsAdult || logic->DrainWell || logic->CanUse(RG_IRON_BOOTS);}}), + 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->IsAdult && ctx->GetTrickOption(RT_VISIBLE_COLLISION));}}), + Entrance(RR_KAK_WATCHTOWER, {[]{return logic->IsAdult || logic->AtDay || logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer());}}), + Entrance(RR_KAK_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && logic->IsAdult);}}), + Entrance(RR_KAK_IMPAS_ROOFTOP, {[]{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_KAK_ROOFTOP_GS) && logic->CanUse(RG_HOVER_BOOTS));}}), + Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), + Entrance(RR_KAK_BEHIND_GATE, {[]{return logic->IsAdult || logic->KakarikoVillageGateOpen;}}), + //adult can jump from the fence near the windmill to ledgegrab the fence near granny's shop. is in logic on N64 + Entrance(RR_KAK_BACKYARD, {[]{return logic->IsAdult || logic->AtDay;}}), }); areaTable[RR_KAK_IMPAS_LEDGE] = Region("Kak Impas Ledge", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, {}, { @@ -46,26 +60,42 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_IMPAS_ROOFTOP] = Region("Kak Impas Rooftop", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_KAK_GS_ABOVE_IMPAS_HOUSE, logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS() && (logic->CanJumpslashExceptHammer() || logic->CanUseProjectile())), + LOCATION(RC_KAK_GS_ABOVE_IMPAS_HOUSE, logic->IsAdult && logic->CanGetNightTimeGS() && logic->CanKillEnemy(RE_GOLD_SKULLTULA)), }, { //Exits Entrance(RR_KAK_IMPAS_LEDGE, {[]{return true;}}), Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); + areaTable[RR_KAK_WATCHTOWER] = Region("Kak Watchtower", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //exists for when age change is in logic. + LOCATION(RC_KAK_GS_WATCHTOWER, logic->IsChild && logic->CanUse(RG_DINS_FIRE) && logic->CanGetNightTimeGS()), + }, { + //Exits + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), + Entrance(RR_KAK_ROOFTOP, {[]{return ctx->GetTrickOption(RT_KAK_MAN_ON_ROOF) && logic->IsChild;}}), + }); + areaTable[RR_KAK_ROOFTOP] = Region("Kak Rooftop", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KAK_MAN_ON_ROOF, true), }, { //Exits - Entrance(RR_KAK_BACKYARD, {[]{return true;}}), + Entrance(RR_KAK_BACKYARD, {[]{return true;}}), + Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), }); - areaTable[RR_KAK_BACKYARD] = Region("Kak Backyard", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KAK_BACKYARD] = Region("Kak Backyard", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //There's probably a trick to get these with rang from the main region + LOCATION(RC_KAK_NEAR_MEDICINE_SHOP_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_KAK_NEAR_MEDICINE_SHOP_POT_2, logic->IsChild && logic->CanBreakPots()), + }, { //Exits 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_ODD_POTION_BUILDING, {[]{return logic->IsAdult;}}), Entrance(RR_KAK_POTION_SHOP_BACK, {[]{return logic->IsAdult && logic->AtDay;}}), }); @@ -79,11 +109,11 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_HOUSE_OF_SKULLTULA] = Region("Kak House of Skulltula", "Kak House of Skulltula", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - 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_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 @@ -113,7 +143,6 @@ void RegionTable_Init_Kakariko() { }, { //Locations LOCATION(RC_KAK_WINDMILL_FREESTANDING_POH, logic->CanUse(RG_BOOMERANG) || logic->DampesWindmillAccess || (logic->IsAdult && ctx->GetTrickOption(RT_KAK_ADULT_WINDMILL_POH)) || (logic->IsChild && logic->CanJumpslashExceptHammer() && ctx->GetTrickOption(RT_KAK_CHILD_WINDMILL_POH))), - //PoH as child not added to trick options yet (needs uncommenting in randomizer_tricks.cpp) LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA)), }, { //Exits @@ -179,7 +208,7 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_REDEAD_GROTTO] = Region("Kak Redead Grotto", "Kak Redead Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_KAK_REDEAD_GROTTO_CHEST, logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)), + LOCATION(RC_KAK_REDEAD_GROTTO_CHEST, logic->CanKillEnemy(RE_REDEAD)), }, { //Exits Entrance(RR_KAKARIKO_VILLAGE, {[]{return true;}}), @@ -187,27 +216,44 @@ void RegionTable_Init_Kakariko() { areaTable[RR_KAK_OPEN_GROTTO] = Region("Kak Open Grotto", "Kak Open Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LOCATION(RC_KAK_OPEN_GROTTO_CHEST, true), - LOCATION(RC_KAK_OPEN_GROTTO_FISH, logic->HasBottle()), - LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), - LOCATION(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), + LOCATION(RC_KAK_OPEN_GROTTO_CHEST, true), + LOCATION(RC_KAK_OPEN_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + 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(RR_KAK_BACKYARD, {[]{return true;}}), }); + areaTable[RR_KAK_BEHIND_GATE] = Region("Kak Behind Gate", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_KAKARIKO_VILLAGE, {[]{return logic->IsAdult || ctx->GetTrickOption(RT_VISIBLE_COLLISION) || logic->KakarikoVillageGateOpen;}}), + Entrance(RR_DEATH_MOUNTAIN_TRAIL, {[]{return true;}}), + }); + + areaTable[RR_KAK_WELL] = Region("Kak Behind Gate", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_KAKARIKO_VILLAGE, {[]{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->DrainWell;}}), + Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, {[]{return logic->IsChild || (logic->DrainWell && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF));}}), + }); + areaTable[RR_THE_GRAVEYARD] = Region("The Graveyard", "The Graveyard", {RA_THE_GRAVEYARD}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}), - EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_THE_GRAVEYARD) && logic->CanUse(RG_SONG_OF_STORMS));}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}}), EventAccess(&logic->BugRock, {[]{return true;}}), }, { //Locations LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT) || (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_WALL, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), LOCATION(RC_GRAVEYARD_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()), + LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits Entrance(RR_GRAVEYARD_SHIELD_GRAVE, {[]{return logic->IsAdult || logic->AtNight;}}), @@ -222,7 +268,22 @@ void RegionTable_Init_Kakariko() { areaTable[RR_GRAVEYARD_SHIELD_GRAVE] = Region("Graveyard Shield Grave", "Graveyard Shield Grave", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_CHEST, true), - //Free Fairies + }, { + //Exits + Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), + Entrance(RR_GRAVEYARD_SHIELD_GRAVE_BACK, {[]{return Here(RR_GRAVEYARD_SHIELD_GRAVE, []{return logic->CanBreakMudWalls();});}}), + }); + + areaTable[RR_GRAVEYARD_SHIELD_GRAVE_BACK] = Region("Graveyard Shield Grave Back", "Graveyard Shield Grave", {}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, true), + LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, true), + LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, true), + LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, true), + LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, true), + LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, true), + LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, true), + LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, true), }, { //Exits Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), @@ -253,6 +314,20 @@ void RegionTable_Init_Kakariko() { //Locations LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, true), LOCATION(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, logic->IsAdult || ctx->GetTrickOption(RT_GY_CHILD_DAMPE_RACE_POH)), + LOCATION(RC_GY_DAMPES_GRAVE_POT_1, logic->CanBreakPots()), + LOCATION(RC_GY_DAMPES_GRAVE_POT_2, logic->CanBreakPots()), + LOCATION(RC_GY_DAMPES_GRAVE_POT_3, logic->CanBreakPots()), + LOCATION(RC_GY_DAMPES_GRAVE_POT_4, logic->CanBreakPots()), + LOCATION(RC_GY_DAMPES_GRAVE_POT_5, logic->CanBreakPots()), + LOCATION(RC_GY_DAMPES_GRAVE_POT_6, logic->CanBreakPots()), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_1, true), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_2, true), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_3, true), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_4, true), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_5, true), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_6, true), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_7, true), + LOCATION(RC_GRAVEYARD_DAMPE_RACE_RUPEE_8, true), }, { //Exits Entrance(RR_THE_GRAVEYARD, {[]{return true;}}), @@ -272,16 +347,13 @@ void RegionTable_Init_Kakariko() { EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), }, { //Locations - LOCATION(RC_GRAVEYARD_GOSSIP_STONE, true), + LOCATION(RC_GRAVEYARD_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_GRAVEYARD_GOSSIP_STONE, true), }, { //Exits - 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));}}), + 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[RR_KAK_BEHIND_GATE] = Region("Kak Behind Gate", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, {}, { - //Exits - Entrance(RR_KAKARIKO_VILLAGE, {[]{return logic->IsAdult || 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 85e3c8c49..e81e03505 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 @@ -6,16 +6,39 @@ using namespace Rando; void RegionTable_Init_LostWoods() { areaTable[RR_KOKIRI_FOREST] = Region("Kokiri Forest", "Kokiri Forest", {RA_KOKIRI_FOREST}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_KOKIRI_FOREST) && logic->CanUse(RG_SONG_OF_STORMS));}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}}), EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}), }, { //Locations - LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild), - LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->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), + LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild), + LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && (/*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->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_KF_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_BRIDGE_RUPEE, logic->IsChild), + LOCATION(RC_KF_BEHIND_MIDOS_RUPEE, logic->IsChild), + LOCATION(RC_KF_SOUTH_GRASS_WEST_RUPEE, logic->IsChild), + LOCATION(RC_KF_SOUTH_GRASS_EAST_RUPEE, logic->IsChild), + LOCATION(RC_KF_NORTH_GRASS_WEST_RUPEE, logic->IsChild), + LOCATION(RC_KF_NORTH_GRASS_EAST_RUPEE, logic->IsChild), + LOCATION(RC_KF_BOULDER_RUPEE_1, logic->IsChild), + LOCATION(RC_KF_BOULDER_RUPEE_2, logic->IsChild), + LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_SARIAS_ROOF_WEST_HEART, logic->IsChild), + LOCATION(RC_KF_SARIAS_ROOF_EAST_HEART, logic->IsChild), + LOCATION(RC_KF_SARIAS_ROOF_NORTH_HEART, logic->IsChild), + LOCATION(RC_KF_GOSSIP_STONE, true), }, { //Exits Entrance(RR_KF_LINKS_HOUSE, {[]{return true;}}), @@ -24,30 +47,35 @@ void RegionTable_Init_LostWoods() { Entrance(RR_KF_HOUSE_OF_TWINS, {[]{return true;}}), Entrance(RR_KF_KNOW_IT_ALL_HOUSE, {[]{return true;}}), Entrance(RR_KF_KOKIRI_SHOP, {[]{return true;}}), - Entrance(RR_KF_OUTSIDE_DEKU_TREE, {[]{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_FOREST_OPEN) || logic->ShowedMidoSwordAndShield;}}), + Entrance(RR_KF_OUTSIDE_DEKU_TREE, {[]{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || 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_LW_BRIDGE_FROM_FOREST, {[]{return logic->IsAdult || ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || 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(&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->CanJumpslashExceptHammer() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE))));}}), + EventAccess(&logic->DekuBabaSticks, {[]{return logic->CanKillEnemy(RE_WITHERED_DEKU_BABA);}}), + EventAccess(&logic->DekuBabaNuts, {[]{return logic->CanGetDekuBabaNuts();}}), EventAccess(&logic->ShowedMidoSwordAndShield, {[]{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}}), }, { //Locations - LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, true), - LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, true), + LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, true), + LOCATION(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, true), }, { //Exits - Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return logic->IsChild || (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;}}), + Entrance(RR_DEKU_TREE_ENTRYWAY, {[]{return logic->IsChild || (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) && (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield));}}), + Entrance(RR_KOKIRI_FOREST, {[]{return (logic->IsAdult && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || logic->ForestTempleClear)) || ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_OFF) || logic->ShowedMidoSwordAndShield;}}), }); areaTable[RR_KF_LINKS_HOUSE] = Region("KF Link's House", "KF Link's House", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_KF_LINKS_HOUSE_COW, logic->IsAdult && logic->CanUse(RG_EPONAS_SONG) && logic->LinksCow), + LOCATION(RC_KF_LINKS_HOUSE_POT, logic->CanBreakPots()), }, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}) @@ -64,17 +92,31 @@ void RegionTable_Init_LostWoods() { Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[RR_KF_SARIAS_HOUSE] = Region("KF Saria's House", "KF Saria's House", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KF_SARIAS_HOUSE] = Region("KF Saria's House", "KF Saria's House", {}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_KF_SARIAS_TOP_LEFT_HEART, true), + LOCATION(RC_KF_SARIAS_TOP_RIGHT_HEART, true), + LOCATION(RC_KF_SARIAS_BOTTOM_LEFT_HEART, true), + LOCATION(RC_KF_SARIAS_BOTTOM_RIGHT_HEART, true), + }, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[RR_KF_HOUSE_OF_TWINS] = Region("KF House of Twins", "KF House of Twins", {}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_KF_HOUSE_OF_TWINS] = Region("KF House of Twins", "KF House of Twins", {}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_KF_TWINS_HOUSE_POT_1, logic->CanBreakPots()), + LOCATION(RC_KF_TWINS_HOUSE_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); - areaTable[RR_KF_KNOW_IT_ALL_HOUSE] = Region("KF Know It All House", "KF Know It All House", {}, 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, {}, { + // Locations + LOCATION(RC_KF_BROTHERS_HOUSE_POT_1, logic->CanBreakPots()), + LOCATION(RC_KF_BROTHERS_HOUSE_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_KOKIRI_FOREST, {[]{return true;}}), }); @@ -98,6 +140,8 @@ void RegionTable_Init_LostWoods() { //Locations LOCATION(RC_KF_STORMS_GROTTO_CHEST, true), LOCATION(RC_KF_STORMS_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), 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()), @@ -114,14 +158,14 @@ void RegionTable_Init_LostWoods() { areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", "Lost Woods", {RA_THE_LOST_WOODS}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), - EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || logic->CanUse(RG_SONG_OF_STORMS);}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}}), EventAccess(&logic->BugShrub, {[]{return logic->IsChild && logic->CanCutShrubs();}}), }, { //Locations - LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)), - LOCATION(RC_LW_TRADE_COJIRO, logic->IsAdult && logic->CanUse(RG_COJIRO)), + 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)), + 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: @@ -130,11 +174,26 @@ void RegionTable_Init_LostWoods() { //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), + 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()), + //RANDOTODO handle collecting some of these as you leave the shortcut from the other side + LOCATION(RC_LW_SHORTCUT_RUPEE_1, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_2, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_3, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_4, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_5, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_6, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_7, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_SHORTCUT_RUPEE_8, logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_LW_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_SHORTCUT_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_GOSSIP_STONE, true), }, { //Exits Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}), @@ -152,8 +211,12 @@ void RegionTable_Init_LostWoods() { //Locations LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku()), LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, logic->IsChild && logic->CanStunDeku()), - LOCATION(RC_LW_GS_ABOVE_THEATER, logic->IsAdult && logic->AtNight && ((CanPlantBean(RR_LW_BEYOND_MIDO) && logic->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_ABOVE_THEATER, logic->IsAdult && ((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()))), + LOCATION(RC_LW_BOULDER_RUPEE, logic->BlastOrSmash()), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, logic->IsChild && logic->HasItem(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits Entrance(RR_LW_FOREST_EXIT, {[]{return true;}}), @@ -165,11 +228,13 @@ void RegionTable_Init_LostWoods() { areaTable[RR_LW_NEAR_SHORTCUTS_GROTTO] = Region("LW Near Shortcuts Grotto", "LW Near Shortcuts Grotto", {}, NO_DAY_NIGHT_CYCLE, grottoEvents, { //Locations - LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, true), - LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, logic->HasBottle()), - LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, true), - LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, logic->CanBreakLowerBeehives()), - LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, logic->CanBreakLowerBeehives()), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, true), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + 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(RR_THE_LOST_WOODS, {[]{return true;}}), @@ -206,12 +271,18 @@ void RegionTable_Init_LostWoods() { EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairyExceptSuns();}}), }, { //Locations - 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), + 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->CanGetNightTimeGS()), + LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + 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(RR_SFM_ENTRYWAY, {[]{return true;}}), @@ -223,14 +294,24 @@ void RegionTable_Init_LostWoods() { areaTable[RR_SFM_FAIRY_GROTTO] = Region("SFM Fairy Grotto", "SFM Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FreeFairies, {[]{return true;}}), - }, {}, { + }, { + //Locations + LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_1, true), + LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_2, true), + LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_3, true), + LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_4, true), + LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_5, true), + LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_6, true), + LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_7, true), + LOCATION(RC_SFM_FAIRY_GROTTO_FAIRY_8, true), + }, { //Exits Entrance(RR_SACRED_FOREST_MEADOW, {[]{return true;}}), }); areaTable[RR_SFM_WOLFOS_GROTTO] = Region("SFM Wolfos Grotto", "SFM Wolfos Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - 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? + LOCATION(RC_SFM_WOLFOS_GROTTO_CHEST, logic->CanKillEnemy(RE_WOLFOS, ED_CLOSE, true, 2)), }, { //Exits Entrance(RR_SFM_ENTRYWAY, {[]{return true;}}), diff --git a/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp b/soh/soh/Enhancements/randomizer/3drando/location_access/locacc_shadow_temple.cpp index b2dd0febb..6a6f20e15 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 @@ -11,7 +11,7 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_ENTRYWAY] = Region("Shadow Temple Entryway", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits Entrance(RR_SHADOW_TEMPLE_BEGINNING, {[]{return 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_SHADOW_TEMPLE_MQ_BEGINNING, {[]{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ();}}), Entrance(RR_GRAVEYARD_WARP_PAD_REGION, {[]{return true;}}), }); @@ -24,8 +24,16 @@ void RegionTable_Init_ShadowTemple() { EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))), + LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST, logic->CanJumpslashExceptHammer()), + LOCATION(RC_SHADOW_TEMPLE_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND)), + LOCATION(RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, logic->CanBreakPots()), }, { //Exits Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}), @@ -40,6 +48,7 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_COMPASS_CHEST, logic->CanJumpslashExceptHammer()), 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), + LOCATION(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_HUGE_PIT, {[]{return logic->HasExplosives() && logic->IsAdult && logic->SmallKeys(RR_SHADOW_TEMPLE, 1, 2);}}), @@ -58,6 +67,14 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, logic->CanJumpslashExceptHammer()), LOCATION(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS))), LOCATION(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, logic->SmallKeys(RR_SHADOW_TEMPLE, 2, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, logic->CanBreakPots() && (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)), + //We cannot repeat the MQ invisible blades trick for these hearts as the like-like does not respawn if the room is cleared + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_WIND_TUNNEL, {[]{return ((ctx->GetTrickOption(RT_LENS_SHADOW_PLATFORM) && ctx->GetTrickOption(RT_LENS_SHADOW)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3, 4);}}), @@ -69,6 +86,11 @@ void RegionTable_Init_ShadowTemple() { LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslashExceptHammer()), 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)), + LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), + LOCATION(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)), }, { //Exits Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, {[]{return logic->CanJumpslashExceptHammer() && logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5);}}), @@ -76,11 +98,21 @@ void RegionTable_Init_ShadowTemple() { areaTable[RR_SHADOW_TEMPLE_BEYOND_BOAT] = Region("Shadow Temple Beyond Boat", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)), - LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanJumpslashExceptHammer()), + 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->CanJumpslashExceptHammer()), //RANDOTODO check if child can reach the token - LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->IsAdult && logic->CanAttack()), + LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->IsAdult && logic->CanAttack()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, logic->CanBreakPots() && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5)))), + LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, logic->CanBreakPots() && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5)))), + LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanUse(RG_HOVER_BOOTS))), }, { //Exits Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}) @@ -94,88 +126,273 @@ void RegionTable_Init_ShadowTemple() { //RANDOTODO doublecheck CanAttack when rewriting, as I assumed it only checked adult due to the entrance areaTable[RR_SHADOW_TEMPLE_MQ_BEGINNING] = Region("Shadow Temple MQ Beginning", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || logic->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);}}), + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, {[]{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}}), }); + areaTable[RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM] = Region("Shadow Temple MQ Spinner Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}) && + (logic->CanUse(RG_HOVER_BOOTS) || Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_FIRE_ARROWS);}) || (ctx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslashExceptHammer()));}}), + Entrance(RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, {[]{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->HasExplosives();}) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}), + }); + +//Assumes we're in the "main" area and needed lens to enter. logic will need changes if a void warp puts us somewhere weird areaTable[RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA] = Region("Shadow Temple MQ Dead Hand Region", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanJumpslashExceptHammer() && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)), - }, {}); - - areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Region("Shadow Temple MQ First Beamos", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanAttack() || logic->CanUse(RG_NUTS)), - LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanJumpslashExceptHammer()), - LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, logic->CanAttack() || logic->CanUse(RG_NUTS)), + LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_REDEAD)), + //There's a shared flag tied to some glass here. eye target here and killing an enemy group later in the dungeon toggles. I'm building the logic as "intended", assuming the switch needs flipping + LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanHitEyeTargets()), + LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, {[]{return true;}}), + }); + +//also includes the B2 gibdo room + areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Region("Shadow Temple MQ First Beamos", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //Doing this sets the shared flag for the glass in RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, but doesn't seem to affect the chest + LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanKillEnemy(RE_GIBDO) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, {[]{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM] = Region("Shadow Temple MQ B2 Spinning Blade Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return Here(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, []{return logic->CanKillEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));});}}), + Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH] = Region("Shadow Temple MQ Shortcut Path", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, {[]{return logic->ShadowShortcutBlock;}}), + //WARNING if there's any way past here to ship without already reaching the other side the key logic in this dungeon becomes Quantum + }); + +//Room exists for if it's ever possible to go backwards or void warp into the middle of shadow + areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR] = Region("Shadow Temple MQ B2 to B3 Corridor", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return true;}}), + //bunnyhovers + lens lets you go from the very top of upper pit to the stationary invisible platform below quite easily }); areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT] = Region("Shadow Temple MQ Upper Huge Pit", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanUse(RG_SONG_OF_TIME) || (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)) + LOCATION(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return (logic->HasFireSource() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))) || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, {[]{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM] = Region("Shadow Temple MQ Invisible Blades Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //RT_SHADOW_MQ_INVISIBLE_BLADES does not work with NL as like-likes will not swallow you, likewise like-likes will not spit you with a fairy revive + //you take half a heart base from a spit out, double check EffectiveHealth when damage logic gets reworked + //Child is too small to get hit by the blades doesn't need the trick or lens for dodging them + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1)) && + (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1)) && + ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE))) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1) || logic->CanUse(RG_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, (logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1) || logic->CanUse(RG_BOOMERANG)), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return logic->HasFireSource() || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}}), - //Trick: logic->HasFireSource() || LogicShadowMQHugePit + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return true;}}), }); areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT] = Region("Shadow Temple MQ Lower Huge Pit", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->IsAdult && logic->CanUse(RG_LONGSHOT)), - LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, (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->CanJumpslashExceptHammer() && 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))), + LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->CanUse(RG_LONGSHOT)), }, { //Exits - 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);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, {[]{return Here(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->CanJumpslash() || logic->HasExplosives();});}}), + Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, {[]{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}}), }); - areaTable[RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL] = Region("Shadow Temple MQ Wind Tunnel", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM] = Region("Shadow Temple MQ Stone Umbrella Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true), + //Assuming the known setup for RT_SHADOW_UMBRELLA and RT_SHADOW_UMBRELLA_GS, probably possible without sword + shield. + //Handling the trick here instead of upper as using the block to climb is not a valid method for getting this skull without other tricks to use the block before it is intended + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || + (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))), + LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, logic->CanUse(RG_BOOMERANG)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return Here(RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) || logic->CanHitSwitch();});}}), + //Assuming the known setup for RT_SHADOW_UMBRELLA, probably possible without sword + shield + Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA, {[]{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD)));}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA] = Region("Shadow Temple MQ Upper Stone Umbrella", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, {[]{return true;}}), + }); + +//while the spikes here are annoying, they don't really stop you doing anything, so I'll assume either lens trick, lens to see them, or taking damage from them. Not hovers though as a new player won't see the threat without lens to react properly + areaTable[RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM] = Region("Shadow Temple MQ Floor Spikes Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events //lens or trick is always required for hookshot targets. We handle it here to not complicate the RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_UPPER_DOOR logic + EventAccess(&logic->MQShadowFloorSpikeRupees, {[]{return (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && + //Upper door side high rupee needs (hookshot and redead kill(as either age) for chest and adult) or longshot. hovers can cross from the left side with a backflip but that would be a trick + //East midair rupee needs (hookshot and(hover boots or jumpslash from the upper door platform)) or longshot. + //Combined these are longshot or (IsAdult && hookshot && (CanJumpslash || (Hover Boots && Here(CanKillRedeads)))) + (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->CanJumpslash() || (logic->CanUse(RG_HOVER_BOOTS) && Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);}))))) && + //1 rupee is in spikes, needs hovers or damage + (logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS));}}), + }, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->TakeDamage() || logic->CanUse(RG_LENS_OF_TRUTH))), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, {[]{return logic->MQShadowFloorSpikeRupees;}}), + //We need to assume we can get here with or without the glass platforms + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && + (logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) && + (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM] = Region("Shadow Temple MQ Stalfos Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, {[]{return Here(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL] = Region("Shadow Temple MQ Wind Tunnel", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT));}}), + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}}), + Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM] = Region("Shadow Temple MQ Wind Hint Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanPassEnemy(RE_REDEAD)), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return true;}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM] = Region("Shadow Temple MQ B4 Gibdo Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, true), - LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslashExceptHammer()), - 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), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO)), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, logic->HasExplosives() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, logic->HasExplosives()), + LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, logic->CanBreakPots()), }, { //Exits - Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}}), + //child can make it using the wind strat + Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return (ctx->GetTrickOption(RT_SHADOW_MQ_WINDY_WALKWAY)) || logic->CanUse(RG_HOVER_BOOTS);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_DOCK] = Region("Shadow Temple MQ Dock", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->ShadowShortcutBlock, {[]{return logic->HasItem(RG_GORONS_BRACELET);}}), + }, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + LOCATION(RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, logic->CanUse(RG_DISTANT_SCARECROW)), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, {[]{return logic->ShadowShortcutBlock;}}), + Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}}), + //funnily enough, the wheel jump seems to be in logic as there's no strength requirement in N64 + Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}}), }); areaTable[RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Region("Shadow Temple MQ Beyond Boat", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, true), - LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))), - }, { + //It's a trick on N64 to kill this and drop down to collect this with normal weapons, as doing so without the statue being dropped voids you to before the boat + //hilariously, you can also hit this with a pot before you bring down the statue, but there's no great way to reset it without crossing. the statues collision is very inconvenient afterwards + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, logic->CanBreakPots()), + }, { //Exits - 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);}}), + Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, {[]{return Here(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5));});}}), }); + areaTable[RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM] = Region("Shadow Temple MQ Across Chasm", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, logic->CanUse(RG_SONG_OF_TIME) && logic->CanHitEyeTargets() && logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, logic->CanUse(RG_SONG_OF_TIME) && logic->CanHitEyeTargets() && logic->CanUse(RG_LONGSHOT)), + //There's invisible floor collision that makes aiming for the heart with rang harder than it should be, so it's a trick. + LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, logic->IsAdult), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return Here(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanDetonateUprightBombFlower();}) && logic->IsAdult;}}), + //assumes RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT by previous access. If backwards shadow ever exists remember that child cannot jump onto the statue from this side and make an event for the switch + //Lens isn't needed to reach it but is needed to navigate the next room + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return Here(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanHitEyeTargets() && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_LONGSHOT);});}}), + Entrance(RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, {[]{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_BOSS_DOOR] = Region("Shadow Temple MQ Boss Door", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //you can drop onto this and the respawn is reasonable + LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER)) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, {[]{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}), + Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}), + }); + + //Assumes lens is checked on entry areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Region("Shadow Temple MQ Invisible Maze", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6)), - LOCATION(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6)), - //below previously returned true - LOCATION(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_SHADOW_MQ_DEADHAND)), - LOCATION(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, true), - }, {}); + LOCATION(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, (logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_SHADOW_MQ_DEADHAND)) && logic->CanKillEnemy(RE_DEAD_HAND) && logic->CanDetonateUprightBombFlower()), + LOCATION(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, true), + LOCATION(RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, logic->CanBreakPots()), + LOCATION(RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return true;}}), + Entrance(RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 6);}}), + }); + + areaTable[RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM] = Region("Shadow Temple MQ Spike Walls Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}),}); } /*--------------------------- 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 dce2ce1f0..6be9bb707 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 @@ -10,16 +10,20 @@ void RegionTable_Init_SpiritTemple() { ---------------------------*/ areaTable[RR_SPIRIT_TEMPLE_ENTRYWAY] = Region("Spirit Temple Entryway", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_SPIRIT_TEMPLE_LOBBY, {[]{return 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;}}), + 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_OUTSIDE_TEMPLE, {[]{return true;}}), }); /*-------------------------- | VANILLA DUNGEON | ---------------------------*/ if (ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla()) { - areaTable[RR_SPIRIT_TEMPLE_LOBBY] = Region("Spirit Temple Lobby", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_SPIRIT_TEMPLE_LOBBY] = Region("Spirit Temple Lobby", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_LOBBY_POT_1, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_LOBBY_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), Entrance(RR_SPIRIT_TEMPLE_CHILD, {[]{return logic->IsChild;}}), @@ -34,6 +38,10 @@ void RegionTable_Init_SpiritTemple() { 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))))), + LOCATION(RC_SPIRIT_TEMPLE_ANUBIS_POT_1, (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_ANUBIS_POT_2, (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_ANUBIS_POT_3, (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_ANUBIS_POT_4, (logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_FAIRY_SLINGSHOT) || (logic->CanUse(RG_BOMBCHU_5) && ctx->GetTrickOption(RT_SPIRIT_CHILD_CHU))) && (logic->HasExplosives() || ((logic->CanUse(RG_NUTS) || logic->CanUse(RG_BOOMERANG)) && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_FAIRY_SLINGSHOT))))), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}), @@ -47,6 +55,7 @@ void RegionTable_Init_SpiritTemple() { (logic->TakeDamage() && (logic->CanJumpslashExceptHammer() || logic->HasProjectile(HasProjectileAge::Child))) || (logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasProjectile(HasProjectileAge::Child)) || ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 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->CanJumpslashExceptHammer())))), + LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, logic->CanBreakPots()), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->HasExplosives() || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}}), @@ -59,6 +68,7 @@ void RegionTable_Init_SpiritTemple() { 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)))), + LOCATION(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->CanUse(RG_BOMBCHU_5) || (logic->CanUse(RG_BOMB_BAG) && logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOWER_ADULT_SWITCH))) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}), @@ -87,11 +97,21 @@ void RegionTable_Init_SpiritTemple() { ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) || (ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_BOOMERANG)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)))), + LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 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)))), + LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, logic->CanBreakPots() && (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)))), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, logic->CanBreakPots() && (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)))), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, logic->CanBreakPots() && (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)))), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, logic->CanBreakPots() && (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)))), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, logic->CanBreakPots() && (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)))), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, logic->CanBreakPots() && (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)))), + LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, logic->CanBreakPots() && (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)))), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_OUTDOOR_HANDS, {[]{return logic->CanJumpslashExceptHammer() || logic->HasExplosives();}}), Entrance(RR_SPIRIT_TEMPLE_BEYOND_CENTRAL_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SILVER_GAUNTLETS);}}), Entrance(RR_SPIRIT_TEMPLE_CHILD_CLIMB, {[]{return true;}}), + // RT_SPIRIT_PLATFORM_HOOKSHOT is currently disabled + Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, {[]{return ctx->GetTrickOption(RT_SPIRIT_PLATFORM_HOOKSHOT) && logic->CanUse(RG_HOOKSHOT);}}), }); areaTable[RR_SPIRIT_TEMPLE_OUTDOOR_HANDS] = Region("Spirit Temple Outdoor Hands", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { @@ -108,6 +128,8 @@ void RegionTable_Init_SpiritTemple() { 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()), + LOCATION(RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, logic->HasExplosives() && logic->CanUse(RG_SUNS_SONG)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && (ctx->GetTrickOption(RT_SPIRIT_WALL) || logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_BOMBCHU_5) || ((logic->CanUse(RG_BOMB_BAG) || logic->CanUse(RG_NUTS) || logic->CanUse(RG_DINS_FIRE)) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_MEGATON_HAMMER))));}}), @@ -115,8 +137,10 @@ void RegionTable_Init_SpiritTemple() { areaTable[RR_SPIRIT_TEMPLE_BEYOND_FINAL_LOCKED_DOOR] = Region("Spirit Temple Beyond Final Locked Door", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && ((logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS)) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT)))), - LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanAttack()) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), + LOCATION(RC_SPIRIT_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && ((logic->TakeDamage() && ctx->GetTrickOption(RT_FLAMING_CHESTS)) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_HOOKSHOT)))), + LOCATION(RC_SPIRIT_TEMPLE_TOPMOST_CHEST, (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanAttack()) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))), + LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, logic->CanUse(RG_HOOKSHOT)), }, { //Exits Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->HasExplosives() && logic->CanUse(RG_HOOKSHOT);}}), @@ -137,102 +161,387 @@ void RegionTable_Init_SpiritTemple() { if (ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ()) { areaTable[RR_SPIRIT_TEMPLE_MQ_LOBBY] = Region("Spirit Temple MQ Lobby", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true), - LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->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)))), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanHitSwitch(ED_BOOMERANG)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Spirit1FSilverRupees), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, logic->CanBreakPots()), }, { //Exits - 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);}}), + Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return logic->IsChild;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH, {[]{return logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_BOMBCHU_5);}}), }); - areaTable[RR_SPIRIT_TEMPLE_MQ_CHILD] = Region("Spirit Temple MQ Child", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + areaTable[RR_SPIRIT_TEMPLE_MQ_1F_WEST] = Region("Spirit Temple MQ 1F West", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_SLINGSHOT));}}), + //not technically a rusted switch, but a boulder through a wall, but is part of the same trick on N64 + EventAccess(&logic->MQSpiritCrawlBoulder, {[]{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}}), }, { //Locations - 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))))) + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->MQSpiritTimeTravelChest), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, logic->CanHitEyeTargets()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, logic->CanHitEyeTargets()), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, {[]{return logic->IsChild && logic->MQSpiritCrawlBoulder;}}), }); - areaTable[RR_SPIRIT_TEMPLE_MQ_ADULT] = Region("Spirit Temple MQ Adult", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanJumpslashExceptHammer() || 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)), - }, { + areaTable[RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH] = Region("Spirit Temple MQ 1F Gibdo Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - 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->CanJumpslashExceptHammer() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->CanHitEyeTargets();}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->CanHitEyeTargets() && logic->CanKillEnemy(RE_GIBDO);}}), }); - areaTable[RR_SPIRIT_TEMPLE_MQ_SHARED] = Region("Spirit Temple MQ Shared", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { +// Room to store the 2 pots in to handle glitch logic going backwards around the loop later + areaTable[RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH] = Region("Spirit Temple MQ Gibdo Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 6)), - LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->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(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->CanJumpslashExceptHammer() && (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->CanJumpslashExceptHammer() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult);}}), - //Trick: (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && (LogicLensSpiritMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult) - }); - - areaTable[RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT] = Region("Spirit Temple MQ Lower Adult", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, true), - LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->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)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, logic->CanBreakPots()), }, {}); - areaTable[RR_SPIRIT_TEMPLE_MQ_BOSS_AREA] = Region("Spirit Temple MQ Boss Region", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM] = Region("Spirit Temple Turntable Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + //For non-fairy pot items, you can also get them with rang without killing the stalfos + EventAccess(&logic->FairyPot, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}}), + }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + //implies logic->CanBreakPots() + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, logic->CanUse(RG_BOOMERANG) || logic->CanKillEnemy(RE_STALFOS)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, logic->CanUse(RG_BOOMERANG) || logic->CanKillEnemy(RE_STALFOS)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, logic->CanUse(RG_BOOMERANG) || logic->CanKillEnemy(RE_STALFOS)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, logic->CanUse(RG_BOOMERANG) || logic->CanKillEnemy(RE_STALFOS)), }, { //Exits - Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}}), }); - 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(RR_SPIRIT_TEMPLE_MQ_SHARED, { [] { return true; } }), - Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY); } }), - }); - - areaTable[RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Region("Spirit Temple MQ Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + areaTable[RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH] = Region("Spirit Temple MQ Map Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->MQSpiritMapRoomEnemies, {[]{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE);}}), + }, { //Locations - LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true), - }, {}); + LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->MQSpiritMapRoomEnemies), + }, { + //Exits + //Stalfos room blocks you in with fire until you kill the stalfos, which won't spawn from behind the fire + Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, {[]{return true;}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH] = Region("Spirit Temple MQ Map Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + //You can lure the keese over by aggroing them with dins if you use it as close to the torch keese as possible, but it's a trick as it's not intuitive and basically never comes up + EventAccess(&logic->MQSpiritMapRoomEnemies, {[]{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE, ED_BOOMERANG);}}), + }, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, true), + }, { + //Exits + //The bridge is a temp flag, so not a way to cross south to north in logic + Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH, {[]{return logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return true;}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH] = Region("Spirit Temple MQ West 1F Rusted Switch", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->MQSpiritTimeTravelChest, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), + EventAccess(&logic->MQSpiritCrawlBoulder, {[]{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}}), + }, {}, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return logic->IsChild && logic->MQSpiritCrawlBoulder;}}), + //This tracks possible child access, if adult has not entered STATUE_ROOM. Certain Child Access is checked for separately as 7 Keys + Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE] = Region("Spirit Temple MQ Under Like Like", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, MQSpiritSharedBrokenWallRoom(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, []{return logic->CanBreakPots();})), + }, { + //Exits + //This covers adult access only, as child arrives here from the other side of this door + Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, {[]{return logic->CanHitSwitch();}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM] = Region("Spirit Temple MQ Broken Wall Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //Implies CanKillEnemy(RE_LIKE_LIKE) + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, MQSpiritSharedBrokenWallRoom(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanKillEnemy(RE_BEAMOS);})), + //Sunlights only temp spawn this chest, which is unintuitive/a bug. + //chest is only reachable as adult glitchlessly, so we can skip the shared in favour of IsAdult as adult access is always Certain + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->IsAdult && logic->HasExplosives() && (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)) && logic->CanUse(RG_HOOKSHOT)), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, {[]{return logic->CanHitSwitch();}}), + //This exit only governs child possible access, adult access starts on the other side so never checks this + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM] = Region("Spirit Temple MQ Statue Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets();})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return ((logic->IsAdult || logic->CanJumpslash()) && logic->CanUse(RG_BOOMERANG)) || + ((logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) && logic->CanBreakPots());})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SONG_OF_TIME) || (logic->IsAdult && ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)) && logic->CanBreakPots());})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanBreakPots();})), + }, { + //Exits + //we check possible adult access directly in MQSpiritSharedBrokenWallRoom, so this exit only covers Certain Access + Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}), + //We can use Here instead of Shared here because adult will never need to rely on child access to reach this room, and adult access is Certain + Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->HasFireSource() || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME));});}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, {[]{return logic->IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->CanUse(RG_SONG_OF_TIME);}}), + //explicit adult check here is a precaution against possible child logic leaking, child with a hookshot can do this + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, {[]{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM] = Region("Spirit Temple MQ Sun Block Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //We don't need Shared here because If we are checking as child, universe 2 adult access needs nothing so it always passes, and if we are checking as adult, it is Certain Access + LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG));})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanBreakPots();})), + LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanBreakPots();})), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return true;}}), + //This door causes the Universes to merge as it requires 7 keys for both ages + Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE] = Region("Spirit Temple MQ East Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return logic->CanKillEnemy(RE_IRON_KNUCKLE);}}), + }); areaTable[RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND] = Region("Spirit Temple MQ Silver Gauntlets Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, true), - }, {}); + }, { + //Exits + //If it is ever relevent for 1 age to spawn the mirror shield chest for the other can longshot across, it needs an eventAccess + Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, {[]{return true;}}), + Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH] = Region("Spirit Temple MQ Block Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return true;}}), + //The block here is unusual in that it is a permanent flag, but reset anyway as child. This is because there's a check that would be blocked off by pushing them otherwise + //It may be worth considering making this always temp in future so adult doesn't have the same issue + Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, {[]{return logic->IsChild ? logic->CanUse(RG_SILVER_GAUNTLETS) : Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->CanUse(RG_SILVER_GAUNTLETS);});}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH] = Region("Spirit Temple MQ Block Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //Does not need to be shared as it's hard child locked, because adult pushing the block is a permanent flag that blocks the eye target and cannot be undone + LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanHitEyeTargets()), + }, { + //Exits + //if going to RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH from here is ever relevant, there needs to be an event to handle the block + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return true;}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST] = Region("Spirit Temple MQ Statue Room East", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_HOOKSHOT) & 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)) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS))), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return true;}}), + //!QUANTUM LOGIC! + //We only need 4 keys, access to Shield hand and longshot to reach Gauntlets hand, as if we waste the 5th key we have given ourselves Gauntlets hand access through child climb + //This exit handles that possibility as cleanly as possible without quantum logic, but will not survive glitch logic + //logic->CanKillEnemy(RE_FLOORMASTER) is implied + Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && + logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) && + logic->CanJumpslash() && + (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && + logic->CanKillEnemy(RE_IRON_KNUCKLE) && + logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, {[]{return logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE));}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F] = Region("Spirit Temple MQ Three Suns Room 2F", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + //implies logic->CanKillEnemy(RE_WALLMASTER). If we have lights, we can kill stalfos and wallmasters with bow + EventAccess(&logic->MQSpirit3SunsEnemies, {[]{return (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)) || + (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}}), + }, {}, { + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, {[]{return logic->MQSpirit3SunsEnemies;}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F] = Region("Spirit Temple MQ Three Suns Room 1F", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, {[]{return logic->MQSpirit3SunsEnemies;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, {[]{return true;}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_1F_EAST] = Region("Spirit Temple MQ 1F East", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + //Assumes RR_SPIRIT_TEMPLE_MQ_LOBBY access + EventAccess(&logic->Spirit1FSilverRupees, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), + }, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM] = Region("Spirit Temple MQ Leever Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, logic->CanKillEnemy(RE_PURPLE_LEEVER) && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + }, { + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM] = Region("Spirit Temple MQ Symphony Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}), + //Implies CanPassEnemy(RE_MOBLIN_CHIEF) + Entrance(RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM, {[]{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && + logic->CanUse(RG_SUNS_SONG) && logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY);}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM] = Region("Spirit Temple MQ After Symphony Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, {[]{return true;}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM] = Region("Spirit Temple MQ Four Beamos Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->CanKillEnemy(RE_BEAMOS)), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, {[]{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, {[]{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6);}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM] = Region("Spirit Temple MQ SoT Sun Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, true), + LOCATION(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, {[]{return logic->CanJumpslash();}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, []{return (logic->IsAdult || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanUse(RG_MIRROR_SHIELD);});}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND] = Region("Spirit Temple MQ East Stairs to Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, {[]{return (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && + Here(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, []{return logic->CanKillEnemy(RE_FLOORMASTER);});}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE] = Region("Spirit Temple MQ East Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Region("Spirit Temple MQ Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, {[]{return true;}}), + Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM] = Region("Spirit Temple MQ 3F Gibdo Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, true), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, {[]{return true;}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_WALL] = Region("Spirit Temple MQ Big Wall", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return true;}}), + //technically we only need to avoid them, but the sheer height and the moving walls makes getting to the top after only stunning them very difficult/impossible + //The silver rupees are irrelevant without silver shuffle + Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, {[]{return logic->CanKillEnemy(RE_KEESE);}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL] = Region("Spirit Temple MQ 4F Central", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM] = Region("Spirit Temple MQ Nine Chairs Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + //These skulls rely on the iron knuckle existing without a trick to shoot through the chairs + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, {[]{return true;}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM] = Region("Spirit Temple MQ Big Mirror Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, {[]{return true;}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);});}}), + }); + + areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE] = Region("Spirit Temple MQ Big Mirror Cave", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)), + }, { + //Exits + //If it's ever relevant to longshot into head from lobby, this needs to be an event access + Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return logic->CanUse(RG_MIRROR_SHIELD);}) && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return logic->CanUse(RG_MIRROR_SHIELD);});}}), + }); + + 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(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return true;} }), + Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);}}), + }); } /*--------------------------- 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 a02e51e83..e630c997e 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 @@ -10,9 +10,9 @@ void RegionTable_Init_WaterTemple() { ---------------------------*/ areaTable[RR_WATER_TEMPLE_ENTRYWAY] = Region("Water Temple Entryway", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->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;}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->HasItem(RG_BRONZE_SCALE) && ctx->GetDungeon(WATER_TEMPLE)->IsVanilla();}}), + Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->HasItem(RG_BRONZE_SCALE) && ctx->GetDungeon(WATER_TEMPLE)->IsMQ();}}), + Entrance(RR_LAKE_HYLIA, {[]{return true;}}), }); /*-------------------------- @@ -20,32 +20,40 @@ void RegionTable_Init_WaterTemple() { ---------------------------*/ if (ctx->GetDungeon(WATER_TEMPLE)->IsVanilla()) { //Water Temple logic currently assumes that the locked door leading to the upper water raising location is unlocked from the start - areaTable[RR_WATER_TEMPLE_LOBBY] = Region("Water Temple Lobby", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_LOBBY] = Region("Water Temple Lobby", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, logic->CanBreakPots() && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)))), + LOCATION(RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, logic->CanBreakPots() && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)))), + }, { //Exits 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_EAST_LOWER, {[]{return logic->CanWaterTempleLowFromHigh || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && (logic->CanUse(RG_IRON_BOOTS) || (logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_WATER_LONGSHOT_TORCH))));}}), + Entrance(RR_WATER_TEMPLE_NORTH_LOWER, {[]{return logic->CanWaterTempleLowFromHigh || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_WATER_TEMPLE_SOUTH_LOWER, {[]{return logic->CanWaterTempleLowFromHigh && logic->HasExplosives() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}}), + Entrance(RR_WATER_TEMPLE_WEST_LOWER, {[]{return logic->CanWaterTempleLowFromHigh && logic->HasItem(RG_GORONS_BRACELET) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return logic->CanWaterTempleLowFromHigh && logic->SmallKeys(RR_WATER_TEMPLE, 5);}}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle) && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}}), + Entrance(RR_WATER_TEMPLE_EAST_MIDDLE, {[]{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_WEST_MIDDLE, {[]{return logic->CanWaterTempleMiddle;}}), Entrance(RR_WATER_TEMPLE_HIGH_WATER, {[]{return logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DAMAGE_BOOST) && logic->CanUse(RG_BOMB_BAG) && logic->TakeDamage()));}}), - Entrance(RR_WATER_TEMPLE_BLOCK_CORRIDOR, {[]{return (logic->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);}}), + Entrance(RR_WATER_TEMPLE_BLOCK_CORRIDOR, {[]{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_WATER_CENTRAL_BOW) && (logic->IsAdult || logic->CanWaterTempleMiddle)));}}), + Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return logic->CanWaterTempleHigh && logic->SmallKeys(RR_WATER_TEMPLE, 4);}}), + Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, {[]{return (logic->CanWaterTempleHigh && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS));}}), }); areaTable[RR_WATER_TEMPLE_EAST_LOWER] = Region("Water Temple East Lower", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->WaterTempleLow, {[]{return logic->WaterTempleLow || logic->CanUse(RG_ZELDAS_LULLABY);}}), - }, {}, { + EventAccess(&logic->CanWaterTempleLowFromHigh, {[]{return logic->CanWaterTempleLowFromHigh || logic->CanUse(RG_ZELDAS_LULLABY);}}), + }, { + //Locations + LOCATION(RC_WATER_TEMPLE_TORCH_POT_1, logic->CanBreakPots() && (logic->CanWaterTempleLowFromHigh || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)))), + LOCATION(RC_WATER_TEMPLE_TORCH_POT_2, logic->CanBreakPots() && (logic->CanWaterTempleLowFromHigh || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)))), + }, { //Exits - 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));}}), + Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanWaterTempleLowFromHigh || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_WATER_TEMPLE_MAP_ROOM, {[]{return logic->CanWaterTempleHigh;}}), + Entrance(RR_WATER_TEMPLE_CRACKED_WALL, {[]{return logic->CanWaterTempleMiddle || (logic->CanWaterTempleHigh && logic->CanWaterTempleLowFromHigh && ((logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_WATER_CRACKED_WALL_HOVERS)) || ctx->GetTrickOption(RT_WATER_CRACKED_WALL)));}}), + Entrance(RR_WATER_TEMPLE_TORCH_ROOM, {[]{return logic->CanWaterTempleLowFromHigh && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}}), }); areaTable[RR_WATER_TEMPLE_MAP_ROOM] = Region("Water Temple Map Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { @@ -88,7 +96,11 @@ void RegionTable_Init_WaterTemple() { Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, {[]{return (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP))) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanUse(RG_IRON_BOOTS));}}), }); - areaTable[RR_WATER_TEMPLE_BLOCK_ROOM] = Region("Water Temple Block Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_BLOCK_ROOM] = Region("Water Temple Block Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, logic->CanBreakPots()), + }, { //Exits 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));}}), @@ -113,6 +125,8 @@ void RegionTable_Init_WaterTemple() { }, { //Locations LOCATION(RC_WATER_TEMPLE_BOSS_KEY_CHEST, true), + LOCATION(RC_WATER_TEMPLE_BOSS_KEY_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_BOSS_KEY_POT_2, logic->CanBreakPots()), }, { //Exits Entrance(RR_WATER_TEMPLE_BOULDERS_UPPER, {[]{return (logic->CanUse(RG_IRON_BOOTS) || (logic->IsAdult && ctx->GetTrickOption(RT_WATER_BK_JUMP_DIVE)) || logic->IsChild || logic->HasItem(RG_SILVER_SCALE)) && logic->SmallKeys(RR_WATER_TEMPLE, 5);}}), @@ -120,7 +134,11 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_SOUTH_LOWER] = Region("Water Temple South Lower", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_BEHIND_GATE, logic->CanJumpslash() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_WATER_TEMPLE_GS_BEHIND_GATE, logic->CanJumpslash() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_WATER_TEMPLE_BEHIND_GATE_POT_1, logic->CanJumpslash() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_WATER_TEMPLE_BEHIND_GATE_POT_2, logic->CanJumpslash() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_WATER_TEMPLE_BEHIND_GATE_POT_3, logic->CanJumpslash() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), + LOCATION(RC_WATER_TEMPLE_BEHIND_GATE_POT_4, logic->CanJumpslash() && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_IRON_BOOTS);}}), @@ -145,15 +163,15 @@ void RegionTable_Init_WaterTemple() { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 5);}}), Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return logic->CanUse(RG_HOOKSHOT);}}), - Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, {[]{return logic->WaterTempleMiddle && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40;}}), + Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, {[]{return logic->CanWaterTempleMiddle && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40;}}), }); areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER] = Region("Water Temple Central Pillar Upper", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->WaterTempleMiddle, {[]{return logic->WaterTempleMiddle || logic->CanUse(RG_ZELDAS_LULLABY);}}), + EventAccess(&logic->CanWaterTempleMiddle, {[]{return logic->CanWaterTempleMiddle || logic->CanUse(RG_ZELDAS_LULLABY);}}), }, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(RR_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->WaterTempleHigh && logic->HookshotOrBoomerang())), + LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(RR_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->CanWaterTempleHigh && logic->HookshotOrBoomerang())), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), @@ -171,6 +189,9 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_EAST_MIDDLE] = Region("Water Temple East Middle", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations LOCATION(RC_WATER_TEMPLE_COMPASS_CHEST, logic->CanUseProjectile()), + LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, logic->CanBreakPots()), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_IRON_BOOTS);}}), @@ -184,7 +205,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_HIGH_WATER] = Region("Water Temple High Water", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events - EventAccess(&logic->WaterTempleHigh, {[]{return logic->WaterTempleHigh || logic->CanUse(RG_ZELDAS_LULLABY);}}), + EventAccess(&logic->CanWaterTempleHigh, {[]{return logic->CanWaterTempleHigh || logic->CanUse(RG_ZELDAS_LULLABY);}}), }, {}, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), @@ -192,7 +213,9 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BLOCK_CORRIDOR] = Region("Water Temple Block Corridor", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->WaterTempleLow || logic->WaterTempleMiddle)), + LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle)), + LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, logic->CanBreakPots() && logic->HasItem(RG_GORONS_BRACELET) && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle)), + LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, logic->CanBreakPots() && logic->HasItem(RG_GORONS_BRACELET) && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle)), }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_HOOKSHOT);}}), @@ -207,7 +230,11 @@ void RegionTable_Init_WaterTemple() { Entrance(RR_WATER_TEMPLE_DRAGON_PILLARS_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_WATER_TEMPLE, 5);}}), }); - areaTable[RR_WATER_TEMPLE_DRAGON_PILLARS_ROOM] = Region("Water Temple Dragon Pillars Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + areaTable[RR_WATER_TEMPLE_DRAGON_PILLARS_ROOM] = Region("Water Temple Dragon Pillars Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_LIKE_LIKE_POT_1, logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_LIKE_LIKE_POT_2, logic->CanUse(RG_HOOKSHOT)), + }, { //Exits Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return logic->CanUseProjectile();}}), Entrance(RR_WATER_TEMPLE_DARK_LINK_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT);}}), @@ -230,8 +257,14 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_RIVER] = Region("Water Temple River", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_RIVER_CHEST, (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))), - LOCATION(RC_WATER_TEMPLE_GS_RIVER, (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT)) || (ctx->GetTrickOption(RT_WATER_RIVER_GS) && logic->CanUse(RG_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))), + LOCATION(RC_WATER_TEMPLE_RIVER_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_RIVER_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_RIVER_HEART_1, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_WATER_TEMPLE_RIVER_HEART_2, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_WATER_TEMPLE_RIVER_HEART_3, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->HasItem(RG_BRONZE_SCALE)), + LOCATION(RC_WATER_TEMPLE_RIVER_HEART_4, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24) || logic->HasItem(RG_BRONZE_SCALE)), }, { //Exits Entrance(RR_WATER_TEMPLE_DRAGON_ROOM, {[]{return (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}), @@ -240,7 +273,11 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_PRE_BOSS_ROOM] = Region("Water Temple Pre Boss Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), - }, {}, { + }, { + // Locations + LOCATION(RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, logic->CanBreakPots()), + }, { //Exits Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}), Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY);}}), @@ -251,53 +288,462 @@ void RegionTable_Init_WaterTemple() { | MASTER QUEST DUNGEON | ---------------------------*/ 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, {}, {}, { + areaTable[RR_WATER_TEMPLE_MQ_3F_SOUTH_LEDGE] = Region("Water Temple MQ 3F South Ledge", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { //Exits - Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return true;}}), - Entrance(RR_WATER_TEMPLE_MQ_DIVE, {[]{return logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_IRON_BOOTS);}}), - Entrance(RR_WATER_TEMPLE_MQ_DARK_LINK_REGION, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslashExceptHammer();}}), - Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY) && logic->IsAdult && logic->CanJumpslashExceptHammer() && logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}), + //If we are not on WL_HIGH, we reach RR_WATER_TEMPLE_MQ_3F_MAIN with hookshot via 2F, otherwise we can reach the platform + Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_MQ_2F_CENTRAL, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID);}}), }); - areaTable[RR_WATER_TEMPLE_MQ_DIVE] = Region("Water Temple MQ Dive", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { - //Locations - LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->HasFireSource() && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)), - LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->IsAdult && logic->CanUse(RG_ZORA_TUNIC) && logic->CanUse(RG_HOOKSHOT) && ((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))) +//This region covers simply existing in the area around the central pillar without being on a specific platform, either swimming or walking on the lakebed +//Entry should only include being in the correct area, taking any possible fall damage, and floating up to the surface of WL_HIGH if coming from below +//This area then leads to others based on level and worst-case water timers for follow-up exits from the water's surface +//remember that any solution that works for any level doesn't need to be given a level, even if that solution is overkill for a lower level + areaTable[RR_WATER_TEMPLE_MQ_MAIN] = Region("Water Temple MQ Main", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_3F_SOUTH_LEDGE, {[]{return logic->HasItem(RG_BRONZE_SCALE) && logic->MQWaterLevel(WL_HIGH);}}), + //Jumping across is possible but a trick due to the janky ledge + Entrance(RR_WATER_TEMPLE_MQ_EAST_TOWER, {[]{return (logic->WaterTimer() >= 24 && logic->CanUse(RG_IRON_BOOTS)) || + (logic->MQWaterLevel(WL_MID) && logic->HasItem(RG_GOLDEN_SCALE) && logic->WaterTimer() >= 16) || + logic->MQWaterLevel(WL_LOW);}}), + Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->MQWaterLevel(WL_HIGH) && logic->HasItem(RG_BRONZE_SCALE);}}), + //First water timer uses the hook to go from the top of center to storage room/central pillar as coming from the bottom + //Second water timer is simply diving down and entering the door as fast as possible from the surface + Entrance(RR_WATER_TEMPLE_MQ_2F_CENTRAL, {[]{return ((logic->MQWaterLevel(WL_LOW) || (logic->CanUse(RG_IRON_BOOTS) && (logic->MQWaterLevel(WL_MID) || logic->WaterTimer() >= 16))) && logic->CanUse(RG_LONGSHOT)) || + ((logic->MQWaterLevel(WL_MID) || (logic->MQWaterLevel(WL_HIGH_OR_MID) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)) && logic->HasItem(RG_BRONZE_SCALE));}}), + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_1F, {[]{return logic->MQWaterLevel(WL_LOW);}}), + //A special entry as we can't set it to high after entering at a lower height + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, {[]{return logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT));}}), + Entrance(RR_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY, {[]{return (logic->MQWaterLevel(WL_MID) || (logic->MQWaterLevel(WL_HIGH_OR_MID) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->HasItem(RG_BRONZE_SCALE);}}), + Entrance(RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH, {[]{return logic->MQWaterB1Switch && (logic->MQWaterLevel(WL_LOW) || ((logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24) && logic->HasItem(RG_BRONZE_SCALE)));}}), + Entrance(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM, {[]{return logic->MQWaterB1Switch && + ((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_SILVER_SCALE)) || + (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))));}}), + //Adult needs to jump in instead of dive for swim access, but you just hold forward. RT_WATER_BK_REGION Isn't relevant unless the Dark Link loop can be done without longshot with other tricks + Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, {[]{return logic->MQWaterB1Switch && + ((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanUse(RG_HOOKSHOT))) && + (logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_WATER_BK_REGION) && logic->CanUse(RG_HOVER_BOOTS)));}}), + }); + +//This region specifically covers the topmost platform around central pillar + areaTable[RR_WATER_TEMPLE_MQ_3F_CENTRAL] = Region("Water Temple MQ 3F Central", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_3F_SOUTH_LEDGE, {[]{return logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_MQ_2F_CENTRAL, {[]{return (logic->MQWaterLevel(WL_LOW_OR_MID) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, {[]{return logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_3F_NORTH_LEDGE, {[]{return (logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS));}}), + //Jumping across is possible but a trick due to the janky ledge + Entrance(RR_WATER_TEMPLE_MQ_HIGH_EMBLEM, {[]{return logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}}), + //room access is (logic->IsAdult || (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT))) + Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_LONGSHOT);}}), + //this swimless jump with irons may be a trick as you have to put irons on quite late. + Entrance(RR_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY, {[]{return (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->MQWaterLevel(WL_LOW_OR_MID);}}), + }); + +//This region specifically covers walking on the lower platform around central pillar. This is underwater when WL_HIGH +//RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH should be accessed directly to use the central pillar door while at WL_HIGH + areaTable[RR_WATER_TEMPLE_MQ_2F_CENTRAL] = Region("Water Temple MQ 2F Central", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_2F, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID);}}), + Entrance(RR_WATER_TEMPLE_MQ_STORAGE_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_2F, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID) && logic->CanUse(RG_HOVER_BOOTS);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_HIGH_EMBLEM] = Region("Water Temple MQ High Emblem", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->ReachedWaterHighEmblem, {[]{return true;}}), + EventAccess(&logic->CanWaterTempleHigh, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}), + }, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_3F_NORTH_LEDGE] = Region("Water Temple MQ 3F North Ledge", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + //what we need if WL_LOW, we can't guarantee repeated access otherwise. + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->TakeDamage();}}), + Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_BOSS_DOOR, {[]{return logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_ICE_ARROWS) || logic->CanUse(RG_NAYRUS_LOVE);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_BOSS_DOOR] = Region("Water Temple MQ Main", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_3F_NORTH_LEDGE, {[]{return logic->CanUse(RG_ICE_ARROWS) || logic->TakeDamage();}}), + Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_EAST_TOWER] = Region("Water Temple MQ East Tower", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + //if we can't reach these, we can't move the water at all, so no need to specify level or account for WL_LOW access here + //review is some way to play ocarina underwater exists + EventAccess(&logic->CouldWaterTempleLow, {[]{return true;}}), + EventAccess(&logic->CanWaterTempleLowFromHigh, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}), + //Reserved for glitches/tricks that could do this + //EventAccess(&logic->CanWaterTempleLowFromMid, {[]{return false;}}), }, { - //Exits - Entrance(RR_WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}), + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->MQWaterLevel(WL_HIGH) && logic->HasFireSource() && logic->CanUse(RG_HOOKSHOT)), + //easy to get at WL_HIGH with the hook-the-underwater-chest glitch + LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, logic->MQWaterLevel(WL_MID) && logic->CanUse(RG_HOOKSHOT)), + LOCATION(RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, (logic->MQWaterLevel(WL_LOW) && logic->CanBreakPots()) || + (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 16)), + LOCATION(RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, (logic->MQWaterLevel(WL_LOW) && logic->CanBreakPots()) || + (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 16)), + }, { + Entrance(RR_WATER_TEMPLE_MQ_EAST_TOWER_1F_ROOM, {[]{return logic->MQWaterLevel(WL_LOW) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_STICKS));}}), }); - areaTable[RR_WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS] = Region("Water Temple MQ Lowered Water Levels", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Raising the targets by clearing this room achieves nothing logically because it requires WL_LOW to do and hookshot to use, which implies access to WL_MID and WL_HIGH already + areaTable[RR_WATER_TEMPLE_MQ_EAST_TOWER_1F_ROOM] = Region("Water Temple MQ East Tower 1F Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, ((logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || logic->CanUse(RG_DINS_FIRE) || Here(RR_WATER_TEMPLE_MQ_LOBBY, []{return logic->IsChild && logic->CanUse(RG_STICKS) && logic->HasExplosives();})) && - (logic->CanJumpslashExceptHammer() || 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)), + LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_LIZALFOS) && logic->CanKillEnemy(RE_SPIKE)), + }, { + Entrance(RR_WATER_TEMPLE_MQ_EAST_TOWER, {[]{return true;}}), + }); + +//This area assumes we entered through the lower door, so water is low and cannot be changed without leaving. + areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_1F] = Region("Water Temple MQ Central Pillar 1F", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + //This is harder than the other possibilities as you have to move between shots on top of the extra range, but there's basically no universe this should matter. + EventAccess(&logic->MQWaterB1Switch, {[]{return ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS);}}), + }, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, {[]{return logic->MQWaterLevel(WL_HIGH) && ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && logic->HasItem(RG_BRONZE_SCALE);}}), + //I don't know if this FW trick can ever matter but maybe it's needed to get child to CENTRAL_2F or something + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_2F, {[]{return logic->CanUse(RG_HOOKSHOT) || + (logic->MQWaterLevel(WL_MID) && ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && logic->HasItem(RG_BRONZE_SCALE));}}), + //if the gate is open, you sink straight in, so you can't climb up this way in logic without swimming + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, {[]{return logic->MQWaterOpenedPillarB1 && logic->MQWaterLevel(WL_HIGH_OR_MID) && + ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && + logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}}), + }); + +//If we enter here in WL_HIGH, go to RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH instead, Assumes WL_MID_OR_LOW + areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_2F] = Region("Water Temple MQ Central Pillar 2F", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->CouldWaterTempleMiddle, {[]{return true;}}), + EventAccess(&logic->CanWaterTempleMiddle, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}), + //It's possible to do this even on low water, but more awkward. I'm not sure if it's even possible for it to be relevant though. + EventAccess(&logic->MQWaterOpenedPillarB1, {[]{return ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS);}}), + //this could theoretically matter once OI and equip swap is in logic, as one age may be able to get here dry and not wet, and the other may not be able to OI, but as you can OI with hookshot it probably never happens + //EventAccess(&logic->MQWaterPillarSoTBlock, {[]{return logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME);}}), + }, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, {[]{return logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_FARORES_WIND) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}), + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, {[]{return logic->MQWaterOpenedPillarB1 && logic->MQWaterLevel(WL_MID) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH] = Region("Water Temple MQ Central Pillar High", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->MQWaterOpenedPillarB1, {[]{return ((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_DINS_FIRE)) || (ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS))) && + (logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslash()));}}), + }, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, {[]{return logic->MQWaterB1Switch && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}}), + }); + +//Assuming tunic and irons was checked on entry + areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1] = Region("Water Temple MQ Central Pillar B1", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + //Can't know water level, so we'll just assume any possibility and skip to MAIN + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->MQWaterOpenedPillarB1 && logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE);}}), + //Child needs to release irons for height to push down the larger "peg", however they can push the lower one down by climbing and then hit the switch through the larger peg, but it's a trick + Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1_FINAL, {[]{return ((logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE)));}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1_FINAL] = Region("Water Temple MQ Central Pillar B1 Final", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT)), }, {}); - areaTable[RR_WATER_TEMPLE_MQ_DARK_LINK_REGION] = Region("Water Temple MQ Dark Link Region", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { +//Region exists to add crate/pot/box locations + areaTable[RR_WATER_TEMPLE_MQ_STORAGE_ROOM] = Region("Water Temple MQ Storage Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_2F] = Region("Water Temple MQ Behind Blue Switch 2F", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_3F, {[]{return logic->CanUse(RG_LONGSHOT);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_3F] = Region("Water Temple MQ Behind Blue Switch 2F", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_2F, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_HIGH_EMBLEM, {[]{return true;}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY] = Region("Water Temple MQ Lizalfos Hallway", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_WEST_POT, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SOUTH_POT, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SE_POT, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_LIZALFOS_CAGE, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID) && logic->CanUse(RG_DINS_FIRE);}}), + //this technically exists, but only complicates things, uncomment if some edge case/glitch can use RR_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY to reach RR_WATER_TEMPLE_MQ_3F_CENTRAL, or if a void warp goes here + /*Entrance(RR_WATER_TEMPLE_MQ_3F_EAST_LEDGE, {[]{return (logic->CanUse(RG_HOOKSHOT) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS))) || + (logic->MQWaterLevel(WL_LOW_OR_MID) && logic->CanUse(RG_HOOKSHOT)) || + logic->MQWaterLevel(WL_HIGH) && (logic->HasItem(RG_BRONZE_SCALE));}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_3F_EAST_LEDGE] = Region("Water Temple MQ 3F East Ledge", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}),*/ + }); + + areaTable[RR_WATER_TEMPLE_MQ_LIZALFOS_CAGE] = Region("Water Temple MQ Lizalfos Cage", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, logic->CanKillEnemy(RE_GOLD_SKULLTULA)), + LOCATION(RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_SOUTH_POT, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_NORTH_POT, logic->CanBreakPots()), + }, {}); + +//This room exists to hold the wonderitems that drop from the emblems here. Specifically this assumes you are standing on the final ledge + areaTable[RR_WATER_TEMPLE_MQ_WATERFALL] = Region("Water Temple Waterfall", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, {[]{return (logic->MQWaterStalfosPit && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_HOVER_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, {[]{return logic->MQWaterStalfosPit && logic->CanUse(RG_LONGSHOT);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT] = Region("Water Temple MQ Stalfos Pit", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->MQWaterStalfosPit, {[]{return ((logic->IsAdult && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3, false, true)) || + (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanKillEnemy(RE_STALFOS, ED_BOMB_THROW, true, 3, false, true)));}}), + }, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, {[]{return logic->MQWaterStalfosPit && logic->CanUse(RG_HOOKSHOT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8);}}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, {[]{return (logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || + (logic->CanUse(RG_HOOKSHOT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) && (logic->CanUse(RG_HOVER_BOOTS) || logic->MQWaterStalfosPit));}}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, {[]{return logic->MQWaterStalfosPit && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) && logic->CanUse(RG_HOOKSHOT);}}), + }); + + //also includes the suns fairy in the middle + areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS] = Region("Water Temple MQ Stalfos Pit Pots", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FairyPot, {[]{return true;}}), EventAccess(&logic->NutPot, {[]{return true;}}), }, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_DINS_FIRE) && (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), + LOCATION(RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + }, { //Exits - Entrance(RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS, {[]{return logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_IRON_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, {[]{return logic->MQWaterStalfosPit && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, {[]{return logic->MQWaterStalfosPit && logic->CanUse(RG_HOOKSHOT);}}), }); - areaTable[RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS] = Region("Water Temple MQ Basement Gated Areas", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { +//specifically the area past the spikes + areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER] = Region("Water Temple MQ Stalfos Pit Upper", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { //Locations - 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->CanJumpslashExceptHammer())), - //Trick: LogicWaterMQLockedGS || (logic->SmallKeys(RR_WATER_TEMPLE, 2) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW) || LogicWaterNorthBasementLedgeJump)) + LOCATION(RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, {[]{return logic->IsAdult || logic->TakeDamage();}}), + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, {[]{return logic->IsAdult || logic->TakeDamage();}}), + Entrance(RR_WATER_TEMPLE_MQ_AFTER_DARK_LINK, {[]{return logic->CanKillEnemy(RE_DARK_LINK);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_AFTER_DARK_LINK] = Region("Water Temple MQ After Dark Link", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->FairyPot, {[]{return true;}}), + }, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, {[]{return logic->CanKillEnemy(RE_DARK_LINK);}}), + Entrance(RR_WATER_TEMPLE_MQ_RIVER_SKULL, {[]{return logic->CanUse(RG_HOOKSHOT) && (logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) || logic->CanUse(RG_LONGSHOT));}}), + }); + +//if we can use hookshot, we are standing on the targets, otherwise assume we're in the water + areaTable[RR_WATER_TEMPLE_MQ_RIVER_SKULL] = Region("Water Temple MQ River Skull", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_GS_RIVER, logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_RIVER_POTS, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_RIVER_POTS] = Region("Water Temple MQ River Pots", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->FairyPot, {[]{return true;}}), + }, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_RIVER_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_RIVER_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_RIVER_SKULL, {[]{return logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && logic->CanUse(RG_HOOKSHOT));}}), + //You don't need to swim for this if you put irons on in midair and hold forward while aiming for the tunnel with a tight angle, but if you miss you have to void unless you have a hook. It's only relevant with glitches anyway + Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16;}}), + Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE, {[]{return logic->HasItem(RG_SILVER_SCALE) || (logic->IsAdult && logic->HasItem(RG_BRONZE_SCALE) && ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE));}}), + Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanJumpslash());}}), + }); + +//This region assumes Iron boots to access + areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL] = Region("Water Temple MQ Dragon Room Tunnel", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_RIVER_POTS, {[]{return logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE] = Region("Water Temple MQ Dragon Room Alcove", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + EventAccess(&logic->MQWaterDragonTorches, {[]{return true;}}), + }, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16;}}), + Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, {[]{return logic->HasItem(RG_SILVER_SCALE);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR] = Region("Water Temple MQ Dragon Room Door", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_RIVER_POTS, {[]{return logic->CanUse(RG_LONGSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanUse(RG_HOOKSHOT);}}), + Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE, {[]{return logic->HasItem(RG_SILVER_SCALE);}}), + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, {[]{return logic->MQWaterDragonTorches;}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH] = Region("Water Temple MQ Boss Key Room Switch", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_POT, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, {[]{return logic->CanHitSwitch() && Here(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, []{return logic->CanUse(RG_DINS_FIRE);});}}), + }); + +//this exists for the crates in preparation for clips through the grate + areaTable[RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT] = Region("Water Temple MQ Boss Key Room Pit", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, {[]{return logic->CanHitSwitch(ED_BOOMERANG);}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST] = Region("Water Temple MQ Boss Key Room Chest", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, true), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, {[]{return logic->CanHitSwitch(ED_BOMB_THROW) || logic->CanUse(RG_HOVER_BOOTS);}}), + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT, {[]{return true;}}), + Entrance(RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH, {[]{return logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && (logic->HasItem(RG_BRONZE_SCALE) || (logic->WaterTimer() >= 24 && logic->CanUse(RG_LONGSHOT))));}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH] = Region("Water Temple MQ B1 Gate Switch", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, { + //Events + //If the water is low, the switch is underwater and needs irons to press, otherwise, the water is too low to climb up and you need irons to hookshot a target + //If a glitch clips through the gate on low, have it logically press the switch and let entrance logic enter + EventAccess(&logic->MQWaterB1Switch, {[]{return logic->CanUse(RG_IRON_BOOTS);}}), + }, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->MQWaterB1Switch && (logic->MQWaterLevel(WL_LOW) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16));}}), + Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && (logic->MQWaterLevel(WL_LOW) || logic->WaterTimer() >= 24);}}) + }); + + areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM] = Region("Water Temple MQ Triangle Torch Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->MQWaterB1Switch && + ((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_GOLDEN_SCALE)) || + (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))));}}), + Entrance(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE, {[]{return logic->CanUse(RG_FIRE_ARROWS) && + ((logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (logic->CanUse(RG_LONGSHOT) && Here(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE, []{return logic->ScarecrowsSong();})));}}) + }); + + areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE] = Region("Water Temple MQ Triangle Torch Cage", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), + LOCATION(RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, logic->CanBreakPots()), }, {}); + + areaTable[RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM] = Region("Water Temple MQ Crates Whirlpools Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + //we can backflip over the spikes, but land in water. + Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->MQWaterB1Switch && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && (logic->CanUse(RG_LONGSHOT) || logic->HasItem(RG_BRONZE_SCALE));}}), + //Child can use the crate to get the height to make it with hovers, but it's annoyingly tight so would be a trick + Entrance(RR_WATER_TEMPLE_MQ_SINGLE_STALFOS_ROOM, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && + //We're putting the requirement to get out of the water here as the scarecrow method in includes hook which satisfies it + ((logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP)) && (logic->CanUse(RG_HOOKSHOT) || logic->HasItem(RG_BRONZE_SCALE))) || + (Here(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, []{return logic->ScarecrowsSong();}) && logic->CanUse(RG_HOOKSHOT)));}}), + Entrance(RR_WATER_TEMPLE_MQ_4_TORCH_ROOM, {[]{return logic->IsAdult && + (logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP) || + (Here(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, []{return logic->ScarecrowsSong();}) && logic->CanUse(RG_HOOKSHOT)));}}), + Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_CAGE, {[]{return ctx->GetTrickOption(RT_WATER_MQ_LOCKED_GS) && (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT));}}), + }); + + areaTable[RR_WATER_TEMPLE_MQ_SINGLE_STALFOS_ROOM] = Region("Water Temple MQ Single Stalfos Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, true), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, {[]{return logic->HasItem(RG_SILVER_SCALE) || (logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)) || + (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT)));}}) + }); + + areaTable[RR_WATER_TEMPLE_MQ_4_TORCH_ROOM] = Region("Water Temple MQ 4 Torch Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, {[]{return (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())) || + (logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && logic->CanUse(RG_HOOKSHOT) ));}}), + Entrance(RR_WATER_TEMPLE_MQ_DODONGO_ROOM, {[]{return logic->CanHitSwitch() && logic->HasFireSource();}}) + }); + + areaTable[RR_WATER_TEMPLE_MQ_DODONGO_ROOM] = Region("Water Temple MQ Dodongo Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, logic->CanBreakPots()), + LOCATION(RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, logic->CanBreakPots()), + }, { + //Exits + Entrance(RR_WATER_TEMPLE_MQ_4_TORCH_ROOM, {[]{return (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)) && + Here(RR_WATER_TEMPLE_MQ_DODONGO_ROOM, []{return logic->CanKillEnemy(RE_DODONGO, ED_CLOSE, true, 5);});}}), + Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_CAGE, {[]{return (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)) && + Here(RR_WATER_TEMPLE_MQ_DODONGO_ROOM, []{return logic->CanKillEnemy(RE_DODONGO, ED_CLOSE, true, 5);});}}) + }); + + areaTable[RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_CAGE] = Region("Water Temple MQ Basement Gated Areas", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, { + //Locations + LOCATION(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)), + }, { + Entrance(RR_WATER_TEMPLE_MQ_DODONGO_ROOM, {[]{return true;}}) + }); } /*--------------------------- @@ -307,9 +753,9 @@ void RegionTable_Init_WaterTemple() { Region("Water Temple Boss Entryway", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, { // Exits - 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; } }), + Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, {[]{return ctx->GetDungeon(WATER_TEMPLE)->IsVanilla() && false;}}), + Entrance(RR_WATER_TEMPLE_MQ_BOSS_DOOR, {[]{return ctx->GetDungeon(WATER_TEMPLE)->IsMQ() && false;}}), + Entrance(RR_WATER_TEMPLE_BOSS_ROOM, {[]{return true;}}), }); areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", "Water Temple", {}, NO_DAY_NIGHT_CYCLE, 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 6ad5ec758..ab1fd4366 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 @@ -16,26 +16,37 @@ void RegionTable_Init_ZorasDomain() { areaTable[RR_ZORAS_RIVER] = Region("Zora River", "Zora River", {RA_ZORAS_RIVER}, DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->GossipStoneFairy, {[]{return logic->CallGossipFairy();}}), - EventAccess(&logic->BeanPlantFairy, {[]{return logic->BeanPlantFairy || (CanPlantBean(RR_ZORAS_RIVER) && logic->CanUse(RG_SONG_OF_STORMS));}}), + EventAccess(&logic->BeanPlantFairy, {[]{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && 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 - 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), + 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->CanAttack() && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_NEAR_RAISED_GROTTOS, logic->IsAdult && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_GS_ABOVE_BRIDGE, logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && logic->CanGetNightTimeGS()), + LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, true), + LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), }, { //Exits Entrance(RR_ZR_FRONT, {[]{return true;}}), @@ -43,7 +54,12 @@ void RegionTable_Init_ZorasDomain() { 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));}}), + Entrance(RR_ZR_BEHIND_WATERFALL, {[]{ + return ctx->GetOption(RSK_SLEEPING_WATERFALL).Is(RO_WATERFALL_OPEN) || + Here(RR_ZORAS_RIVER, []{return logic->CanUse(RG_ZELDAS_LULLABY);}) || + (logic->IsChild && ctx->GetTrickOption(RT_ZR_CUCCO)) || + (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_ZR_HOVERS)); + }}), }); areaTable[RR_ZR_BEHIND_WATERFALL] = Region("ZR Behind Waterfall", "Zora River", {RA_ZORAS_RIVER}, DAY_NIGHT_CYCLE, {}, {}, { @@ -56,6 +72,8 @@ void RegionTable_Init_ZorasDomain() { //Locations LOCATION(RC_ZR_OPEN_GROTTO_CHEST, true), LOCATION(RC_ZR_OPEN_GROTTO_FISH, logic->HasBottle()), + LOCATION(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), + LOCATION(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), 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()), @@ -67,7 +85,17 @@ void RegionTable_Init_ZorasDomain() { areaTable[RR_ZR_FAIRY_GROTTO] = Region("ZR Fairy Grotto", "ZR Fairy Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Event EventAccess(&logic->FreeFairies, {[]{return true;}}), - }, {}, { + }, { + //Locations + LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_1, true), + LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_2, true), + LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_3, true), + LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_4, true), + LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_5, true), + LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_6, true), + LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_7, true), + LOCATION(RC_ZR_FAIRY_GROTTO_FAIRY_8, true), + }, { //Exits Entrance(RR_ZORAS_RIVER, {[]{return true;}}), }); @@ -96,22 +124,35 @@ void RegionTable_Init_ZorasDomain() { 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->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), + LOCATION(RC_ZD_GS_FROZEN_WATERFALL, logic->IsAdult && (logic->HookshotOrBoomerang() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || (logic->CanUse(RG_MAGIC_SINGLE) && (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))) || (ctx->GetTrickOption(RT_ZD_GS) && logic->CanJumpslashExceptHammer())) && logic->CanGetNightTimeGS()), LOCATION(RC_ZD_FISH_1, logic->IsChild && logic->HasBottle()), LOCATION(RC_ZD_FISH_2, logic->IsChild && logic->HasBottle()), 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_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_ZD_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_ZD_GOSSIP_STONE, true), LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, logic->CanBreakUpperBeehives()), LOCATION(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, logic->CanBreakUpperBeehives()), + LOCATION(RC_ZD_NEAR_SHOP_POT_1, logic->CanBreakPots()), + LOCATION(RC_ZD_NEAR_SHOP_POT_2, logic->CanBreakPots()), + LOCATION(RC_ZD_NEAR_SHOP_POT_3, logic->CanBreakPots()), + LOCATION(RC_ZD_NEAR_SHOP_POT_4, logic->CanBreakPots()), + LOCATION(RC_ZD_NEAR_SHOP_POT_5, logic->CanBreakPots()), }, { //Exits 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();}}), + Entrance(RR_ZORAS_DOMAIN_ISLAND, {[]{return true;}}), + }); + + areaTable[RR_ZORAS_DOMAIN_ISLAND] = Region("Zoras Domain Island", "Zoras Domain", {RA_ZORAS_DOMAIN}, NO_DAY_NIGHT_CYCLE, {}, {}, { + //Exits + Entrance(RR_ZORAS_DOMAIN, {[]{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}}), + Entrance(RR_ZD_STORMS_GROTTO, {[]{return logic->CanOpenStormsGrotto();}}), }); areaTable[RR_ZD_BEHIND_KING_ZORA] = Region("ZD Behind King Zora", "Zoras Domain", {RA_ZORAS_DOMAIN}, NO_DAY_NIGHT_CYCLE, {}, { @@ -141,9 +182,19 @@ void RegionTable_Init_ZorasDomain() { areaTable[RR_ZD_STORMS_GROTTO] = Region("ZD Storms Grotto", "ZD Storms Grotto", {}, NO_DAY_NIGHT_CYCLE, { //Events EventAccess(&logic->FreeFairies, {[]{return true;}}), - }, {}, { + }, { + //Locations + LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_1, true), + LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_2, true), + LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_3, true), + LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_4, true), + LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_5, true), + LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_6, true), + LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_7, true), + LOCATION(RC_ZD_FAIRY_GROTTO_FAIRY_8, true), + }, { //Exits - Entrance(RR_ZORAS_DOMAIN, {[]{return true;}}), + Entrance(RR_ZORAS_DOMAIN_ISLAND, {[]{return true;}}), }); areaTable[RR_ZORAS_FOUNTAIN] = Region("Zoras Fountain", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, { @@ -152,19 +203,48 @@ void RegionTable_Init_ZorasDomain() { EventAccess(&logic->ButterflyFairy, {[]{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}}), }, { //Locations - LOCATION(RC_ZF_ICEBERC_FREESTANDING_POH, logic->IsAdult), - LOCATION(RC_ZF_BOTTOM_FREESTANDING_POH, logic->IsAdult && logic->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), + LOCATION(RC_ZF_ICEBERG_FREESTANDING_POH, logic->IsAdult), + LOCATION(RC_ZF_BOTTOM_FREESTANDING_POH, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_GS_TREE, logic->IsChild), + LOCATION(RC_ZF_GS_ABOVE_THE_LOG, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_ZF_GS_HIDDEN_CAVE, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash() && logic->HookshotOrBoomerang() && logic->IsAdult && logic->CanGetNightTimeGS()), + LOCATION(RC_ZF_HIDDEN_CAVE_POT_1, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), + LOCATION(RC_ZF_HIDDEN_CAVE_POT_2, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), + LOCATION(RC_ZF_HIDDEN_CAVE_POT_3, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->IsAdult && logic->BlastOrSmash() && logic->CanBreakPots()), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), + LOCATION(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_ZF_BOTTOM_NORTH_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTH_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTH_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTH_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, logic->IsAdult && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16), + LOCATION(RC_ZF_FAIRY_GOSSIP_STONE, true), + LOCATION(RC_ZF_JABU_GOSSIP_STONE, true), + LOCATION(RC_ZF_NEAR_JABU_POT_1, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_NEAR_JABU_POT_2, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_NEAR_JABU_POT_3, logic->IsChild && logic->CanBreakPots()), + LOCATION(RC_ZF_NEAR_JABU_POT_4, logic->IsChild && logic->CanBreakPots()), }, { //Exits Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return true;}}), Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, {[]{return (logic->IsChild && logic->CanUse(RG_BOTTLE_WITH_FISH));}}), Entrance(RR_ICE_CAVERN_ENTRYWAY, {[]{return logic->IsAdult;}}), - Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives();}}), + Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, {[]{return logic->HasExplosives() || (ctx->GetTrickOption(RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SILVER_GAUNTLETS));}}), }); areaTable[RR_ZF_GREAT_FAIRY_FOUNTAIN] = Region("ZF Great Fairy Fountain", "ZF Great Fairy Fountain", {}, NO_DAY_NIGHT_CYCLE, {}, { diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index ab064bfe0..b15bfd552 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -7,7 +7,6 @@ #include "menu.hpp" #include "playthrough.hpp" -#include "randomizer.hpp" #include "spoiler_log.hpp" #include "location_access.hpp" #include "soh/Enhancements/debugger/performanceTimer.h" diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.hpp b/soh/soh/Enhancements/randomizer/3drando/menu.hpp index f9393d90e..e0e6e4210 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.hpp @@ -13,16 +13,4 @@ #define DELETE_PRESET 6 #define RESET_TO_DEFAULTS 8 -// #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" - 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 0d4f39c5c..23503638d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp @@ -10,6 +10,7 @@ #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "variables.h" #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" #include "../option.h" #include "soh/Enhancements/debugger/performanceTimer.h" @@ -79,14 +80,6 @@ int Playthrough_Init(uint32_t seed, std::set excludedLocations, SPDLOG_ERROR("Writing Spoiler Log Failed"); } StopPerformanceTimer(PT_SPOILER_LOG); -#ifdef ENABLE_DEBUG - SPDLOG_INFO("Writing Placement Log..."); - if (PlacementLog_Write()) { - SPDLOG_INFO("Writing Placement Log Done"); - } else { - SPDLOG_ERROR("Writing Placement Log Failed"); - } -#endif } ctx->playthroughLocations.clear(); @@ -104,7 +97,7 @@ int Playthrough_Repeat(std::set excludedLocations, std::setGetSettings()->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)); + SPDLOG_DEBUG("testing seed: %d", repeatedSeed); ClearProgress(); Playthrough_Init(ctx->GetSettings()->GetSeed(), excludedLocations, enabledTricks); SPDLOG_INFO("Seeds Generated: {}", i + 1); diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp index d4d7ebdd7..a2ed98072 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp @@ -4,20 +4,16 @@ #include "location_access.hpp" #include "rando_main.hpp" #include "../context.h" -// #include #include #include #include #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" void RandoMain::GenerateRando(std::set excludedLocations, std::set enabledTricks, std::string seedString) { - // std::string settingsFileName = "./randomizer/latest_settings.json"; - // CVarSetString(CVAR_RANDOMIZER_SETTING("LoadedPreset"), settingsFileName.c_str()); - Rando::Context::GetInstance()->SetSeedGenerated(GenerateRandomizer(excludedLocations, enabledTricks, seedString)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); - Rando::Context::GetInstance()->SetPlandoLoaded(false); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } diff --git a/soh/soh/Enhancements/randomizer/3drando/random.hpp b/soh/soh/Enhancements/randomizer/3drando/random.hpp index 2d2f11dbe..24ab78dcd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/random.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/random.hpp @@ -40,6 +40,7 @@ const T RandomElementFromSet(const std::set& set) { for (uint32_t i = 0; i < rand; i++) { it++; } + auto test = *it; return *it; } diff --git a/soh/soh/Enhancements/randomizer/3drando/randomizer.hpp b/soh/soh/Enhancements/randomizer/3drando/randomizer.hpp deleted file mode 100644 index 1b02c9037..000000000 --- a/soh/soh/Enhancements/randomizer/3drando/randomizer.hpp +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -#define RANDOMIZER_VERSION "v3.1" -#define COMMIT_NUMBER "develop" diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.hpp b/soh/soh/Enhancements/randomizer/3drando/settings.hpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index f6c73de32..ecf4ea1be 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -156,7 +156,7 @@ int GetPriceFromMax(int max) { uint16_t GetPriceFromSettings(Rando::Location *loc, PriceSettingsStruct priceSettings) { auto ctx = Rando::Context::GetInstance(); - switch (ctx->GetOption(priceSettings.main).Value()){ + switch (ctx->GetOption(priceSettings.main).GetContextOptionIndex()){ case RO_PRICE_VANILLA: return loc->GetVanillaPrice(); case RO_PRICE_CHEAP_BALANCED: @@ -172,19 +172,19 @@ uint16_t GetPriceFromSettings(Rando::Location *loc, PriceSettingsStruct priceSet return 150; } case RO_PRICE_FIXED: - return (uint16_t)ctx->GetOption(priceSettings.fixedPrice).Value() * 5; + return (uint16_t)ctx->GetOption(priceSettings.fixedPrice).GetContextOptionIndex() * 5; case RO_PRICE_RANGE:{ - uint16_t range1 = (uint16_t)ctx->GetOption(priceSettings.range1).Value() * 5; - uint16_t range2 = (uint16_t)ctx->GetOption(priceSettings.range2).Value() * 5; + uint16_t range1 = (uint16_t)ctx->GetOption(priceSettings.range1).GetContextOptionIndex() * 5; + uint16_t range2 = (uint16_t)ctx->GetOption(priceSettings.range2).GetContextOptionIndex() * 5; return range1 < range2 ? Random(range1, range2+1) : Random(range2, range1+1); } case RO_PRICE_SET_BY_WALLET:{ - bool isTycoon = ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET).Value(); - uint16_t noWeight = ctx->GetOption(priceSettings.noWallet).Value(); - uint16_t childWeight = ctx->GetOption(priceSettings.childWallet).Value(); - uint16_t adultWeight = ctx->GetOption(priceSettings.adultWallet).Value(); - uint16_t giantWeight = ctx->GetOption(priceSettings.giantWallet).Value(); - uint16_t tycoonWeight = isTycoon ? ctx->GetOption(priceSettings.tycoonWallet).Value() : 0; + bool isTycoon = ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET).GetContextOptionIndex(); + uint16_t noWeight = ctx->GetOption(priceSettings.noWallet).GetContextOptionIndex(); + uint16_t childWeight = ctx->GetOption(priceSettings.childWallet).GetContextOptionIndex(); + uint16_t adultWeight = ctx->GetOption(priceSettings.adultWallet).GetContextOptionIndex(); + uint16_t giantWeight = ctx->GetOption(priceSettings.giantWallet).GetContextOptionIndex(); + uint16_t tycoonWeight = isTycoon ? ctx->GetOption(priceSettings.tycoonWallet).GetContextOptionIndex() : 0; uint16_t totalWeight = noWeight + childWeight + adultWeight + giantWeight + tycoonWeight; if (totalWeight == 0){ //if no weight, return from sane range return Random(0, 501); diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index a418b8b5d..bed532e9b 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -6,8 +6,6 @@ #include "../entrance.h" #include "random.hpp" #include "../trial.h" -#include "tinyxml2.h" -#include "utils.hpp" #include "hints.hpp" #include "pool_functions.hpp" #include "soh/Enhancements/randomizer/randomizer_check_objects.h" @@ -56,9 +54,6 @@ void GenerateHash() { int number = std::stoi(hash.substr(j, 2)); ctx->hashIconIndexes[i] = number; } - - // Clear out spoiler log data here, in case we aren't going to re-generate it - // spoilerData = { 0 }; } static auto GetGeneralPath() { @@ -79,7 +74,6 @@ static void WriteLocation( Rando::Location* location = Rando::StaticData::GetLocation(locationKey); Rando::ItemLocation* itemLocation = Rando::Context::GetInstance()->GetItemLocation(locationKey); - // auto node = parentNode->InsertNewChildElement("location"); switch (gSaveContext.language) { case LANGUAGE_ENG: default: @@ -89,35 +83,6 @@ static void WriteLocation( jsonData["playthrough"][sphere][location->GetName()] = itemLocation->GetPlacedItemName().GetFrench(); break; } - // node->SetAttribute("name", location->GetName().c_str()); - // node->SetText(location->GetPlacedItemName().GetEnglish().c_str()); - - // if (withPadding) { - // constexpr int16_t LONGEST_NAME = 56; // The longest name of a location. - // constexpr int16_t PRICE_ATTRIBUTE = 12; // Length of a 3-digit price attribute. - - // // Insert a padding so we get a kind of table in the XML document. - // int16_t requiredPadding = LONGEST_NAME - location->GetName().length(); - // if (location->GetRCType() == RCTYPE_SHOP) { - // // Shop items have short location names, but come with an additional price attribute. - // requiredPadding -= PRICE_ATTRIBUTE; - // } - // if (requiredPadding >= 0) { - // std::string padding(requiredPadding, ' '); - // node->SetAttribute("_", padding.c_str()); - // } - // } - - // if (location->GetRCType() == RCTYPE_SHOP) { - // char price[6]; - // sprintf(price, "%03d", location->GetPrice()); - // node->SetAttribute("price", price); - // } - // if (!location->IsAddedToPool()) { - // #ifdef ENABLE_DEBUG - // node->SetAttribute("not-added", true); - // #endif - // } } //Writes a shuffled entrance to the specified node @@ -173,39 +138,34 @@ static void WriteShuffledEntrance(std::string sphereString, Entrance* entrance) // Writes the settings (without excluded locations, starting inventory and tricks) to the spoilerLog document. static void WriteSettings() { auto ctx = Rando::Context::GetInstance(); - auto allOptionGroups = ctx->GetSettings()->GetOptionGroups(); - for (const Rando::OptionGroup& optionGroup : allOptionGroups) { - if (optionGroup.GetContainsType() == Rando::OptionGroupType::DEFAULT && optionGroup.PrintInSpoiler()) { - for (const Rando::Option* option : optionGroup.GetOptions()) { - std::string settingName = optionGroup.GetName() + ":" + option->GetName(); - jsonData["settings"][settingName] = option->GetSelectedOptionText(); - } - } + std::array options = ctx->GetSettings()->GetAllOptions(); + for (const Rando::Option& option : options) { + if (option.GetName() != ""){ + jsonData["settings"][option.GetName()] = option.GetSelectedOptionText(); + } } } +// Removes any line breaks from s. +std::string RemoveLineBreaks(std::string s) { + s.erase(std::remove(s.begin(), s.end(), '\n'), s.end()); + return s; +} + // Writes the excluded locations to the spoiler log, if there are any. static void WriteExcludedLocations() { - // auto parentNode = spoilerLog.NewElement("excluded-locations"); auto ctx = Rando::Context::GetInstance(); for (size_t i = 1; i < ctx->GetSettings()->GetExcludeLocationsOptions().size(); i++) { for (const auto& location : ctx->GetSettings()->GetExcludeLocationsOptions()[i]) { - if (location->GetSelectedOptionIndex() == RO_LOCATION_INCLUDE) { + if (location->GetContextOptionIndex() == RO_LOCATION_INCLUDE) { continue; } jsonData["excludedLocations"].push_back(RemoveLineBreaks(location->GetName())); - // tinyxml2::XMLElement* node = spoilerLog.NewElement("location"); - // node->SetAttribute("name", RemoveLineBreaks(location->GetName()).c_str()); - // parentNode->InsertEndChild(node); } } - - // if (!parentNode->NoChildren()) { - // spoilerLog.RootElement()->InsertEndChild(parentNode); - // } } // Writes the starting inventory to the spoiler log, if there is any. @@ -214,63 +174,27 @@ static void WriteStartingInventory() { const Rando::OptionGroup& optionGroup = ctx->GetSettings()->GetOptionGroup(RSG_STARTING_INVENTORY); for (const Rando::OptionGroup* subGroup : optionGroup.GetSubGroups()) { if (subGroup->GetContainsType() == Rando::OptionGroupType::DEFAULT) { - for (const Rando::Option* option : subGroup->GetOptions()) { + for (Rando::Option* option : subGroup->GetOptions()) { jsonData["settings"][option->GetName()] = option->GetSelectedOptionText(); } } } } -// Writes the enabled tricks to the spoiler log, if there are any. -static void WriteEnabledTricks(tinyxml2::XMLDocument& spoilerLog) { - //auto parentNode = spoilerLog.NewElement("enabled-tricks"); +//Writes the enabled tricks to the spoiler log, if there are any. +static void WriteEnabledTricks() { auto ctx = Rando::Context::GetInstance(); for (const auto& setting : ctx->GetSettings()->GetOptionGroup(RSG_TRICKS).GetOptions()) { - if (setting->GetSelectedOptionIndex() != RO_GENERIC_ON/* || !setting->IsCategory(OptionCategory::Setting)*/) { + if (setting->GetContextOptionIndex() != RO_GENERIC_ON) { continue; } jsonData["enabledTricks"].push_back(RemoveLineBreaks(setting->GetName()).c_str()); - //auto node = parentNode->InsertNewChildElement("trick"); - //node->SetAttribute("name", RemoveLineBreaks(setting->GetName()).c_str()); } - - // if (!parentNode->NoChildren()) { - // spoilerLog.RootElement()->InsertEndChild(parentNode); - //} } -// Writes the enabled glitches to the spoiler log, if there are any. -// TODO: Implement Glitches -// static void WriteEnabledGlitches(tinyxml2::XMLDocument& spoilerLog) { -// auto parentNode = spoilerLog.NewElement("enabled-glitches"); - -// for (const auto& setting : Settings::glitchCategories) { -// if (setting->Value() == 0) { -// continue; -// } - -// auto node = parentNode->InsertNewChildElement("glitch-category"); -// node->SetAttribute("name", setting->GetName().c_str()); -// node->SetText(setting->GetSelectedOptionText().c_str()); -// } - -// for (const auto& setting : Settings::miscGlitches) { -// if (!setting->Value()) { -// continue; -// } - -// auto node = parentNode->InsertNewChildElement("misc-glitch"); -// node->SetAttribute("name", RemoveLineBreaks(setting->GetName()).c_str()); -// } - -// if (!parentNode->NoChildren()) { -// spoilerLog.RootElement()->InsertEndChild(parentNode); -// } -// } - // Writes the Master Quest dungeons to the spoiler log, if there are any. -static void WriteMasterQuestDungeons(tinyxml2::XMLDocument& spoilerLog) { +static void WriteMasterQuestDungeons() { auto ctx = Rando::Context::GetInstance(); for (const auto* dungeon : ctx->GetDungeons()->GetDungeonList()) { std::string dungeonName; @@ -294,7 +218,6 @@ static void WriteRequiredTrials() { // Writes the intended playthrough to the spoiler log, separated into spheres. static void WritePlaythrough() { - // auto playthroughNode = spoilerLog.NewElement("playthrough"); auto ctx = Rando::Context::GetInstance(); for (uint32_t i = 0; i < ctx->playthroughLocations.size(); ++i) { @@ -306,8 +229,6 @@ static void WritePlaythrough() { WriteLocation(sphereString, key, true); } } - - // spoilerLog.RootElement()->InsertEndChild(playthroughNode); } //Write the randomized entrance playthrough to the spoiler log, if applicable @@ -389,11 +310,6 @@ static void WriteAllLocations() { const char* SpoilerLog_Write() { auto ctx = Rando::Context::GetInstance(); - auto spoilerLog = tinyxml2::XMLDocument(false); - spoilerLog.InsertEndChild(spoilerLog.NewDeclaration()); - - auto rootNode = spoilerLog.NewElement("spoiler-log"); - spoilerLog.InsertEndChild(rootNode); jsonData.clear(); @@ -413,11 +329,8 @@ const char* SpoilerLog_Write() { WriteSettings(); WriteExcludedLocations(); WriteStartingInventory(); - WriteEnabledTricks(spoilerLog); //RANDOTODO clean up spoilerLog refernces - //if (Settings::Logic.Is(LOGIC_GLITCHED)) { - // WriteEnabledGlitches(spoilerLog); - //} - WriteMasterQuestDungeons(spoilerLog); + WriteEnabledTricks(); + WriteMasterQuestDungeons(); WriteRequiredTrials(); WritePlaythrough(); @@ -466,30 +379,3 @@ void PlacementLog_Clear() { placementtxt = ""; } -// RANDOTODO: Do we even use this? -bool PlacementLog_Write() { - auto placementLog = tinyxml2::XMLDocument(false); - placementLog.InsertEndChild(placementLog.NewDeclaration()); - - auto rootNode = placementLog.NewElement("placement-log"); - placementLog.InsertEndChild(rootNode); - - // rootNode->SetAttribute("version", Settings::version.c_str()); - // rootNode->SetAttribute("seed", Settings::seed); - - // WriteSettings(placementLog, true); // Include hidden settings. - // WriteExcludedLocations(placementLog); - // WriteStartingInventory(placementLog); - WriteEnabledTricks(placementLog); - //WriteEnabledGlitches(placementLog); - WriteMasterQuestDungeons(placementLog); - //WriteRequiredTrials(placementLog); - - placementtxt = "\n" + placementtxt; - - auto node = rootNode->InsertNewChildElement("log"); - auto contentNode = node->InsertNewText(placementtxt.c_str()); - contentNode->SetCData(true); - - return true; -} diff --git a/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp b/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp index 781b54ad3..4e1afddb7 100644 --- a/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp @@ -61,7 +61,7 @@ void GenerateStartingInventory() { AddItemToInventory(RG_GANONS_CASTLE_BOSS_KEY); } - if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN) && !ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) && !ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { AddItemToInventory(RG_GERUDO_MEMBERSHIP_CARD); } @@ -112,7 +112,7 @@ void GenerateStartingInventory() { // AddItemToInventory(RG_EMPTY_BOTTLE, 1); // } // AddItemToInventory(RG_RUTOS_LETTER, StartingRutoBottle.Value()); - AddItemToInventory(RG_PROGRESSIVE_OCARINA, ctx->GetOption(RSK_STARTING_OCARINA).Value()); + AddItemToInventory(RG_PROGRESSIVE_OCARINA, ctx->GetOption(RSK_STARTING_OCARINA).GetContextOptionIndex()); AddItemToInventory(RG_ZELDAS_LULLABY, ctx->GetOption(RSK_STARTING_ZELDAS_LULLABY) ? 1 : 0); AddItemToInventory(RG_EPONAS_SONG, ctx->GetOption(RSK_STARTING_EPONAS_SONG) ? 1 : 0); AddItemToInventory(RG_SARIAS_SONG, ctx->GetOption(RSK_STARTING_SARIAS_SONG) ? 1 : 0); @@ -153,21 +153,21 @@ void GenerateStartingInventory() { // AddItemToInventory(RG_SPIRIT_MEDALLION, StartingSpiritMedallion.Value()); // AddItemToInventory(RG_SHADOW_MEDALLION, StartingShadowMedallion.Value()); // AddItemToInventory(RG_LIGHT_MEDALLION, StartingLightMedallion.Value()); - AddItemToInventory(RG_GOLD_SKULLTULA_TOKEN, ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Value()); + AddItemToInventory(RG_GOLD_SKULLTULA_TOKEN, ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).GetContextOptionIndex()); - int8_t hearts = ctx->GetOption(RSK_STARTING_HEARTS).Value() - 2; + int8_t hearts = ctx->GetOption(RSK_STARTING_HEARTS).GetContextOptionIndex() - 2; AdditionalHeartContainers = 0; if (hearts < 0) { AddItemToInventory(RG_PIECE_OF_HEART, 4); // Plentiful and minimal have less than 4 standard pieces of heart so also replace the winner heart - if (ctx->GetOption(RSK_ITEM_POOL).Value() == 0 || ctx->GetOption(RSK_ITEM_POOL).Value() == 3) { + if (ctx->GetOption(RSK_ITEM_POOL).GetContextOptionIndex() == 0 || ctx->GetOption(RSK_ITEM_POOL).GetContextOptionIndex() == 3) { AddItemToInventory(RG_TREASURE_GAME_HEART); } AdditionalHeartContainers = 1 - hearts; } else if (hearts > 0) { // 16 containers in plentiful, 8 in balanced and 0 in the others - uint8_t maxContainers = 8 * std::max(0, 2 - ctx->GetOption(RSK_ITEM_POOL).Value()); + uint8_t maxContainers = 8 * std::max(0, 2 - ctx->GetOption(RSK_ITEM_POOL).GetContextOptionIndex()); if (hearts <= maxContainers) { AddItemToInventory(RG_HEART_CONTAINER, hearts); diff --git a/soh/soh/Enhancements/randomizer/3drando/utils.cpp b/soh/soh/Enhancements/randomizer/3drando/utils.cpp deleted file mode 100644 index 1cbe8c072..000000000 --- a/soh/soh/Enhancements/randomizer/3drando/utils.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "utils.hpp" - -// Removes any line breaks from s. -std::string RemoveLineBreaks(std::string s) { - s.erase(std::remove(s.begin(), s.end(), '\n'), s.end()); - return s; -} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/utils.hpp b/soh/soh/Enhancements/randomizer/3drando/utils.hpp deleted file mode 100644 index 3f5f69882..000000000 --- a/soh/soh/Enhancements/randomizer/3drando/utils.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include -#include - -std::string RemoveLineBreaks(std::string s); diff --git a/soh/soh/Enhancements/randomizer/Plandomizer.cpp b/soh/soh/Enhancements/randomizer/Plandomizer.cpp new file mode 100644 index 000000000..6dd6a5175 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/Plandomizer.cpp @@ -0,0 +1,1146 @@ +#include "Plandomizer.h" +#include "soh/UIWidgets.hpp" +#include "soh/util.h" +#include +#include "soh/Notification/Notification.h" +#include +#include "soh/Enhancements/randomizer/3drando/hints.hpp" + +#include +#include + +#include "soh/OTRGlobals.h" +#include "soh/ImGuiUtils.h" +#include "soh/Enhancements/randomizer/logic.h" +#include "soh/Enhancements/randomizer/randomizer_check_objects.h" +#include "soh/Enhancements/randomizer/rando_hash.h" +#include "soh/Enhancements/randomizer/3drando/shops.hpp" + +extern "C" { + #include "include/z64item.h" + #include "objects/gameplay_keep/gameplay_keep.h" + extern SaveContext gSaveContext; + extern PlayState* gPlayState; +} + +const std::string randomizeButton = ICON_FA_RANDOM; + +static int32_t correctedItemID = -1; +static int32_t getTabID = TAB_HINTS; + +Rando::Item temporaryItem; +std::string shortName = ""; +std::string logTemp = ""; +std::string lastLoadedSpoiler = ""; +int32_t temporaryItemIndex = -1; +RandomizerCheckArea selectedArea = RCAREA_INVALID; + +ImVec4 itemColor = ImVec4( 1.0f, 1.0f, 1.0f, 1.0f ); +ImTextureID textureID; +ImVec2 imageSize = ImVec2(32.0f, 32.0f); +float imagePadding = 2.0f; +ImVec2 textureUV0 = ImVec2( 0, 0 ); +ImVec2 textureUV1 = ImVec2( 1, 1 ); + +bool shouldPopup = false; +bool shouldTrapPopup = false; +bool shouldRemove = false; + +namespace fs = std::filesystem; +std::vector existingSeedList; + +std::vector spoilerHash; +std::vector plandoHash; +std::vector spoilerLogData; +std::vector plandoLogData; +std::vector> drawnItemsList; + +std::vector spoilerHintData; +std::vector plandoHintData; + +extern std::map rcAreaNames; + +std::unordered_map bossKeyShortNames = { + { RG_FOREST_TEMPLE_BOSS_KEY, "Frst" }, + { RG_FIRE_TEMPLE_BOSS_KEY, "Fire" }, + { RG_WATER_TEMPLE_BOSS_KEY, "Watr" }, + { RG_SPIRIT_TEMPLE_BOSS_KEY, "Sprt" }, + { RG_SHADOW_TEMPLE_BOSS_KEY, "Shdw" }, + { RG_GANONS_CASTLE_BOSS_KEY, "Ganon" }, +}; + +std::unordered_map ocarinaButtonNames = { + { RG_OCARINA_A_BUTTON, "A" }, + { RG_OCARINA_C_UP_BUTTON, "C-UP" }, + { RG_OCARINA_C_DOWN_BUTTON, "C-DWN" }, + { RG_OCARINA_C_LEFT_BUTTON, "C-LFT" }, + { RG_OCARINA_C_RIGHT_BUTTON, "C-RHT" }, +}; + +std::map bossSoulMapping = { + { RG_GOHMA_SOUL, { 0.00f, 1.00f, 0.00f, 1.0f } }, + { RG_KING_DODONGO_SOUL, { 1.00f, 0.00f, 0.39f, 1.0f } }, + { RG_BARINADE_SOUL, { 0.20f, 1.00f, 1.00f, 1.0f } }, + { RG_PHANTOM_GANON_SOUL, { 0.02f, 0.76f, 0.18f, 1.0f } }, + { RG_VOLVAGIA_SOUL, { 0.93f, 0.37f, 0.37f, 1.0f } }, + { RG_MORPHA_SOUL, { 0.33f, 0.71f, 0.87f, 1.0f } }, + { RG_BONGO_BONGO_SOUL, { 0.49f, 0.06f, 0.69f, 1.0f } }, + { RG_TWINROVA_SOUL, { 0.87f, 0.62f, 0.18f, 1.0f } }, + { RG_GANON_SOUL, { 0.31f, 0.31f, 0.31f, 1.0f } } +}; + + +std::vector infiniteItemList = { + RG_GREEN_RUPEE, RG_BLUE_RUPEE, RG_RED_RUPEE, RG_PURPLE_RUPEE, RG_HUGE_RUPEE, + RG_ARROWS_5, RG_ARROWS_10, RG_ARROWS_30, + RG_DEKU_STICK_1, RG_DEKU_SEEDS_30, RG_DEKU_NUTS_5, RG_DEKU_NUTS_10, + RG_BOMBS_5, RG_BOMBS_10, RG_BOMBS_20, RG_BOMBCHU_5, RG_BOMBCHU_10, RG_BOMBCHU_20, + RG_RECOVERY_HEART, RG_ICE_TRAP, RG_SOLD_OUT +}; + +std::unordered_map itemImageMap = { + { RG_NONE, "ITEM_SOLD_OUT" }, + { RG_KOKIRI_SWORD, "ITEM_SWORD_KOKIRI" }, + { RG_GIANTS_KNIFE, "ITEM_SWORD_KNIFE" }, + { RG_BIGGORON_SWORD, "ITEM_SWORD_BGS" }, + { RG_DEKU_SHIELD, "ITEM_SHIELD_DEKU" }, + { RG_HYLIAN_SHIELD, "ITEM_SHIELD_HYLIAN" }, + { RG_MIRROR_SHIELD, "ITEM_SHIELD_MIRROR" }, + { RG_GORON_TUNIC, "ITEM_TUNIC_GORON" }, + { RG_ZORA_TUNIC, "ITEM_TUNIC_ZORA" }, + { RG_IRON_BOOTS, "ITEM_BOOTS_IRON" }, + { RG_HOVER_BOOTS, "ITEM_BOOTS_HOVER" }, + { RG_BOOMERANG, "ITEM_BOOMERANG" }, + { RG_LENS_OF_TRUTH, "ITEM_LENS" }, + { RG_MEGATON_HAMMER, "ITEM_HAMMER" }, + { RG_STONE_OF_AGONY, "ITEM_STONE_OF_AGONY" }, + { RG_DINS_FIRE, "ITEM_DINS_FIRE" }, + { RG_FARORES_WIND, "ITEM_FARORES_WIND" }, + { RG_NAYRUS_LOVE, "ITEM_NAYRUS_LOVE" }, + { RG_FIRE_ARROWS, "ITEM_ARROW_FIRE" }, + { RG_ICE_ARROWS, "ITEM_ARROW_ICE" }, + { RG_LIGHT_ARROWS, "ITEM_ARROW_LIGHT" }, + { RG_GERUDO_MEMBERSHIP_CARD, "ITEM_GERUDO_CARD" }, + { RG_MAGIC_BEAN, "ITEM_BEAN" }, + { RG_MAGIC_BEAN_PACK, "ITEM_BEAN" }, + { RG_DOUBLE_DEFENSE, "ITEM_HEART_CONTAINER" }, + { RG_WEIRD_EGG, "ITEM_WEIRD_EGG" }, + { RG_ZELDAS_LETTER, "ITEM_LETTER_ZELDA" }, + { RG_POCKET_EGG, "ITEM_POCKET_EGG" }, + { RG_COJIRO, "ITEM_COJIRO" }, + { RG_ODD_MUSHROOM, "ITEM_ODD_MUSHROOM" }, + { RG_ODD_POTION, "ITEM_ODD_POTION" }, + { RG_POACHERS_SAW, "ITEM_SAW" }, + { RG_BROKEN_SWORD, "ITEM_SWORD_BROKEN" }, + { RG_PRESCRIPTION, "ITEM_PRESCRIPTION" }, + { RG_EYEBALL_FROG, "ITEM_FROG" }, + { RG_EYEDROPS, "ITEM_EYEDROPS" }, + { RG_CLAIM_CHECK, "ITEM_CLAIM_CHECK" }, + { RG_GOLD_SKULLTULA_TOKEN, "ITEM_SKULL_TOKEN" }, + { RG_PROGRESSIVE_HOOKSHOT, "ITEM_HOOKSHOT" }, + { RG_PROGRESSIVE_STRENGTH, "ITEM_BRACELET" }, + { RG_PROGRESSIVE_BOMB_BAG, "ITEM_BOMB_BAG_30" }, + { RG_PROGRESSIVE_BOW, "ITEM_QUIVER_30" }, + { RG_PROGRESSIVE_SLINGSHOT, "ITEM_SLINGSHOT" }, + { RG_PROGRESSIVE_WALLET, "ITEM_WALLET_ADULT" }, + { RG_PROGRESSIVE_SCALE, "ITEM_SCALE_SILVER" }, + { RG_PROGRESSIVE_NUT_UPGRADE, "ITEM_NUT" }, + { RG_PROGRESSIVE_STICK_UPGRADE, "ITEM_STICK" }, + { RG_PROGRESSIVE_BOMBCHUS, "ITEM_BOMBCHU" }, + { RG_PROGRESSIVE_MAGIC_METER, "ITEM_MAGIC_SMALL" }, + { RG_MAGIC_SINGLE, "ITEM_MAGIC_SMALL" }, + { RG_MAGIC_DOUBLE, "ITEM_MAGIC_LARGE" }, + { RG_PROGRESSIVE_OCARINA, "ITEM_OCARINA_FAIRY" }, + { RG_PROGRESSIVE_GORONSWORD, "ITEM_SWORD_BGS" }, + { RG_EMPTY_BOTTLE, "ITEM_BOTTLE" }, + { RG_BOTTLE_WITH_MILK, "ITEM_MILK_BOTTLE" }, + { RG_BOTTLE_WITH_RED_POTION, "ITEM_POTION_RED" }, + { RG_BOTTLE_WITH_GREEN_POTION, "ITEM_POTION_GREEN" }, + { RG_BOTTLE_WITH_BLUE_POTION, "ITEM_POTION_BLUE" }, + { RG_BOTTLE_WITH_FAIRY, "ITEM_FAIRY" }, + { RG_BOTTLE_WITH_FISH, "ITEM_FISH" }, + { RG_BOTTLE_WITH_BLUE_FIRE, "ITEM_BLUE_FIRE" }, + { RG_BOTTLE_WITH_BUGS, "ITEM_BUG" }, + { RG_BOTTLE_WITH_POE, "ITEM_POE" }, + { RG_RUTOS_LETTER, "ITEM_LETTER_RUTO" }, + { RG_BOTTLE_WITH_BIG_POE, "ITEM_BIG_POE" }, + { RG_ZELDAS_LULLABY, "ITEM_SONG_LULLABY" }, + { RG_EPONAS_SONG, "ITEM_SONG_EPONA" }, + { RG_SARIAS_SONG, "ITEM_SONG_SARIA" }, + { RG_SUNS_SONG, "ITEM_SONG_SUN" }, + { RG_SONG_OF_TIME, "ITEM_SONG_TIME" }, + { RG_SONG_OF_STORMS, "ITEM_SONG_STORMS" }, + { RG_MINUET_OF_FOREST, "ITEM_SONG_MINUET" }, + { RG_BOLERO_OF_FIRE, "ITEM_SONG_BOLERO" }, + { RG_SERENADE_OF_WATER, "ITEM_SONG_SERENADE" }, + { RG_REQUIEM_OF_SPIRIT, "ITEM_SONG_REQUIEM" }, + { RG_NOCTURNE_OF_SHADOW, "ITEM_SONG_NOCTURNE" }, + { RG_PRELUDE_OF_LIGHT, "ITEM_SONG_PRELUDE" }, + { RG_DEKU_TREE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_DODONGOS_CAVERN_MAP, "ITEM_DUNGEON_MAP" }, + { RG_JABU_JABUS_BELLY_MAP, "ITEM_DUNGEON_MAP" }, + { RG_FOREST_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_FIRE_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_WATER_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_SPIRIT_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_SHADOW_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_BOTTOM_OF_THE_WELL_MAP, "ITEM_DUNGEON_MAP" }, + { RG_ICE_CAVERN_MAP, "ITEM_DUNGEON_MAP" }, + { RG_DEKU_TREE_COMPASS, "ITEM_COMPASS" }, + { RG_DODONGOS_CAVERN_COMPASS, "ITEM_COMPASS" }, + { RG_JABU_JABUS_BELLY_COMPASS, "ITEM_COMPASS" }, + { RG_FOREST_TEMPLE_COMPASS, "ITEM_COMPASS" }, + { RG_FIRE_TEMPLE_COMPASS, "ITEM_COMPASS" }, + { RG_WATER_TEMPLE_COMPASS, "ITEM_COMPASS" }, + { RG_SPIRIT_TEMPLE_COMPASS, "ITEM_COMPASS" }, + { RG_SHADOW_TEMPLE_COMPASS, "ITEM_COMPASS" }, + { RG_BOTTOM_OF_THE_WELL_COMPASS, "ITEM_COMPASS" }, + { RG_ICE_CAVERN_COMPASS, "ITEM_COMPASS" }, + { RG_FOREST_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_FIRE_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_WATER_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_SPIRIT_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_SHADOW_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_GANONS_CASTLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_FOREST_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_FIRE_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_WATER_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_SPIRIT_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_SHADOW_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_BOTTOM_OF_THE_WELL_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_GERUDO_TRAINING_GROUND_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_GERUDO_FORTRESS_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_GANONS_CASTLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_TREASURE_GAME_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_KOKIRI_EMERALD, "ITEM_KOKIRI_EMERALD" }, + { RG_GORON_RUBY, "ITEM_GORON_RUBY" }, + { RG_ZORA_SAPPHIRE, "ITEM_ZORA_SAPPHIRE" }, + { RG_FOREST_MEDALLION, "ITEM_MEDALLION_FOREST" }, + { RG_FIRE_MEDALLION, "ITEM_MEDALLION_FIRE" }, + { RG_WATER_MEDALLION, "ITEM_MEDALLION_WATER" }, + { RG_SPIRIT_MEDALLION, "ITEM_MEDALLION_SPIRIT" }, + { RG_SHADOW_MEDALLION, "ITEM_MEDALLION_SHADOW" }, + { RG_LIGHT_MEDALLION, "ITEM_MEDALLION_LIGHT" }, + { RG_RECOVERY_HEART, "ITEM_HEART_GRAYSCALE" }, + { RG_GREEN_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_GREG_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_BLUE_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_RED_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_PURPLE_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_HUGE_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_TREASURE_GAME_GREEN_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_PIECE_OF_HEART, "ITEM_HEART_PIECE" }, + { RG_HEART_CONTAINER, "ITEM_HEART_CONTAINER" }, + { RG_ICE_TRAP, "ITEM_ICE_TRAP" }, + { RG_MILK, "ITEM_MILK_BOTTLE"}, + { RG_BOMBS_5, "ITEM_BOMB" }, + { RG_BOMBS_10, "ITEM_BOMB" }, + { RG_BOMBS_20, "ITEM_BOMB" }, + { RG_BUY_BOMBS_525, "ITEM_BOMB" }, + { RG_BUY_BOMBS_535, "ITEM_BOMB" }, + { RG_BUY_BOMBS_10, "ITEM_BOMB" }, + { RG_BUY_BOMBS_20, "ITEM_BOMB" }, + { RG_BUY_BOMBS_30, "ITEM_BOMB" }, + { RG_DEKU_NUTS_5, "ITEM_NUT" }, + { RG_DEKU_NUTS_10, "ITEM_NUT" }, + { RG_BUY_DEKU_NUTS_5, "ITEM_NUT" }, + { RG_BUY_DEKU_NUTS_10, "ITEM_NUT" }, + { RG_BOMBCHU_5, "ITEM_BOMBCHU" }, + { RG_BOMBCHU_10, "ITEM_BOMBCHU" }, + { RG_BOMBCHU_20, "ITEM_BOMBCHU" }, + { RG_BUY_BOMBCHUS_20, "ITEM_BOMBCHU" }, + { RG_ARROWS_5, "ITEM_ARROWS_SMALL" }, + { RG_BUY_ARROWS_10, "ITEM_ARROWS_SMALL" }, + { RG_ARROWS_10, "ITEM_ARROWS_MEDIUM" }, + { RG_BUY_ARROWS_30, "ITEM_ARROWS_MEDIUM" }, + { RG_ARROWS_30, "ITEM_ARROWS_LARGE" }, + { RG_BUY_ARROWS_50, "ITEM_ARROWS_LARGE" }, + { RG_TREASURE_GAME_HEART, "ITEM_HEART_PIECE" }, + { RG_DEKU_SEEDS_30, "ITEM_SEEDS" }, + { RG_BUY_DEKU_SEEDS_30, "ITEM_SEEDS" }, + { RG_BUY_HEART, "ITEM_HEART_GRAYSCALE" }, + { RG_FISHING_POLE, "ITEM_FISHING_POLE" }, + { RG_SOLD_OUT, "ITEM_SOLD_OUT" }, + { RG_TRIFORCE_PIECE, "TRIFORCE_PIECE" }, + { RG_SKELETON_KEY, "ITEM_KEY_SMALL" } +}; + +Rando::Item plandomizerRandoRetrieveItem(RandomizerGet randoGetItem) { + auto randoGetItemEntry = Rando::StaticData::RetrieveItem(randoGetItem); + return randoGetItemEntry; +} + +void PlandoPushImageButtonStyle(){ + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 1.0f, 1.0f, 0.0f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 1.0f, 1.0f, 0.2f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 1.0f, 1.0f, 0.1f)); +} + +void PlandoPopImageButtonStyle(){ + ImGui::PopStyleColor(3); +} + +ImVec4 plandomizerGetItemColor(Rando::Item randoItem) { + itemColor = ImVec4( 1.0f, 1.0f, 1.0f, 1.0f ); + if (randoItem.GetItemType() == ITEMTYPE_SMALLKEY || randoItem.GetItemType() == ITEMTYPE_FORTRESS_SMALLKEY + || randoItem.GetItemType() == ITEMTYPE_BOSSKEY) { + if (randoItem.GetRandomizerGet() == RG_FOREST_TEMPLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_FOREST_TEMPLE_KEY_RING) { + itemColor = ImVec4( 0.02f, 0.76f, 0.18f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_FIRE_TEMPLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_FIRE_TEMPLE_KEY_RING) { + itemColor = ImVec4( 0.93f, 0.37f, 0.37f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_WATER_TEMPLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_WATER_TEMPLE_KEY_RING) { + itemColor = ImVec4( 0.33f, 0.71f, 0.87f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_SPIRIT_TEMPLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_SPIRIT_TEMPLE_KEY_RING) { + itemColor = ImVec4( 0.87f, 0.62f, 0.18f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_SHADOW_TEMPLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_SHADOW_TEMPLE_KEY_RING) { + itemColor = ImVec4( 0.49f, 0.06f, 0.69f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_BOTTOM_OF_THE_WELL_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_BOTTOM_OF_THE_WELL_KEY_RING) { + itemColor = ImVec4( 0.89f, 0.43f, 1.0f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_GERUDO_TRAINING_GROUND_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_GERUDO_TRAINING_GROUND_KEY_RING) { + itemColor = ImVec4( 1.0f, 1.0f, 0, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_GERUDO_FORTRESS_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_GERUDO_FORTRESS_KEY_RING) { + itemColor = ImVec4( 1.0f, 1.0f, 1.0f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_GANONS_CASTLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_GANONS_CASTLE_KEY_RING) { + itemColor = ImVec4( 0.5f, 0.5f, 0.5f, 1.0f ); + } + return itemColor; + } + if (randoItem.GetItemType() == ITEMTYPE_SONG) { + uint32_t questID = Rando::Logic::RandoGetToQuestItem[randoItem.GetRandomizerGet()]; + textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(songMapping.at((QuestItem)questID).name); + itemColor = songMapping.at((QuestItem)questID).color; + imageSize = ImVec2(24.0f, 32.0f); + imagePadding = 6.0f; + return itemColor; + } + if (randoItem.GetRandomizerGet() >= RG_GREEN_RUPEE && randoItem.GetRandomizerGet() <= RG_HUGE_RUPEE) { + if (randoItem.GetRandomizerGet() == RG_GREG_RUPEE || randoItem.GetRandomizerGet() == RG_GREEN_RUPEE + || randoItem.GetRandomizerGet() == RG_TREASURE_GAME_GREEN_RUPEE) { + itemColor = ImVec4( 0.02f, 0.76f, 0.18f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_BLUE_RUPEE) { + itemColor = ImVec4( 0.33f, 0.71f, 0.87f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_RED_RUPEE) { + itemColor = ImVec4( 0.93f, 0.37f, 0.37f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_PURPLE_RUPEE) { + itemColor = ImVec4( 0.89f, 0.43f, 1.0f, 1.0f ); + } else if (randoItem.GetRandomizerGet() == RG_HUGE_RUPEE) { + itemColor = ImVec4( 1.0f, 1.0f, 0, 1.0f ); + } + return itemColor; + } + + if (randoItem.GetRandomizerGet() >= RG_GOHMA_SOUL && randoItem.GetRandomizerGet() <= RG_GANON_SOUL) { + itemColor = bossSoulMapping.at(randoItem.GetRandomizerGet()); + } + + return itemColor; +} + +std::string plandomizerHintsTooltip() { + std::string hintTootip; + hintTootip = + "The following options are available:\n" + "- Use \\n to create New Lines.\n" + "- Use %g to change the text color to Green,\n" + " - %r for Red, %y for Yellow, and %w for White\n" + " can also be used as color examples."; + + return hintTootip; +} + +std::string extractNumberInParentheses(const std::string& text) { + size_t start = text.find('('); + size_t end = text.find(')'); + + if (start != std::string::npos && end != std::string::npos && start < end) { + return text.substr(start + 1, end - start - 1); + } + return ""; +} + +void PlandomizerPopulateSeedList() { + existingSeedList.clear(); + auto spoilerPath = Ship::Context::GetPathRelativeToAppDirectory("Randomizer"); + + if (std::filesystem::exists(spoilerPath)) { + for (const auto& entry : std::filesystem::directory_iterator(spoilerPath)) { + if (entry.is_regular_file() && entry.path().extension() == ".json") { + existingSeedList.push_back(entry.path().stem().string()); + } + } + } +} + +void PlandomizerItemImageCorrection(Rando::Item randoItem) { + textureID = 0; + imageSize = ImVec2( 32.0f, 32.0f ); + imagePadding = 2.0f; + textureUV0 = ImVec2( 0, 0 ); + textureUV1 = ImVec2( 1, 1 ); + + + itemColor = plandomizerGetItemColor(randoItem); + + if (randoItem.GetItemType() == ITEMTYPE_SMALLKEY || randoItem.GetItemType() == ITEMTYPE_FORTRESS_SMALLKEY) { + textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_KEY_SMALL"); + return; + } + if (randoItem.GetItemType() == ITEMTYPE_BOSSKEY) { + textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_KEY_BOSS"); + return; + } + + for (auto& map : itemImageMap) { + if (map.first == randoItem.GetRandomizerGet()) { + textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(map.second.c_str()); + if (map.second.find("ITEM_ARROWS") != std::string::npos) { + textureUV0 = ImVec2( 0, 1 ); + textureUV1 = ImVec2( 1, 0 ); + } + if (map.second == "ITEM_TRIFORCE" || map.first == RG_SKELETON_KEY) { + textureUV0 = ImVec2( 1, 1 ); + textureUV1 = ImVec2( 0, 0 ); + } + break; + } + } + + if (randoItem.GetRandomizerGet() >= RG_GOHMA_SOUL && randoItem.GetRandomizerGet() <= RG_GANON_SOUL) { + textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("BOSS_SOUL"); + } + + if (randoItem.GetRandomizerGet() >= RG_OCARINA_A_BUTTON && randoItem.GetRandomizerGet() <= RG_OCARINA_C_RIGHT_BUTTON) { + textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_TIME"); + } + + if (textureID == 0) { + textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[randoItem.GetGIEntry()->itemId].name); + } +} + +void PlandomizerRandomizeHint(int32_t status, int32_t index) { + if (status == HINT_SINGLE) { + plandoHintData[index].hintText = Rando::StaticData::hintTextTable[GetRandomJunkHint()].GetHintMessage().GetForCurrentLanguage(MF_ENCODE); + } else { + for (auto& hint : plandoHintData) { + hint.hintText = Rando::StaticData::hintTextTable[GetRandomJunkHint()].GetHintMessage().GetForCurrentLanguage(MF_ENCODE); + } + } +} + +void PlandomizerRemoveAllHints() { + if (plandoHintData.size() > 0) { + for (auto& remove : plandoHintData) { + remove.hintText.clear(); + } + } +} + +void PlandomizerSortDrawnItems() { + std::sort(drawnItemsList.begin(), drawnItemsList.end(), + [](const auto& a, const auto& b) { + auto typeA = a.first.GetItemType(); + auto typeB = b.first.GetItemType(); + if (typeA != typeB){ + return typeA < typeB; + } + return a.first.GetRandomizerGet() < b.first.GetRandomizerGet(); + }); +} + +void PlandomizerRemoveAllItems() { + if (drawnItemsList.size() == 1) { + drawnItemsList.clear(); + } + for (auto& remove : plandoLogData) { + if (std::find(infiniteItemList.begin(), infiniteItemList.end(), remove.checkRewardItem.GetRandomizerGet()) == infiniteItemList.end()) { + bool itemExists = false; + for (auto& itemToCheck : drawnItemsList) { + if (itemToCheck.first.GetRandomizerGet() == remove.checkRewardItem.GetRandomizerGet()) { + itemToCheck.second += 1; + itemExists = true; + break; + } + } + if (!itemExists) { + drawnItemsList.push_back(std::make_pair(remove.checkRewardItem, 1)); + } + } + remove.checkRewardItem = plandomizerRandoRetrieveItem(RG_SOLD_OUT); + } + PlandomizerSortDrawnItems(); +} + +void PlandomizerRemoveFromItemList(Rando::Item randoItem) { + if (std::find(infiniteItemList.begin(), infiniteItemList.end(), randoItem.GetRandomizerGet()) == infiniteItemList.end()) { + uint32_t index = 0; + for (auto& itemToCheck : drawnItemsList) { + if (itemToCheck.first.GetRandomizerGet() == randoItem.GetRandomizerGet()) { + if (shouldRemove) { + drawnItemsList.erase(drawnItemsList.begin() + index); + break; + } else { + itemToCheck.second -= 1; + } + } + index++; + } + shouldRemove = false; + } + PlandomizerSortDrawnItems(); +} + +void PlandomizerAddToItemList(Rando::Item randoItem) { + if (std::find(infiniteItemList.begin(), infiniteItemList.end(), randoItem.GetRandomizerGet()) == infiniteItemList.end()) { + bool itemExists = false; + for (auto& itemToCheck : drawnItemsList) { + if (itemToCheck.first.GetRandomizerGet() == randoItem.GetRandomizerGet()) { + itemToCheck.second += 1; + itemExists = true; + break; + } + } + + if (!itemExists) { + drawnItemsList.push_back(std::make_pair(randoItem, 1)); + } + } + PlandomizerSortDrawnItems(); +} + +void PlandomizerSaveSpoilerLog() { + nlohmann::json spoilerSave; + std::string filename = lastLoadedSpoiler; + + std::ifstream inputFile(filename); + if (inputFile.is_open()) { + inputFile >> spoilerSave; + inputFile.close(); + } + + spoilerSave["file_hash"] = { + plandoHash[0], plandoHash[1], plandoHash[2], plandoHash[3], plandoHash[4] + }; + + for (auto& import : plandoHintData) { + spoilerSave["Gossip Stone Hints"][import.hintName] = { + { "type", import.hintType.c_str() }, + { "message", import.hintText.c_str() } + }; + } + + for (auto& import : plandoLogData) { + if (import.checkRewardItem.GetRandomizerGet() == RG_ICE_TRAP) { + spoilerSave["locations"][import.checkName] = { + { "item", import.checkRewardItem.GetName().english }, + { "model", import.iceTrapModel.GetName().english }, + { "trickName", import.iceTrapName.c_str() } + }; + if (import.shopPrice > -1) { + spoilerSave["locations"][import.checkName]["price"] = import.shopPrice; + } + } else if (import.shopPrice > -1) { + spoilerSave["locations"][import.checkName] = { + { "item", import.checkRewardItem.GetName().english }, + { "price", import.shopPrice } + }; + } else { + spoilerSave["locations"][import.checkName] = import.checkRewardItem.GetName().english; + } + } + + std::ofstream outputFile(filename); + if (outputFile.is_open()) { + outputFile << spoilerSave.dump(4); + outputFile.close(); + } +} + +void PlandomizerLoadSpoilerLog(std::string logFile) { + spoilerHash.clear(); + plandoHash.clear(); + spoilerLogData.clear(); + plandoLogData.clear(); + spoilerHintData.clear(); + plandoHintData.clear(); + drawnItemsList.clear(); + + nlohmann::json spoilerLogInput; + auto spoilerPath = Ship::Context::GetPathRelativeToAppDirectory("Randomizer"); + std::string spoilerStr = spoilerPath + "/" + logFile.c_str() + ".json"; + + if (!std::filesystem::exists(spoilerStr)) { + return; + } + + std::ifstream file(spoilerStr); + + if (file.is_open()) { + try { + file >> spoilerLogInput; + file.close(); + + if (spoilerLogInput.contains("file_hash")) { + auto hash = spoilerLogInput["file_hash"]; + for (auto& load : hash) { + spoilerHash.push_back(load); + plandoHash.push_back(load); + } + } + + if (spoilerLogInput.contains("Gossip Stone Hints")) { + auto hints = spoilerLogInput["Gossip Stone Hints"]; + for (auto& [key, value] : hints.items()) { + SpoilerHintObject hintObject; + hintObject.hintName = key.c_str(); + hintObject.hintType = "Hardcoded Message"; + hintObject.hintText = value["message"]; + + spoilerHintData.push_back(hintObject); + plandoHintData.push_back(hintObject); + } + } + + if (spoilerLogInput.contains("locations")) { + auto locations = spoilerLogInput["locations"]; + for (auto& [key, value] : locations.items()) { + if (key == "Ganon" || key == "Completed Triforce") { + continue; + } + SpoilerCheckObject checkObject; + checkObject.checkName = key; + auto type = value; + if (value.is_object()) { + checkObject.checkRewardItem = plandomizerRandoRetrieveItem(Rando::StaticData::itemNameToEnum[value["item"]]); + if (value["price"].is_number()) { + checkObject.shopPrice = value["price"]; + } else { + checkObject.shopPrice = -1; + } + if (checkObject.checkRewardItem.GetRandomizerGet() == RG_ICE_TRAP) { + checkObject.iceTrapModel = plandomizerRandoRetrieveItem(Rando::StaticData::itemNameToEnum[value["model"]]); + checkObject.iceTrapName = value["trickName"]; + } + } else { + checkObject.checkRewardItem = plandomizerRandoRetrieveItem(Rando::StaticData::itemNameToEnum[value.get()]); + checkObject.shopPrice = -1; + if (checkObject.shopPrice == -1 + && checkObject.checkRewardItem.GetName().english.find("Buy") != std::string::npos) { + checkObject.shopPrice = checkObject.checkRewardItem.GetPrice(); + } + } + spoilerLogData.push_back(checkObject); + plandoLogData.push_back(checkObject); + PlandomizerAddToItemList(plandomizerRandoRetrieveItem(RG_SOLD_OUT)); + } + } + } catch (nlohmann::json::parse_error& e) { + Notification::Emit({ .message = "Invalid Spoiler Log Format", .remainingTime = 10.0f }); + } + } + lastLoadedSpoiler = spoilerStr; +} + +void PlandomizerOverlayText(std::pair drawObject ) { + // Overlay the item count text on the existing button + ImVec2 imageMin = ImGui::GetItemRectMin(); + ImVec2 imageMax = ImGui::GetItemRectMax(); + ImVec2 textPos = ImVec2(imageMax.x - ImGui::CalcTextSize(std::to_string(drawObject.second).c_str()).x - 2, + imageMax.y - ImGui::CalcTextSize(std::to_string(drawObject.second).c_str()).y - 2); + + ImGui::SetCursorScreenPos(textPos); + ImGui::Text(std::to_string(drawObject.second).c_str()); + + // Overlay item info + if (drawObject.first.GetRandomizerGet() >= RG_PROGRESSIVE_HOOKSHOT && + drawObject.first.GetRandomizerGet() <= RG_PROGRESSIVE_GORONSWORD) { + textPos = ImVec2(imageMin.x + 2, imageMin.y + 2); + + ImGui::SetCursorScreenPos(textPos); + ImGui::Text("+"); + } + if (extractNumberInParentheses(drawObject.first.GetName().english.c_str()) != "" && + extractNumberInParentheses(drawObject.first.GetName().english.c_str()) != "WINNER" && + extractNumberInParentheses(drawObject.first.GetName().english.c_str()) != "LOSER") { + textPos = ImVec2(imageMin.x + 2, imageMin.y + 2); + + ImGui::SetCursorScreenPos(textPos); + std::string overlayText = "+"; + overlayText += extractNumberInParentheses(drawObject.first.GetName().english.c_str()); + ImGui::Text(overlayText.c_str()); + } + if (drawObject.first.GetRandomizerGet() >= RG_FOREST_TEMPLE_BOSS_KEY && + drawObject.first.GetRandomizerGet() <= RG_GANONS_CASTLE_BOSS_KEY) { + textPos = ImVec2(imageMin.x + 1, imageMin.y + 1); + ImGui::SetCursorScreenPos(textPos); + shortName = ""; + for (auto& name : bossKeyShortNames) { + if (name.first == drawObject.first.GetRandomizerGet()) { + shortName = name.second; + break; + } + } + ImGui::Text(shortName.c_str()); + } + if (drawObject.first.GetRandomizerGet() >= RG_OCARINA_A_BUTTON && + drawObject.first.GetRandomizerGet() <= RG_OCARINA_C_RIGHT_BUTTON) { + textPos = ImVec2(imageMin.x + 1, imageMin.y + 1); + ImGui::SetCursorScreenPos(textPos); + shortName = ""; + for (auto& name : ocarinaButtonNames) { + if (name.first == drawObject.first.GetRandomizerGet()) { + shortName = name.second; + break; + } + } + ImGui::Text(shortName.c_str()); + } +} + +void PlandomizerDrawItemPopup(uint32_t index) { + if (shouldPopup && ImGui::BeginPopup("ItemList")) { + PlandoPushImageButtonStyle(); + ImGui::SeparatorText("Resources"); + ImGui::BeginTable("Infinite Item Table", 7); + for (auto& item : infiniteItemList) { + ImGui::PushID(item); + ImGui::TableNextColumn(); + PlandomizerItemImageCorrection(plandomizerRandoRetrieveItem(item)); + if (ImGui::ImageButton(textureID, + imageSize, textureUV0, textureUV1, imagePadding, ImVec4(0, 0, 0, 0), itemColor)) { + if (std::find(infiniteItemList.begin(), infiniteItemList.end(), plandoLogData[index].checkRewardItem.GetRandomizerGet()) == infiniteItemList.end()) { + PlandomizerAddToItemList(plandoLogData[index].checkRewardItem); + } + plandoLogData[index].checkRewardItem = plandomizerRandoRetrieveItem(item); + ImGui::CloseCurrentPopup(); + } + UIWidgets::Tooltip(plandomizerRandoRetrieveItem(item).GetName().english.c_str()); + PlandomizerOverlayText(std::make_pair(plandomizerRandoRetrieveItem(item), 1)); + ImGui::PopID(); + } + + + ImGui::EndTable(); + ImGui::SeparatorText("Spoiler Log Rewards"); + ImGui::BeginTable("Item Button Table", 8); + uint32_t itemIndex = 0; + + bool isClicked = false; + for (auto& drawSlots : drawnItemsList) { + ImGui::TableNextColumn(); + ImGui::BeginGroup(); + ImGui::PushID(itemIndex); + auto itemToDraw = drawSlots.first; + PlandomizerItemImageCorrection(drawSlots.first); + if (ImGui::ImageButton(textureID, + imageSize, textureUV0, textureUV1, imagePadding, ImVec4(0, 0, 0, 0), itemColor)) { + if (itemToDraw.GetRandomizerGet() >= RG_PROGRESSIVE_HOOKSHOT && + itemToDraw.GetRandomizerGet() <= RG_PROGRESSIVE_GORONSWORD) { + plandoLogData[index].checkRewardItem = drawSlots.first; + } else { + plandoLogData[index].checkRewardItem = itemToDraw; + } + temporaryItemIndex = itemIndex; + if (drawSlots.second == 1) { + shouldRemove = true; + } + isClicked = true; + ImGui::CloseCurrentPopup(); + } + if (!isClicked) { + UIWidgets::Tooltip(drawSlots.first.GetName().english.c_str()); + } + ImGui::PopID(); + + PlandomizerOverlayText(drawSlots); + + ImGui::EndGroup(); + itemIndex++; + } + if (isClicked) { + PlandomizerRemoveFromItemList(drawnItemsList[temporaryItemIndex].first); + PlandomizerAddToItemList(temporaryItem); + } + PlandoPopImageButtonStyle(); + ImGui::EndTable(); + ImGui::EndPopup(); + } +} + +void PlandomizerDrawIceTrapPopUp(uint32_t index) { + if (shouldTrapPopup && ImGui::BeginPopup("TrapList")) { + ImGui::BeginTable("Ice Trap Table", 8); + PlandoPushImageButtonStyle(); + for (auto& items : itemImageMap) { + if (items.first == RG_ICE_TRAP) { + continue; + } + ImGui::TableNextColumn(); + ImGui::PushID(items.first); + PlandomizerItemImageCorrection(Rando::StaticData::RetrieveItem(items.first)); + if (ImGui::ImageButton(textureID, imageSize, textureUV0, textureUV1, imagePadding, ImVec4(0, 0, 0, 0), itemColor)) { + plandoLogData[index].iceTrapModel = Rando::StaticData::RetrieveItem(items.first); + ImGui::CloseCurrentPopup(); + }; + UIWidgets::Tooltip(Rando::StaticData::RetrieveItem(items.first).GetName().english.c_str()); + + auto itemObject = Rando::StaticData::RetrieveItem(items.first); + PlandomizerOverlayText(std::make_pair(itemObject, 1)); + + ImGui::PopID(); + } + PlandoPopImageButtonStyle(); + ImGui::EndTable(); + ImGui::EndPopup(); + } +} + +void PlandomizerDrawItemSlots(uint32_t index) { + ImGui::PushID(index); + PlandoPushImageButtonStyle(); + PlandomizerItemImageCorrection(plandoLogData[index].checkRewardItem); + if (ImGui::ImageButton(textureID, imageSize, textureUV0, textureUV1, imagePadding, ImVec4(0, 0, 0, 0), itemColor)) { + shouldPopup = true; + temporaryItem = plandoLogData[index].checkRewardItem; + ImGui::OpenPopup("ItemList"); + }; + PlandoPopImageButtonStyle(); + UIWidgets::Tooltip(plandoLogData[index].checkRewardItem.GetName().english.c_str()); + PlandomizerOverlayText(std::make_pair(plandoLogData[index].checkRewardItem, 1)); + PlandomizerDrawItemPopup(index); + ImGui::PopID(); +} + +void PlandomizerDrawShopSlider(uint32_t index) { + ImGui::PushID(index); + ImGui::Text("Price:"); + ImGui::SameLine(); + std::string MinusBTNName = " - ##Price"; + if (ImGui::Button(MinusBTNName.c_str()) && plandoLogData[index].shopPrice > 0) { + plandoLogData[index].shopPrice--; + } + ImGui::SameLine(); + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x - 40.0f); + ImGui::SliderInt("", &plandoLogData[index].shopPrice, 0, 999, "%d Rupees"); + ImGui::PopItemWidth(); + ImGui::SameLine(); + std::string PlusBTNName = " + ##Price"; + if (ImGui::Button(PlusBTNName.c_str()) && plandoLogData[index].shopPrice < 999) { + plandoLogData[index].shopPrice++; + } + ImGui::PopID(); +} + +void PlandomizerDrawIceTrapSetup(uint32_t index) { + std::string trapTextInput = plandoLogData[index].iceTrapName.c_str(); + + ImGui::PushID(index); + ImGui::BeginTable("IceTrap", 2, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInner); + ImGui::TableSetupColumn("Model", ImGuiTableColumnFlags_WidthFixed, 36.0f); + ImGui::TableSetupColumn("Trap Options"); + ImGui::TableHeadersRow(); + + ImGui::TableNextColumn(); + PlandomizerItemImageCorrection(plandoLogData[index].iceTrapModel); + PlandoPushImageButtonStyle(); + if (ImGui::ImageButton(textureID, imageSize, textureUV0, textureUV1, imagePadding, ImVec4(0, 0, 0, 0), itemColor)) { + shouldTrapPopup = true; + ImGui::OpenPopup("TrapList"); + }; + PlandoPopImageButtonStyle(); + UIWidgets::Tooltip(plandoLogData[index].iceTrapModel.GetName().english.c_str()); + PlandomizerDrawIceTrapPopUp(index); + ImGui::SameLine(); + ImGui::TableNextColumn(); + ImGui::Text("Name: "); + ImGui::SameLine(); + if (plandoLogData[index].iceTrapModel.GetRandomizerGet() != RG_NONE && + plandoLogData[index].iceTrapModel.GetRandomizerGet() != RG_SOLD_OUT) { + if (ImGui::Button(randomizeButton.c_str())) { + plandoLogData[index].iceTrapName = + GetIceTrapName(plandoLogData[index].iceTrapModel.GetRandomizerGet()).GetForLanguage(CVarGetInteger(CVAR_SETTING("Languages"), 0)).c_str(); + } + ImGui::SameLine(); + } + if (UIWidgets::InputString("##TrapName", &trapTextInput)) { + plandoLogData[index].iceTrapName = trapTextInput.c_str(); + } + + if (plandoLogData[index].shopPrice >= 0) { + PlandomizerDrawShopSlider(index); + } + ImGui::EndTable(); + + ImGui::PopID(); +} + +void PlandomizerDrawOptions() { + if (ImGui::BeginTable("LoadSpoiler", 2)) { + ImGui::TableNextColumn(); + ImGui::SeparatorText("Load/Save Spoiler Log"); + PlandomizerPopulateSeedList(); + static size_t selectedList = 0; + if (existingSeedList.size() != 0) { + if (ImGui::BeginCombo("##JsonFiles", existingSeedList[selectedList].c_str())) { + for (size_t i = 0; i < existingSeedList.size(); i++) { + bool isSelected = (selectedList == i); + if (ImGui::Selectable(existingSeedList[i].c_str(), isSelected)) { + selectedList = i; + } + if (isSelected) { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + } + else { + ImGui::Text("No Spoiler Logs found."); + } + ImGui::BeginDisabled(existingSeedList.empty()); + if (ImGui::Button("Load")) { + logTemp = existingSeedList[selectedList].c_str(); + PlandomizerLoadSpoilerLog(logTemp.c_str()); + } + ImGui::EndDisabled(); + ImGui::BeginDisabled(spoilerLogData.empty()); + ImGui::SameLine(); + if (ImGui::Button("Save")) { + PlandomizerSaveSpoilerLog(); + } + ImGui::EndDisabled(); + + ImGui::TableNextColumn(); + ImGui::SeparatorText("Current Seed Hash"); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (ImGui::GetContentRegionAvail().x * 0.5f) - (34.0f * 5.0f)); + if (spoilerLogData.size() > 0) { + if (ImGui::BeginTable("HashIcons", 5)) { + for (int i = 0; i < 5; i++) { + ImGui::TableSetupColumn("Icon", ImGuiTableColumnFlags_WidthFixed, 34.0f); + } + ImGui::TableNextColumn(); + + size_t index = 0; + PlandoPushImageButtonStyle(); + for (auto& hash : plandoHash) { + ImGui::PushID(index); + textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(gSeedTextures[hash].tex); + if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("HASH_ARROW_UP"), + ImVec2(35.0f, 18.0f), ImVec2(1, 1), ImVec2(0, 0), 2.0f, ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + if (hash + 1 >= gSeedTextures.size()) { + hash = 0; + } + else { + hash++; + } + } + ImGui::Image(textureID, ImVec2(35.0f, 35.0f)); + if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("HASH_ARROW_DWN"), + ImVec2(35.0f, 18.0f), ImVec2(0, 0), ImVec2(1, 1), 2.0f, ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1))) { + if (hash == 0) { + hash = gSeedTextures.size() - 1; + } + else { + hash--; + } + } + if (index != spoilerHash.size() - 1) { + ImGui::TableNextColumn(); + } + ImGui::PopID(); + index++; + } + PlandoPopImageButtonStyle(); + ImGui::EndTable(); + } + } + else { + ImGui::Text("No Spoiler Log Loaded"); + } + ImGui::EndTable(); + } + + ImGui::SeparatorText("Options"); + if (plandoLogData.size() == 0) { + ImGui::Text("Please Load Spoiler Data..."); + return; + } + + if (getTabID == TAB_HINTS) { + if (ImGui::Button("Clear All Hints")) { + PlandomizerRemoveAllHints(); + } + ImGui::SameLine(); + if (ImGui::Button("Randomize All Hints")) { + PlandomizerRandomizeHint(HINT_ALL, 0); + } + } + if (getTabID == TAB_LOCATIONS) { + if (plandoLogData.size() > 0) { + const char* comboLabel = rcAreaNames[selectedArea].c_str(); + if (selectedArea == RCAREA_INVALID) { + comboLabel = "All"; + } + ImGui::Text("Filter by Area:"); + ImGui::SameLine(); + ImGui::PushItemWidth(300.0f); + if (ImGui::BeginCombo("##AreaFilter", comboLabel)) { + for (const auto& [area, name] : rcAreaNames) { + bool isSelected = (selectedArea == area); + + const char* displayName = name.c_str(); + if (area == RCAREA_INVALID) { + displayName = "All"; + } + if (ImGui::Selectable(displayName, isSelected)) { + selectedArea = area; + } + if (isSelected) { + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndCombo(); + } + ImGui::PopItemWidth(); + + ImGui::SameLine(); + if (ImGui::Button("Empty All Rewards")) { + PlandomizerRemoveAllItems(); + } + } + } +} + +void PlandomizerDrawHintsWindow() { + uint32_t index = 0; + std::string hintInputText; + + ImGui::BeginChild("Hints"); + if (ImGui::BeginTable("Hints Window", 1, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_ScrollY)) { + ImGui::TableSetupColumn("Hint Entries"); + ImGui::TableSetupScrollFreeze(0, 1); + ImGui::TableHeadersRow(); + + for (auto& hintData : spoilerHintData) { + ImGui::PushID(index); + ImGui::TableNextColumn(); + ImGui::SeparatorText(hintData.hintName.c_str()); + ImGui::Text("Current Hint: "); + ImGui::SameLine(); + ImGui::TextWrapped(hintData.hintText.c_str()); + + if (spoilerHintData.size() > 0) { + hintInputText = plandoHintData[index].hintText.c_str(); + } + ImGui::Text("New Hint: "); + ImGui::SameLine(); + if (ImGui::Button(randomizeButton.c_str())) { + PlandomizerRandomizeHint(HINT_SINGLE, index); + } + UIWidgets::Tooltip("Randomize Hint"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 10); + if (UIWidgets::InputString("##HintMessage", &hintInputText)) { + plandoHintData[index].hintText = hintInputText.c_str(); + } + UIWidgets::Tooltip(plandomizerHintsTooltip().c_str()); + index++; + ImGui::PopID(); + } + + ImGui::EndTable(); + } + ImGui::EndChild(); +} + +void PlandomizerDrawLocationsWindow(RandomizerCheckArea rcArea) { + uint32_t index = 0; + ImGui::BeginChild("Locations"); + if (ImGui::BeginTable("Locations Window", 4, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_ScrollY)) { + ImGui::TableSetupColumn("Spoiler Log Check Name", ImGuiTableColumnFlags_WidthFixed, 250.0f); + ImGui::TableSetupColumn("Spoiler Log Reward", ImGuiTableColumnFlags_WidthFixed, 190.0f); + ImGui::TableSetupColumn("New Reward", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 34.0f); + ImGui::TableSetupColumn("Additional Options"); + ImGui::TableSetupScrollFreeze(0, 1); + ImGui::TableHeadersRow(); + + for (auto& spoilerData : spoilerLogData) { + auto checkID = Rando::StaticData::locationNameToEnum[spoilerData.checkName]; + auto randoArea = Rando::StaticData::GetLocation(checkID)->GetArea(); + if (rcArea == RCAREA_INVALID || rcArea == randoArea) { + ImGui::TableNextColumn(); + ImGui::TextWrapped(spoilerData.checkName.c_str()); + ImGui::TableNextColumn(); + ImGui::TextWrapped(spoilerData.checkRewardItem.GetName().english.c_str()); + ImGui::TableNextColumn(); + PlandomizerDrawItemSlots(index); + if (plandoLogData[index].checkRewardItem.GetRandomizerGet() == RG_ICE_TRAP) { + ImGui::TableNextColumn(); + PlandomizerDrawIceTrapSetup(index); + } + else if (spoilerData.shopPrice != -1) { + ImGui::TableNextColumn(); + ImGui::BeginTable("Shops", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInner); + ImGui::TableSetupColumn("Shop Price"); + ImGui::TableHeadersRow(); + ImGui::TableNextColumn(); + PlandomizerDrawShopSlider(index); + ImGui::EndTable(); + } + else { + ImGui::TableNextColumn(); + } + } + index++; + } + ImGui::EndTable(); + } + ImGui::EndChild(); +} + +void PlandomizerDrawSpoilerTable() { + ImGui::BeginChild("Main"); + if (ImGui::BeginTabBar("Check Tabs")) { + if (ImGui::BeginTabItem("Gossip Stones")) { + getTabID = TAB_HINTS; + PlandomizerDrawHintsWindow(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Locations")) { + getTabID = TAB_LOCATIONS; + PlandomizerDrawLocationsWindow(selectedArea); + ImGui::EndTabItem(); + } + } + ImGui::EndTabBar(); + ImGui::EndChild(); +} + +void PlandomizerWindow::DrawElement() { + PlandomizerDrawOptions(); + UIWidgets::PaddedSeparator(); + PlandomizerDrawSpoilerTable(); +} + +void PlandomizerWindow::InitElement() { + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_RUPEE_GRAYSCALE", gRupeeCounterIconTex, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_HEART_GRAYSCALE", gHeartFullTex, ImVec4(0.87f, 0.10f, 0.10f, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_SEEDS", gItemIconDekuSeedsTex, ImVec4( 1, 1, 1, 1 )); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_SMALL", gDropArrows1Tex, ImVec4( 1, 1, 1, 1 )); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_MEDIUM", gDropArrows2Tex, ImVec4( 1, 1, 1, 1 )); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_LARGE", gDropArrows3Tex, ImVec4( 1, 1, 1, 1 )); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ICE_TRAP", gMagicArrowEquipEffectTex, ImVec4( 1, 1, 1, 1 )); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("HASH_ARROW_UP", gEmptyCDownArrowTex, ImVec4( 1, 1, 1, 1 )); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("HASH_ARROW_DWN", gEmptyCDownArrowTex, ImVec4( 1, 1, 1, 1 )); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("BOSS_SOUL", gBossSoulTex, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("TRIFORCE_PIECE", gTriforcePieceTex, ImVec4(1, 1, 1, 1)); +} diff --git a/soh/soh/Enhancements/randomizer/Plandomizer.h b/soh/soh/Enhancements/randomizer/Plandomizer.h new file mode 100644 index 000000000..d337e4da6 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/Plandomizer.h @@ -0,0 +1,52 @@ +#pragma once +#ifndef PLANDOMIZER_H +#define PLANDOMIZER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif // PLANDOMIZER_H + +#include +#include "soh/Enhancements/randomizer/item.h" + +#ifdef __cplusplus +class PlandomizerWindow : public Ship::GuiWindow { + public: + using GuiWindow::GuiWindow; + + void InitElement() override; + void DrawElement() override; + void UpdateElement() override{}; +}; + +typedef struct { + std::string checkName; + Rando::Item checkRewardItem; + int32_t shopPrice; + Rando::Item iceTrapModel; + std::string iceTrapName; +} SpoilerCheckObject; + +typedef struct { + std::string hintName; + std::string hintType; + std::string hintText; +} SpoilerHintObject; + +typedef enum { + TAB_HINTS, + TAB_LOCATIONS +}; + +typedef enum { + HINT_SINGLE, + HINT_ALL, +}; + +#endif \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp new file mode 100644 index 000000000..d5d1cfe94 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp @@ -0,0 +1,177 @@ +#include "ShuffleFairies.h" +#include "randomizer_grotto.h" +#include "draw.h" +#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h" +#include "src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h" +#include "src/overlays/actors/ovl_En_Gs/z_en_gs.h" +#include "../../OTRGlobals.h" +#include "../../cvar_prefixes.h" + +#define FAIRY_FLAG_TIMED (1 << 8) + +void ShuffleFairies_DrawRandomizedItem(EnElf* enElf, PlayState* play) { + GetItemEntry randoGetItem = enElf->sohFairyIdentity.itemEntry; + if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { + randoGetItem = GET_ITEM_MYSTERY; + } + Matrix_Push(); + Matrix_Scale(37.5, 37.5, 37.5, MTXMODE_APPLY); + EnItem00_CustomItemsParticles(&enElf->actor, play, randoGetItem); + GetItemEntry_Draw(play, randoGetItem); + Matrix_Pop(); +} + +bool ShuffleFairies_FairyExists(FairyIdentity fairyIdentity) { + Actor* actor = gPlayState->actorCtx.actorLists[ACTORCAT_ITEMACTION].head; + + while (actor != NULL) { + if (actor->id != ACTOR_EN_ELF) { + actor = actor->next; + } else { + EnElf* enElf = (EnElf*)(actor); + if (fairyIdentity.randomizerInf == enElf->sohFairyIdentity.randomizerInf) { + return true; + } + actor = actor->next; + } + } + + return false; +} + +FairyIdentity ShuffleFairies_GetFairyIdentity(int32_t params) { + FairyIdentity fairyIdentity; + s16 sceneNum = gPlayState->sceneNum; + fairyIdentity.randomizerInf = RAND_INF_MAX; + + if (sceneNum == SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT || sceneNum == SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS) { + sceneNum = SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY; + } + + Rando::Location* location = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_ELF, sceneNum, params); + + if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("FairyGetIdentity did not receive a valid RC value (%d).", location->GetRandomizerCheck()); + assert(false); + } else { + fairyIdentity.randomizerInf = static_cast(location->GetCollectionCheck().flag); + fairyIdentity.itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(location->GetRandomizerCheck(), true, GI_FAIRY); + } + + return fairyIdentity; +} + +bool ShuffleFairies_SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params) { + FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params); + if (!Flags_GetRandomizerInf(fairyIdentity.randomizerInf)) { + EnElf* fairy = (EnElf*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_ELF, posX, posY - 30.0f, posZ, 0, + 0, 0, FAIRY_HEAL, true); + fairy->sohFairyIdentity = fairyIdentity; + fairy->actor.draw = (ActorFunc)ShuffleFairies_DrawRandomizedItem; + return true; + } + return false; +} + +void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { + va_list args; + va_copy(args, originalArgs); + + Actor* actor = va_arg(args, Actor*); + + va_end(args); + + // Grant item when picking up fairy. If randomized, disable healing effect. + if (id == VB_FAIRY_HEAL) { + EnElf* enElf = (EnElf*)(actor); + if (enElf->sohFairyIdentity.randomizerInf && enElf->sohFairyIdentity.randomizerInf != RAND_INF_MAX) { + Flags_SetRandomizerInf(enElf->sohFairyIdentity.randomizerInf); + } + // Spawn fairies in fairy fountains + } else if (id == VB_SPAWN_FOUNTAIN_FAIRIES) { + bool fairySpawned = false; + s16 grottoId = (gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN) ? Grotto_CurrentGrotto() : 0; + for (s16 index = 0; index < 8; index++) { + int32_t params = (grottoId << 8) | index; + if (ShuffleFairies_SpawnFairy(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, + params)) { + fairySpawned = true; + } + } + if (fairySpawned) { + *should = false; + } + // Spawn 3 fairies when playing Song of Storms next to a planted bean + } else if (id == VB_SPAWN_BEAN_STALK_FAIRIES) { + ObjBean* objBean = (ObjBean*)(actor); + bool fairySpawned = false; + for (s16 index = 0; index < 3; index++) { + int32_t params = ((objBean->dyna.actor.params & 0x3F) << 8) | index; + if (ShuffleFairies_SpawnFairy(objBean->dyna.actor.world.pos.x, objBean->dyna.actor.world.pos.y, + objBean->dyna.actor.world.pos.z, + params)) { + fairySpawned = true; + } + } + if (fairySpawned) { + *should = false; + } + // Handle playing both misc songs and song of storms in front of a gossip stone. + } else if (id == VB_SPAWN_GOSSIP_STONE_FAIRY) { + EnGs* gossipStone = (EnGs*)(actor); + + // If not any of the songs that normally spawn a fairy, mimic vanilla behaviour. + if (gPlayState->msgCtx.ocarinaMode == OCARINA_MODE_01) { + Player* player = GET_PLAYER(gPlayState); + player->stateFlags2 |= PLAYER_STATE2_NEAR_OCARINA_ACTOR; + return; + } else if (gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_LULLABY && + gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_SARIAS && + gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_EPONAS && + gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_SUNS && + gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_TIME && + gPlayState->msgCtx.unk_E3F2 != OCARINA_SONG_STORMS && + gPlayState->msgCtx.ocarinaMode != OCARINA_MODE_04) { + return; + } + + int32_t params = (gPlayState->sceneNum == SCENE_GROTTOS) ? Grotto_CurrentGrotto() : 0; + // Distinguish storms fairies from the normal song fairies + if (gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_STORMS) { + params |= 0x1000; + } + + // Combine actor + song params with position to get the right randomizer check + params = TWO_ACTOR_PARAMS(params, (int32_t)gossipStone->actor.world.pos.z); + + // Check if a fairy already exists with the same identity as the stone is trying to spawn. + // Because the gossip stone code runs several times after playing the song, we need to + // stop spawning the vanilla fairy as well when these fairies exist, otherwise both + // the randomized and the vanilla fairy will spawn. When the randomized fairy is already + // collected, the vanilla code will handle that part automatically. + FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params); + if (!ShuffleFairies_FairyExists(fairyIdentity)) { + if (ShuffleFairies_SpawnFairy(gossipStone->actor.world.pos.x, gossipStone->actor.world.pos.y, + gossipStone->actor.world.pos.z, params)) { + Audio_PlayActorSound2(&gossipStone->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); + // Set vanilla check for fairy spawned so it doesn't spawn the vanilla fairy afterwards as well. + gossipStone->unk_19D = 0; + *should = false; + } + } else { + *should = false; + } + } +} + +uint32_t onVanillaBehaviorHook = 0; + +void ShuffleFairies_RegisterHooks() { + onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(ShuffleFairies_OnVanillaBehaviorHandler); +} + +void ShuffleFairies_UnregisterHooks() { + GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); + + onVanillaBehaviorHook = 0; +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.h b/soh/soh/Enhancements/randomizer/ShuffleFairies.h new file mode 100644 index 000000000..f10537ae1 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleFairies.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include "soh/Enhancements/item-tables/ItemTableTypes.h" +#include "randomizer_inf.h" + +typedef struct FairyIdentity { + RandomizerInf randomizerInf; + GetItemEntry itemEntry; +} FairyIdentity; + +void ShuffleFairies_RegisterHooks(); +void ShuffleFairies_UnregisterHooks(); diff --git a/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp b/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp new file mode 100644 index 000000000..e08bfbb92 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp @@ -0,0 +1,45 @@ +#include "ShuffleFreestanding.h" + +extern "C" { +#include "functions.h" +extern PlayState* gPlayState; +} + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +void ShuffleFreestanding_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { + va_list args; + va_copy(args, originalArgs); + + if (id == VB_ITEM00_DESPAWN) { + EnItem00* item00 = va_arg(args, EnItem00*); + + // Heart pieces and small keys are handled by default non-freestanding shuffles. + if (item00->actor.params == ITEM00_HEART_PIECE || item00->actor.params == ITEM00_SMALL_KEY) { + return; + } + + uint32_t params = TWO_ACTOR_PARAMS((int32_t)item00->actor.world.pos.x, (int32_t)item00->actor.world.pos.z); + Rando::Location* loc = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(item00->actor.id, gPlayState->sceneNum, params); + uint8_t isDungeon = loc->IsDungeon(); + uint8_t freestandingSetting = + Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_FREESTANDING).GetContextOptionIndex(); + RandomizerCheck randomizerCheck = loc->GetRandomizerCheck(); + bool checkObtained = Rando::Context::GetInstance()->GetItemLocation(randomizerCheck)->HasObtained(); + + // Don't change to randomized item if current freestanding item isn't shuffled or already obtained. + if ((freestandingSetting == RO_SHUFFLE_FREESTANDING_OVERWORLD && isDungeon) || + (freestandingSetting == RO_SHUFFLE_FREESTANDING_DUNGEONS && !isDungeon) || + checkObtained || randomizerCheck == RC_UNKNOWN_CHECK) { + return; + } + + item00->randoInf = static_cast(loc->GetCollectionCheck().flag); + item00->randoCheck = randomizerCheck; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(randomizerCheck, true); + item00->actor.params = ITEM00_SOH_DUMMY; + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + + *should = false; + } +} diff --git a/soh/soh/Enhancements/randomizer/ShuffleFreestanding.h b/soh/soh/Enhancements/randomizer/ShuffleFreestanding.h new file mode 100644 index 000000000..9234f76fa --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleFreestanding.h @@ -0,0 +1,9 @@ +#ifndef SHUFFLE_FREESTANDING_H +#define SHUFFLE_FREESTANDING_H + +#include +#include + +void ShuffleFreestanding_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs); + +#endif diff --git a/soh/soh/Enhancements/randomizer/ShufflePots.cpp b/soh/soh/Enhancements/randomizer/ShufflePots.cpp new file mode 100644 index 000000000..f5c7070dd --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShufflePots.cpp @@ -0,0 +1,98 @@ +#include "ShufflePots.h" +#include "soh_assets.h" +#include "static_data.h" + +extern "C" { +#include "variables.h" +#include "overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h" +#include "overlays/actors/ovl_Door_Shutter/z_door_shutter.h" +extern PlayState* gPlayState; +} + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + + +extern "C" void ObjTsubo_RandomizerDraw(Actor* thisx, PlayState* play) { + float potSize = 1.0f; + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + Matrix_Scale(potSize, potSize, potSize, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gRandoPotDL); + CLOSE_DISPS(play->state.gfxCtx); +} + +uint8_t ObjTsubo_RandomizerHoldsItem(ObjTsubo* potActor, PlayState* play) { + RandomizerCheck rc = potActor->potIdentity.randomizerCheck; + uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); + uint8_t potSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_POTS).GetContextOptionIndex(); + + // Don't pull randomized item if pot isn't randomized or is already checked + if (!IS_RANDO || (potSetting == RO_SHUFFLE_POTS_OVERWORLD && isDungeon) || + (potSetting == RO_SHUFFLE_POTS_DUNGEONS && !isDungeon) || + Flags_GetRandomizerInf(potActor->potIdentity.randomizerInf) || + potActor->potIdentity.randomizerCheck == RC_UNKNOWN_CHECK) { + return false; + } else { + return true; + } +} + +void ObjTsubo_RandomizerSpawnCollectible(ObjTsubo* potActor, PlayState* play) { + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &potActor->actor.world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = potActor->potIdentity.randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(potActor->potIdentity.randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + item00->actor.velocity.y = 8.0f; + item00->actor.speedXZ = 2.0f; + item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f); +} + +void ObjTsubo_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + + // Check for Lake Hylia specifically because the game spawns 2 pots out of bounds there for some reason. + if (actor->id != ACTOR_OBJ_TSUBO || gPlayState->sceneNum == SCENE_LAKE_HYLIA || gPlayState->sceneNum == SCENE_HYRULE_CASTLE) return; + + ObjTsubo* potActor = static_cast(actorRef); + + potActor->potIdentity = OTRGlobals::Instance->gRandomizer->IdentifyPot(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); +} + +void ShufflePots_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { + va_list args; + va_copy(args, originalArgs); + + // Draw custom model for pot to indicate it holding a randomized item. + if (id == VB_POT_SETUP_DRAW) { + ObjTsubo* potActor = va_arg(args, ObjTsubo*); + if (ObjTsubo_RandomizerHoldsItem(potActor, gPlayState)) { + potActor->actor.draw = (ActorFunc)ObjTsubo_RandomizerDraw; + *should = false; + } + } + + // Do not spawn vanilla item from pot, instead spawn the ranomized item. + if (id == VB_POT_DROP_ITEM) { + ObjTsubo* potActor = va_arg(args, ObjTsubo*); + if (ObjTsubo_RandomizerHoldsItem(potActor, gPlayState)) { + ObjTsubo_RandomizerSpawnCollectible(potActor, gPlayState); + *should = false; + } + } + + // Unlock early Ganon's Boss Key doors to allow access to the pots there when pots are shuffled in dungeon + if (id == VB_LOCK_BOSS_DOOR) { + DoorShutter* doorActor = va_arg(args, DoorShutter*); + uint8_t shufflePotSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_POTS).GetContextOptionIndex(); + if (gPlayState->sceneNum == SCENE_GANONS_TOWER && doorActor->dyna.actor.world.pos.y == 800 && + (shufflePotSetting == RO_SHUFFLE_POTS_DUNGEONS || shufflePotSetting == RO_SHUFFLE_POTS_ALL)) { + *should = false; + } + } + + va_end(args); +} diff --git a/soh/soh/Enhancements/randomizer/ShufflePots.h b/soh/soh/Enhancements/randomizer/ShufflePots.h new file mode 100644 index 000000000..28c4e2f4a --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShufflePots.h @@ -0,0 +1,17 @@ +#ifndef SHUFFLEPOTS_H +#define SHUFFLEPOTS_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +void ObjTsubo_RandomizerInit(void* actorRef); +#ifdef __cplusplus +}; +#endif + +void ShufflePots_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs); + +#endif //SHUFFLEPOTS_H diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index e0c269057..7b33df771 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -92,12 +92,8 @@ ItemOverride& Context::GetItemOverride(size_t locKey) { void Context::PlaceItemInLocation(const RandomizerCheck locKey, const RandomizerGet item, const bool applyEffectImmediately, const bool setHidden) { const auto loc = GetItemLocation(locKey); - SPDLOG_DEBUG("\n"); - SPDLOG_DEBUG(StaticData::RetrieveItem(item).GetName().GetEnglish()); - SPDLOG_DEBUG(" placed at "); - SPDLOG_DEBUG(StaticData::GetLocation(locKey)->GetName()); - SPDLOG_DEBUG("\n\n"); - + SPDLOG_DEBUG(StaticData::RetrieveItem(item).GetName().GetEnglish() + " placed at " + StaticData::GetLocation(locKey)->GetName() + "\n"); + if (applyEffectImmediately || mSettings->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS) || mSettings->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) { StaticData::RetrieveItem(item).ApplyEffect(); } @@ -125,6 +121,13 @@ void Context::AddLocations(const Container& locations, std::vectorinsert(destination->end(), std::cbegin(locations), std::cend(locations)); } +bool Context::IsQuestOfLocationActive(RandomizerCheck rc) { + const auto loc = Rando::StaticData::GetLocation(rc); + return loc->GetQuest() == RCQUEST_BOTH || + loc->GetQuest() == RCQUEST_MQ && mDungeons->GetDungeonFromScene(loc->GetScene())->IsMQ() || + loc->GetQuest() == RCQUEST_VANILLA && mDungeons->GetDungeonFromScene(loc->GetScene())->IsVanilla(); +} + void Context::GenerateLocationPool() { allLocations.clear(); if (mSettings->GetOption(RSK_TRIFORCE_HUNT)) { @@ -136,6 +139,11 @@ void Context::GenerateLocationPool() { AddLocations(mFishsanity->GetFishsanityLocations().first); } + if (mSettings->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_OVERWORLD) || + mSettings->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL)) { + AddLocations(StaticData::GetOverworldPotLocations()); + } + AddLocations(StaticData::GetAllDungeonLocations()); } @@ -228,14 +236,6 @@ void Context::SetSpoilerLoaded(const bool spoilerLoaded) { mSpoilerLoaded = spoilerLoaded; } -bool Context::IsPlandoLoaded() const { - return mPlandoLoaded; -} - -void Context::SetPlandoLoaded(const bool plandoLoaded) { - mPlandoLoaded = plandoLoaded; -} - GetItemEntry Context::GetFinalGIEntry(const RandomizerCheck rc, const bool checkObtainability, const GetItemID ogItemId) { const auto itemLoc = GetItemLocation(rc); if (itemLoc->GetPlacedRandomizerGet() == RG_NONE) { @@ -278,27 +278,23 @@ std::string sanitize(std::string stringValue) { return stringValue; } -void Context::ParseSpoiler(const char* spoilerFileName, const bool plandoMode) { +void Context::ParseSpoiler(const char* spoilerFileName) { std::ifstream spoilerFileStream(sanitize(spoilerFileName)); if (!spoilerFileStream) { return; } mSeedGenerated = false; mSpoilerLoaded = false; - mPlandoLoaded = false; try { nlohmann::json spoilerFileJson; spoilerFileStream >> spoilerFileJson; ParseHashIconIndexesJson(spoilerFileJson); mSettings->ParseJson(spoilerFileJson); - if (plandoMode) { - ParseItemLocationsJson(spoilerFileJson); - ParseHintJson(spoilerFileJson); - mEntranceShuffler->ParseJson(spoilerFileJson); - mDungeons->ParseJson(spoilerFileJson); - mTrials->ParseJson(spoilerFileJson); - mPlandoLoaded = true; - } + ParseItemLocationsJson(spoilerFileJson); + ParseHintJson(spoilerFileJson); + mEntranceShuffler->ParseJson(spoilerFileJson); + mDungeons->ParseJson(spoilerFileJson); + mTrials->ParseJson(spoilerFileJson); mSpoilerLoaded = true; mSeedGenerated = false; } catch (...) { diff --git a/soh/soh/Enhancements/randomizer/context.h b/soh/soh/Enhancements/randomizer/context.h index 842b73c25..e2baf9559 100644 --- a/soh/soh/Enhancements/randomizer/context.h +++ b/soh/soh/Enhancements/randomizer/context.h @@ -50,6 +50,7 @@ class Context { void AddLocation(RandomizerCheck loc, std::vector* destination = nullptr); template void AddLocations(const Container& locations, std::vector* destination = nullptr); + bool IsQuestOfLocationActive(RandomizerCheck rc); void GenerateLocationPool(); static std::vector GetLocations(const std::vector& locationPool, const RandomizerCheckType checkType); void AddExcludedOptions(); @@ -62,8 +63,6 @@ class Context { void SetSeedGenerated(bool seedGenerated = true); bool IsSpoilerLoaded() const; void SetSpoilerLoaded(bool spoilerLoaded = true); - bool IsPlandoLoaded() const; - void SetPlandoLoaded(bool plandoLoaded = true); std::shared_ptr GetSettings(); std::shared_ptr GetEntranceShuffler(); std::shared_ptr GetDungeons(); @@ -78,7 +77,7 @@ class Context { Option& GetOption(RandomizerSettingKey key) const; TrickOption& GetTrickOption(RandomizerTrick key) const; GetItemEntry GetFinalGIEntry(RandomizerCheck rc, bool checkObtainability = true, GetItemID ogItemId = GI_NONE); - void ParseSpoiler(const char* spoilerFileName, bool plandoMode); + void ParseSpoiler(const char* spoilerFileName); void ParseHashIconIndexesJson(nlohmann::json spoilerFileJson); void ParseItemLocationsJson(nlohmann::json spoilerFileJson); void WriteHintJson(nlohmann::ordered_json& spoilerFileJson); @@ -106,6 +105,5 @@ class Context { std::shared_ptr mKaleido; bool mSeedGenerated = false; bool mSpoilerLoaded = false; - bool mPlandoLoaded = false; }; } // namespace Rando \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index e643acd70..bd7f92a84 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -5,6 +5,7 @@ #include "functions.h" #include "variables.h" #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" #include "randomizerTypes.h" #include #include "objects/object_gi_key/object_gi_key.h" @@ -38,7 +39,7 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn { 222, 158, 47 }, // Spirit Temple { 126, 16, 177 }, // Shadow Temple { 227, 110, 255 }, // Bottom of the Well - { 221, 212, 60 }, // Gerudo Training Grounds + { 221, 212, 60 }, // Gerudo Training Ground { 255, 255, 255 }, // Thieves' Hideout { 80, 80, 80 } // Ganon's Castle }; @@ -83,7 +84,7 @@ extern "C" void Randomizer_DrawCompass(PlayState* play, GetItemEntry* getItemEnt { 222, 158, 47 }, // Spirit Temple { 126, 16, 177 }, // Shadow Temple { 227, 110, 255 }, // Bottom of the Well - { 221, 212, 60 }, // Gerudo Training Grounds + { 221, 212, 60 }, // Gerudo Training Ground { 255, 255, 255 }, // Thieves' Hideout { 80, 80, 80 } // Ganon's Castle }; @@ -169,7 +170,7 @@ extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEnt { 222, 158, 47 }, // Spirit Temple { 126, 16, 177 }, // Shadow Temple { 227, 110, 255 }, // Bottom of the Well - { 221, 212, 60 }, // Gerudo Training Grounds + { 221, 212, 60 }, // Gerudo Training Ground { 255, 255, 255 }, // Thieves' Hideout { 80, 80, 80 } // Ganon's Castle }; diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index d0ba3c747..538494685 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -25,7 +25,7 @@ void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry getItemEntry); #define GET_ITEM_MYSTERY \ - { ITEM_NONE_FE, 0, 0, 0, 0, 0, 0, ITEM_NONE_FE, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, NULL, MOD_RANDOMIZER, (CustomDrawFunc)Randomizer_DrawMysteryItem } + { ITEM_NONE_FE, 0, 0, 0, 0, MOD_RANDOMIZER, MOD_RANDOMIZER, ITEM_NONE_FE, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, ITEM_NONE_FE, MOD_RANDOMIZER, (CustomDrawFunc)Randomizer_DrawMysteryItem } #ifdef __cplusplus }; #endif diff --git a/soh/soh/Enhancements/randomizer/dungeon.cpp b/soh/soh/Enhancements/randomizer/dungeon.cpp index 9998e17da..85afc0d3e 100644 --- a/soh/soh/Enhancements/randomizer/dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/dungeon.cpp @@ -10,11 +10,13 @@ DungeonInfo::DungeonInfo(std::string name_, const RandomizerHintTextKey hintKey_ const RandomizerGet bossKey_, RandomizerArea area_, const uint8_t vanillaKeyCount_, const uint8_t mqKeyCount_, const RandomizerSettingKey mqSetting_, std::vector vanillaLocations_, std::vector mqLocations_, + std::vector vanillaPots_, std::vector mqPots_, std::vector sharedLocations_, std::vector bossRoomLocations_) : name(std::move(name_)), hintKey(hintKey_), map(map_), compass(compass_), smallKey(smallKey_), keyRing(keyRing_), bossKey(bossKey_), area(area_), vanillaKeyCount(vanillaKeyCount_), mqKeyCount(mqKeyCount_), mqSetting(mqSetting_), vanillaLocations(std::move(vanillaLocations_)), mqLocations(std::move(mqLocations_)), + vanillaPots(std::move(vanillaPots_)), mqPots(std::move(mqPots_)), sharedLocations(std::move(sharedLocations_)), bossRoomLocations(std::move(bossRoomLocations_)) { } DungeonInfo::DungeonInfo() : hintKey(RHT_NONE), map(RG_NONE), compass(RG_NONE), smallKey(RG_NONE), keyRing(RG_NONE), @@ -146,6 +148,11 @@ void DungeonInfo::PlaceVanillaSmallKeys() const { // Gets the chosen dungeon locations for a playthrough (so either MQ or Vanilla) std::vector DungeonInfo::GetDungeonLocations() const { auto locations = masterQuest ? mqLocations : vanillaLocations; + if (Context::GetInstance()->GetSettings()->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_DUNGEONS) || + Context::GetInstance()->GetSettings()->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL)) { + auto potLocations = masterQuest ? mqPots : vanillaPots; + AddElementsToPool(locations, potLocations); + } AddElementsToPool(locations, sharedLocations); AddElementsToPool(locations, bossRoomLocations); return locations; @@ -155,6 +162,8 @@ std::vector DungeonInfo::GetDungeonLocations() const { std::vector DungeonInfo::GetEveryLocation() const { auto locations = vanillaLocations; AddElementsToPool(locations, mqLocations); + AddElementsToPool(locations, vanillaPots); + AddElementsToPool(locations, mqPots); AddElementsToPool(locations, sharedLocations); AddElementsToPool(locations, bossRoomLocations); return locations; @@ -175,6 +184,11 @@ Dungeons::Dungeons() { RC_DEKU_TREE_GS_BASEMENT_GATE, RC_DEKU_TREE_GS_BASEMENT_VINES, RC_DEKU_TREE_GS_COMPASS_ROOM, + RC_DEKU_TREE_LOBBY_LOWER_HEART, + RC_DEKU_TREE_LOBBY_UPPER_HEART, + RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, + RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, + RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, }, { // MQ Locations @@ -190,8 +204,15 @@ Dungeons::Dungeons() { RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, + RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, + RC_DEKU_TREE_MQ_DEKU_BABA_HEART, + RC_DEKU_TREE_MQ_LOBBY_HEART, + RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, }, - {}, + {}, {}, {}, { // Boss Room Locations RC_DEKU_TREE_QUEEN_GOHMA_HEART, @@ -215,6 +236,12 @@ Dungeons::Dungeons() { RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, RC_DODONGOS_CAVERN_GS_BACK_ROOM, RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, + RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, + RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, + RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, + RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, + RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, + RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, }, { // MQ Locations @@ -233,6 +260,74 @@ Dungeons::Dungeons() { RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, + RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, + RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, + RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, + }, + { + // Vanilla Pots + RC_DODONGOS_CAVERN_LIZALFOS_POT_1, + RC_DODONGOS_CAVERN_LIZALFOS_POT_2, + RC_DODONGOS_CAVERN_LIZALFOS_POT_3, + RC_DODONGOS_CAVERN_LIZALFOS_POT_4, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_4, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_5, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_6, + RC_DODONGOS_CAVERN_TORCH_ROOM_POT_1, + RC_DODONGOS_CAVERN_TORCH_ROOM_POT_2, + RC_DODONGOS_CAVERN_TORCH_ROOM_POT_3, + RC_DODONGOS_CAVERN_TORCH_ROOM_POT_4, + RC_DODONGOS_CAVERN_STAIRCASE_POT_1, + RC_DODONGOS_CAVERN_STAIRCASE_POT_2, + RC_DODONGOS_CAVERN_STAIRCASE_POT_3, + RC_DODONGOS_CAVERN_STAIRCASE_POT_4, + RC_DODONGOS_CAVERN_SINGLE_EYE_POT_1, + RC_DODONGOS_CAVERN_SINGLE_EYE_POT_2, + RC_DODONGOS_CAVERN_BLADE_POT_1, + RC_DODONGOS_CAVERN_BLADE_POT_2, + RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, + RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, + RC_DODONGOS_CAVERN_BACK_ROOM_POT_1, + RC_DODONGOS_CAVERN_BACK_ROOM_POT_2, + RC_DODONGOS_CAVERN_BACK_ROOM_POT_3, + RC_DODONGOS_CAVERN_BACK_ROOM_POT_4, + }, + { + // MQ Pots + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, + RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, + RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, + RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, + RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, + RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, + RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, + RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, + RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, + RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT, + RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, + RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, + RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, + RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1, + RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2, + RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, + RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, + RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, + RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, + RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT, + RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT, + RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT, + RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SW_POT, + RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT, + RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT, + RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, + RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, }, {}, { @@ -272,7 +367,54 @@ Dungeons::Dungeons() { RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, + RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, + RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, }, + { + // Vanilla Pots + RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, + RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, + RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, + RC_JABU_JABUS_BELLY_BASEMENT_POT_1, + RC_JABU_JABUS_BELLY_BASEMENT_POT_2, + RC_JABU_JABUS_BELLY_BASEMENT_POT_3, + RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, + RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, + RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, + RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, + RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, + + // Shared Pots so in both vanilla and MQ + RC_JABU_JABUS_BELLY_BARINADE_POT_1, + RC_JABU_JABUS_BELLY_BARINADE_POT_2, + RC_JABU_JABUS_BELLY_BARINADE_POT_3, + RC_JABU_JABUS_BELLY_BARINADE_POT_4, + RC_JABU_JABUS_BELLY_BARINADE_POT_5, + RC_JABU_JABUS_BELLY_BARINADE_POT_6, + }, + { + // MQ Pots + RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, + RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, + RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, + RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, + RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, + RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, + RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, + RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, + RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, + + // Shared Pots so in both vanilla and MQ + RC_JABU_JABUS_BELLY_BARINADE_POT_1, + RC_JABU_JABUS_BELLY_BARINADE_POT_2, + RC_JABU_JABUS_BELLY_BARINADE_POT_3, + RC_JABU_JABUS_BELLY_BARINADE_POT_4, + RC_JABU_JABUS_BELLY_BARINADE_POT_5, + RC_JABU_JABUS_BELLY_BARINADE_POT_6, + }, {}, { // Boss Room Locations @@ -302,6 +444,10 @@ Dungeons::Dungeons() { RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, RC_FOREST_TEMPLE_GS_LOBBY, RC_FOREST_TEMPLE_GS_BASEMENT, + RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, + RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, + RC_FOREST_TEMPLE_WELL_WEST_HEART, + RC_FOREST_TEMPLE_WELL_EAST_HEART, }, { // MQ Locations @@ -322,6 +468,58 @@ Dungeons::Dungeons() { RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, RC_FOREST_TEMPLE_MQ_GS_WELL, + RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, + RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, + RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, + RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART, + RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART, + RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, + }, + { + // Vanilla Pots + RC_FOREST_TEMPLE_LOBBY_POT_1, + RC_FOREST_TEMPLE_LOBBY_POT_2, + RC_FOREST_TEMPLE_LOBBY_POT_3, + RC_FOREST_TEMPLE_LOBBY_POT_4, + RC_FOREST_TEMPLE_LOBBY_POT_5, + RC_FOREST_TEMPLE_LOBBY_POT_6, + RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, + RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, + RC_FOREST_TEMPLE_GREEN_POE_POT_1, + RC_FOREST_TEMPLE_GREEN_POE_POT_2, + RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, + RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, + RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, + RC_FOREST_TEMPLE_UPPER_STALFOS_POT_4, + RC_FOREST_TEMPLE_BLUE_POE_POT_1, + RC_FOREST_TEMPLE_BLUE_POE_POT_2, + RC_FOREST_TEMPLE_BLUE_POE_POT_3, + RC_FOREST_TEMPLE_FROZEN_EYE_POT_1, + RC_FOREST_TEMPLE_FROZEN_EYE_POT_2, + }, + { + // MQ Pots + RC_FOREST_TEMPLE_MQ_LOBBY_POT_1, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_2, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_3, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_4, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_5, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_6, + RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, + RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, + RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, + RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, + RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, + RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, + RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, + RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, + RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, + RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, + RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, + RC_FOREST_TEMPLE_MQ_BASEMENT_POT_1, + RC_FOREST_TEMPLE_MQ_BASEMENT_POT_2, + RC_FOREST_TEMPLE_MQ_BASEMENT_POT_3, + RC_FOREST_TEMPLE_MQ_BASEMENT_POT_4, }, {}, { @@ -353,6 +551,15 @@ Dungeons::Dungeons() { RC_FIRE_TEMPLE_GS_BOULDER_MAZE, RC_FIRE_TEMPLE_GS_SCARECROW_TOP, RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, + RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, + RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, + RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, }, { // MQ Locations @@ -373,6 +580,60 @@ Dungeons::Dungeons() { RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, + RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, + RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, + }, + { + // Vanilla Pots + RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, + RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, + RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, + RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, + RC_FIRE_TEMPLE_BIG_LAVA_POT_1, + RC_FIRE_TEMPLE_BIG_LAVA_POT_2, + RC_FIRE_TEMPLE_BIG_LAVA_POT_3, + RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, + RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, + RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, + RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, + RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, + RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, + RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, + RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, + }, + { + // MQ Pots + RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, + RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, + RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, + RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, + RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, + RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, + RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, + RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, + RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, + RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, + RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, + RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, + RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, + RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, + RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT, + RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, }, {}, { @@ -400,6 +661,10 @@ Dungeons::Dungeons() { RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, RC_WATER_TEMPLE_GS_RIVER, + RC_WATER_TEMPLE_RIVER_HEART_1, + RC_WATER_TEMPLE_RIVER_HEART_2, + RC_WATER_TEMPLE_RIVER_HEART_3, + RC_WATER_TEMPLE_RIVER_HEART_4, }, { // MQ Locations @@ -414,6 +679,69 @@ Dungeons::Dungeons() { RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, RC_WATER_TEMPLE_MQ_GS_RIVER, RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, + RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, + RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, + RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, + }, + { + // Vanilla Pots + RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, + RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, + RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, + RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, + RC_WATER_TEMPLE_TORCH_POT_1, + RC_WATER_TEMPLE_TORCH_POT_2, + RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, + RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, + RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, + RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, + RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, + RC_WATER_TEMPLE_BEHIND_GATE_POT_1, + RC_WATER_TEMPLE_BEHIND_GATE_POT_2, + RC_WATER_TEMPLE_BEHIND_GATE_POT_3, + RC_WATER_TEMPLE_BEHIND_GATE_POT_4, + RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, + RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, + RC_WATER_TEMPLE_RIVER_POT_1, + RC_WATER_TEMPLE_RIVER_POT_2, + RC_WATER_TEMPLE_LIKE_LIKE_POT_1, + RC_WATER_TEMPLE_LIKE_LIKE_POT_2, + RC_WATER_TEMPLE_BOSS_KEY_POT_1, + RC_WATER_TEMPLE_BOSS_KEY_POT_2, + }, + { + // MQ Pots + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_WEST_POT, + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SOUTH_POT, + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SE_POT, + RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_SOUTH_POT, + RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_NORTH_POT, + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, + RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, + RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, + RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, + RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, + RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, + RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, + RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, + RC_WATER_TEMPLE_MQ_RIVER_POT_1, + RC_WATER_TEMPLE_MQ_RIVER_POT_2, + RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, + RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, + RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, + RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, + RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, + RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, + RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, + RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, + RC_WATER_TEMPLE_MQ_BOSS_KEY_POT, }, {}, { @@ -448,6 +776,10 @@ Dungeons::Dungeons() { RC_SPIRIT_TEMPLE_GS_LOBBY, RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, RC_SPIRIT_TEMPLE_GS_METAL_FENCE, + RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, + RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, + RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, + RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, }, { // MQ Locations @@ -476,6 +808,60 @@ Dungeons::Dungeons() { RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, + RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, + RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, + RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, + }, + { + // Vanilla Pots + RC_SPIRIT_TEMPLE_LOBBY_POT_1, + RC_SPIRIT_TEMPLE_LOBBY_POT_2, + RC_SPIRIT_TEMPLE_ANUBIS_POT_1, + RC_SPIRIT_TEMPLE_ANUBIS_POT_2, + RC_SPIRIT_TEMPLE_ANUBIS_POT_3, + RC_SPIRIT_TEMPLE_ANUBIS_POT_4, + RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, + RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, + RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, + RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, + }, + { + // MQ Pots + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, + RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, + RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, + RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, + RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, + RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, + RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, + RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, + RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, + RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, + RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, + RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, + RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, + RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, + RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, + RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, + RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, + RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, + RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, + RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, + RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, + RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, }, { // Shared Locations @@ -514,6 +900,16 @@ Dungeons::Dungeons() { RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, RC_SHADOW_TEMPLE_GS_NEAR_SHIP, + RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, + RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, + RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, + RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, + RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, + RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, + RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, }, { // MQ Locations @@ -542,6 +938,60 @@ Dungeons::Dungeons() { RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, + RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, + RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, + RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, + RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, + RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, + RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, + RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, + }, + { + // Vanilla Pots + RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, + RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, + RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, + RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, + RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, + RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, + RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, + RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, + RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, + RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, + RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, + RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, + RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, + RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, + RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, + RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, + RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, + RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, + RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, + RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, + RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, + }, + { + // MQ Pots + RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, + RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, + RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, + RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, + RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, + RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, + RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, + RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, + RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, + RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, + RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, + RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, + RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, + RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, + RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, + RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, + RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, }, {}, { @@ -571,6 +1021,14 @@ Dungeons::Dungeons() { RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, + RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, }, { // MQ Locations @@ -582,6 +1040,47 @@ Dungeons::Dungeons() { RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, + RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, + }, + { + // Vanilla Pots + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, + RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, + RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, + RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, + RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, + RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, + RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, + RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, + }, + { + // MQ Pots + RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, + RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, + RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, + RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, + RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, + RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2, + RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, }, {}, {}); dungeonList[ICE_CAVERN] = DungeonInfo("Ice Cavern", RHT_ICE_CAVERN, RG_ICE_CAVERN_MAP, RG_ICE_CAVERN_COMPASS, @@ -595,6 +1094,14 @@ Dungeons::Dungeons() { RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, + RC_ICE_CAVERN_LOBBY_RUPEE, + RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, + RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, + RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, + RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, }, { // MQ Locations @@ -606,14 +1113,39 @@ Dungeons::Dungeons() { RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, RC_ICE_CAVERN_MQ_GS_RED_ICE, }, + { + // Vanilla Pots + RC_ICE_CAVERN_HALL_POT_1, + RC_ICE_CAVERN_HALL_POT_2, + RC_ICE_CAVERN_SPINNING_BLADE_POT_1, + RC_ICE_CAVERN_SPINNING_BLADE_POT_2, + RC_ICE_CAVERN_SPINNING_BLADE_POT_3, + RC_ICE_CAVERN_NEAR_END_POT_1, + RC_ICE_CAVERN_NEAR_END_POT_2, + RC_ICE_CAVERN_FROZEN_POT_1, + }, + { + // MQ Pots + RC_ICE_CAVERN_MQ_ENTRANCE_POT, + RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, + RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, + RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, + RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, + RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, + RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, + RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, + RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, + RC_ICE_CAVERN_MQ_COMPASS_POT_1, + RC_ICE_CAVERN_MQ_COMPASS_POT_2, + }, { // Shared Locations RC_SHEIK_IN_ICE_CAVERN, }, {}); - dungeonList[GERUDO_TRAINING_GROUNDS] = - DungeonInfo("Gerudo Training Grounds", RHT_GERUDO_TRAINING_GROUND, RG_NONE, RG_NONE, - RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, RG_GERUDO_TRAINING_GROUNDS_KEY_RING, RG_NONE, RA_GERUDO_TRAINING_GROUND, 9, 3, RSK_MQ_GTG, + dungeonList[GERUDO_TRAINING_GROUND] = + DungeonInfo("Gerudo Training Ground", RHT_GERUDO_TRAINING_GROUND, RG_NONE, RG_NONE, + RG_GERUDO_TRAINING_GROUND_SMALL_KEY, RG_GERUDO_TRAINING_GROUND_KEY_RING, RG_NONE, RA_GERUDO_TRAINING_GROUND, 9, 3, RSK_MQ_GTG, { // Vanilla Locations RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, @@ -638,6 +1170,9 @@ Dungeons::Dungeons() { RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, + RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, + RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, + RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, }, { // MQ Locations @@ -659,7 +1194,14 @@ Dungeons::Dungeons() { RC_GERUDO_TRAINING_GROUND_MQ_UNDERWATER_SILVER_RUPEE_CHEST, RC_GERUDO_TRAINING_GROUND_MQ_HEAVY_BLOCK_CHEST, }, - {}, {}); + {}, + { + // MQ Pots + RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, + RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, + RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, + RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, + }, {}, {}); dungeonList[GANONS_CASTLE] = DungeonInfo("Ganon's Castle", RHT_GANONS_CASTLE, RG_NONE, RG_NONE, RG_GANONS_CASTLE_SMALL_KEY, RG_GANONS_CASTLE_KEY_RING, RG_GANONS_CASTLE_BOSS_KEY, RA_GANONS_CASTLE, 2, 3, RSK_MQ_GANONS_CASTLE, @@ -684,6 +1226,20 @@ Dungeons::Dungeons() { RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, + RC_GANONS_CASTLE_FIRE_TRIAL_HEART, + RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, + RC_GANONS_CASTLE_SCRUBS_FAIRY_1, + RC_GANONS_CASTLE_SCRUBS_FAIRY_2, + RC_GANONS_CASTLE_SCRUBS_FAIRY_3, + RC_GANONS_CASTLE_SCRUBS_FAIRY_4, + RC_GANONS_CASTLE_SCRUBS_FAIRY_5, + RC_GANONS_CASTLE_SCRUBS_FAIRY_6, + RC_GANONS_CASTLE_SCRUBS_FAIRY_7, + RC_GANONS_CASTLE_SCRUBS_FAIRY_8, + RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, }, { // MQ Locations @@ -705,6 +1261,91 @@ Dungeons::Dungeons() { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, + RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, + }, + { + // Vanilla Pots + RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, + RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, + RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, + RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, + RC_GANONS_CASTLE_WATER_TRIAL_POT_1, + RC_GANONS_CASTLE_WATER_TRIAL_POT_2, + RC_GANONS_CASTLE_WATER_TRIAL_POT_3, + RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, + RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, + RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, + RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, + RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, + RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, + RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, + RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, + RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, + + // Shared Pots so in both vanilla and MQ + RC_GANONS_CASTLE_GANONS_TOWER_POT_1, + RC_GANONS_CASTLE_GANONS_TOWER_POT_2, + RC_GANONS_CASTLE_GANONS_TOWER_POT_3, + RC_GANONS_CASTLE_GANONS_TOWER_POT_4, + RC_GANONS_CASTLE_GANONS_TOWER_POT_5, + RC_GANONS_CASTLE_GANONS_TOWER_POT_6, + RC_GANONS_CASTLE_GANONS_TOWER_POT_7, + RC_GANONS_CASTLE_GANONS_TOWER_POT_8, + RC_GANONS_CASTLE_GANONS_TOWER_POT_9, + RC_GANONS_CASTLE_GANONS_TOWER_POT_10, + RC_GANONS_CASTLE_GANONS_TOWER_POT_11, + RC_GANONS_CASTLE_GANONS_TOWER_POT_12, + RC_GANONS_CASTLE_GANONS_TOWER_POT_13, + RC_GANONS_CASTLE_GANONS_TOWER_POT_14, + RC_GANONS_CASTLE_GANONS_TOWER_POT_15, + RC_GANONS_CASTLE_GANONS_TOWER_POT_16, + RC_GANONS_CASTLE_GANONS_TOWER_POT_17, + RC_GANONS_CASTLE_GANONS_TOWER_POT_18, + }, + { + // MQ Pots + RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, + RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, + RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, + RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, + RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, + + // Shared Pots so in both vanilla and MQ + RC_GANONS_CASTLE_GANONS_TOWER_POT_1, + RC_GANONS_CASTLE_GANONS_TOWER_POT_2, + RC_GANONS_CASTLE_GANONS_TOWER_POT_3, + RC_GANONS_CASTLE_GANONS_TOWER_POT_4, + RC_GANONS_CASTLE_GANONS_TOWER_POT_5, + RC_GANONS_CASTLE_GANONS_TOWER_POT_6, + RC_GANONS_CASTLE_GANONS_TOWER_POT_7, + RC_GANONS_CASTLE_GANONS_TOWER_POT_8, + RC_GANONS_CASTLE_GANONS_TOWER_POT_9, + RC_GANONS_CASTLE_GANONS_TOWER_POT_10, + RC_GANONS_CASTLE_GANONS_TOWER_POT_11, + RC_GANONS_CASTLE_GANONS_TOWER_POT_12, + RC_GANONS_CASTLE_GANONS_TOWER_POT_13, + RC_GANONS_CASTLE_GANONS_TOWER_POT_14, + RC_GANONS_CASTLE_GANONS_TOWER_POT_15, + RC_GANONS_CASTLE_GANONS_TOWER_POT_16, + RC_GANONS_CASTLE_GANONS_TOWER_POT_17, + RC_GANONS_CASTLE_GANONS_TOWER_POT_18, }, { // Shared Locations @@ -743,7 +1384,7 @@ DungeonInfo* Dungeons::GetDungeonFromScene(const uint16_t scene) { case SCENE_ICE_CAVERN: return &dungeonList[ICE_CAVERN]; case SCENE_GERUDO_TRAINING_GROUND: - return &dungeonList[GERUDO_TRAINING_GROUNDS]; + return &dungeonList[GERUDO_TRAINING_GROUND]; case SCENE_INSIDE_GANONS_CASTLE: return &dungeonList[GANONS_CASTLE]; default: diff --git a/soh/soh/Enhancements/randomizer/dungeon.h b/soh/soh/Enhancements/randomizer/dungeon.h index b9176f707..c8ecd247e 100644 --- a/soh/soh/Enhancements/randomizer/dungeon.h +++ b/soh/soh/Enhancements/randomizer/dungeon.h @@ -13,8 +13,9 @@ class DungeonInfo { DungeonInfo(std::string name_, RandomizerHintTextKey hintKey_, RandomizerGet map_, RandomizerGet compass_, RandomizerGet smallKey_, RandomizerGet keyRing_, RandomizerGet bossKey_, RandomizerArea area_, uint8_t vanillaKeyCount_, uint8_t mqKeyCount_, RandomizerSettingKey mqSetting_, - std::vector vanillaLocations_, - std::vector mqLocations_, std::vector sharedLocations_, + std::vector vanillaLocations_, std::vector mqLocations_, + std::vector vanillaPots_, std::vector mqPots_, + std::vector sharedLocations_, std::vector bossRoomLocations_); DungeonInfo(); ~DungeonInfo(); @@ -61,6 +62,8 @@ class DungeonInfo { bool hasKeyRing = false; std::vector vanillaLocations; std::vector mqLocations; + std::vector vanillaPots; + std::vector mqPots; std::vector sharedLocations; std::vector bossRoomLocations; }; @@ -76,8 +79,8 @@ typedef enum { SHADOW_TEMPLE, BOTTOM_OF_THE_WELL, ICE_CAVERN, - GERUDO_TRAINING_GROUNDS, - GANONS_CASTLE + GANONS_CASTLE, + GERUDO_TRAINING_GROUND } DungeonKey; class Dungeons { diff --git a/soh/soh/Enhancements/randomizer/entrance.cpp b/soh/soh/Enhancements/randomizer/entrance.cpp index 7fbeed879..7f63d8625 100644 --- a/soh/soh/Enhancements/randomizer/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/entrance.cpp @@ -672,11 +672,8 @@ bool EntranceShuffler::PlaceOneWayPriorityEntrance( } } } -#ifdef ENABLE_DEBUG - auto message = "ERROR: Unable to place priority one-way entrance for " + priorityName + "\n"; - SPDLOG_DEBUG(message); - PlacementLog_Write(); -#endif + SPDLOG_DEBUG("ERROR: Unable to place priority one-way entrance for " + priorityName + "\n"); + assert(false); return false; } @@ -871,295 +868,310 @@ int EntranceShuffler::ShuffleAllEntrances() { mCurNumRandomizedEntrances = 0; std::vector entranceShuffleTable = { - // Type Parent Region Connected Region Index - { { EntranceType::Dungeon, RR_KF_OUTSIDE_DEKU_TREE, RR_DEKU_TREE_ENTRYWAY, 0x0000 }, - { EntranceType::Dungeon, RR_DEKU_TREE_ENTRYWAY, RR_KF_OUTSIDE_DEKU_TREE, 0x0209 } }, - { { EntranceType::Dungeon, RR_DEATH_MOUNTAIN_TRAIL, RR_DODONGOS_CAVERN_ENTRYWAY, 0x0004 }, - { EntranceType::Dungeon, RR_DODONGOS_CAVERN_ENTRYWAY, RR_DEATH_MOUNTAIN_TRAIL, 0x0242 } }, - { { EntranceType::Dungeon, RR_ZORAS_FOUNTAIN, RR_JABU_JABUS_BELLY_ENTRYWAY, 0x0028 }, - { EntranceType::Dungeon, RR_JABU_JABUS_BELLY_ENTRYWAY, RR_ZORAS_FOUNTAIN, 0x0221 } }, - { { EntranceType::Dungeon, RR_SACRED_FOREST_MEADOW, RR_FOREST_TEMPLE_ENTRYWAY, 0x0169 }, - { EntranceType::Dungeon, RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW, 0x0215 } }, - { { EntranceType::Dungeon, RR_DMC_CENTRAL_LOCAL, RR_FIRE_TEMPLE_ENTRYWAY, 0x0165 }, - { EntranceType::Dungeon, RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_CENTRAL_LOCAL, 0x024A } }, - { { EntranceType::Dungeon, RR_LAKE_HYLIA, RR_WATER_TEMPLE_ENTRYWAY, 0x0010 }, - { EntranceType::Dungeon, RR_WATER_TEMPLE_ENTRYWAY, RR_LAKE_HYLIA, 0x021D } }, - { { EntranceType::Dungeon, RR_DESERT_COLOSSUS, RR_SPIRIT_TEMPLE_ENTRYWAY, 0x0082 }, - { EntranceType::Dungeon, RR_SPIRIT_TEMPLE_ENTRYWAY, RR_DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY, 0x01E1 } }, - { { EntranceType::Dungeon, RR_GRAVEYARD_WARP_PAD_REGION, RR_SHADOW_TEMPLE_ENTRYWAY, 0x0037 }, - { EntranceType::Dungeon, RR_SHADOW_TEMPLE_ENTRYWAY, RR_GRAVEYARD_WARP_PAD_REGION, 0x0205 } }, - { { EntranceType::Dungeon, RR_KAKARIKO_VILLAGE, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, 0x0098 }, - { EntranceType::Dungeon, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, RR_KAKARIKO_VILLAGE, 0x02A6 } }, - { { EntranceType::Dungeon, RR_ZORAS_FOUNTAIN, RR_ICE_CAVERN_ENTRYWAY, 0x0088 }, - { EntranceType::Dungeon, RR_ICE_CAVERN_ENTRYWAY, RR_ZORAS_FOUNTAIN, 0x03D4 } }, - { { EntranceType::Dungeon, RR_GERUDO_FORTRESS, RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, 0x0008 }, - { EntranceType::Dungeon, RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, RR_GERUDO_FORTRESS, 0x03A8 } }, - { { EntranceType::GanonDungeon, RR_GANONS_CASTLE_LEDGE, RR_GANONS_CASTLE_ENTRYWAY, 0x0467 }, - { EntranceType::GanonDungeon, RR_GANONS_CASTLE_ENTRYWAY, RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE, 0x023D } }, + // Type Parent Region Connected Region Index + { { EntranceType::Dungeon, RR_KF_OUTSIDE_DEKU_TREE, RR_DEKU_TREE_ENTRYWAY, ENTR_DEKU_TREE_ENTRANCE }, + { EntranceType::Dungeon, RR_DEKU_TREE_ENTRYWAY, RR_KF_OUTSIDE_DEKU_TREE, ENTR_KOKIRI_FOREST_OUTSIDE_DEKU_TREE } }, + { { EntranceType::Dungeon, RR_DEATH_MOUNTAIN_TRAIL, RR_DODONGOS_CAVERN_ENTRYWAY, ENTR_DODONGOS_CAVERN_ENTRANCE }, + { EntranceType::Dungeon, RR_DODONGOS_CAVERN_ENTRYWAY, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN } }, + { { EntranceType::Dungeon, RR_ZORAS_FOUNTAIN, RR_JABU_JABUS_BELLY_ENTRYWAY, ENTR_JABU_JABU_ENTRANCE }, + { EntranceType::Dungeon, RR_JABU_JABUS_BELLY_ENTRYWAY, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU } }, + { { EntranceType::Dungeon, RR_SACRED_FOREST_MEADOW, RR_FOREST_TEMPLE_ENTRYWAY, ENTR_FOREST_TEMPLE_ENTRANCE }, + { EntranceType::Dungeon, RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE } }, + { { EntranceType::Dungeon, RR_DMC_CENTRAL_LOCAL, RR_FIRE_TEMPLE_ENTRYWAY, ENTR_FIRE_TEMPLE_ENTRANCE }, + { EntranceType::Dungeon, RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE } }, + { { EntranceType::Dungeon, RR_LAKE_HYLIA, RR_WATER_TEMPLE_ENTRYWAY, ENTR_WATER_TEMPLE_ENTRANCE }, + { EntranceType::Dungeon, RR_WATER_TEMPLE_ENTRYWAY, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE } }, + { { EntranceType::Dungeon, RR_DESERT_COLOSSUS, RR_SPIRIT_TEMPLE_ENTRYWAY, ENTR_SPIRIT_TEMPLE_ENTRANCE }, + { EntranceType::Dungeon, RR_SPIRIT_TEMPLE_ENTRYWAY, RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE } }, + { { EntranceType::Dungeon, RR_GRAVEYARD_WARP_PAD_REGION, RR_SHADOW_TEMPLE_ENTRYWAY, ENTR_SHADOW_TEMPLE_ENTRANCE }, + { EntranceType::Dungeon, RR_SHADOW_TEMPLE_ENTRYWAY, RR_GRAVEYARD_WARP_PAD_REGION, ENTR_GRAVEYARD_OUTSIDE_TEMPLE } }, + { { EntranceType::Dungeon, RR_KAK_WELL, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, ENTR_BOTTOM_OF_THE_WELL_ENTRANCE }, + { EntranceType::Dungeon, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, RR_KAK_WELL, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL } }, + { { EntranceType::Dungeon, RR_ZORAS_FOUNTAIN, RR_ICE_CAVERN_ENTRYWAY, ENTR_ICE_CAVERN_ENTRANCE }, + { EntranceType::Dungeon, RR_ICE_CAVERN_ENTRYWAY, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN } }, + { { EntranceType::Dungeon, RR_GERUDO_FORTRESS, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE }, + { EntranceType::Dungeon, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, RR_GERUDO_FORTRESS, ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND } }, + { { EntranceType::GanonDungeon, RR_GANONS_CASTLE_LEDGE, RR_GANONS_CASTLE_ENTRYWAY, ENTR_INSIDE_GANONS_CASTLE_ENTRANCE }, + { EntranceType::GanonDungeon, RR_GANONS_CASTLE_ENTRYWAY, RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE, ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT } }, - { { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_MIDOS_HOUSE, 0x0433 }, - { EntranceType::Interior, RR_KF_MIDOS_HOUSE, RR_KOKIRI_FOREST, 0x0443 } }, - { { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_SARIAS_HOUSE, 0x0437 }, - { EntranceType::Interior, RR_KF_SARIAS_HOUSE, RR_KOKIRI_FOREST, 0x0447 } }, - { { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_HOUSE_OF_TWINS, 0x009C }, - { EntranceType::Interior, RR_KF_HOUSE_OF_TWINS, RR_KOKIRI_FOREST, 0x033C } }, - { { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_KNOW_IT_ALL_HOUSE, 0x00C9 }, - { EntranceType::Interior, RR_KF_KNOW_IT_ALL_HOUSE, RR_KOKIRI_FOREST, 0x026A } }, - { { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_KOKIRI_SHOP, 0x00C1 }, - { EntranceType::Interior, RR_KF_KOKIRI_SHOP, RR_KOKIRI_FOREST, 0x0266 } }, - { { EntranceType::Interior, RR_LAKE_HYLIA, RR_LH_LAB, 0x0043 }, - { EntranceType::Interior, RR_LH_LAB, RR_LAKE_HYLIA, 0x03CC } }, - { { EntranceType::Interior, RR_LH_FISHING_ISLAND, RR_LH_FISHING_HOLE, 0x045F }, - { EntranceType::Interior, RR_LH_FISHING_HOLE, RR_LH_FISHING_ISLAND, 0x0309 } }, - { { EntranceType::Interior, RR_GV_FORTRESS_SIDE, RR_GV_CARPENTER_TENT, 0x03A0 }, - { EntranceType::Interior, RR_GV_CARPENTER_TENT, RR_GV_FORTRESS_SIDE, 0x03D0 } }, - { { EntranceType::Interior, RR_MARKET_ENTRANCE, RR_MARKET_GUARD_HOUSE, 0x007E }, - { EntranceType::Interior, RR_MARKET_GUARD_HOUSE, RR_MARKET_ENTRANCE, 0x026E } }, - { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_MASK_SHOP, 0x0530 }, - { EntranceType::Interior, RR_MARKET_MASK_SHOP, RR_THE_MARKET, 0x01D1 } }, - { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_BOMBCHU_BOWLING, 0x0507 }, - { EntranceType::Interior, RR_MARKET_BOMBCHU_BOWLING, RR_THE_MARKET, 0x03BC } }, - { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_POTION_SHOP, 0x0388 }, - { EntranceType::Interior, RR_MARKET_POTION_SHOP, RR_THE_MARKET, 0x02A2 } }, - { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_TREASURE_CHEST_GAME, 0x0063 }, - { EntranceType::Interior, RR_MARKET_TREASURE_CHEST_GAME, RR_THE_MARKET, 0x01D5 } }, - { { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_BOMBCHU_SHOP, 0x0528 }, - { EntranceType::Interior, RR_MARKET_BOMBCHU_SHOP, RR_MARKET_BACK_ALLEY, 0x03C0 } }, - { { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_MAN_IN_GREEN_HOUSE, 0x043B }, - { EntranceType::Interior, RR_MARKET_MAN_IN_GREEN_HOUSE, RR_MARKET_BACK_ALLEY, 0x0067 } }, - { { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_CARPENTER_BOSS_HOUSE, 0x02FD }, - { EntranceType::Interior, RR_KAK_CARPENTER_BOSS_HOUSE, RR_KAKARIKO_VILLAGE, 0x0349 } }, - { { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_HOUSE_OF_SKULLTULA, 0x0550 }, - { EntranceType::Interior, RR_KAK_HOUSE_OF_SKULLTULA, RR_KAKARIKO_VILLAGE, 0x04EE } }, - { { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_IMPAS_HOUSE, 0x039C }, - { EntranceType::Interior, RR_KAK_IMPAS_HOUSE, RR_KAKARIKO_VILLAGE, 0x0345 } }, - { { EntranceType::Interior, RR_KAK_IMPAS_LEDGE, RR_KAK_IMPAS_HOUSE_BACK, 0x05C8 }, - { EntranceType::Interior, RR_KAK_IMPAS_HOUSE_BACK, RR_KAK_IMPAS_LEDGE, 0x05DC } }, - { { EntranceType::Interior, RR_KAK_BACKYARD, RR_KAK_ODD_POTION_BUILDING, 0x0072 }, - { EntranceType::Interior, RR_KAK_ODD_POTION_BUILDING, RR_KAK_BACKYARD, 0x034D } }, - { { EntranceType::Interior, RR_THE_GRAVEYARD, RR_GRAVEYARD_DAMPES_HOUSE, 0x030D }, - { EntranceType::Interior, RR_GRAVEYARD_DAMPES_HOUSE, RR_THE_GRAVEYARD, 0x0355 } }, - { { EntranceType::Interior, RR_GORON_CITY, RR_GC_SHOP, 0x037C }, - { EntranceType::Interior, RR_GC_SHOP, RR_GORON_CITY, 0x03FC } }, - { { EntranceType::Interior, RR_ZORAS_DOMAIN, RR_ZD_SHOP, 0x0380 }, - { EntranceType::Interior, RR_ZD_SHOP, RR_ZORAS_DOMAIN, 0x03C4 } }, - { { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_TALONS_HOUSE, 0x004F }, - { EntranceType::Interior, RR_LLR_TALONS_HOUSE, RR_LON_LON_RANCH, 0x0378 } }, - { { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_STABLES, 0x02F9 }, - { EntranceType::Interior, RR_LLR_STABLES, RR_LON_LON_RANCH, 0x042F } }, - { { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_TOWER, 0x05D0 }, - { EntranceType::Interior, RR_LLR_TOWER, RR_LON_LON_RANCH, 0x05D4 } }, - { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_BAZAAR, 0x052C }, - { EntranceType::Interior, RR_MARKET_BAZAAR, RR_THE_MARKET, 0x03B8 } }, - { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_SHOOTING_GALLERY, 0x016D }, - { EntranceType::Interior, RR_MARKET_SHOOTING_GALLERY, RR_THE_MARKET, 0x01CD } }, - { { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_BAZAAR, 0x00B7 }, - { EntranceType::Interior, RR_KAK_BAZAAR, RR_KAKARIKO_VILLAGE, 0x0201 } }, - { { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_SHOOTING_GALLERY, 0x003B }, - { EntranceType::Interior, RR_KAK_SHOOTING_GALLERY, RR_KAKARIKO_VILLAGE, 0x0463 } }, - { { EntranceType::Interior, RR_DESERT_COLOSSUS, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, 0x0588 }, - { EntranceType::Interior, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, RR_DESERT_COLOSSUS, 0x057C } }, - { { EntranceType::Interior, RR_HYRULE_CASTLE_GROUNDS, RR_HC_GREAT_FAIRY_FOUNTAIN, 0x0578 }, - { EntranceType::Interior, RR_HC_GREAT_FAIRY_FOUNTAIN, RR_CASTLE_GROUNDS, 0x0340 } }, - { { EntranceType::Interior, RR_GANONS_CASTLE_GROUNDS, RR_OGC_GREAT_FAIRY_FOUNTAIN, 0x04C2 }, - { EntranceType::Interior, RR_OGC_GREAT_FAIRY_FOUNTAIN, RR_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, RR_DMC_LOWER_NEARBY, RR_DMC_GREAT_FAIRY_FOUNTAIN, 0x04BE }, - { EntranceType::Interior, RR_DMC_GREAT_FAIRY_FOUNTAIN, RR_DMC_LOWER_LOCAL, 0x0482 } }, - { { EntranceType::Interior, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_GREAT_FAIRY_FOUNTAIN, 0x0315 }, - { EntranceType::Interior, RR_DMT_GREAT_FAIRY_FOUNTAIN, RR_DEATH_MOUNTAIN_SUMMIT, 0x045B } }, - { { EntranceType::Interior, RR_ZORAS_FOUNTAIN, RR_ZF_GREAT_FAIRY_FOUNTAIN, 0x0371 }, - { EntranceType::Interior, RR_ZF_GREAT_FAIRY_FOUNTAIN, RR_ZORAS_FOUNTAIN, 0x0394 } }, + { { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_MIDOS_HOUSE, ENTR_MIDOS_HOUSE_0 }, + { EntranceType::Interior, RR_KF_MIDOS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_MIDOS_HOUSE } }, + { { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_SARIAS_HOUSE, ENTR_SARIAS_HOUSE_0 }, + { EntranceType::Interior, RR_KF_SARIAS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_SARIAS_HOUSE } }, + { { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_HOUSE_OF_TWINS, ENTR_TWINS_HOUSE_0 }, + { EntranceType::Interior, RR_KF_HOUSE_OF_TWINS, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_TWINS_HOUSE } }, + { { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_KNOW_IT_ALL_HOUSE, ENTR_KNOW_IT_ALL_BROS_HOUSE_0 }, + { EntranceType::Interior, RR_KF_KNOW_IT_ALL_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_KNOW_IT_ALL_HOUSE } }, + { { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_KOKIRI_SHOP, ENTR_KOKIRI_SHOP_0 }, + { EntranceType::Interior, RR_KF_KOKIRI_SHOP, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_SHOP } }, + { { EntranceType::Interior, RR_LAKE_HYLIA, RR_LH_LAB, ENTR_LAKESIDE_LABORATORY_0 }, + { EntranceType::Interior, RR_LH_LAB, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_OUTSIDE_LAB } }, + { { EntranceType::Interior, RR_LH_FISHING_ISLAND, RR_LH_FISHING_POND, ENTR_FISHING_POND_0 }, + { EntranceType::Interior, RR_LH_FISHING_POND, RR_LH_FISHING_ISLAND, ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND } }, + { { EntranceType::Interior, RR_GV_FORTRESS_SIDE, RR_GV_CARPENTER_TENT, ENTR_CARPENTERS_TENT_0 }, + { EntranceType::Interior, RR_GV_CARPENTER_TENT, RR_GV_FORTRESS_SIDE, ENTR_GERUDO_VALLEY_OUTSIDE_TENT } }, + { { EntranceType::Interior, RR_MARKET_ENTRANCE, RR_MARKET_GUARD_HOUSE, ENTR_MARKET_GUARD_HOUSE_0 }, + { EntranceType::Interior, RR_MARKET_GUARD_HOUSE, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_OUTSIDE_GUARD_HOUSE } }, + { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_MASK_SHOP, ENTR_HAPPY_MASK_SHOP_0 }, + { EntranceType::Interior, RR_MARKET_MASK_SHOP, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_HAPPY_MASK_SHOP } }, + { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_BOMBCHU_BOWLING, ENTR_BOMBCHU_BOWLING_ALLEY_0 }, + { EntranceType::Interior, RR_MARKET_BOMBCHU_BOWLING, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_BOMBCHU_BOWLING } }, + { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_POTION_SHOP, ENTR_POTION_SHOP_MARKET_0 }, + { EntranceType::Interior, RR_MARKET_POTION_SHOP, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP } }, + { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_TREASURE_CHEST_GAME, ENTR_TREASURE_BOX_SHOP_0 }, + { EntranceType::Interior, RR_MARKET_TREASURE_CHEST_GAME, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_TREASURE_BOX_SHOP } }, + { { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_BOMBCHU_SHOP, ENTR_BOMBCHU_SHOP_1 }, + { EntranceType::Interior, RR_MARKET_BOMBCHU_SHOP, RR_MARKET_BACK_ALLEY, ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP } }, + { { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_MAN_IN_GREEN_HOUSE, ENTR_BACK_ALLEY_MAN_IN_GREEN_HOUSE }, + { EntranceType::Interior, RR_MARKET_MAN_IN_GREEN_HOUSE, RR_MARKET_BACK_ALLEY, ENTR_BACK_ALLEY_DAY_OUTSIDE_MAN_IN_GREEN_HOUSE } }, + { { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_CARPENTER_BOSS_HOUSE, ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0 }, + { EntranceType::Interior, RR_KAK_CARPENTER_BOSS_HOUSE, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_CENTER_GUEST_HOUSE } }, + { { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_HOUSE_OF_SKULLTULA, ENTR_HOUSE_OF_SKULLTULA_0 }, + { EntranceType::Interior, RR_KAK_HOUSE_OF_SKULLTULA, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SKULKLTULA_HOUSE } }, + { { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_IMPAS_HOUSE, ENTR_IMPAS_HOUSE_FRONT }, + { EntranceType::Interior, RR_KAK_IMPAS_HOUSE, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_FRONT } }, + { { EntranceType::Interior, RR_KAK_IMPAS_LEDGE, RR_KAK_IMPAS_HOUSE_BACK, ENTR_IMPAS_HOUSE_BACK }, + { EntranceType::Interior, RR_KAK_IMPAS_HOUSE_BACK, RR_KAK_IMPAS_LEDGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_BACK } }, + { { EntranceType::Interior, RR_KAK_BACKYARD, RR_KAK_ODD_POTION_BUILDING, ENTR_POTION_SHOP_GRANNY_0 }, + { EntranceType::Interior, RR_KAK_ODD_POTION_BUILDING, RR_KAK_BACKYARD, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOP_GRANNY } }, + { { EntranceType::Interior, RR_THE_GRAVEYARD, RR_GRAVEYARD_DAMPES_HOUSE, ENTR_GRAVEKEEPERS_HUT_0 }, + { EntranceType::Interior, RR_GRAVEYARD_DAMPES_HOUSE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_OUTSIDE_DAMPES_HUT } }, + { { EntranceType::Interior, RR_GORON_CITY, RR_GC_SHOP, ENTR_GORON_SHOP_0 }, + { EntranceType::Interior, RR_GC_SHOP, RR_GORON_CITY, ENTR_GORON_CITY_OUTSIDE_SHOP } }, + { { EntranceType::Interior, RR_ZORAS_DOMAIN, RR_ZD_SHOP, ENTR_ZORA_SHOP_0 }, + { EntranceType::Interior, RR_ZD_SHOP, RR_ZORAS_DOMAIN, ENTR_ZORAS_DOMAIN_OUTSIDE_SHOP } }, + { { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_TALONS_HOUSE, ENTR_LON_LON_BUILDINGS_TALONS_HOUSE }, + { EntranceType::Interior, RR_LLR_TALONS_HOUSE, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE } }, + { { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_STABLES, ENTR_STABLE_0 }, + { EntranceType::Interior, RR_LLR_STABLES, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_OUTSIDE_STABLES } }, + { { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_TOWER, ENTR_LON_LON_BUILDINGS_TOWER }, + { EntranceType::Interior, RR_LLR_TOWER, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_OUTSIDE_TOWER } }, + { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_BAZAAR, ENTR_BAZAAR_1 }, + { EntranceType::Interior, RR_MARKET_BAZAAR, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_BAZAAR } }, + { { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_SHOOTING_GALLERY, ENTR_SHOOTING_GALLERY_1 }, + { EntranceType::Interior, RR_MARKET_SHOOTING_GALLERY, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_SHOOTING_GALLERY } }, + { { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_BAZAAR, ENTR_BAZAAR_0 }, + { EntranceType::Interior, RR_KAK_BAZAAR, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BAZAAR } }, + { { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_SHOOTING_GALLERY, ENTR_SHOOTING_GALLERY_0 }, + { EntranceType::Interior, RR_KAK_SHOOTING_GALLERY, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY } }, + { { EntranceType::Interior, RR_DESERT_COLOSSUS, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_NAYRUS_COLOSSUS }, + { EntranceType::Interior, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT } }, + { { EntranceType::Interior, RR_HYRULE_CASTLE_GROUNDS, RR_HC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC }, + { EntranceType::Interior, RR_HC_GREAT_FAIRY_FOUNTAIN, RR_CASTLE_GROUNDS, ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT } }, + { { EntranceType::Interior, RR_GANONS_CASTLE_GROUNDS, RR_OGC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD }, + // 0x3E8 is an unused entrance index repruposed to differentiate between the HC and OGC fairy + // fountain exits (normally they both use 0x340) + { EntranceType::Interior, RR_OGC_GREAT_FAIRY_FOUNTAIN, RR_CASTLE_GROUNDS, ENTR_POTION_SHOP_KAKARIKO_1 } }, + { { EntranceType::Interior, RR_DMC_LOWER_NEARBY, RR_DMC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC }, + { EntranceType::Interior, RR_DMC_GREAT_FAIRY_FOUNTAIN, RR_DMC_LOWER_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT } }, + { { EntranceType::Interior, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT }, + { EntranceType::Interior, RR_DMT_GREAT_FAIRY_FOUNTAIN, RR_DEATH_MOUNTAIN_SUMMIT, ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT } }, + { { EntranceType::Interior, RR_ZORAS_FOUNTAIN, RR_ZF_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF }, + { EntranceType::Interior, RR_ZF_GREAT_FAIRY_FOUNTAIN, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY } }, - { { EntranceType::SpecialInterior, RR_KOKIRI_FOREST, RR_KF_LINKS_HOUSE, 0x0272 }, - { EntranceType::SpecialInterior, RR_KF_LINKS_HOUSE, RR_KOKIRI_FOREST, 0x0211 } }, - { { EntranceType::SpecialInterior, RR_TOT_ENTRANCE, RR_TEMPLE_OF_TIME, 0x0053 }, - { EntranceType::SpecialInterior, RR_TEMPLE_OF_TIME, RR_TOT_ENTRANCE, 0x0472 } }, - { { EntranceType::SpecialInterior, RR_KAKARIKO_VILLAGE, RR_KAK_WINDMILL, 0x0453 }, - { EntranceType::SpecialInterior, RR_KAK_WINDMILL, RR_KAKARIKO_VILLAGE, 0x0351 } }, - { { EntranceType::SpecialInterior, RR_KAKARIKO_VILLAGE, RR_KAK_POTION_SHOP_FRONT, 0x0384 }, - { EntranceType::SpecialInterior, RR_KAK_POTION_SHOP_FRONT, RR_KAKARIKO_VILLAGE, 0x044B } }, - { { EntranceType::SpecialInterior, RR_KAK_BACKYARD, RR_KAK_POTION_SHOP_BACK, 0x03EC }, - { EntranceType::SpecialInterior, RR_KAK_POTION_SHOP_BACK, RR_KAK_BACKYARD, 0x04FF } }, + { { EntranceType::SpecialInterior, RR_KOKIRI_FOREST, RR_KF_LINKS_HOUSE, ENTR_LINKS_HOUSE_1 }, + { EntranceType::SpecialInterior, RR_KF_LINKS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE } }, + { { EntranceType::SpecialInterior, RR_TOT_ENTRANCE, RR_TEMPLE_OF_TIME, ENTR_TEMPLE_OF_TIME_ENTRANCE }, + { EntranceType::SpecialInterior, RR_TEMPLE_OF_TIME, RR_TOT_ENTRANCE, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE } }, + { { EntranceType::SpecialInterior, RR_KAKARIKO_VILLAGE, RR_KAK_WINDMILL, ENTR_WINDMILL_AND_DAMPES_GRAVE_WINDMILL }, + { EntranceType::SpecialInterior, RR_KAK_WINDMILL, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_WINDMILL } }, + { { EntranceType::SpecialInterior, RR_KAKARIKO_VILLAGE, RR_KAK_POTION_SHOP_FRONT, ENTR_POTION_SHOP_KAKARIKO_FRONT }, + { EntranceType::SpecialInterior, RR_KAK_POTION_SHOP_FRONT, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_FRONT } }, + { { EntranceType::SpecialInterior, RR_KAK_BACKYARD, RR_KAK_POTION_SHOP_BACK, ENTR_POTION_SHOP_KAKARIKO_BACK }, + { EntranceType::SpecialInterior, RR_KAK_POTION_SHOP_BACK, RR_KAK_BACKYARD, ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_BACK } }, // 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, RR_DESERT_COLOSSUS, RR_COLOSSUS_GROTTO, 0x0700 }, - { EntranceType::GrottoGrave, RR_COLOSSUS_GROTTO, RR_DESERT_COLOSSUS, 0x0800 } }, - { { EntranceType::GrottoGrave, RR_LAKE_HYLIA, RR_LH_GROTTO, 0x0701 }, - { EntranceType::GrottoGrave, RR_LH_GROTTO, RR_LAKE_HYLIA, 0x0801 } }, - { { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_STORMS_GROTTO, 0x0702 }, - { EntranceType::GrottoGrave, RR_ZR_STORMS_GROTTO, RR_ZORAS_RIVER, 0x0802 } }, - { { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_FAIRY_GROTTO, 0x0703 }, - { EntranceType::GrottoGrave, RR_ZR_FAIRY_GROTTO, RR_ZORAS_RIVER, 0x0803 } }, - { { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_OPEN_GROTTO, 0x0704 }, - { EntranceType::GrottoGrave, RR_ZR_OPEN_GROTTO, RR_ZORAS_RIVER, 0x0804 } }, - { { EntranceType::GrottoGrave, RR_DMC_LOWER_NEARBY, RR_DMC_HAMMER_GROTTO, 0x0705 }, - { EntranceType::GrottoGrave, RR_DMC_HAMMER_GROTTO, RR_DMC_LOWER_LOCAL, 0x0805 } }, - { { EntranceType::GrottoGrave, RR_DMC_UPPER_NEARBY, RR_DMC_UPPER_GROTTO, 0x0706 }, - { EntranceType::GrottoGrave, RR_DMC_UPPER_GROTTO, RR_DMC_UPPER_LOCAL, 0x0806 } }, - { { EntranceType::GrottoGrave, RR_GC_GROTTO_PLATFORM, RR_GC_GROTTO, 0x0707 }, - { EntranceType::GrottoGrave, RR_GC_GROTTO, RR_GC_GROTTO_PLATFORM, 0x0807 } }, - { { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_TRAIL, RR_DMT_STORMS_GROTTO, 0x0708 }, - { EntranceType::GrottoGrave, RR_DMT_STORMS_GROTTO, RR_DEATH_MOUNTAIN_TRAIL, 0x0808 } }, - { { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_COW_GROTTO, 0x0709 }, - { EntranceType::GrottoGrave, RR_DMT_COW_GROTTO, RR_DEATH_MOUNTAIN_SUMMIT, 0x0809 } }, - { { EntranceType::GrottoGrave, RR_KAK_BACKYARD, RR_KAK_OPEN_GROTTO, 0x070A }, - { EntranceType::GrottoGrave, RR_KAK_OPEN_GROTTO, RR_KAK_BACKYARD, 0x080A } }, - { { EntranceType::GrottoGrave, RR_KAKARIKO_VILLAGE, RR_KAK_REDEAD_GROTTO, 0x070B }, - { EntranceType::GrottoGrave, RR_KAK_REDEAD_GROTTO, RR_KAKARIKO_VILLAGE, 0x080B } }, - { { EntranceType::GrottoGrave, RR_HYRULE_CASTLE_GROUNDS, RR_HC_STORMS_GROTTO, 0x070C }, - { EntranceType::GrottoGrave, RR_HC_STORMS_GROTTO, RR_CASTLE_GROUNDS, 0x080C } }, - { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_TEKTITE_GROTTO, 0x070D }, - { EntranceType::GrottoGrave, RR_HF_TEKTITE_GROTTO, RR_HYRULE_FIELD, 0x080D } }, - { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_NEAR_KAK_GROTTO, 0x070E }, - { EntranceType::GrottoGrave, RR_HF_NEAR_KAK_GROTTO, RR_HYRULE_FIELD, 0x080E } }, - { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_FAIRY_GROTTO, 0x070F }, - { EntranceType::GrottoGrave, RR_HF_FAIRY_GROTTO, RR_HYRULE_FIELD, 0x080F } }, - { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_NEAR_MARKET_GROTTO, 0x0710 }, - { EntranceType::GrottoGrave, RR_HF_NEAR_MARKET_GROTTO, RR_HYRULE_FIELD, 0x0810 } }, - { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_COW_GROTTO, 0x0711 }, - { EntranceType::GrottoGrave, RR_HF_COW_GROTTO, RR_HYRULE_FIELD, 0x0811 } }, - { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_INSIDE_FENCE_GROTTO, 0x0712 }, - { EntranceType::GrottoGrave, RR_HF_INSIDE_FENCE_GROTTO, RR_HYRULE_FIELD, 0x0812 } }, - { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_OPEN_GROTTO, 0x0713 }, - { EntranceType::GrottoGrave, RR_HF_OPEN_GROTTO, RR_HYRULE_FIELD, 0x0813 } }, - { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_SOUTHEAST_GROTTO, 0x0714 }, - { EntranceType::GrottoGrave, RR_HF_SOUTHEAST_GROTTO, RR_HYRULE_FIELD, 0x0814 } }, - { { EntranceType::GrottoGrave, RR_LON_LON_RANCH, RR_LLR_GROTTO, 0x0715 }, - { EntranceType::GrottoGrave, RR_LLR_GROTTO, RR_LON_LON_RANCH, 0x0815 } }, - { { EntranceType::GrottoGrave, RR_SFM_ENTRYWAY, RR_SFM_WOLFOS_GROTTO, 0x0716 }, - { EntranceType::GrottoGrave, RR_SFM_WOLFOS_GROTTO, RR_SFM_ENTRYWAY, 0x0816 } }, - { { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_STORMS_GROTTO, 0x0717 }, - { EntranceType::GrottoGrave, RR_SFM_STORMS_GROTTO, RR_SACRED_FOREST_MEADOW, 0x0817 } }, - { { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_FAIRY_GROTTO, 0x0718 }, - { EntranceType::GrottoGrave, RR_SFM_FAIRY_GROTTO, RR_SACRED_FOREST_MEADOW, 0x0818 } }, - { { EntranceType::GrottoGrave, RR_LW_BEYOND_MIDO, RR_LW_SCRUBS_GROTTO, 0x0719 }, - { EntranceType::GrottoGrave, RR_LW_SCRUBS_GROTTO, RR_LW_BEYOND_MIDO, 0x0819 } }, - { { EntranceType::GrottoGrave, RR_THE_LOST_WOODS, RR_LW_NEAR_SHORTCUTS_GROTTO, 0x071A }, - { EntranceType::GrottoGrave, RR_LW_NEAR_SHORTCUTS_GROTTO, RR_THE_LOST_WOODS, 0x081A } }, - { { EntranceType::GrottoGrave, RR_KOKIRI_FOREST, RR_KF_STORMS_GROTTO, 0x071B }, - { EntranceType::GrottoGrave, RR_KF_STORMS_GROTTO, RR_KOKIRI_FOREST, 0x081B } }, - { { EntranceType::GrottoGrave, RR_ZORAS_DOMAIN, RR_ZD_STORMS_GROTTO, 0x071C }, - { EntranceType::GrottoGrave, RR_ZD_STORMS_GROTTO, RR_ZORAS_DOMAIN, 0x081C } }, - { { EntranceType::GrottoGrave, RR_GERUDO_FORTRESS, RR_GF_STORMS_GROTTO, 0x071D }, - { EntranceType::GrottoGrave, RR_GF_STORMS_GROTTO, RR_GERUDO_FORTRESS, 0x081D } }, - { { EntranceType::GrottoGrave, RR_GV_FORTRESS_SIDE, RR_GV_STORMS_GROTTO, 0x071E }, - { EntranceType::GrottoGrave, RR_GV_STORMS_GROTTO, RR_GV_FORTRESS_SIDE, 0x081E } }, - { { EntranceType::GrottoGrave, RR_GV_GROTTO_LEDGE, RR_GV_OCTOROK_GROTTO, 0x071F }, - { EntranceType::GrottoGrave, RR_GV_OCTOROK_GROTTO, RR_GV_GROTTO_LEDGE, 0x081F } }, - { { EntranceType::GrottoGrave, RR_LW_BEYOND_MIDO, RR_DEKU_THEATER, 0x0720 }, - { EntranceType::GrottoGrave, RR_DEKU_THEATER, RR_LW_BEYOND_MIDO, 0x0820 } }, + { { EntranceType::GrottoGrave, RR_DESERT_COLOSSUS, RR_COLOSSUS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_COLOSSUS_OFFSET) }, + { EntranceType::GrottoGrave, RR_COLOSSUS_GROTTO, RR_DESERT_COLOSSUS, ENTRANCE_GROTTO_EXIT(GROTTO_COLOSSUS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_LAKE_HYLIA, RR_LH_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LH_OFFSET) }, + { EntranceType::GrottoGrave, RR_LH_GROTTO, RR_LAKE_HYLIA, ENTRANCE_GROTTO_EXIT(GROTTO_LH_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET) }, + { EntranceType::GrottoGrave, RR_ZR_STORMS_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_FAIRY_OFFSET) }, + { EntranceType::GrottoGrave, RR_ZR_FAIRY_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_FAIRY_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_OPEN_OFFSET) }, + { EntranceType::GrottoGrave, RR_ZR_OPEN_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_OPEN_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_DMC_LOWER_NEARBY, RR_DMC_HAMMER_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET) }, + { EntranceType::GrottoGrave, RR_DMC_HAMMER_GROTTO, RR_DMC_LOWER_LOCAL, ENTRANCE_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_DMC_UPPER_NEARBY, RR_DMC_UPPER_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMC_UPPER_OFFSET) }, + { EntranceType::GrottoGrave, RR_DMC_UPPER_GROTTO, RR_DMC_UPPER_LOCAL, ENTRANCE_GROTTO_EXIT(GROTTO_DMC_UPPER_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_GC_GROTTO_PLATFORM, RR_GC_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET) }, + { EntranceType::GrottoGrave, RR_GC_GROTTO, RR_GC_GROTTO_PLATFORM, ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_TRAIL, RR_DMT_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_STORMS_OFFSET) }, + { EntranceType::GrottoGrave, RR_DMT_STORMS_GROTTO, RR_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_STORMS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_COW_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET) }, + { EntranceType::GrottoGrave, RR_DMT_COW_GROTTO, RR_DEATH_MOUNTAIN_SUMMIT, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_KAK_BACKYARD, RR_KAK_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KAK_OPEN_OFFSET) }, + { EntranceType::GrottoGrave, RR_KAK_OPEN_GROTTO, RR_KAK_BACKYARD, ENTRANCE_GROTTO_EXIT(GROTTO_KAK_OPEN_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_KAKARIKO_VILLAGE, RR_KAK_REDEAD_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KAK_REDEAD_OFFSET) }, + { EntranceType::GrottoGrave, RR_KAK_REDEAD_GROTTO, RR_KAKARIKO_VILLAGE, ENTRANCE_GROTTO_EXIT(GROTTO_KAK_REDEAD_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_HYRULE_CASTLE_GROUNDS, RR_HC_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET) }, + { EntranceType::GrottoGrave, RR_HC_STORMS_GROTTO, RR_CASTLE_GROUNDS, ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_TEKTITE_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_TEKTITE_OFFSET) }, + { EntranceType::GrottoGrave, RR_HF_TEKTITE_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_TEKTITE_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_NEAR_KAK_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_KAK_OFFSET) }, + { EntranceType::GrottoGrave, RR_HF_NEAR_KAK_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_KAK_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_FAIRY_OFFSET) }, + { EntranceType::GrottoGrave, RR_HF_FAIRY_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_FAIRY_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_NEAR_MARKET_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_MARKET_OFFSET) }, + { EntranceType::GrottoGrave, RR_HF_NEAR_MARKET_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_MARKET_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_COW_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_COW_OFFSET) }, + { EntranceType::GrottoGrave, RR_HF_COW_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_COW_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_INSIDE_FENCE_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET) }, + { EntranceType::GrottoGrave, RR_HF_INSIDE_FENCE_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_OPEN_OFFSET) }, + { EntranceType::GrottoGrave, RR_HF_OPEN_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_OPEN_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_SOUTHEAST_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_SOUTHEAST_OFFSET) }, + { EntranceType::GrottoGrave, RR_HF_SOUTHEAST_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_SOUTHEAST_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_LON_LON_RANCH, RR_LLR_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LLR_OFFSET) }, + { EntranceType::GrottoGrave, RR_LLR_GROTTO, RR_LON_LON_RANCH, ENTRANCE_GROTTO_EXIT(GROTTO_LLR_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_SFM_ENTRYWAY, RR_SFM_WOLFOS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_WOLFOS_OFFSET) }, + { EntranceType::GrottoGrave, RR_SFM_WOLFOS_GROTTO, RR_SFM_ENTRYWAY, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_WOLFOS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_STORMS_OFFSET) }, + { EntranceType::GrottoGrave, RR_SFM_STORMS_GROTTO, RR_SACRED_FOREST_MEADOW, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_STORMS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET) }, + { EntranceType::GrottoGrave, RR_SFM_FAIRY_GROTTO, RR_SACRED_FOREST_MEADOW, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_LW_BEYOND_MIDO, RR_LW_SCRUBS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET) }, + { EntranceType::GrottoGrave, RR_LW_SCRUBS_GROTTO, RR_LW_BEYOND_MIDO, ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_THE_LOST_WOODS, RR_LW_NEAR_SHORTCUTS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) }, + { EntranceType::GrottoGrave, RR_LW_NEAR_SHORTCUTS_GROTTO, RR_THE_LOST_WOODS, ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_KOKIRI_FOREST, RR_KF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET) }, + { EntranceType::GrottoGrave, RR_KF_STORMS_GROTTO, RR_KOKIRI_FOREST, ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_ZORAS_DOMAIN_ISLAND, RR_ZD_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET) }, + { EntranceType::GrottoGrave, RR_ZD_STORMS_GROTTO, RR_ZORAS_DOMAIN_ISLAND, ENTRANCE_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_GERUDO_FORTRESS, RR_GF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET) }, + { EntranceType::GrottoGrave, RR_GF_STORMS_GROTTO, RR_GERUDO_FORTRESS, ENTRANCE_GROTTO_EXIT(GROTTO_GF_STORMS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_GV_FORTRESS_SIDE, RR_GV_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GV_STORMS_OFFSET) }, + { EntranceType::GrottoGrave, RR_GV_STORMS_GROTTO, RR_GV_FORTRESS_SIDE, ENTRANCE_GROTTO_EXIT(GROTTO_GV_STORMS_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_GV_GROTTO_LEDGE, RR_GV_OCTOROK_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GV_OCTOROK_OFFSET) }, + { EntranceType::GrottoGrave, RR_GV_OCTOROK_GROTTO, RR_GV_GROTTO_LEDGE, ENTRANCE_GROTTO_EXIT(GROTTO_GV_OCTOROK_OFFSET) } }, + { { EntranceType::GrottoGrave, RR_LW_BEYOND_MIDO, RR_DEKU_THEATER, ENTRANCE_GROTTO_LOAD(GROTTO_LW_DEKU_THEATRE_OFFSET) }, + { EntranceType::GrottoGrave, RR_DEKU_THEATER, RR_LW_BEYOND_MIDO, ENTRANCE_GROTTO_EXIT(GROTTO_LW_DEKU_THEATRE_OFFSET) } }, // Graves have their own specified entrance indices - { { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_SHIELD_GRAVE, 0x004B }, - { EntranceType::GrottoGrave, RR_GRAVEYARD_SHIELD_GRAVE, RR_THE_GRAVEYARD, 0x035D } }, - { { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_HEART_PIECE_GRAVE, 0x031C }, - { EntranceType::GrottoGrave, RR_GRAVEYARD_HEART_PIECE_GRAVE, RR_THE_GRAVEYARD, 0x0361 } }, - { { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_COMPOSERS_GRAVE, 0x002D }, - { EntranceType::GrottoGrave, RR_GRAVEYARD_COMPOSERS_GRAVE, RR_THE_GRAVEYARD, 0x050B } }, - { { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_DAMPES_GRAVE, 0x044F }, - { EntranceType::GrottoGrave, RR_GRAVEYARD_DAMPES_GRAVE, RR_THE_GRAVEYARD, 0x0359 } }, + { { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_SHIELD_GRAVE, ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0 }, + { EntranceType::GrottoGrave, RR_GRAVEYARD_SHIELD_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_SHIELD_GRAVE_EXIT } }, + { { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_HEART_PIECE_GRAVE, ENTR_REDEAD_GRAVE_0 }, + { EntranceType::GrottoGrave, RR_GRAVEYARD_HEART_PIECE_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_HEART_PIECE_GRAVE_EXIT } }, + { { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_COMPOSERS_GRAVE, ENTR_ROYAL_FAMILYS_TOMB_0 }, + { EntranceType::GrottoGrave, RR_GRAVEYARD_COMPOSERS_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_ROYAL_TOMB_EXIT } }, + { { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_DAMPES_GRAVE, ENTR_WINDMILL_AND_DAMPES_GRAVE_GRAVE }, + { EntranceType::GrottoGrave, RR_GRAVEYARD_DAMPES_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_DAMPES_GRAVE_EXIT } }, - { { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_LW_BRIDGE_FROM_FOREST, 0x05E0 }, - { EntranceType::Overworld, RR_LW_BRIDGE, RR_KOKIRI_FOREST, 0x020D } }, - { { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_THE_LOST_WOODS, 0x011E }, - { EntranceType::Overworld, RR_LW_FOREST_EXIT, RR_KOKIRI_FOREST, 0x0286 } }, - { { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_GC_WOODS_WARP, 0x04E2 }, - { EntranceType::Overworld, RR_GC_WOODS_WARP, RR_THE_LOST_WOODS, 0x04D6 } }, - { { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_ZORAS_RIVER, 0x01DD }, - { EntranceType::Overworld, RR_ZORAS_RIVER, RR_THE_LOST_WOODS, 0x04DA } }, - { { EntranceType::Overworld, RR_LW_BEYOND_MIDO, RR_SFM_ENTRYWAY, 0x00FC }, - { EntranceType::Overworld, RR_SFM_ENTRYWAY, RR_LW_BEYOND_MIDO, 0x01A9 } }, - { { EntranceType::Overworld, RR_LW_BRIDGE, RR_HYRULE_FIELD, 0x0185 }, - { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LW_BRIDGE, 0x04DE } }, - { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LAKE_HYLIA, 0x0102 }, - { EntranceType::Overworld, RR_LAKE_HYLIA, RR_HYRULE_FIELD, 0x0189 } }, - { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_GERUDO_VALLEY, 0x0117 }, - { EntranceType::Overworld, RR_GERUDO_VALLEY, RR_HYRULE_FIELD, 0x018D } }, - { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_MARKET_ENTRANCE, 0x0276 }, - { EntranceType::Overworld, RR_MARKET_ENTRANCE, RR_HYRULE_FIELD, 0x01FD } }, - { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_KAKARIKO_VILLAGE, 0x00DB }, - { EntranceType::Overworld, RR_KAKARIKO_VILLAGE, RR_HYRULE_FIELD, 0x017D } }, - { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_ZR_FRONT, 0x00EA }, - { EntranceType::Overworld, RR_ZR_FRONT, RR_HYRULE_FIELD, 0x0181 } }, - { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LON_LON_RANCH, 0x0157 }, - { EntranceType::Overworld, RR_LON_LON_RANCH, RR_HYRULE_FIELD, 0x01F9 } }, - { { EntranceType::Overworld, RR_LAKE_HYLIA, RR_ZORAS_DOMAIN, 0x0328 }, - { EntranceType::Overworld, RR_ZORAS_DOMAIN, RR_LAKE_HYLIA, 0x0560 } }, - { { EntranceType::Overworld, RR_GV_FORTRESS_SIDE, RR_GERUDO_FORTRESS, 0x0129 }, - { EntranceType::Overworld, RR_GERUDO_FORTRESS, RR_GV_FORTRESS_SIDE, 0x022D } }, - { { EntranceType::Overworld, RR_GF_OUTSIDE_GATE, RR_WASTELAND_NEAR_FORTRESS, 0x0130 }, - { EntranceType::Overworld, RR_WASTELAND_NEAR_FORTRESS, RR_GF_OUTSIDE_GATE, 0x03AC } }, - { { EntranceType::Overworld, RR_WASTELAND_NEAR_COLOSSUS, RR_DESERT_COLOSSUS, 0x0123 }, - { EntranceType::Overworld, RR_DESERT_COLOSSUS, RR_WASTELAND_NEAR_COLOSSUS, 0x0365 } }, - { { EntranceType::Overworld, RR_MARKET_ENTRANCE, RR_THE_MARKET, 0x00B1 }, - { EntranceType::Overworld, RR_THE_MARKET, RR_MARKET_ENTRANCE, 0x0033 } }, - { { EntranceType::Overworld, RR_THE_MARKET, RR_CASTLE_GROUNDS, 0x0138 }, - { EntranceType::Overworld, RR_CASTLE_GROUNDS, RR_THE_MARKET, 0x025A } }, - { { EntranceType::Overworld, RR_THE_MARKET, RR_TOT_ENTRANCE, 0x0171 }, - { EntranceType::Overworld, RR_TOT_ENTRANCE, RR_THE_MARKET, 0x025E } }, - { { EntranceType::Overworld, RR_KAKARIKO_VILLAGE, RR_THE_GRAVEYARD, 0x00E4 }, - { EntranceType::Overworld, RR_THE_GRAVEYARD, RR_KAKARIKO_VILLAGE, 0x0195 } }, - { { EntranceType::Overworld, RR_KAK_BEHIND_GATE, RR_DEATH_MOUNTAIN_TRAIL, 0x013D }, - { EntranceType::Overworld, RR_DEATH_MOUNTAIN_TRAIL, RR_KAK_BEHIND_GATE, 0x0191 } }, - { { EntranceType::Overworld, RR_DEATH_MOUNTAIN_TRAIL, RR_GORON_CITY, 0x014D }, - { EntranceType::Overworld, RR_GORON_CITY, RR_DEATH_MOUNTAIN_TRAIL, 0x01B9 } }, - { { EntranceType::Overworld, RR_GC_DARUNIAS_CHAMBER, RR_DMC_LOWER_LOCAL, 0x0246 }, - { EntranceType::Overworld, RR_DMC_LOWER_NEARBY, RR_GC_DARUNIAS_CHAMBER, 0x01C1 } }, - { { EntranceType::Overworld, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMC_UPPER_LOCAL, 0x0147 }, - { EntranceType::Overworld, RR_DMC_UPPER_NEARBY, RR_DEATH_MOUNTAIN_SUMMIT, 0x01BD } }, - { { EntranceType::Overworld, RR_ZR_BEHIND_WATERFALL, RR_ZORAS_DOMAIN, 0x0108 }, - { EntranceType::Overworld, RR_ZORAS_DOMAIN, RR_ZR_BEHIND_WATERFALL, 0x019D } }, - { { EntranceType::Overworld, RR_ZD_BEHIND_KING_ZORA, RR_ZORAS_FOUNTAIN, 0x0225 }, - { EntranceType::Overworld, RR_ZORAS_FOUNTAIN, RR_ZD_BEHIND_KING_ZORA, 0x01A1 } }, + { { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_LW_BRIDGE_FROM_FOREST, ENTR_LOST_WOODS_BRIDGE_EAST_EXIT }, + { EntranceType::Overworld, RR_LW_BRIDGE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_LOWER_EXIT } }, + { { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_SOUTH_EXIT }, + { EntranceType::Overworld, RR_LW_FOREST_EXIT, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_UPPER_EXIT } }, + { { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_GC_WOODS_WARP, ENTR_GORON_CITY_TUNNEL_SHORTCUT }, + { EntranceType::Overworld, RR_GC_WOODS_WARP, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_TUNNEL_SHORTCUT } }, + { { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_ZORAS_RIVER, ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT }, + { EntranceType::Overworld, RR_ZORAS_RIVER, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_UNDERWATER_SHORTCUT } }, + { { EntranceType::Overworld, RR_LW_BEYOND_MIDO, RR_SFM_ENTRYWAY, ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT }, + { EntranceType::Overworld, RR_SFM_ENTRYWAY, RR_LW_BEYOND_MIDO, ENTR_LOST_WOODS_NORTH_EXIT } }, + { { EntranceType::Overworld, RR_LW_BRIDGE, RR_HYRULE_FIELD, ENTR_LOST_WOODS_BRIDGE_WEST_EXIT }, + { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LW_BRIDGE, ENTR_HYRULE_FIELD_WOODED_EXIT } }, + { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_NORTH_EXIT }, + { EntranceType::Overworld, RR_LAKE_HYLIA, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_FENCE_EXIT } }, + { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_GERUDO_VALLEY, ENTR_GERUDO_VALLEY_EAST_EXIT }, + { EntranceType::Overworld, RR_GERUDO_VALLEY, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_ROCKY_PATH } }, + { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT }, + { EntranceType::Overworld, RR_MARKET_ENTRANCE, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN } }, + { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_FRONT_GATE }, + { EntranceType::Overworld, RR_KAKARIKO_VILLAGE, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_STAIRS_EXIT } }, + { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_ZR_FRONT, ENTR_ZORAS_RIVER_WEST_EXIT }, + { EntranceType::Overworld, RR_ZR_FRONT, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_RIVER_EXIT } }, + { { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_ENTRANCE }, + { EntranceType::Overworld, RR_LON_LON_RANCH, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_CENTER_EXIT } }, + { { EntranceType::Overworld, RR_LAKE_HYLIA, RR_ZORAS_DOMAIN, ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT }, + { EntranceType::Overworld, RR_ZORAS_DOMAIN, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT } }, + { { EntranceType::Overworld, RR_GV_FORTRESS_SIDE, RR_GERUDO_FORTRESS, ENTR_GERUDOS_FORTRESS_EAST_EXIT }, + { EntranceType::Overworld, RR_GERUDO_FORTRESS, RR_GV_FORTRESS_SIDE, ENTR_GERUDO_VALLEY_WEST_EXIT } }, + { { EntranceType::Overworld, RR_GF_OUTSIDE_GATE, RR_WASTELAND_NEAR_FORTRESS, ENTR_HAUNTED_WASTELAND_EAST_EXIT }, + { EntranceType::Overworld, RR_WASTELAND_NEAR_FORTRESS, RR_GF_OUTSIDE_GATE, ENTR_GERUDOS_FORTRESS_GATE_EXIT } }, + { { EntranceType::Overworld, RR_WASTELAND_NEAR_COLOSSUS, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_EAST_EXIT }, + { EntranceType::Overworld, RR_DESERT_COLOSSUS, RR_WASTELAND_NEAR_COLOSSUS, ENTR_HAUNTED_WASTELAND_WEST_EXIT } }, + { { EntranceType::Overworld, RR_MARKET_ENTRANCE, RR_THE_MARKET, ENTR_MARKET_SOUTH_EXIT }, + { EntranceType::Overworld, RR_THE_MARKET, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_NORTH_EXIT } }, + { { EntranceType::Overworld, RR_THE_MARKET, RR_CASTLE_GROUNDS, ENTR_MARKET_DAY_CASTLE_EXIT }, + { EntranceType::Overworld, RR_CASTLE_GROUNDS, RR_THE_MARKET, ENTR_CASTLE_GROUNDS_SOUTH_EXIT } }, + { { EntranceType::Overworld, RR_THE_MARKET, RR_TOT_ENTRANCE, ENTR_MARKET_DAY_TEMPLE_EXIT }, + { EntranceType::Overworld, RR_TOT_ENTRANCE, RR_THE_MARKET, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT } }, + { { EntranceType::Overworld, RR_KAKARIKO_VILLAGE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_ENTRANCE }, + { EntranceType::Overworld, RR_THE_GRAVEYARD, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_SOUTHEAST_EXIT } }, + { { EntranceType::Overworld, RR_KAK_BEHIND_GATE, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT }, + { EntranceType::Overworld, RR_DEATH_MOUNTAIN_TRAIL, RR_KAK_BEHIND_GATE, ENTR_KAKARIKO_VILLAGE_GUARD_GATE } }, + { { EntranceType::Overworld, RR_DEATH_MOUNTAIN_TRAIL, RR_GORON_CITY, ENTR_GORON_CITY_UPPER_EXIT }, + { EntranceType::Overworld, RR_GORON_CITY, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT } }, + { { EntranceType::Overworld, RR_GC_DARUNIAS_CHAMBER, RR_DMC_LOWER_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT }, + { EntranceType::Overworld, RR_DMC_LOWER_NEARBY, RR_GC_DARUNIAS_CHAMBER, ENTR_GORON_CITY_DARUNIA_ROOM_EXIT } }, + { { EntranceType::Overworld, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMC_UPPER_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT }, + { EntranceType::Overworld, RR_DMC_UPPER_NEARBY, RR_DEATH_MOUNTAIN_SUMMIT, ENTR_DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT } }, + { { EntranceType::Overworld, RR_ZR_BEHIND_WATERFALL, RR_ZORAS_DOMAIN, ENTR_ZORAS_DOMAIN_ENTRANCE }, + { EntranceType::Overworld, RR_ZORAS_DOMAIN, RR_ZR_BEHIND_WATERFALL, ENTR_ZORAS_RIVER_WATERFALL_EXIT } }, + { { EntranceType::Overworld, RR_ZD_BEHIND_KING_ZORA, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_TUNNEL_EXIT }, + { EntranceType::Overworld, RR_ZORAS_FOUNTAIN, RR_ZD_BEHIND_KING_ZORA, ENTR_ZORAS_DOMAIN_KING_ZORA_EXIT } }, - { { EntranceType::Overworld, RR_GV_LOWER_STREAM, RR_LAKE_HYLIA, 0x0219 }, NO_RETURN_ENTRANCE }, + { { EntranceType::Overworld, RR_GV_LOWER_STREAM, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_RIVER_EXIT }, + NO_RETURN_ENTRANCE }, - { { EntranceType::OwlDrop, RR_LH_OWL_FLIGHT, RR_HYRULE_FIELD, 0x027E }, NO_RETURN_ENTRANCE }, - { { EntranceType::OwlDrop, RR_DMT_OWL_FLIGHT, RR_KAK_IMPAS_ROOFTOP, 0x0554 }, NO_RETURN_ENTRANCE }, + { { EntranceType::OwlDrop, RR_LH_OWL_FLIGHT, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_OWL_DROP }, + NO_RETURN_ENTRANCE }, + { { EntranceType::OwlDrop, RR_DMT_OWL_FLIGHT, RR_KAK_IMPAS_ROOFTOP, ENTR_KAKARIKO_VILLAGE_OWL_DROP }, + NO_RETURN_ENTRANCE }, - { { EntranceType::Spawn, RR_CHILD_SPAWN, RR_KF_LINKS_HOUSE, 0x00BB }, NO_RETURN_ENTRANCE }, - { { EntranceType::Spawn, RR_ADULT_SPAWN, RR_TEMPLE_OF_TIME, 0x0282 }, + { { EntranceType::Spawn, RR_CHILD_SPAWN, RR_KF_LINKS_HOUSE, ENTR_LINKS_HOUSE_CHILD_SPAWN }, + NO_RETURN_ENTRANCE }, + { { EntranceType::Spawn, RR_ADULT_SPAWN, RR_TEMPLE_OF_TIME, ENTR_HYRULE_FIELD_10 }, 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, RR_MINUET_OF_FOREST_WARP, RR_SACRED_FOREST_MEADOW, 0x0600 }, NO_RETURN_ENTRANCE }, - { { EntranceType::WarpSong, RR_BOLERO_OF_FIRE_WARP, RR_DMC_CENTRAL_LOCAL, 0x04F6 }, NO_RETURN_ENTRANCE }, - { { EntranceType::WarpSong, RR_SERENADE_OF_WATER_WARP, RR_LAKE_HYLIA, 0x0604 }, NO_RETURN_ENTRANCE }, - { { EntranceType::WarpSong, RR_REQUIEM_OF_SPIRIT_WARP, RR_DESERT_COLOSSUS, 0x01F1 }, NO_RETURN_ENTRANCE }, - { { EntranceType::WarpSong, RR_NOCTURNE_OF_SHADOW_WARP, RR_GRAVEYARD_WARP_PAD_REGION, 0x0568 }, + { { EntranceType::WarpSong, RR_MINUET_OF_FOREST_WARP, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_WARP_PAD }, NO_RETURN_ENTRANCE }, - { { EntranceType::WarpSong, RR_PRELUDE_OF_LIGHT_WARP, RR_TEMPLE_OF_TIME, 0x05F4 }, NO_RETURN_ENTRANCE }, - - { { EntranceType::ChildBoss, RR_DEKU_TREE_BOSS_ENTRYWAY, RR_DEKU_TREE_BOSS_ROOM, 0x040F }, - { EntranceType::ChildBoss, RR_DEKU_TREE_BOSS_ROOM, RR_DEKU_TREE_BOSS_ENTRYWAY, 0x0252 } }, - { { EntranceType::ChildBoss, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, RR_DODONGOS_CAVERN_BOSS_ROOM, 0x040B }, - { EntranceType::ChildBoss, RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, 0x00C5 } }, - { { EntranceType::ChildBoss, RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, RR_JABU_JABUS_BELLY_BOSS_ROOM, 0x0301 }, - { EntranceType::ChildBoss, RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, 0x0407 } }, - { { EntranceType::AdultBoss, RR_FOREST_TEMPLE_BOSS_ENTRYWAY, RR_FOREST_TEMPLE_BOSS_ROOM, 0x000C }, - { EntranceType::AdultBoss, RR_FOREST_TEMPLE_BOSS_ROOM, RR_FOREST_TEMPLE_BOSS_ENTRYWAY, 0x024E } }, - { { EntranceType::AdultBoss, RR_FIRE_TEMPLE_BOSS_ENTRYWAY, RR_FIRE_TEMPLE_BOSS_ROOM, 0x0305 }, - { EntranceType::AdultBoss, RR_FIRE_TEMPLE_BOSS_ROOM, RR_FIRE_TEMPLE_BOSS_ENTRYWAY, 0x0175 } }, - { { EntranceType::AdultBoss, RR_WATER_TEMPLE_BOSS_ENTRYWAY, RR_WATER_TEMPLE_BOSS_ROOM, 0x0417 }, - { EntranceType::AdultBoss, RR_WATER_TEMPLE_BOSS_ROOM, RR_WATER_TEMPLE_BOSS_ENTRYWAY, 0x0423 } }, - { { EntranceType::AdultBoss, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, RR_SPIRIT_TEMPLE_BOSS_ROOM, 0x008D }, - { EntranceType::AdultBoss, RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, 0x02F5 } }, - { { EntranceType::AdultBoss, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, RR_SHADOW_TEMPLE_BOSS_ROOM, 0x0413 }, - { EntranceType::AdultBoss, RR_SHADOW_TEMPLE_BOSS_ROOM, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, 0x02B2 } }, - - { { EntranceType::BlueWarp, RR_DEKU_TREE_BOSS_ROOM, RR_KF_OUTSIDE_DEKU_TREE, 0x0457 }, NO_RETURN_ENTRANCE }, - { { EntranceType::BlueWarp, RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DEATH_MOUNTAIN_TRAIL, 0x047A }, + { { EntranceType::WarpSong, RR_BOLERO_OF_FIRE_WARP, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD }, NO_RETURN_ENTRANCE }, - { { EntranceType::BlueWarp, RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_ZORAS_FOUNTAIN, 0x010E }, NO_RETURN_ENTRANCE }, - { { EntranceType::BlueWarp, RR_FOREST_TEMPLE_BOSS_ROOM, RR_SACRED_FOREST_MEADOW, 0x0608 }, NO_RETURN_ENTRANCE }, - { { EntranceType::BlueWarp, RR_FIRE_TEMPLE_BOSS_ROOM, RR_DMC_CENTRAL_LOCAL, 0x0564 }, NO_RETURN_ENTRANCE }, - { { EntranceType::BlueWarp, RR_WATER_TEMPLE_BOSS_ROOM, RR_LAKE_HYLIA, 0x060C }, NO_RETURN_ENTRANCE }, - { { EntranceType::BlueWarp, RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_DESERT_COLOSSUS, 0x0610 }, NO_RETURN_ENTRANCE }, - { { EntranceType::BlueWarp, RR_SHADOW_TEMPLE_BOSS_ROOM, RR_GRAVEYARD_WARP_PAD_REGION, 0x0580 }, + { { EntranceType::WarpSong, RR_SERENADE_OF_WATER_WARP, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_WARP_PAD }, + NO_RETURN_ENTRANCE }, + { { EntranceType::WarpSong, RR_REQUIEM_OF_SPIRIT_WARP, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_WARP_PAD }, + NO_RETURN_ENTRANCE }, + { { EntranceType::WarpSong, RR_NOCTURNE_OF_SHADOW_WARP, RR_GRAVEYARD_WARP_PAD_REGION, ENTR_GRAVEYARD_WARP_PAD }, + NO_RETURN_ENTRANCE }, + { { EntranceType::WarpSong, RR_PRELUDE_OF_LIGHT_WARP, RR_TEMPLE_OF_TIME, ENTR_TEMPLE_OF_TIME_WARP_PAD }, + NO_RETURN_ENTRANCE }, + + { { EntranceType::ChildBoss, RR_DEKU_TREE_BOSS_ENTRYWAY, RR_DEKU_TREE_BOSS_ROOM, ENTR_DEKU_TREE_BOSS_ENTRANCE }, + { EntranceType::ChildBoss, RR_DEKU_TREE_BOSS_ROOM, RR_DEKU_TREE_BOSS_ENTRYWAY, ENTR_DEKU_TREE_BOSS_DOOR } }, + { { EntranceType::ChildBoss, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, RR_DODONGOS_CAVERN_BOSS_ROOM, ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE }, + { EntranceType::ChildBoss, RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, ENTR_DODONGOS_CAVERN_BOSS_DOOR } }, + { { EntranceType::ChildBoss, RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, RR_JABU_JABUS_BELLY_BOSS_ROOM, ENTR_JABU_JABU_BOSS_ENTRANCE }, + { EntranceType::ChildBoss, RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, ENTR_JABU_JABU_BOSS_DOOR } }, + { { EntranceType::AdultBoss, RR_FOREST_TEMPLE_BOSS_ENTRYWAY, RR_FOREST_TEMPLE_BOSS_ROOM, ENTR_FOREST_TEMPLE_BOSS_ENTRANCE }, + { EntranceType::AdultBoss, RR_FOREST_TEMPLE_BOSS_ROOM, RR_FOREST_TEMPLE_BOSS_ENTRYWAY, ENTR_FOREST_TEMPLE_BOSS_DOOR } }, + { { EntranceType::AdultBoss, RR_FIRE_TEMPLE_BOSS_ENTRYWAY, RR_FIRE_TEMPLE_BOSS_ROOM, ENTR_FIRE_TEMPLE_BOSS_ENTRANCE }, + { EntranceType::AdultBoss, RR_FIRE_TEMPLE_BOSS_ROOM, RR_FIRE_TEMPLE_BOSS_ENTRYWAY, ENTR_FIRE_TEMPLE_BOSS_DOOR } }, + { { EntranceType::AdultBoss, RR_WATER_TEMPLE_BOSS_ENTRYWAY, RR_WATER_TEMPLE_BOSS_ROOM, ENTR_WATER_TEMPLE_BOSS_ENTRANCE }, + { EntranceType::AdultBoss, RR_WATER_TEMPLE_BOSS_ROOM, RR_WATER_TEMPLE_BOSS_ENTRYWAY, ENTR_WATER_TEMPLE_BOSS_DOOR } }, + { { EntranceType::AdultBoss, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, RR_SPIRIT_TEMPLE_BOSS_ROOM, ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE }, + { EntranceType::AdultBoss, RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, ENTR_SPIRIT_TEMPLE_BOSS_DOOR } }, + { { EntranceType::AdultBoss, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, RR_SHADOW_TEMPLE_BOSS_ROOM, ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE }, + { EntranceType::AdultBoss, RR_SHADOW_TEMPLE_BOSS_ROOM, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, ENTR_SHADOW_TEMPLE_BOSS_DOOR } }, + + { { EntranceType::BlueWarp, RR_DEKU_TREE_BOSS_ROOM, RR_KF_OUTSIDE_DEKU_TREE, ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP }, + NO_RETURN_ENTRANCE }, + { { EntranceType::BlueWarp, RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP }, + NO_RETURN_ENTRANCE }, + { { EntranceType::BlueWarp, RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP }, + NO_RETURN_ENTRANCE }, + { { EntranceType::BlueWarp, RR_FOREST_TEMPLE_BOSS_ROOM, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP }, + NO_RETURN_ENTRANCE }, + { { EntranceType::BlueWarp, RR_FIRE_TEMPLE_BOSS_ROOM, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP }, + NO_RETURN_ENTRANCE }, + { { EntranceType::BlueWarp, RR_WATER_TEMPLE_BOSS_ROOM, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP }, + NO_RETURN_ENTRANCE }, + { { EntranceType::BlueWarp, RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP }, + NO_RETURN_ENTRANCE }, + { { EntranceType::BlueWarp, RR_SHADOW_TEMPLE_BOSS_ROOM, RR_GRAVEYARD_WARP_PAD_REGION, ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP }, NO_RETURN_ENTRANCE }, }; @@ -1169,7 +1181,7 @@ int EntranceShuffler::ShuffleAllEntrances() { { { RR_GRAVEYARD_WARP_PAD_REGION }, { EntranceType::OwlDrop, EntranceType::Spawn, EntranceType::WarpSong } } }, { "Requiem", - { { RR_DESERT_COLOSSUS, RR_DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY }, + { { RR_DESERT_COLOSSUS, RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE }, { EntranceType::OwlDrop, EntranceType::Spawn, EntranceType::WarpSong } } }, }; @@ -1210,7 +1222,7 @@ int EntranceShuffler::ShuffleAllEntrances() { 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 (ctx->GetOption(RSK_FOREST).Is(RO_FOREST_CLOSED) && + if (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_ON) && !(ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES))) { FilterAndEraseFromPool(entrancePools[EntranceType::Boss], [](const Entrance* entrance) { return entrance->GetParentRegionKey() == RR_DEKU_TREE_BOSS_ENTRYWAY && @@ -1226,7 +1238,7 @@ int EntranceShuffler::ShuffleAllEntrances() { entrancePools[EntranceType::ChildBoss] = GetShuffleableEntrances(EntranceType::ChildBoss); entrancePools[EntranceType::AdultBoss] = GetShuffleableEntrances(EntranceType::AdultBoss); // If forest is closed, ensure Ghoma is inside the Deku tree - if (ctx->GetOption(RSK_FOREST).Is(RO_FOREST_CLOSED) && + if (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_ON) && !(ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES))) { FilterAndEraseFromPool(entrancePools[EntranceType::ChildBoss], [](const Entrance* entrance) { return entrance->GetParentRegionKey() == RR_DEKU_TREE_BOSS_ENTRYWAY && @@ -1253,7 +1265,7 @@ int EntranceShuffler::ShuffleAllEntrances() { GetShuffleableEntrances(EntranceType::GanonDungeon)); } // If forest is closed don't allow a forest escape via spirit temple hands - if (ctx->GetOption(RSK_FOREST).Is(RO_FOREST_CLOSED) && + if (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_ON) && !(ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES))) { FilterAndEraseFromPool(entrancePools[EntranceType::Dungeon], [](const Entrance* entrance) { return entrance->GetParentRegionKey() == RR_KF_OUTSIDE_DEKU_TREE && @@ -1318,12 +1330,12 @@ int EntranceShuffler::ShuffleAllEntrances() { (ctx->GetOption(RSK_MIX_OVERWORLD_ENTRANCES) ? 1 : 0) + (ctx->GetOption(RSK_MIX_INTERIOR_ENTRANCES) ? 1 : 0) + (ctx->GetOption(RSK_MIX_GROTTO_ENTRANCES) ? 1 : 0); if (totalMixedPools < 2) { - ctx->GetOption(RSK_MIXED_ENTRANCE_POOLS).SetSelectedIndex(RO_GENERIC_OFF); - ctx->GetOption(RSK_MIX_DUNGEON_ENTRANCES).SetSelectedIndex(RO_GENERIC_OFF); - ctx->GetOption(RSK_MIX_BOSS_ENTRANCES).SetSelectedIndex(RO_GENERIC_OFF); - ctx->GetOption(RSK_MIX_OVERWORLD_ENTRANCES).SetSelectedIndex(RO_GENERIC_OFF); - ctx->GetOption(RSK_MIX_INTERIOR_ENTRANCES).SetSelectedIndex(RO_GENERIC_OFF); - ctx->GetOption(RSK_MIX_GROTTO_ENTRANCES).SetSelectedIndex(RO_GENERIC_OFF); + ctx->GetOption(RSK_MIXED_ENTRANCE_POOLS).SetContextIndex(RO_GENERIC_OFF); + ctx->GetOption(RSK_MIX_DUNGEON_ENTRANCES).SetContextIndex(RO_GENERIC_OFF); + ctx->GetOption(RSK_MIX_BOSS_ENTRANCES).SetContextIndex(RO_GENERIC_OFF); + ctx->GetOption(RSK_MIX_OVERWORLD_ENTRANCES).SetContextIndex(RO_GENERIC_OFF); + ctx->GetOption(RSK_MIX_INTERIOR_ENTRANCES).SetContextIndex(RO_GENERIC_OFF); + ctx->GetOption(RSK_MIX_GROTTO_ENTRANCES).SetContextIndex(RO_GENERIC_OFF); } if (ctx->GetOption(RSK_MIXED_ENTRANCE_POOLS)) { std::set poolsToMix = {}; @@ -1497,7 +1509,7 @@ int EntranceShuffler::ShuffleAllEntrances() { { EntranceNameByRegions(RR_WATER_TEMPLE_BOSS_ROOM, RR_WATER_TEMPLE_BOSS_ENTRYWAY), GetEntrance(EntranceNameByRegions(RR_WATER_TEMPLE_ENTRYWAY, RR_LAKE_HYLIA)) }, { EntranceNameByRegions(RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY), - GetEntrance(EntranceNameByRegions(RR_SPIRIT_TEMPLE_ENTRYWAY, RR_DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY)) }, + GetEntrance(EntranceNameByRegions(RR_SPIRIT_TEMPLE_ENTRYWAY, RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE)) }, { EntranceNameByRegions(RR_SHADOW_TEMPLE_BOSS_ROOM, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY), GetEntrance(EntranceNameByRegions(RR_SHADOW_TEMPLE_ENTRYWAY, RR_GRAVEYARD_WARP_PAD_REGION)) }, }; @@ -1517,7 +1529,7 @@ int EntranceShuffler::ShuffleAllEntrances() { GetEntrance(EntranceNameByRegions(RR_FIRE_TEMPLE_BOSS_ROOM, RR_DMC_CENTRAL_LOCAL)) }, { EntranceNameByRegions(RR_WATER_TEMPLE_ENTRYWAY, RR_LAKE_HYLIA), GetEntrance(EntranceNameByRegions(RR_WATER_TEMPLE_BOSS_ROOM, RR_LAKE_HYLIA)) }, - { EntranceNameByRegions(RR_SPIRIT_TEMPLE_ENTRYWAY, RR_DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY), + { EntranceNameByRegions(RR_SPIRIT_TEMPLE_ENTRYWAY, RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE), GetEntrance(EntranceNameByRegions(RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_DESERT_COLOSSUS)) }, { EntranceNameByRegions(RR_SHADOW_TEMPLE_ENTRYWAY, RR_GRAVEYARD_WARP_PAD_REGION), GetEntrance(EntranceNameByRegions(RR_SHADOW_TEMPLE_BOSS_ROOM, RR_GRAVEYARD_WARP_PAD_REGION)) }, @@ -1663,4 +1675,4 @@ void EntranceShuffler::ParseJson(nlohmann::json spoilerFileJson) { extern "C" EntranceOverride* Randomizer_GetEntranceOverrides() { return Rando::Context::GetInstance()->GetEntranceShuffler()->entranceOverrides.data(); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/fishsanity.cpp b/soh/soh/Enhancements/randomizer/fishsanity.cpp index 5fa2974ae..f3ff89d70 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.cpp +++ b/soh/soh/Enhancements/randomizer/fishsanity.cpp @@ -17,7 +17,7 @@ extern PlayState* gPlayState; #define FSi OTRGlobals::Instance->gRandoContext->GetFishsanity() -#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex() +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetContextOptionIndex() /** * @brief Parallel list of pond fish checks for both ages @@ -59,6 +59,7 @@ namespace Rando { const FishIdentity Fishsanity::defaultIdentity = { RAND_INF_MAX, RC_UNKNOWN_CHECK }; bool Fishsanity::fishsanityHelpersInit = false; s16 Fishsanity::fishGroupCounter = 0; + bool Fishsanity::enableAdvance = false; std::unordered_map Fishsanity::pondFishAgeMap; std::vector Fishsanity::childPondFish; std::vector Fishsanity::adultPondFish; @@ -395,22 +396,6 @@ namespace Rando { } } - void Fishsanity::OnFlagSetHandler(int16_t flagType, int16_t flag) { - if (flagType != FLAG_RANDOMIZER_INF) { - return; - } - RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)flag); - FishsanityCheckType fsType = Rando::Fishsanity::GetCheckType(rc); - if (fsType == FSC_NONE) { - return; - } - - // When a pond fish is caught, advance the pond. - if (fsType == FSC_POND) { - OTRGlobals::Instance->gRandoContext->GetFishsanity()->AdvancePond(); - } - } - void Fishsanity::OnActorUpdateHandler(void* refActor) { if (gPlayState->sceneNum != SCENE_GROTTOS && gPlayState->sceneNum != SCENE_ZORAS_DOMAIN && gPlayState->sceneNum != SCENE_FISHING_POND) { return; @@ -428,6 +413,7 @@ namespace Rando { FishIdentity identity = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); if (identity.randomizerCheck != RC_UNKNOWN_CHECK) { Flags_SetRandomizerInf(identity.randomizerInf); + enableAdvance = true; // Remove uncaught effect if (actor->shape.shadowDraw != NULL) { actor->shape.shadowDraw = NULL; @@ -483,6 +469,13 @@ namespace Rando { } } } + + void Fishsanity::OnItemReceiveHandler(GetItemEntry itemEntry) { + if (enableAdvance) { + enableAdvance = false; + OTRGlobals::Instance->gRandoContext->GetFishsanity()->AdvancePond(); + } + } } // namespace Rando // C interface diff --git a/soh/soh/Enhancements/randomizer/fishsanity.h b/soh/soh/Enhancements/randomizer/fishsanity.h index c98e9ab9c..91d021157 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.h +++ b/soh/soh/Enhancements/randomizer/fishsanity.h @@ -133,11 +133,6 @@ class Fishsanity { */ static void OnActorInitHandler(void* refActor); - /** - * @brief FlagSet hook handler for fishsanity - */ - static void OnFlagSetHandler(int16_t flagType, int16_t flag); - /** * @brief PlayerUpdate hook handler for fishsanity */ @@ -158,6 +153,8 @@ class Fishsanity { */ static void OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs); + static void OnItemReceiveHandler(GetItemEntry itemEntry); + private: /** * @brief Initialize helper statics if they have not been initialized yet @@ -184,6 +181,7 @@ class Fishsanity { static bool fishsanityHelpersInit; static s16 fishGroupCounter; + static bool enableAdvance; ///////////////////////////////////////////////////////// //// Helper data structures derived from static data //// diff --git a/soh/soh/Enhancements/randomizer/hint.cpp b/soh/soh/Enhancements/randomizer/hint.cpp index b6463cab3..e248eebe0 100644 --- a/soh/soh/Enhancements/randomizer/hint.cpp +++ b/soh/soh/Enhancements/randomizer/hint.cpp @@ -148,7 +148,7 @@ void Hint::FillGapsInData(){ for(uint8_t c = 0; c < locations.size(); c++){ //if area matters for the hint, it should be specified and not left to this if (fillAreas){ - areas.push_back(*ctx->GetItemLocation(locations[c])->GetAreas().begin()); + areas.push_back(ctx->GetItemLocation(locations[c])->GetFirstArea()); } if (fillItems){ items.push_back(ctx->GetItemLocation(locations[c])->GetPlacedRandomizerGet()); @@ -559,23 +559,23 @@ CustomMessage Hint::GetBridgeReqsText() { } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES)) { bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_STONES_HINT].GetHintMessage(); - bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Value()); + bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).GetContextOptionIndex()); } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS)) { bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_MEDALLIONS_HINT].GetHintMessage(); - bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Value()); + bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).GetContextOptionIndex()); } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_REWARDS_HINT].GetHintMessage(); - bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Value()); + bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).GetContextOptionIndex()); } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS)) { bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_DUNGEONS_HINT].GetHintMessage(); - bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Value()); + bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).GetContextOptionIndex()); } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) { bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_TOKENS_HINT].GetHintMessage(); - bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Value()); + bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).GetContextOptionIndex()); } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG)) { return StaticData::hintTextTable[RHT_BRIDGE_GREG_HINT].GetHintMessage(); @@ -613,23 +613,23 @@ CustomMessage Hint::GetGanonBossKeyText() { } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) { ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_STONES_HINT].GetHintMessage(); - ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_STONE_COUNT).Value()); + ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_STONE_COUNT).GetContextOptionIndex()); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) { ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_MEDALLIONS_HINT].GetHintMessage(); - ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Value()); + ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_MEDALLION_COUNT).GetContextOptionIndex()); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) { ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_REWARDS_HINT].GetHintMessage(); - ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_REWARD_COUNT).Value()); + ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_REWARD_COUNT).GetContextOptionIndex()); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) { ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_DUNGEONS_HINT].GetHintMessage(); - ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Value()); + ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).GetContextOptionIndex()); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) { ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_TOKENS_HINT].GetHintMessage(); - ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_TOKEN_COUNT).Value()); + ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_TOKEN_COUNT).GetContextOptionIndex()); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_TRIFORCE_HUNT)) { return StaticData::hintTextTable[RHT_GANON_BK_TRIFORCE_HINT].GetHintMessage(); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index 60b1c84b7..6e88a249f 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1,21 +1,29 @@ #include #include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/custom-message/CustomMessageTypes.h" #include "soh/Enhancements/item-tables/ItemTableManager.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/randomizer/dungeon.h" #include "soh/Enhancements/randomizer/fishsanity.h" +#include "soh/Enhancements/randomizer/static_data.h" +#include "soh/Enhancements/randomizer/ShufflePots.h" +#include "soh/Enhancements/randomizer/ShuffleFreestanding.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/ImGuiUtils.h" #include "soh/Notification/Notification.h" +#include "soh/SaveManager.h" +#include "soh/Enhancements/randomizer/ShuffleFairies.h" extern "C" { #include "macros.h" #include "functions.h" #include "variables.h" #include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/Enhancements/randomizer/randomizer_entrance.h" +#include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" #include "src/overlays/actors/ovl_En_Si/z_en_si.h" #include "src/overlays/actors/ovl_En_Cow/z_en_cow.h" @@ -47,6 +55,7 @@ extern "C" { #include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.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_En_Mk/z_en_mk.h" #include "adult_trade_shuffle.h" #include "draw.h" @@ -55,9 +64,11 @@ extern PlayState* gPlayState; extern void func_8084DFAC(PlayState* play, Player* player); extern void Player_SetupActionPreserveAnimMovement(PlayState* play, Player* player, PlayerActionFunc actionFunc, s32 flags); extern s32 Player_SetupWaitForPutAway(PlayState* play, Player* player, AfterPutAwayFunc func); +extern void Play_InitEnvironment(PlayState * play, s16 skyboxId); +extern void EnMk_Wait(EnMk* enMk, PlayState* play); } -#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex() +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetContextOptionIndex() bool LocMatchesQuest(Rando::Location loc) { if (loc.GetQuest() == RCQUEST_BOTH) { @@ -320,6 +331,7 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { if (randomizerQueuedItemEntry.modIndex == receivedItemEntry.modIndex && randomizerQueuedItemEntry.itemId == receivedItemEntry.itemId) { SPDLOG_INFO("Item received mod {} item {} from RC {}", receivedItemEntry.modIndex, receivedItemEntry.itemId, static_cast(randomizerQueuedCheck)); loc->SetCheckStatus(RCSHOW_COLLECTED); + CheckTracker::SpoilAreaFromCheck(randomizerQueuedCheck); CheckTracker::RecalculateAllAreaTotals(); SaveManager::Instance->SaveSection(gSaveContext.fileNum, SECTION_ID_TRACKER_DATA, true); randomizerQueuedCheck = RC_UNKNOWN_CHECK; @@ -349,7 +361,7 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { return; } - gPlayState->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0; + gPlayState->nextEntranceIndex = ENTR_DESERT_COLOSSUS_EAST_EXIT; gPlayState->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.nextCutsceneIndex = 0xFFF1; gPlayState->transitionType = TRANS_TYPE_SANDSTORM_END; @@ -467,7 +479,7 @@ void ItemEtcetera_func_80B85824_Randomized(ItemEtcetera* itemEtcetera, PlayState void ItemEtcetera_MoveRandomizedFireArrowDown(ItemEtcetera* itemEtcetera, PlayState* play) { Actor_UpdateBgCheckInfo(play, &itemEtcetera->actor, 10.0f, 10.0f, 0.0f, 5); - Actor_MoveForward(&itemEtcetera->actor); + Actor_MoveXZGravity(&itemEtcetera->actor); if (!(itemEtcetera->actor.bgCheckFlags & 1)) { ItemEtcetera_SpawnSparkles(itemEtcetera, play); } @@ -614,11 +626,11 @@ void func_8083A434_override(PlayState* play, Player* player) { bool ShouldGiveFishingPrize(f32 sFishOnHandLength){ // RANDOTODO: update the enhancement sliders to not allow // values above rando fish weight values when rando'd - if(LINK_IS_CHILD) { + if(LINK_IS_CHILD) { int32_t weight = CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0) ? CVarGetInteger(CVAR_ENHANCEMENT("MinimumFishWeightChild"), 10) : 10; f32 score = sqrt(((f32)weight - 0.5f) / 0.0036f); return sFishOnHandLength >= score && (IS_RANDO ? !Flags_GetRandomizerInf(RAND_INF_CHILD_FISHING) : !(HIGH_SCORE(HS_FISHING) & HS_FISH_PRIZE_CHILD)); - } else + } else { int32_t weight = CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0) ? CVarGetInteger(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 13) : 13; f32 score = sqrt(((f32)weight - 0.5f) / 0.0036f); @@ -626,6 +638,147 @@ bool ShouldGiveFishingPrize(f32 sFishOnHandLength){ } } +void RandomizerOnDialogMessageHandler() { + MessageContext *msgCtx = &gPlayState->msgCtx; + Actor *actor = msgCtx->talkActor; + auto ctx = Rando::Context::GetInstance(); + bool revealMerchant = ctx->GetOption(RSK_MERCHANT_TEXT_HINT).GetContextOptionIndex() != RO_GENERIC_OFF; + bool nonBeanMerchants = ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL); + + RandomizerCheck reveal = RC_UNKNOWN_CHECK; + if (ctx->GetOption(RSK_CHICKENS_HINT) && (msgCtx->textId >= TEXT_ANJU_PLEASE_BRING_MY_CUCCOS_BACK && msgCtx->textId <= TEXT_ANJU_PLEASE_BRING_1_CUCCO)) { + reveal = RC_KAK_ANJU_AS_CHILD; + } else { + switch (msgCtx->textId) { + case TEXT_SKULLTULA_PEOPLE_IM_CURSED: + if (actor->params == 1 && ctx->GetOption(RSK_KAK_10_SKULLS_HINT)){ + reveal = RC_KAK_10_GOLD_SKULLTULA_REWARD; + } else if (actor->params == 2 && ctx->GetOption(RSK_KAK_20_SKULLS_HINT)){ + reveal = RC_KAK_20_GOLD_SKULLTULA_REWARD; + } else if (actor->params == 3 && ctx->GetOption(RSK_KAK_30_SKULLS_HINT)){ + reveal = RC_KAK_30_GOLD_SKULLTULA_REWARD; + } else if (actor->params == 4 && ctx->GetOption(RSK_KAK_40_SKULLS_HINT)){ + reveal = RC_KAK_40_GOLD_SKULLTULA_REWARD; + } else if (ctx->GetOption(RSK_KAK_50_SKULLS_HINT)){ + reveal = RC_KAK_50_GOLD_SKULLTULA_REWARD; + } + break; + case TEXT_SKULLTULA_PEOPLE_MAKE_YOU_VERY_RICH: + if (ctx->GetOption(RSK_KAK_100_SKULLS_HINT)) { + reveal = RC_KAK_100_GOLD_SKULLTULA_REWARD; + } + break; + case TEXT_MASK_SHOP_SIGN: + if (ctx->GetOption(RSK_MASK_SHOP_HINT)) { + auto itemSkull_loc = ctx->GetItemLocation(RC_DEKU_THEATER_SKULL_MASK); + if (itemSkull_loc->GetCheckStatus() == RCSHOW_UNCHECKED) { + itemSkull_loc->SetCheckStatus(RCSHOW_IDENTIFIED); + } + reveal = RC_DEKU_THEATER_MASK_OF_TRUTH; + } + break; + case TEXT_GHOST_SHOP_EXPLAINATION: + case TEXT_GHOST_SHOP_CARD_HAS_POINTS: + if (ctx->GetOption(RSK_BIG_POES_HINT)) { + reveal = RC_MARKET_10_BIG_POES; + } + break; + case TEXT_MALON_EVERYONE_TURNING_EVIL: + case TEXT_MALON_I_SING_THIS_SONG: + case TEXT_MALON_HOW_IS_EPONA_DOING: + case TEXT_MALON_OBSTICLE_COURSE: + case TEXT_MALON_INGO_MUST_HAVE_BEEN_TEMPTED: + if (ctx->GetOption(RSK_MALON_HINT)) { + reveal = RC_KF_LINKS_HOUSE_COW; + } + break; + case TEXT_FROGS_UNDERWATER: + if (ctx->GetOption(RSK_FROGS_HINT)) { + reveal = RC_ZR_FROGS_OCARINA_GAME; + } + break; + case TEXT_GF_HBA_SIGN: + case TEXT_HBA_NOT_ON_HORSE: + case TEXT_HBA_INITIAL_EXPLAINATION: + case TEXT_HBA_ALREADY_HAVE_1000: + if (ctx->GetOption(RSK_HBA_HINT)) { + auto item1000_loc = ctx->GetItemLocation(RC_GF_HBA_1000_POINTS); + if (item1000_loc->GetCheckStatus() == RCSHOW_UNCHECKED) { + item1000_loc->SetCheckStatus(RCSHOW_IDENTIFIED); + } + reveal = RC_GF_HBA_1500_POINTS; + } + break; + case TEXT_SCRUB_RANDOM: + if (ctx->GetOption(RSK_SCRUB_TEXT_HINT).GetContextOptionIndex() != RO_GENERIC_OFF) { + EnDns* enDns = (EnDns*)actor; + reveal = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)enDns->sohScrubIdentity.randomizerInf); + } + break; + case TEXT_BEAN_SALESMAN_BUY_FOR_10: + if (revealMerchant && (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL))) { + reveal = RC_ZR_MAGIC_BEAN_SALESMAN; + } + break; + case TEXT_GRANNYS_SHOP: + if (revealMerchant && nonBeanMerchants && + (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)) { + reveal = RC_KAK_GRANNYS_SHOP; + } + break; + case TEXT_MEDIGORON: + if (revealMerchant && nonBeanMerchants) { + reveal = RC_GC_MEDIGORON; + } + break; + case TEXT_CARPET_SALESMAN_1: + if (revealMerchant && nonBeanMerchants) { + reveal = RC_WASTELAND_BOMBCHU_SALESMAN; + } + break; + case TEXT_BIGGORON_BETTER_AT_SMITHING: + case TEXT_BIGGORON_WAITING_FOR_YOU: + case TEXT_BIGGORON_RETURN_AFTER_A_FEW_DAYS: + case TEXT_BIGGORON_I_MAAAADE_THISSSS: + if (ctx->GetOption(RSK_BIGGORON_HINT)) { + reveal = RC_DMT_TRADE_CLAIM_CHECK; + } + break; + case TEXT_SHEIK_NEED_HOOK: + case TEXT_SHEIK_HAVE_HOOK: + if (ctx->GetOption(RSK_OOT_HINT) && gPlayState->sceneNum == SCENE_TEMPLE_OF_TIME && + !ctx->GetItemLocation(RC_SONG_FROM_OCARINA_OF_TIME)->HasObtained()) { + auto itemoot_loc = ctx->GetItemLocation(RC_HF_OCARINA_OF_TIME_ITEM); + if (itemoot_loc->GetCheckStatus() == RCSHOW_UNCHECKED) { + itemoot_loc->SetCheckStatus(RCSHOW_IDENTIFIED); + } + reveal = RC_SONG_FROM_OCARINA_OF_TIME; + } + break; + case TEXT_FISHING_CLOUDY: + case TEXT_FISHING_TRY_ANOTHER_LURE: + case TEXT_FISHING_SECRETS: + case TEXT_FISHING_GOOD_FISHERMAN: + case TEXT_FISHING_DIFFERENT_POND: + case TEXT_FISHING_SCRATCHING: + case TEXT_FISHING_TRY_ANOTHER_LURE_WITH_SINKING_LURE: + if (ctx->GetOption(RSK_LOACH_HINT)) { + reveal = RC_LH_HYRULE_LOACH; + } + break; + } + } + + if (reveal != RC_UNKNOWN_CHECK) { + auto item_loc = ctx->GetItemLocation(reveal); + if (item_loc->GetCheckStatus() == RCSHOW_UNCHECKED) { + item_loc->SetCheckStatus(RCSHOW_IDENTIFIED); + } + } +} + void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { va_list args; va_copy(args, originalArgs); @@ -651,6 +804,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = false; break; } + case VB_SPAWN_FIRE_ARROW: + *should = !Flags_GetTreasure(gPlayState, 0x1F); + break; case VB_PLAY_NABOORU_CAPTURED_CS: // This behavior is replicated for randomizer in RandomizerOnItemReceiveHandler *should = false; @@ -666,12 +822,12 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST); break; case VB_MIDO_SPAWN: - if (RAND_GET_OPTION(RSK_FOREST) != RO_FOREST_OPEN && !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) { + if (RAND_GET_OPTION(RSK_FOREST) != RO_CLOSED_FOREST_OFF && !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) { *should = true; } break; case VB_MOVE_MIDO_IN_KOKIRI_FOREST: - if (RAND_GET_OPTION(RSK_FOREST) == RO_FOREST_OPEN) { + if (RAND_GET_OPTION(RSK_FOREST) == RO_CLOSED_FOREST_OFF && gSaveContext.cutsceneIndex == 0) { *should = true; } break; @@ -679,7 +835,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD); break; case VB_OPEN_KOKIRI_FOREST: - *should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD) || RAND_GET_OPTION(RSK_FOREST) != RO_FOREST_CLOSED; + *should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD) || RAND_GET_OPTION(RSK_FOREST) != RO_CLOSED_FOREST_ON; break; case VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD: *should = !Flags_GetRandomizerInf(RAND_INF_DARUNIAS_JOY); @@ -724,14 +880,18 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_ITEM00_DESPAWN: { EnItem00* item00 = va_arg(args, EnItem00*); if (item00->actor.params == ITEM00_HEART_PIECE || item00->actor.params == ITEM00_SMALL_KEY) { - RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(item00->actor.id, gPlayState->sceneNum, item00->ogParams); + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor( + item00->actor.id, gPlayState->sceneNum, item00->ogParams); if (rc != RC_UNKNOWN_CHECK) { + item00->randoInf = RAND_INF_MAX; item00->actor.params = ITEM00_SOH_DUMMY; - item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry( + rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; *should = Rando::Context::GetInstance()->GetItemLocation(rc)->HasObtained(); } - } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY || item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY_GI) { + } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY || + item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY_GI) { GetItemEntry itemEntry = randomizerQueuedItemEntry; item00->itemEntry = itemEntry; item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; @@ -793,6 +953,12 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } break; } + case VB_KING_ZORA_TUNIC_CHECK: { + if (!Flags_GetRandomizerInf(RAND_INF_KING_ZORA_THAWED)) { + *should = false; + } + break; + } case VB_BIGGORON_CONSIDER_SWORD_COLLECTED: { *should = Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK); break; @@ -826,7 +992,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l Actor_Kill(&item00->actor); *should = false; } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY) { - Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (item00->itemEntry.modIndex == MOD_NONE) { if (item00->itemEntry.getItemId == GI_SWORD_BGS) { gSaveContext.bgsFlag = true; @@ -855,7 +1021,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l // This is typically called when you close the text box after getting an item, in case a previous // function hid the interface. - Interface_ChangeAlpha(gSaveContext.unk_13EE); + gSaveContext.unk_13EA = 0; + Interface_ChangeAlpha(0x32); // EnItem00_SetupAction(item00, func_8001E5C8); // *should = false; } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY_GI) { @@ -900,17 +1067,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = false; break; } - case VB_GIVE_ITEM_FROM_THAWING_KING_ZORA: { - EnKz* enKz = va_arg(args, EnKz*); - // If we aren't setting up the item offer, then we're just checking if it should be possible. - if (enKz->actionFunc != (EnKzActionFunc)EnKz_SetupGetItem) { - // Always give the reward in rando - *should = true; - break; - } - *should = false; - break; - } case VB_GIVE_ITEM_FROM_ANJU_AS_CHILD: { Flags_SetItemGetInf(ITEMGETINF_0C); *should = false; @@ -994,19 +1150,15 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } break; } - case VB_GIVE_ITEM_FROM_FROGS: { + case VB_FROGS_GO_TO_IDLE: { EnFr* enFr = va_arg(args, EnFr*); - // Skip GiveReward+SetIdle action func if the reward is an ice trap - if (enFr->actionFunc == (EnFrActionFunc)EnFr_GiveReward) { - RandomizerCheck rc = EnFr_RandomizerCheckFromSongIndex(enFr->songIndex); - GetItemEntry gi = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); - if (gi.getItemId == RG_ICE_TRAP) { - enFr->actionFunc = (EnFrActionFunc)EnFr_Idle; - } + if ( + (enFr->songIndex >= FROG_STORMS && enFr->reward == GI_HEART_PIECE) || + (enFr->songIndex < FROG_STORMS && enFr->reward == GI_RUPEE_PURPLE) + ) { + *should = true; } - - *should = false; break; } case VB_TRADE_POCKET_CUCCO: { @@ -1045,14 +1197,31 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = false; break; } - case VB_TRADE_PRESCRIPTION: { + case VB_ADULT_KING_ZORA_ITEM_GIVE: { EnKz* enKz = va_arg(args, EnKz*); - // If we aren't setting up the item offer, then we're just checking if it should be possible. - if (enKz->actionFunc != (EnKzActionFunc)EnKz_SetupGetItem) { - *should = !Flags_GetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); - break; + Input input = gPlayState->state.input[0]; + + if (CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + // For early eyeball frog hook override, simulate collection delay behavior by just checking for the R + // button being held while wearing a shield, and a trade item lower than frog in inventory + bool hasShieldHoldingR = (CHECK_BTN_ANY(input.cur.button, BTN_R) && + CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) > EQUIP_VALUE_SHIELD_NONE); + + if (func_8002F368(gPlayState) == EXCH_ITEM_PRESCRIPTION || + (hasShieldHoldingR && INV_CONTENT(ITEM_TRADE_ADULT) < ITEM_FROG)) { + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); + } else { + Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); + } + } else { + if (enKz->isTrading){ + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); + Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); + } else { + Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); + } } - Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_PRESCRIPTION); *should = false; break; } @@ -1270,10 +1439,10 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l (item == ITEM_BOMB && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMB_BAG)) || ( (item == ITEM_BOW || item == ITEM_BOW_ARROW_FIRE || item == ITEM_BOW_ARROW_ICE || item == ITEM_BOW_ARROW_LIGHT) && - Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER) + Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER) && gPlayState->shootingGalleryStatus < 2 && gSaveContext.minigameState != 1 ) || - (item == ITEM_SLINGSHOT && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG)) || - (item == ITEM_BOMBCHU && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS)) + (item == ITEM_SLINGSHOT && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG) && gPlayState->shootingGalleryStatus < 2) || + (item == ITEM_BOMBCHU && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS) && gPlayState->bombchuBowlingStatus < 1) ) { *should = false; } @@ -1398,8 +1567,57 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } break; } + case VB_TRADE_TIMER_EYEDROPS:{ + EnMk* enMk = va_arg(args, EnMk*); + Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG); + enMk->actor.flags &= ~ACTOR_FLAG_WILL_TALK; + enMk->actionFunc = EnMk_Wait; + enMk->flags |= 1; + *should = false; + break; + } + // We need to override the vanilla behavior here because the player might sequence break and get Ruto kidnapped before accessing other + // checks that require Ruto. So if she's kidnapped we allow her to spawn again + case VB_RUTO_BE_CONSIDERED_NOT_KIDNAPPED: { + *should = !Flags_GetInfTable(INFTABLE_145) || Flags_GetInfTable(INFTABLE_146); + break; + } + case VB_SET_VOIDOUT_FROM_SURFACE: { + // ENTRTODO: Move all entrance rando handling to a dedicated file + std::vector entrPersistTempFlags = { + ENTR_DEKU_TREE_BOSS_ENTRANCE, ENTR_DEKU_TREE_BOSS_DOOR, ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE, + ENTR_DODONGOS_CAVERN_BOSS_DOOR, ENTR_JABU_JABU_BOSS_ENTRANCE, ENTR_JABU_JABU_BOSS_DOOR, + ENTR_FOREST_TEMPLE_BOSS_ENTRANCE, ENTR_FOREST_TEMPLE_BOSS_DOOR, ENTR_FIRE_TEMPLE_BOSS_ENTRANCE, + ENTR_FIRE_TEMPLE_BOSS_DOOR, ENTR_WATER_TEMPLE_BOSS_ENTRANCE, ENTR_WATER_TEMPLE_BOSS_DOOR, + ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE, ENTR_SPIRIT_TEMPLE_BOSS_DOOR, ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE, + ENTR_SHADOW_TEMPLE_BOSS_DOOR, ENTR_SPIRIT_TEMPLE_ENTRANCE, + }; + + s16 originalEntrance = (s16)va_arg(args, int); + + // In Entrance rando, if our respawnFlag is set for a grotto return, we don't want the void out to happen + if (*should == true && RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) { + // Check for dungeon special entrances that are randomized to a new location + if (std::find(entrPersistTempFlags.begin(), entrPersistTempFlags.end(), originalEntrance) != + entrPersistTempFlags.end() && originalEntrance != gPlayState->nextEntranceIndex) { + // Normally dungeons use a special voidout between scenes so that entering/exiting a boss room, + // or leaving via Spirit Hands and going back in persist temp flags across scenes. + // For ER, the temp flags should be wiped out so that they aren't transferred to the new location. + gPlayState->actorCtx.flags.tempSwch = 0; + gPlayState->actorCtx.flags.tempCollect = 0; + + // If the respawnFlag is set for a grotto return, we don't want the void out to happen. + // Set the data flag to one to prevent the respawn point from being overriden by dungeon doors. + if (gSaveContext.respawnFlag == 2) { + gSaveContext.respawn[RESPAWN_MODE_DOWN].data = 1; + *should = false; + } + } + } + break; + } + case VB_FREEZE_ON_SKULL_TOKEN: case VB_TRADE_TIMER_ODD_MUSHROOM: - case VB_TRADE_TIMER_EYEDROPS: case VB_TRADE_TIMER_FROG: case VB_ANJU_SET_OBTAINED_TRADE_ITEM: case VB_GIVE_ITEM_FROM_TARGET_IN_WOODS: @@ -1463,8 +1681,27 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { CheckTracker::RecalculateAllAreaTotals(); } + // ENTRTODO: Move all entrance rando handling to a dedicated file if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) { + // In ER, override roomNum to load based on scene and spawn during scene init + if (gSaveContext.respawnFlag <= 0) { + s8 origRoom = gPlayState->roomCtx.curRoom.num; + s8 replacedRoom = Entrance_OverrideSpawnSceneRoom(gPlayState->sceneNum, gPlayState->curSpawn, origRoom); + + if (origRoom != replacedRoom) { + // Reset room ctx back to prev room and then load the new room + gPlayState->roomCtx.status = 0; + gPlayState->roomCtx.curRoom = gPlayState->roomCtx.prevRoom; + func_8009728C(gPlayState, &gPlayState->roomCtx, replacedRoom); + } + } + + // Handle updated link spawn positions + Entrance_OverrideSpawnScene(sceneNum, gPlayState->curSpawn); + Entrance_OverrideWeatherState(); + // Need to reinitialize the environment after replacing the weather mode + Play_InitEnvironment(gPlayState, gPlayState->skyboxId); } // LACs & Prelude checks @@ -1720,7 +1957,7 @@ void RandomizerOnActorInitHandler(void* actorRef) { if (actor->id == ACTOR_EN_GE1) { EnGe1* enGe1 = static_cast(actorRef); auto ge1Type = enGe1->actor.params & 0xFF; - if (ge1Type == GE1_TYPE_TRAINING_GROUNDS_GUARD && + if (ge1Type == GE1_TYPE_TRAINING_GROUND_GUARD && Flags_GetRandomizerInf(RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN)) { enGe1->actionFunc = (EnGe1ActionFunc)EnGe1_SetNormalText; } @@ -1734,7 +1971,7 @@ void RandomizerOnActorInitHandler(void* actorRef) { if (actor->id == ACTOR_BG_TREEMOUTH && LINK_IS_ADULT && RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF && - (RAND_GET_OPTION(RSK_FOREST) == RO_FOREST_OPEN || + (RAND_GET_OPTION(RSK_FOREST) == RO_CLOSED_FOREST_OFF || Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD))) { BgTreemouth* bgTreemouth = static_cast(actorRef); bgTreemouth->unk_168 = 1.0f; @@ -1817,7 +2054,7 @@ void RandomizerOnActorInitHandler(void* actorRef) { if ( actor->id == ACTOR_OBJ_OSHIHIKI && LINK_IS_CHILD && - IsGameMasterQuest() && + ResourceMgr_IsGameMasterQuest() && gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE && actor->room == 6 && // Spirit Temple silver block hallway actor->params == 0x9C7 // Silver block that is marked as in the hole ) { @@ -1837,6 +2074,11 @@ void RandomizerOnActorInitHandler(void* actorRef) { Actor_Kill(actor); return; } + + // In ER, once Link has spawned we know the scene has loaded, so we can sanitize the last known entrance type + if (actor->id == ACTOR_PLAYER && RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) { + Grotto_SanitizeEntranceType(); + } } void RandomizerOnGameFrameUpdateHandler() { @@ -1926,31 +2168,31 @@ std::map swimSpecialRespawnInfo = { { { 5730.209, -20, 3725.911 }, -20025 } }, { - ENTR_LOST_WOODS_7,//zr to lw + ENTR_LOST_WOODS_UNDERWATER_SHORTCUT,//zr to lw { { 1978.718, -36.908, -855 }, -16384 } }, { - ENTR_ZORAS_RIVER_4,//lw to zr + ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT,//lw to zr { { 4082.366, 860.442, -1018.949 }, -32768 } }, { - ENTR_LAKE_HYLIA_1,//gv to lh + ENTR_LAKE_HYLIA_RIVER_EXIT,//gv to lh { { -3276.416, -1033, 2908.421 }, 11228 } }, { - ENTR_WATER_TEMPLE_0,//lh to water temple + ENTR_WATER_TEMPLE_ENTRANCE,//lh to water temple { { -182, 780, 759.5 }, -32768 } }, { - ENTR_LAKE_HYLIA_2,//water temple to lh + ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE,//water temple to lh { { -955.028, -1306.9, 6768.954 }, -32768 } }, { - ENTR_ZORAS_DOMAIN_4,//lh to zd + ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT,//lh to zd { { -109.86, 11.396, -9.933 }, -29131 } }, { - ENTR_LAKE_HYLIA_7,//zd to lh + ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT,//zd to lh { { -912, -1326.967, 3391 }, 0 } }, { @@ -1958,11 +2200,11 @@ std::map swimSpecialRespawnInfo = { { { -424, -2051, -74 }, 16384 } }, { - ENTR_HYRULE_FIELD_7,//mk to hf (can be a problem when it then turns night) + ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN,//mk to hf (can be a problem when it then turns night) { { 0, 0, 1100 }, 0 } }, { - ENTR_ZORAS_FOUNTAIN_0,//jabu blue warp to zf + ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP,//jabu blue warp to zf { { -1580, 150, 1670 }, 8000 } }, }; @@ -1977,7 +2219,7 @@ void RandomizerOnPlayerUpdateHandler() { ) { //if you void out in water temple without swim you get instantly kicked out to prevent softlocks if (gPlayState->sceneNum == SCENE_WATER_TEMPLE) { - GameInteractor::RawAction::TeleportPlayer(Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_2));//lake hylia from water temple + GameInteractor::RawAction::TeleportPlayer(Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE));//lake hylia from water temple } else { if (swimSpecialRespawnInfo.find(gSaveContext.entranceIndex) != swimSpecialRespawnInfo.end()) { SpecialRespawnInfo* respawnInfo = &swimSpecialRespawnInfo.at(gSaveContext.entranceIndex); @@ -1998,7 +2240,7 @@ void RandomizerOnPlayerUpdateHandler() { gPlayState->transitionTrigger != TRANS_TRIGGER_START && (1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0 ) { - GiveItemEntryWithoutActor(gPlayState, ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY)); + GiveItemEntryWithoutActor(gPlayState, *Rando::StaticData::GetItemTable().at(RG_GANONS_CASTLE_BOSS_KEY).GetGIEntry()); } if ( @@ -2045,12 +2287,44 @@ void RandomizerOnSceneSpawnActorsHandler() { } } +void RandomizerOnPlayDestroyHandler() { + // In ER, remove link from epona when entering somewhere that doesn't support epona + if (RAND_GET_OPTION(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) { + Entrance_HandleEponaState(); + } +} + +void RandomizerOnExitGameHandler(int32_t fileNum) { + // When going from a rando save to a vanilla save within the same game instance + // we need to reset the entrance table back to its vanilla state + Entrance_ResetEntranceTable(); +} + +void RandomizerOnKaleidoscopeUpdateHandler(int16_t inDungeonScene) { + static uint16_t prevKaleidoState = 0; + + // In ER, handle overriding the game over respawn entrance and dealing with death warp to from grottos + if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) { + if (prevKaleidoState == 0x10 && gPlayState->pauseCtx.state == 0x11 && gPlayState->pauseCtx.promptChoice == 0) { + // Needs to be called before Play_TriggerRespawn when transitioning from state 0x10 to 0x11 + Entrance_SetGameOverEntrance(); + } + if (prevKaleidoState == 0x11 && gPlayState->pauseCtx.state == 0 && gPlayState->pauseCtx.promptChoice == 0) { + // Needs to be called after Play_TriggerRespawn when transitioning from state 0x11 to 0 + Grotto_ForceGrottoReturn(); + } + } + + prevKaleidoState = gPlayState->pauseCtx.state; +} + void RandomizerRegisterHooks() { static uint32_t onFlagSetHook = 0; static uint32_t onSceneFlagSetHook = 0; static uint32_t onPlayerUpdateForRCQueueHook = 0; static uint32_t onPlayerUpdateForItemQueueHook = 0; static uint32_t onItemReceiveHook = 0; + static uint32_t onDialogMessageHook = 0; static uint32_t onVanillaBehaviorHook = 0; static uint32_t onSceneInitHook = 0; static uint32_t onActorInitHook = 0; @@ -2058,12 +2332,20 @@ void RandomizerRegisterHooks() { static uint32_t onPlayerUpdateHook = 0; static uint32_t onGameFrameUpdateHook = 0; static uint32_t onSceneSpawnActorsHook = 0; + static uint32_t onPlayDestroyHook = 0; + static uint32_t onExitGameHook = 0; + static uint32_t onKaleidoUpdateHook = 0; static uint32_t fishsanityOnActorInitHook = 0; - static uint32_t fishsanityOnFlagSetHook = 0; static uint32_t fishsanityOnActorUpdateHook = 0; static uint32_t fishsanityOnSceneInitHook = 0; static uint32_t fishsanityOnVanillaBehaviorHook = 0; + static uint32_t fishsanityOnItemReceiveHook = 0; + + static uint32_t shufflePotsOnActorInitHook = 0; + static uint32_t shufflePotsOnVanillaBehaviorHook = 0; + + static uint32_t shuffleFreestandingOnVanillaBehaviorHook = 0; GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { randomizerQueuedChecks = std::queue(); @@ -2075,6 +2357,7 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onPlayerUpdateForRCQueueHook); GameInteractor::Instance->UnregisterGameHook(onPlayerUpdateForItemQueueHook); GameInteractor::Instance->UnregisterGameHook(onItemReceiveHook); + GameInteractor::Instance->UnregisterGameHook(onDialogMessageHook); GameInteractor::Instance->UnregisterGameHook(onVanillaBehaviorHook); GameInteractor::Instance->UnregisterGameHook(onSceneInitHook); GameInteractor::Instance->UnregisterGameHook(onActorInitHook); @@ -2082,18 +2365,27 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(onPlayerUpdateHook); GameInteractor::Instance->UnregisterGameHook(onGameFrameUpdateHook); GameInteractor::Instance->UnregisterGameHook(onSceneSpawnActorsHook); + GameInteractor::Instance->UnregisterGameHook(onPlayDestroyHook); + GameInteractor::Instance->UnregisterGameHook(onExitGameHook); + GameInteractor::Instance->UnregisterGameHook(onKaleidoUpdateHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorInitHook); - GameInteractor::Instance->UnregisterGameHook(fishsanityOnFlagSetHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorUpdateHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnSceneInitHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnVanillaBehaviorHook); + GameInteractor::Instance->UnregisterGameHook(fishsanityOnItemReceiveHook); + + GameInteractor::Instance->UnregisterGameHook(shufflePotsOnActorInitHook); + GameInteractor::Instance->UnregisterGameHook(shufflePotsOnVanillaBehaviorHook); + + GameInteractor::Instance->UnregisterGameHook(shuffleFreestandingOnVanillaBehaviorHook); onFlagSetHook = 0; onSceneFlagSetHook = 0; onPlayerUpdateForRCQueueHook = 0; onPlayerUpdateForItemQueueHook = 0; onItemReceiveHook = 0; + onDialogMessageHook = 0; onVanillaBehaviorHook = 0; onSceneInitHook = 0; onActorInitHook = 0; @@ -2101,15 +2393,26 @@ void RandomizerRegisterHooks() { onPlayerUpdateHook = 0; onGameFrameUpdateHook = 0; onSceneSpawnActorsHook = 0; + onPlayDestroyHook = 0; + onExitGameHook = 0; + onKaleidoUpdateHook = 0; fishsanityOnActorInitHook = 0; - fishsanityOnFlagSetHook = 0; fishsanityOnActorUpdateHook = 0; fishsanityOnSceneInitHook = 0; fishsanityOnVanillaBehaviorHook = 0; + fishsanityOnItemReceiveHook = 0; + + shufflePotsOnActorInitHook = 0; + shufflePotsOnVanillaBehaviorHook = 0; + + shuffleFreestandingOnVanillaBehaviorHook = 0; + + ShuffleFairies_UnregisterHooks(); if (!IS_RANDO) return; + // ENTRTODO: Move all entrance rando handling to a dedicated file // Setup the modified entrance table and entrance shuffle table for rando Entrance_Init(); @@ -2123,6 +2426,7 @@ void RandomizerRegisterHooks() { onPlayerUpdateForRCQueueHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateForRCQueueHandler); onPlayerUpdateForItemQueueHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateForItemQueueHandler); onItemReceiveHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnItemReceiveHandler); + onDialogMessageHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnDialogMessageHandler); onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnVanillaBehaviorHandler); onSceneInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneInitHandler); onActorInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorInitHandler); @@ -2130,15 +2434,31 @@ void RandomizerRegisterHooks() { onPlayerUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateHandler); onGameFrameUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnGameFrameUpdateHandler); onSceneSpawnActorsHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneSpawnActorsHandler); + onPlayDestroyHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayDestroyHandler); + onExitGameHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnExitGameHandler); + onKaleidoUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnKaleidoscopeUpdateHandler); if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) { OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave(); fishsanityOnActorInitHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnActorInitHandler); - fishsanityOnFlagSetHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnFlagSetHandler); fishsanityOnActorUpdateHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnActorUpdateHandler); fishsanityOnSceneInitHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnSceneInitHandler); fishsanityOnVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnVanillaBehaviorHandler); + fishsanityOnItemReceiveHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnItemReceiveHandler); + } + + if (RAND_GET_OPTION(RSK_SHUFFLE_POTS) != RO_SHUFFLE_POTS_OFF) { + shufflePotsOnActorInitHook = GameInteractor::Instance->RegisterGameHook(ObjTsubo_RandomizerInit); + shufflePotsOnVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(ShufflePots_OnVanillaBehaviorHandler); + } + + if (RAND_GET_OPTION(RSK_SHUFFLE_FREESTANDING) != RO_SHUFFLE_FREESTANDING_OFF) { + shuffleFreestandingOnVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(ShuffleFreestanding_OnVanillaBehaviorHandler); + } + + if (RAND_GET_OPTION(RSK_SHUFFLE_FAIRIES)) { + ShuffleFairies_RegisterHooks(); } }); } diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index 458144411..9c8e68ce6 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -152,8 +152,8 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_SHADOW_TEMPLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_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", "Kleiner Schlüssel für den Grund des Brunnens" }, ITEMTYPE_SMALLKEY, 0xB4, true, LOGIC_BOTTOM_OF_THE_WELL_KEYS, RHT_BOTTOM_OF_THE_WELL_SMALL_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_BOTTOM_OF_THE_WELL_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); - itemTable[RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY] = Item(RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, Text{ "Training Grounds Small Key", "Petite Clé du Gymnase Gerudo", "Kleiner Schlüssel für das Gerudo-Trainingsgelände" }, ITEMTYPE_SMALLKEY, 0xB5, true, LOGIC_GERUDO_TRAINING_GROUNDS_KEYS, RHT_GERUDO_TRAINING_GROUNDS_SMALL_KEY, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); - itemTable[RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); + itemTable[RG_GERUDO_TRAINING_GROUND_SMALL_KEY] = Item(RG_GERUDO_TRAINING_GROUND_SMALL_KEY, Text{ "Training Ground Small Key", "Petite Clé du Gymnase Gerudo", "Kleiner Schlüssel für das Gerudo-Trainingsgelände" }, ITEMTYPE_SMALLKEY, 0xB5, true, LOGIC_GERUDO_TRAINING_GROUND_KEYS, RHT_GERUDO_TRAINING_GROUND_SMALL_KEY, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GERUDO_TRAINING_GROUND_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_GERUDO_FORTRESS_SMALL_KEY] = Item(RG_GERUDO_FORTRESS_SMALL_KEY, Text{ "Gerudo Fortress Small Key", "Petite Clé du Repaire des Voleurs", "Kleiner Schlüssel für die Gerudo-Festung" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xB6, true, LOGIC_GERUDO_FORTRESS_KEYS, RHT_GERUDO_FORTRESS_SMALL_KEY, RG_GERUDO_FORTRESS_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_GERUDO_FORTRESS_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey); itemTable[RG_GANONS_CASTLE_SMALL_KEY] = Item(RG_GANONS_CASTLE_SMALL_KEY, Text{ "Ganon's Castle Small Key", "Petite Clé du Château de Ganon", "Kleiner Schlüssel für Ganons Schloß" }, ITEMTYPE_SMALLKEY, 0xB7, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_SMALL_KEY, RG_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); @@ -172,8 +172,8 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_SHADOW_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_BOTTOM_OF_THE_WELL_KEY_RING] = Item(RG_BOTTOM_OF_THE_WELL_KEY_RING, Text{ "Bottom of the Well Key Ring", "Trousseau du Puits", "Schlüsselbund für den Grund des Brunnens" }, ITEMTYPE_SMALLKEY, 0xDA, true, LOGIC_BOTTOM_OF_THE_WELL_KEYS, RHT_BOTTOM_OF_THE_WELL_KEY_RING, RG_BOTTOM_OF_THE_WELL_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_BOTTOM_OF_THE_WELL_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); - itemTable[RG_GERUDO_TRAINING_GROUNDS_KEY_RING] = Item(RG_GERUDO_TRAINING_GROUNDS_KEY_RING, Text{ "Training Grounds Key Ring", "Trousseau du Gymnase Gerudo", "Schlüsselbund für das Gerudo-Trainingsgelände" }, ITEMTYPE_SMALLKEY, 0xDB, true, LOGIC_GERUDO_TRAINING_GROUNDS_KEYS, RHT_GERUDO_TRAINING_GROUNDS_KEY_RING, RG_GERUDO_TRAINING_GROUNDS_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); - itemTable[RG_GERUDO_TRAINING_GROUNDS_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); + itemTable[RG_GERUDO_TRAINING_GROUND_KEY_RING] = Item(RG_GERUDO_TRAINING_GROUND_KEY_RING, Text{ "Training Ground Key Ring", "Trousseau du Gymnase Gerudo", "Schlüsselbund für das Gerudo-Trainingsgelände" }, ITEMTYPE_SMALLKEY, 0xDB, true, LOGIC_GERUDO_TRAINING_GROUND_KEYS, RHT_GERUDO_TRAINING_GROUND_KEY_RING, RG_GERUDO_TRAINING_GROUND_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); + itemTable[RG_GERUDO_TRAINING_GROUND_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_GERUDO_FORTRESS_KEY_RING] = Item(RG_GERUDO_FORTRESS_KEY_RING, Text{ "Gerudo Fortress Key Ring", "Trousseau du Repaire des Voleurs", "Schlüsselbund für die Gerudo-Festung" }, ITEMTYPE_FORTRESS_SMALLKEY, 0xDC, true, LOGIC_GERUDO_FORTRESS_KEYS, RHT_GERUDO_FORTRESS_KEY_RING, RG_GERUDO_FORTRESS_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); itemTable[RG_GERUDO_FORTRESS_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing); itemTable[RG_GANONS_CASTLE_KEY_RING] = Item(RG_GANONS_CASTLE_KEY_RING, Text{ "Ganon's Castle Key Ring", "Trousseau du Château de Ganon", "Schlüsselbund für Ganons Schloß" }, ITEMTYPE_SMALLKEY, 0xDD, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_KEY_RING, RG_GANONS_CASTLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER); diff --git a/soh/soh/Enhancements/randomizer/item_location.cpp b/soh/soh/Enhancements/randomizer/item_location.cpp index d365081c3..9f0f84509 100644 --- a/soh/soh/Enhancements/randomizer/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/item_location.cpp @@ -72,6 +72,26 @@ std::set ItemLocation::GetAreas() const { return areas; } +RandomizerArea ItemLocation::GetFirstArea() const { + if (areas.empty()){ + assert(false); + return RA_NONE; + } else { + return *areas.begin(); + } +} + +RandomizerArea ItemLocation::GetRandomArea() const { + if (areas.empty()){ + SPDLOG_DEBUG("Attempted to get random area of location with no areas: "); + SPDLOG_DEBUG(Rando::StaticData::GetLocation(rc)->GetName()); + assert(false); + return RA_NONE; + } else { + return RandomElementFromSet(areas); + } +} + void ItemLocation::PlaceVanillaItem() { placedItem = StaticData::GetLocation(rc)->GetVanillaItem(); } @@ -156,8 +176,8 @@ void ItemLocation::SetHidden(const bool hidden_) { hidden = hidden_; } -bool ItemLocation::IsExcluded() const { - return excludedOption.Value(); +bool ItemLocation::IsExcluded() { + return excludedOption.GetContextOptionIndex(); } Option* ItemLocation::GetExcludedOption() { @@ -177,7 +197,7 @@ void ItemLocation::AddExcludeOption() { // RANDOTODO: this without string compares and loops bool alreadyAdded = false; const Location* loc = StaticData::GetLocation(rc); - for (const Option* location : Context::GetInstance()->GetSettings()->GetExcludeOptionsForArea(loc->GetArea())) { + for (Option* location : Context::GetInstance()->GetSettings()->GetExcludeOptionsForArea(loc->GetArea())) { if (location->GetName() == excludedOption.GetName()) { alreadyAdded = true; } diff --git a/soh/soh/Enhancements/randomizer/item_location.h b/soh/soh/Enhancements/randomizer/item_location.h index 7a0014bfb..4ec8b8b9e 100644 --- a/soh/soh/Enhancements/randomizer/item_location.h +++ b/soh/soh/Enhancements/randomizer/item_location.h @@ -23,6 +23,8 @@ class ItemLocation { RandomizerRegion GetParentRegionKey() const; void SetParentRegion (RandomizerRegion region); std::set GetAreas() const; + RandomizerArea GetFirstArea() const; + RandomizerArea GetRandomArea() const; void MergeAreas (std::set newAreas); void PlaceVanillaItem(); void ApplyPlacedItemEffect() const; @@ -43,7 +45,7 @@ class ItemLocation { const std::vector& GetHintedBy() const; void AddHintedBy(RandomizerHint hintKey); bool IsHidden() const; - bool IsExcluded() const; + bool IsExcluded(); void AddExcludeOption(); Option* GetExcludedOption(); void SetHidden(bool hidden_); diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index f593de158..20dc211a8 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -53,9 +53,9 @@ const std::string& Rando::Location::GetShortName() const { bool Rando::Location::IsDungeon() const { return (checkType != RCTYPE_SKULL_TOKEN && - (scene < SCENE_THIEVES_HIDEOUT || scene == SCENE_INSIDE_GANONS_CASTLE || - (scene > SCENE_TREASURE_BOX_SHOP && scene < SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR))) || - (checkType == RCTYPE_SKULL_TOKEN && scene < SCENE_GANONS_TOWER); + (scene <= SCENE_GERUDO_TRAINING_GROUND || scene == SCENE_INSIDE_GANONS_CASTLE || + (scene >= SCENE_DEKU_TREE_BOSS && scene <= SCENE_GANONDORF_BOSS))) || + (checkType == RCTYPE_SKULL_TOKEN && scene <= SCENE_ICE_CAVERN); } bool Rando::Location::IsOverworld() const { @@ -370,6 +370,21 @@ Rando::Location Rando::Location::GrottoFish(RandomizerCheck rc, RandomizerCheckQ SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, SCENE_GROTTOS, flag_)}; } +Rando::Location Rando::Location::Pot(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + std::string&& spoilerName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck) { + return {rc, quest_, RCTYPE_POT, area_, ACTOR_OBJ_TSUBO, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, false, + collectionCheck }; +} + Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_) { return { rc, quest_, RCTYPE_GOSSIP_STONE, area_, ACTOR_EN_GS, scene_, actorParams_, std::move(shortName_), RHT_NONE, RG_NONE, false }; } + +Rando::Location Rando::Location::Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, + RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return {rc, quest_, RCTYPE_FAIRY, area_, ACTOR_EN_ELF, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, RG_NONE, false, collectionCheck}; +} diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index a93fcd94b..9de741dbf 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -170,6 +170,11 @@ class Location { static Location GrottoFish(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, int32_t actorParams_, RandomizerInf flag_, std::string&& shortName_, RandomizerHintTextKey hintKey); + static Location Pot(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck); + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_); @@ -177,6 +182,8 @@ class Location { static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_); + static Location Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck); + static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, std::string&& shortName_); static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_); diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index cdfd88680..2b44ba7cb 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -3,8 +3,6 @@ #include "context.h" #include "dungeon.h" -#define TWO_ACTOR_PARAMS(a, b) (abs(a) << 16) | abs(b) - std::array Rando::StaticData::locationTable; std::multimap, RandomizerCheck> Rando::StaticData::CheckFromActorMultimap; @@ -25,7 +23,6 @@ std::vector Rando::StaticData::GetPondFishLocations() { } return pondFishLocations; } - std::vector Rando::StaticData::GetOverworldFishLocations() { std::vector overworldFishLocations = {}; for (Location& location : locationTable) { @@ -36,6 +33,16 @@ std::vector Rando::StaticData::GetOverworldFishLocations() { return overworldFishLocations; } +std::vector Rando::StaticData::GetOverworldPotLocations() { + std::vector overworldPotLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_POT && location.IsOverworld() && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + overworldPotLocations.push_back(location.GetRandomizerCheck()); + } + } + return overworldPotLocations; +} + std::vector Rando::StaticData::GetStaticHintLocations() { std::vector staticHintLocations = {}; for (Location& location : locationTable) { @@ -96,7 +103,6 @@ std::vector Rando::StaticData::GetShopLocations() { return shopLocations; } - std::vector Rando::StaticData::GetOverworldLocations() { //RANDOTODO better way of filling the initial location pool, among other things. std::vector overworldLocations = {}; @@ -106,7 +112,8 @@ std::vector Rando::StaticData::GetOverworldLocations() { location.IsOverworld() && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK && location.GetRandomizerCheck() != RC_TRIFORCE_COMPLETED && //not really an overworld check - location.GetRCType() != RCTYPE_FISH && //temp fix while locations are properly sorted out + location.GetRCType() != RCTYPE_FISH && // temp fix while locations are properly sorted out + location.GetRCType() != RCTYPE_POT && // Same as fish location.GetRCType() != RCTYPE_CHEST_GAME && //this is supposed to be excluded (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) || location.GetRCType() != RCTYPE_ADULT_TRADE) && //trade is handled elsewhere in location pool location.GetRCType() != RCTYPE_STATIC_HINT && @@ -128,6 +135,16 @@ std::vector Rando::StaticData::GetAllDungeonLocations() { return dungeonLocations; } +std::vector Rando::StaticData::GetOverworldFairyLocations() { + std::vector fairyLocations = {}; + for (Location& location : locationTable) { + if (location.GetRCType() == RCTYPE_FAIRY && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + fairyLocations.push_back(location.GetRandomizerCheck()); + } + } + return fairyLocations; +} + void Rando::StaticData::InitLocationTable() { // Randomizer Check Quest Type Area Actor ID Scene ID Params Flags Short Name Hint Text Key Vanilla Item Spoiler Collection Check Vanilla Progression Price // clang-format off locationTable[RC_UNKNOWN_CHECK] = Location::Base(RC_UNKNOWN_CHECK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_INVALID, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Invalid Location", "Invalid Location", RHT_NONE, RG_NONE); @@ -140,101 +157,101 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_KF_STORMS_GROTTO_CHEST] = Location::Chest(RC_KF_STORMS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_GROTTOS, 22988, 0x0C, "Storms Grotto Chest", RHT_KF_STORMS_GROTTO_CHEST, RG_RED_RUPEE); // Lost Woods locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST] = Location::Chest(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_EN_BOX, SCENE_GROTTOS, 22964, 0x14, "Near Shortcuts Grotto Chest", RHT_KF_STORMS_GROTTO_CHEST, RG_RED_RUPEE); - locationTable[RC_LW_SKULL_KID] = Location::Base(RC_LW_SKULL_KID, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Skull Kid", RHT_LW_SKULL_KID, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(22), true); - locationTable[RC_LW_TRADE_COJIRO] = Location::Base(RC_LW_TRADE_COJIRO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Trade Cojiro", RHT_LW_TRADE_COJIRO, RG_ODD_MUSHROOM, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO), true); - locationTable[RC_LW_TRADE_ODD_POTION] = Location::Base(RC_LW_TRADE_ODD_POTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Trade Odd Potion", RHT_LW_TRADE_COJIRO, RG_POACHERS_SAW, SpoilerCollectionCheck::ItemGetInf(49), true); - locationTable[RC_LW_OCARINA_MEMORY_GAME] = Location::Base(RC_LW_OCARINA_MEMORY_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Ocarina Memory Game", RHT_LW_OCARINA_MEMORY_GAME, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(23), true); - locationTable[RC_LW_TARGET_IN_WOODS] = Location::Base(RC_LW_TARGET_IN_WOODS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Target in Woods", RHT_LW_TARGET_IN_WOODS, RG_PROGRESSIVE_SLINGSHOT, SpoilerCollectionCheck::ItemGetInf(29), true); - locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x00, "Deku Scrub Near Deku Theater Right", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT), false, 20); - locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x01, "Deku Scrub Near Deku Theater Left", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT), false, 15); - locationTable[RC_LW_DEKU_SCRUB_NEAR_BRIDGE] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, "Deku Scrub Near Bridge", RHT_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_PROGRESSIVE_STICK_UPGRADE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE), true, 40); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF5), "Deku Scrub Grotto Rear", RHT_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR), false, 40); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A, 0xF5), "Deku Scrub Grotto Front", RHT_LW_DEKU_SCRUB_GROTTO_FRONT, RG_PROGRESSIVE_NUT_UPGRADE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT), false, 40); - locationTable[RC_DEKU_THEATER_SKULL_MASK] = Location::Base(RC_DEKU_THEATER_SKULL_MASK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, "Deku Theater Skull Mask", RHT_DEKU_THEATER_SKULL_MASK, RG_PROGRESSIVE_STICK_UPGRADE, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE), true); - locationTable[RC_DEKU_THEATER_MASK_OF_TRUTH] = Location::Base(RC_DEKU_THEATER_MASK_OF_TRUTH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, "Deku Theater Mask of Truth", RHT_DEKU_THEATER_MASK_OF_TRUTH, RG_PROGRESSIVE_NUT_UPGRADE, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE), true); + locationTable[RC_LW_SKULL_KID] = Location::Base(RC_LW_SKULL_KID, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Skull Kid", RHT_LW_SKULL_KID, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(22), true); + locationTable[RC_LW_TRADE_COJIRO] = Location::Base(RC_LW_TRADE_COJIRO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Trade Cojiro", RHT_LW_TRADE_COJIRO, RG_ODD_MUSHROOM, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO), true); + locationTable[RC_LW_TRADE_ODD_POTION] = Location::Base(RC_LW_TRADE_ODD_POTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Trade Odd Potion", RHT_LW_TRADE_COJIRO, RG_POACHERS_SAW, SpoilerCollectionCheck::ItemGetInf(49), true); + locationTable[RC_LW_OCARINA_MEMORY_GAME] = Location::Base(RC_LW_OCARINA_MEMORY_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Ocarina Memory Game", RHT_LW_OCARINA_MEMORY_GAME, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(23), true); + locationTable[RC_LW_TARGET_IN_WOODS] = Location::Base(RC_LW_TARGET_IN_WOODS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Target in Woods", RHT_LW_TARGET_IN_WOODS, RG_PROGRESSIVE_SLINGSHOT, SpoilerCollectionCheck::ItemGetInf(29), true); + locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x00, "Deku Scrub Near Deku Theater Right", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT), false, 20); + locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x01, "Deku Scrub Near Deku Theater Left", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT), false, 15); + locationTable[RC_LW_DEKU_SCRUB_NEAR_BRIDGE] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, "Deku Scrub Near Bridge", RHT_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_PROGRESSIVE_STICK_UPGRADE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE), true, 40); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF5), "Deku Scrub Grotto Rear", RHT_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR), false, 40); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A, 0xF5), "Deku Scrub Grotto Front", RHT_LW_DEKU_SCRUB_GROTTO_FRONT, RG_PROGRESSIVE_NUT_UPGRADE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT), false, 40); + locationTable[RC_DEKU_THEATER_SKULL_MASK] = Location::Base(RC_DEKU_THEATER_SKULL_MASK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, "Deku Theater Skull Mask", RHT_DEKU_THEATER_SKULL_MASK, RG_PROGRESSIVE_STICK_UPGRADE, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE), true); + locationTable[RC_DEKU_THEATER_MASK_OF_TRUTH] = Location::Base(RC_DEKU_THEATER_MASK_OF_TRUTH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, "Deku Theater Mask of Truth", RHT_DEKU_THEATER_MASK_OF_TRUTH, RG_PROGRESSIVE_NUT_UPGRADE, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE), true); // Sacred Forest Meadow locationTable[RC_SFM_WOLFOS_GROTTO_CHEST] = Location::Chest(RC_SFM_WOLFOS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_BOX, SCENE_GROTTOS, 31409, 0x11, "Wolfos Grotto Chest", RHT_SFM_WOLFOS_GROTTO_CHEST, RG_PURPLE_RUPEE); - locationTable[RC_SFM_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEE), "Deku Scrub Grotto Rear", RHT_SFM_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR), false, 40); - locationTable[RC_SFM_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEE), "Deku Scrub Grotto Front", RHT_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT), false, 40); + locationTable[RC_SFM_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEE), "Deku Scrub Grotto Rear", RHT_SFM_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR), false, 40); + locationTable[RC_SFM_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEE), "Deku Scrub Grotto Front", RHT_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT), false, 40); // Hyrule Field locationTable[RC_HF_SOUTHEAST_GROTTO_CHEST] = Location::Chest(RC_HF_SOUTHEAST_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22978, 0x02, "Southeast Grotto Chest", RHT_HF_SOUTHEAST_GROTTO_CHEST, RG_RED_RUPEE); locationTable[RC_HF_OPEN_GROTTO_CHEST] = Location::Chest(RC_HF_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22947, 0x03, "Open Grotto Chest", RHT_HF_OPEN_GROTTO_CHEST, RG_BLUE_RUPEE); locationTable[RC_HF_NEAR_MARKET_GROTTO_CHEST] = Location::Chest(RC_HF_NEAR_MARKET_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22944, 0x00, "Near Market Grotto Chest", RHT_HF_NEAR_MARKET_GROTTO_CHEST, RG_BLUE_RUPEE); - locationTable[RC_HF_OCARINA_OF_TIME_ITEM] = Location::Base(RC_HF_OCARINA_OF_TIME_ITEM, RCQUEST_BOTH, RCTYPE_OCARINA, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, "Ocarina of Time Item", RHT_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, SpoilerCollectionCheck::EventChkInf(0x43)); + locationTable[RC_HF_OCARINA_OF_TIME_ITEM] = Location::Base(RC_HF_OCARINA_OF_TIME_ITEM, RCQUEST_BOTH, RCTYPE_OCARINA, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, "Ocarina of Time Item", RHT_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, SpoilerCollectionCheck::EventChkInf(0x43)); locationTable[RC_HF_TEKTITE_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_ITEM00, SCENE_GROTTOS, 262, 0x01, "Tektite Grotto Freestanding PoH", RHT_HF_TEKTITE_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, true); - locationTable[RC_HF_DEKU_SCRUB_GROTTO] = Location::Base(RC_HF_DEKU_SCRUB_GROTTO, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_HYRULE_FIELD, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x02, 0xE6), "Deku Scrub Grotto", RHT_HF_DEKU_SCRUB_GROTTO, RG_PIECE_OF_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO), true, 10); + locationTable[RC_HF_DEKU_SCRUB_GROTTO] = Location::Base(RC_HF_DEKU_SCRUB_GROTTO, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_HYRULE_FIELD, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x02, 0xE6), "Deku Scrub Grotto", RHT_HF_DEKU_SCRUB_GROTTO, RG_PIECE_OF_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO), true, 10); // Lake Hylia - locationTable[RC_LH_CHILD_FISHING] = Location::Base(RC_LH_CHILD_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Child Fishing", RHT_LH_CHILD_FISHING, RG_PIECE_OF_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CHILD_FISHING), true); - locationTable[RC_LH_ADULT_FISHING] = Location::Base(RC_LH_ADULT_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Adult Fishing", RHT_LH_ADULT_FISHING, RG_PROGRESSIVE_SCALE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_FISHING), true); - locationTable[RC_LH_HYRULE_LOACH] = Location::Base(RC_LH_HYRULE_LOACH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Hyrule Loach Reward", RHT_LH_HYRULE_LOACH, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CAUGHT_LOACH)); - locationTable[RC_LH_LAB_DIVE] = Location::Base(RC_LH_LAB_DIVE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, "Lab Dive", RHT_LH_LAB_DIVE, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(16), true); - locationTable[RC_LH_TRADE_FROG] = Location::Base(RC_LH_TRADE_FROG, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, "Lab Trade Eyeball Frog", RHT_LH_TRADE_FROG, RG_EYEDROPS, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG), true); - locationTable[RC_LH_UNDERWATER_ITEM] = Location::Base(RC_LH_UNDERWATER_ITEM, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Underwater Item", RHT_LH_UNDERWATER_ITEM, RG_RUTOS_LETTER, SpoilerCollectionCheck::EventChkInf(0x31), true); - locationTable[RC_LH_SUN] = Location::Base(RC_LH_SUN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Sun", RHT_LH_SUN, RG_FIRE_ARROWS, SpoilerCollectionCheck::Chest(0x57, 0x1F), true); + locationTable[RC_LH_CHILD_FISHING] = Location::Base(RC_LH_CHILD_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Child Fishing", RHT_LH_CHILD_FISHING, RG_PIECE_OF_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CHILD_FISHING), true); + locationTable[RC_LH_ADULT_FISHING] = Location::Base(RC_LH_ADULT_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Adult Fishing", RHT_LH_ADULT_FISHING, RG_PROGRESSIVE_SCALE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_FISHING), true); + locationTable[RC_LH_HYRULE_LOACH] = Location::Base(RC_LH_HYRULE_LOACH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Hyrule Loach Reward", RHT_LH_HYRULE_LOACH, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CAUGHT_LOACH)); + locationTable[RC_LH_LAB_DIVE] = Location::Base(RC_LH_LAB_DIVE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, "Lab Dive", RHT_LH_LAB_DIVE, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(16), true); + locationTable[RC_LH_TRADE_FROG] = Location::Base(RC_LH_TRADE_FROG, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, "Lab Trade Eyeball Frog", RHT_LH_TRADE_FROG, RG_EYEDROPS, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG), true); + locationTable[RC_LH_UNDERWATER_ITEM] = Location::Base(RC_LH_UNDERWATER_ITEM, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Underwater Item", RHT_LH_UNDERWATER_ITEM, RG_RUTOS_LETTER, SpoilerCollectionCheck::EventChkInf(0x31), true); + locationTable[RC_LH_SUN] = Location::Base(RC_LH_SUN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Sun", RHT_LH_SUN, RG_FIRE_ARROWS, SpoilerCollectionCheck::Chest(0x57, 0x1F), true); locationTable[RC_LH_FREESTANDING_POH] = Location::Collectable(RC_LH_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, 7686, 0x1E, "Freestanding PoH", RHT_LH_FREESTANDING_POH, RG_PIECE_OF_HEART, true); - locationTable[RC_LH_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xEF), "Deku Scrub Grotto Left", RHT_LH_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT), false, 20); - locationTable[RC_LH_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xEF), "Deku Scrub Grotto Right", RHT_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT), false, 40); - locationTable[RC_LH_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xEF), "Deku Scrub Grotto Center", RHT_LH_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER), false, 40); + locationTable[RC_LH_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xEF), "Deku Scrub Grotto Left", RHT_LH_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT), false, 20); + locationTable[RC_LH_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xEF), "Deku Scrub Grotto Right", RHT_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT), false, 40); + locationTable[RC_LH_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xEF), "Deku Scrub Grotto Center", RHT_LH_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER), false, 40); // Gerudo Valley locationTable[RC_GV_CHEST] = Location::Chest(RC_GV_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_VALLEY, 23200, 0x00, "Chest", RHT_GV_CHEST, RG_PURPLE_RUPEE); - locationTable[RC_GV_TRADE_SAW] = Location::Base(RC_GV_TRADE_SAW, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_GERUDO_VALLEY, 0x00, "Trade Saw", RHT_GV_TRADE_SAW, RG_BROKEN_SWORD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW), true); + locationTable[RC_GV_TRADE_SAW] = Location::Base(RC_GV_TRADE_SAW, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_GERUDO_VALLEY, 0x00, "Trade Saw", RHT_GV_TRADE_SAW, RG_BROKEN_SWORD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW), true); locationTable[RC_GV_WATERFALL_FREESTANDING_POH] = Location::Collectable(RC_GV_WATERFALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 262, 0x01, "Waterfall Freestanding PoH", RHT_GV_WATERFALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_GV_CRATE_FREESTANDING_POH] = Location::Collectable(RC_GV_CRATE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 518, 0x02, "Crate Freestanding PoH", RHT_GV_CRATE_FREESTANDING_POH, RG_PIECE_OF_HEART, true); - locationTable[RC_GV_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xF0), "Deku Scrub Grotto Rear", RHT_GV_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR), false, 40); - locationTable[RC_GV_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xF0), "Deku Scrub Grotto Front", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT), false, 40); + locationTable[RC_GV_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xF0), "Deku Scrub Grotto Rear", RHT_GV_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR), false, 40); + locationTable[RC_GV_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xF0), "Deku Scrub Grotto Front", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT), false, 40); // Gerudo Fortress locationTable[RC_GF_CHEST] = Location::Chest(RC_GF_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDOS_FORTRESS, 1984, 0x00, "Chest", RHT_GF_CHEST, RG_PIECE_OF_HEART, true); - locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, SpoilerCollectionCheck::InfTable(INFTABLE_190), true); - locationTable[RC_GF_HBA_1500_POINTS] = Location::Base(RC_GF_HBA_1500_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, "GF HBA 1500 Points", RHT_GF_HBA_1500_POINTS, RG_PROGRESSIVE_BOW, SpoilerCollectionCheck::ItemGetInf(15), true); + locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, SpoilerCollectionCheck::InfTable(INFTABLE_190), true); + locationTable[RC_GF_HBA_1500_POINTS] = Location::Base(RC_GF_HBA_1500_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, "GF HBA 1500 Points", RHT_GF_HBA_1500_POINTS, RG_PROGRESSIVE_BOW, SpoilerCollectionCheck::ItemGetInf(15), true); // RandoTodo: Do we replace these with the RC_HIDEOUT keys or keep these? - locationTable[RC_GF_GERUDO_MEMBERSHIP_CARD] = Location::Base(RC_GF_GERUDO_MEMBERSHIP_CARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_THIEVES_HIDEOUT, 0x00, "GF Gerudo Membership Card", RHT_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_ITEM_FROM_LEADER_OF_FORTRESS), true); + locationTable[RC_GF_GERUDO_MEMBERSHIP_CARD] = Location::Base(RC_GF_GERUDO_MEMBERSHIP_CARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_THIEVES_HIDEOUT, 0x00, "GF Gerudo Membership Card", RHT_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_ITEM_FROM_LEADER_OF_FORTRESS), true); locationTable[RC_GF_NORTH_F1_CARPENTER] = Location::Collectable(RC_GF_NORTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3089, 0x0C, "GF North F1 Carpenter", RHT_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, true); locationTable[RC_GF_NORTH_F2_CARPENTER] = Location::Collectable(RC_GF_NORTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 2577, 0x0A, "GF North F2 Carpenter", RHT_GF_NORTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, true); locationTable[RC_GF_SOUTH_F1_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F1_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3601, 0x0E, "GF South F1 Carpenter", RHT_GF_SOUTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, true); locationTable[RC_GF_SOUTH_F2_CARPENTER] = Location::Collectable(RC_GF_SOUTH_F2_CARPENTER, RCQUEST_BOTH, RCTYPE_GF_KEY, ACTOR_EN_ITEM00, SCENE_THIEVES_HIDEOUT, 3857, 0x0F, "GF South F2 Carpenter", RHT_GF_SOUTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, true); // Haunted Wasteland locationTable[RC_WASTELAND_CHEST] = Location::Chest(RC_WASTELAND_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_WASTELAND, ACTOR_EN_BOX, SCENE_HAUNTED_WASTELAND, -30048, 0x00, "Chest", RHT_WASTELAND_CHEST, RG_PURPLE_RUPEE); - locationTable[RC_WASTELAND_BOMBCHU_SALESMAN] = Location::Base(RC_WASTELAND_BOMBCHU_SALESMAN, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, "Carpet Salesman", RHT_WASTELAND_BOMBCHU_SALESMAN, RG_BUY_BOMBCHUS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN), false, 200); + locationTable[RC_WASTELAND_BOMBCHU_SALESMAN] = Location::Base(RC_WASTELAND_BOMBCHU_SALESMAN, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, "Carpet Salesman", RHT_WASTELAND_BOMBCHU_SALESMAN, RG_BUY_BOMBCHUS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN), false, 200); // Desert Colossus locationTable[RC_COLOSSUS_FREESTANDING_POH] = Location::Collectable(RC_COLOSSUS_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DESERT_COLOSSUS, 3334, 0x0D, "Freestanding PoH", RHT_COLOSSUS_FREESTANDING_POH, RG_PIECE_OF_HEART, true); - locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xFD), "Deku Scrub Grotto Rear", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR), false, 40); - locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xFD), "Deku Scrub Grotto Front", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT), false, 40); + locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xFD), "Deku Scrub Grotto Rear", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR), false, 40); + locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xFD), "Deku Scrub Grotto Front", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT), false, 40); // Market - locationTable[RC_MARKET_TREASURE_CHEST_GAME_REWARD] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Treasure Chest Game Reward", RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RG_TREASURE_GAME_HEART, SpoilerCollectionCheck::ItemGetInf(27), true); - locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, "Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, SpoilerCollectionCheck::ItemGetInf(17), true); - locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, "Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(18), true); - locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, "Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, SpoilerCollectionCheck::InfTable(INFTABLE_191), true); - locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, "Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), true); - locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, "10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), true); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game First Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Second Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Third Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fourth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fifth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game First Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_1, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Second Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_2, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Third Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_3, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fourth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_4, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4)); - locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fifth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_5, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_REWARD] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Treasure Chest Game Reward", RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RG_TREASURE_GAME_HEART, SpoilerCollectionCheck::ItemGetInf(27), true); + locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, "Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, SpoilerCollectionCheck::ItemGetInf(17), true); + locationTable[RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, "Bombchu Bowling Second Prize", RHT_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(18), true); + locationTable[RC_MARKET_LOST_DOG] = Location::Base(RC_MARKET_LOST_DOG, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_DOG_LADY_HOUSE, 0x00, "Lost Dog", RHT_MARKET_LOST_DOG, RG_PIECE_OF_HEART, SpoilerCollectionCheck::InfTable(INFTABLE_191), true); + locationTable[RC_MARKET_SHOOTING_GALLERY_REWARD] = Location::Base(RC_MARKET_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, "Shooting Gallery", RHT_MARKET_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_SLINGSHOT, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0D), true); + locationTable[RC_MARKET_10_BIG_POES] = Location::Base(RC_MARKET_10_BIG_POES, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_MARKET_GUARD_HOUSE, 0x00, "10 Big Poes", RHT_MARKET_10_BIG_POES, RG_EMPTY_BOTTLE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_10_BIG_POES), true); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game First Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Second Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Third Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fourth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_ITEM_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fifth Room Item", RHT_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_1] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game First Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_1, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_2] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Second Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_2, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_3] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Third Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_3, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_4] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fourth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_4, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4)); + locationTable[RC_MARKET_TREASURE_CHEST_GAME_KEY_5] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RCQUEST_BOTH, RCTYPE_CHEST_GAME, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Chest Game Fifth Room Key", RHT_MARKET_TREASURE_CHEST_GAME_KEY_5, RG_TREASURE_GAME_SMALL_KEY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5)); // Hyrule Castle - locationTable[RC_HC_MALON_EGG] = Location::Base(RC_HC_MALON_EGG, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HYRULE_CASTLE, 0x00, "Malon Egg", RHT_HC_MALON_EGG, RG_WEIRD_EGG, SpoilerCollectionCheck::EventChkInf(0x12), true); - locationTable[RC_HC_ZELDAS_LETTER] = Location::Base(RC_HC_ZELDAS_LETTER, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_CASTLE_COURTYARD_ZELDA, 0x00, "Zeldas Letter", RHT_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER, SpoilerCollectionCheck::EventChkInf(0x40), true); + locationTable[RC_HC_MALON_EGG] = Location::Base(RC_HC_MALON_EGG, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HYRULE_CASTLE, 0x00, "Malon Egg", RHT_HC_MALON_EGG, RG_WEIRD_EGG, SpoilerCollectionCheck::EventChkInf(0x12), true); + locationTable[RC_HC_ZELDAS_LETTER] = Location::Base(RC_HC_ZELDAS_LETTER, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_CASTLE_COURTYARD_ZELDA, 0x00, "Zeldas Letter", RHT_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER, SpoilerCollectionCheck::EventChkInf(0x40), true); // Kakariko locationTable[RC_KAK_REDEAD_GROTTO_CHEST] = Location::Chest(RC_KAK_REDEAD_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 31434, 0x0A, "Redead Grotto Chest", RHT_KAK_REDEAD_GROTTO_CHEST, RG_HUGE_RUPEE); locationTable[RC_KAK_OPEN_GROTTO_CHEST] = Location::Chest(RC_KAK_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_BOX, SCENE_GROTTOS, 22984, 0x08, "Open Grotto Chest", RHT_KAK_OPEN_GROTTO_CHEST, RG_RED_RUPEE); - locationTable[RC_KAK_10_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_10_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "10 Gold Skulltula Reward", RHT_KAK_10_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, SpoilerCollectionCheck::EventChkInf(0xDA), true); - locationTable[RC_KAK_20_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_20_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "20 Gold Skulltula Reward", RHT_KAK_20_GOLD_SKULLTULA_REWARD, RG_STONE_OF_AGONY, SpoilerCollectionCheck::EventChkInf(0xDB), true); - locationTable[RC_KAK_30_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_30_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "30 Gold Skulltula Reward", RHT_KAK_30_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, SpoilerCollectionCheck::EventChkInf(0xDC), true); - locationTable[RC_KAK_40_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_40_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "40 Gold Skulltula Reward", RHT_KAK_40_GOLD_SKULLTULA_REWARD, RG_BOMBCHU_10, SpoilerCollectionCheck::EventChkInf(0xDD)); - locationTable[RC_KAK_50_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_50_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "50 Gold Skulltula Reward", RHT_KAK_50_GOLD_SKULLTULA_REWARD, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xDE), true); - locationTable[RC_KAK_100_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_100_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "100 Gold Skulltula Reward", RHT_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD)); - locationTable[RC_KAK_MAN_ON_ROOF] = Location::Base(RC_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Man on Roof", RHT_KAK_MAN_ON_ROOF, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(21), true); - locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, "Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0E), true); - locationTable[RC_KAK_TRADE_ODD_MUSHROOM] = Location::Base(RC_KAK_TRADE_ODD_MUSHROOM, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, "Trade Odd Mushroom", RHT_KAK_TRADE_ODD_MUSHROOM, RG_ODD_POTION, SpoilerCollectionCheck::ItemGetInf(48), true); - locationTable[RC_KAK_GRANNYS_SHOP] = Location::Base(RC_KAK_GRANNYS_SHOP, RCQUEST_BOTH, RCTYPE_MERCHANT, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, "Granny's Shop", RHT_KAK_GRANNYS_SHOP, RG_BUY_BLUE_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP), true, 100); - locationTable[RC_KAK_ANJU_AS_ADULT] = Location::Base(RC_KAK_ANJU_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Anju as Adult", RHT_KAK_ANJU_AS_ADULT, RG_CLAIM_CHECK, SpoilerCollectionCheck::ItemGetInf(44), true); - locationTable[RC_KAK_ANJU_AS_CHILD] = Location::Base(RC_KAK_ANJU_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Anju as Child", RHT_KAK_ANJU_AS_CHILD, RG_EMPTY_BOTTLE, SpoilerCollectionCheck::ItemGetInf(12), true); - locationTable[RC_KAK_TRADE_POCKET_CUCCO] = Location::Base(RC_KAK_TRADE_POCKET_CUCCO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Trade Pocket Cucco", RHT_KAK_TRADE_POCKET_CUCCO, RG_COJIRO, SpoilerCollectionCheck::ItemGetInf(46), true); + locationTable[RC_KAK_10_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_10_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "10 Gold Skulltula Reward", RHT_KAK_10_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, SpoilerCollectionCheck::EventChkInf(0xDA), true); + locationTable[RC_KAK_20_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_20_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "20 Gold Skulltula Reward", RHT_KAK_20_GOLD_SKULLTULA_REWARD, RG_STONE_OF_AGONY, SpoilerCollectionCheck::EventChkInf(0xDB), true); + locationTable[RC_KAK_30_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_30_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "30 Gold Skulltula Reward", RHT_KAK_30_GOLD_SKULLTULA_REWARD, RG_PROGRESSIVE_WALLET, SpoilerCollectionCheck::EventChkInf(0xDC), true); + locationTable[RC_KAK_40_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_40_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "40 Gold Skulltula Reward", RHT_KAK_40_GOLD_SKULLTULA_REWARD, RG_BOMBCHU_10, SpoilerCollectionCheck::EventChkInf(0xDD)); + locationTable[RC_KAK_50_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_50_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "50 Gold Skulltula Reward", RHT_KAK_50_GOLD_SKULLTULA_REWARD, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xDE), true); + locationTable[RC_KAK_100_GOLD_SKULLTULA_REWARD] = Location::Base(RC_KAK_100_GOLD_SKULLTULA_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_HOUSE_OF_SKULLTULA, 0x00, "100 Gold Skulltula Reward", RHT_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD)); + locationTable[RC_KAK_MAN_ON_ROOF] = Location::Base(RC_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Man on Roof", RHT_KAK_MAN_ON_ROOF, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(21), true); + locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, "Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0E), true); + locationTable[RC_KAK_TRADE_ODD_MUSHROOM] = Location::Base(RC_KAK_TRADE_ODD_MUSHROOM, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, "Trade Odd Mushroom", RHT_KAK_TRADE_ODD_MUSHROOM, RG_ODD_POTION, SpoilerCollectionCheck::ItemGetInf(48), true); + locationTable[RC_KAK_GRANNYS_SHOP] = Location::Base(RC_KAK_GRANNYS_SHOP, RCQUEST_BOTH, RCTYPE_MERCHANT, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, "Granny's Shop", RHT_KAK_GRANNYS_SHOP, RG_BUY_BLUE_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP), true, 100); + locationTable[RC_KAK_ANJU_AS_ADULT] = Location::Base(RC_KAK_ANJU_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Anju as Adult", RHT_KAK_ANJU_AS_ADULT, RG_CLAIM_CHECK, SpoilerCollectionCheck::ItemGetInf(44), true); + locationTable[RC_KAK_ANJU_AS_CHILD] = Location::Base(RC_KAK_ANJU_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Anju as Child", RHT_KAK_ANJU_AS_CHILD, RG_EMPTY_BOTTLE, SpoilerCollectionCheck::ItemGetInf(12), true); + locationTable[RC_KAK_TRADE_POCKET_CUCCO] = Location::Base(RC_KAK_TRADE_POCKET_CUCCO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Trade Pocket Cucco", RHT_KAK_TRADE_POCKET_CUCCO, RG_COJIRO, SpoilerCollectionCheck::ItemGetInf(46), true); locationTable[RC_KAK_IMPAS_HOUSE_FREESTANDING_POH] = Location::Collectable(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_IMPAS_HOUSE, 262, 0x01, "Impas House Freestanding PoH", RHT_KAK_IMPAS_HOUSE_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_KAK_WINDMILL_FREESTANDING_POH] = Location::Collectable(RC_KAK_WINDMILL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 262, 0x01, "Windmill Freestanding PoH", RHT_KAK_WINDMILL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); // Graveyard @@ -248,58 +265,58 @@ void Rando::StaticData::InitLocationTable() { // // Death Mountain locationTable[RC_DMT_CHEST] = Location::Chest(RC_DMT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEATH_MOUNTAIN_TRAIL, 23201, 0x01, "Chest", RHT_DMT_CHEST, RG_PURPLE_RUPEE); locationTable[RC_DMT_STORMS_GROTTO_CHEST] = Location::Chest(RC_DMT_STORMS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_BOX, SCENE_GROTTOS, 23255, 0x17, "Storms Grotto Chest", RHT_DMT_STORMS_GROTTO_CHEST, RG_HUGE_RUPEE); - locationTable[RC_DMT_TRADE_BROKEN_SWORD] = Location::Base(RC_DMT_TRADE_BROKEN_SWORD, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, "Trade Broken Sword", RHT_DMT_TRADE_BROKEN_SWORD, RG_PRESCRIPTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD), true); - locationTable[RC_DMT_TRADE_EYEDROPS] = Location::Base(RC_DMT_TRADE_EYEDROPS, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, "Trade Eyedrops", RHT_DMT_TRADE_EYEDROPS, RG_CLAIM_CHECK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS), true); - locationTable[RC_DMT_TRADE_CLAIM_CHECK] = Location::Base(RC_DMT_TRADE_CLAIM_CHECK, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, "Trade Claim Check", RHT_DMT_TRADE_CLAIM_CHECK, RG_BIGGORON_SWORD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK), true); + locationTable[RC_DMT_TRADE_BROKEN_SWORD] = Location::Base(RC_DMT_TRADE_BROKEN_SWORD, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, "Trade Broken Sword", RHT_DMT_TRADE_BROKEN_SWORD, RG_PRESCRIPTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD), true); + locationTable[RC_DMT_TRADE_EYEDROPS] = Location::Base(RC_DMT_TRADE_EYEDROPS, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, "Trade Eyedrops", RHT_DMT_TRADE_EYEDROPS, RG_CLAIM_CHECK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS), true); + locationTable[RC_DMT_TRADE_CLAIM_CHECK] = Location::Base(RC_DMT_TRADE_CLAIM_CHECK, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_TRAIL, 0x00, "Trade Claim Check", RHT_DMT_TRADE_CLAIM_CHECK, RG_BIGGORON_SWORD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK), true); locationTable[RC_DMT_FREESTANDING_POH] = Location::Collectable(RC_DMT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, 7686, 0x1E, "Freestanding PoH", RHT_DMT_FREESTANDING_POH, RG_PIECE_OF_HEART, true); // Goron City locationTable[RC_GC_MAZE_LEFT_CHEST] = Location::Chest(RC_GC_MAZE_LEFT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GORON_CITY, 23232, 0x00, "Maze Left Chest", RHT_GC_MAZE_LEFT_CHEST, RG_HUGE_RUPEE); locationTable[RC_GC_MAZE_RIGHT_CHEST] = Location::Chest(RC_GC_MAZE_RIGHT_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GORON_CITY, 23201, 0x01, "Maze Right Chest", RHT_GC_MAZE_RIGHT_CHEST, RG_PURPLE_RUPEE); locationTable[RC_GC_MAZE_CENTER_CHEST] = Location::Chest(RC_GC_MAZE_CENTER_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GORON_CITY, 23202, 0x02, "Maze Center Chest", RHT_GC_MAZE_CENTER_CHEST, RG_PURPLE_RUPEE); - locationTable[RC_GC_ROLLING_GORON_AS_CHILD] = Location::Base(RC_GC_ROLLING_GORON_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Rolling Goron as Child", RHT_GC_ROLLING_GORON_AS_CHILD, RG_PROGRESSIVE_BOMB_BAG, SpoilerCollectionCheck::InfTable(INFTABLE_11E), true); - locationTable[RC_GC_ROLLING_GORON_AS_ADULT] = Location::Base(RC_GC_ROLLING_GORON_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Rolling Goron as Adult", RHT_GC_ROLLING_GORON_AS_ADULT, RG_GORON_TUNIC, SpoilerCollectionCheck::InfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED), true); - locationTable[RC_GC_DARUNIAS_JOY] = Location::Base(RC_GC_DARUNIAS_JOY, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Darunias Joy", RHT_GC_DARUNIAS_JOY, RG_PROGRESSIVE_STRENGTH, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DARUNIAS_JOY), true); + locationTable[RC_GC_ROLLING_GORON_AS_CHILD] = Location::Base(RC_GC_ROLLING_GORON_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Rolling Goron as Child", RHT_GC_ROLLING_GORON_AS_CHILD, RG_PROGRESSIVE_BOMB_BAG, SpoilerCollectionCheck::InfTable(INFTABLE_11E), true); + locationTable[RC_GC_ROLLING_GORON_AS_ADULT] = Location::Base(RC_GC_ROLLING_GORON_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Rolling Goron as Adult", RHT_GC_ROLLING_GORON_AS_ADULT, RG_GORON_TUNIC, SpoilerCollectionCheck::InfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED), true); + locationTable[RC_GC_DARUNIAS_JOY] = Location::Base(RC_GC_DARUNIAS_JOY, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Darunias Joy", RHT_GC_DARUNIAS_JOY, RG_PROGRESSIVE_STRENGTH, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DARUNIAS_JOY), true); locationTable[RC_GC_POT_FREESTANDING_POH] = Location::Collectable(RC_GC_POT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GORON_CITY, 7942, 0x1F, "Pot Freestanding PoH", RHT_GC_POT_FREESTANDING_POH, RG_PIECE_OF_HEART, true); - locationTable[RC_GC_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFB), "Deku Scrub Grotto Left", RHT_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT), false, 20); - locationTable[RC_GC_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFB), "Deku Scrub Grotto Right", RHT_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT), false, 40); - locationTable[RC_GC_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFB), "Deku Scrub Grotto Center", RHT_GC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER), false, 70); - locationTable[RC_GC_MEDIGORON] = Location::Base(RC_GC_MEDIGORON, RCQUEST_BOTH, RCTYPE_MERCHANT, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Medigoron", RHT_GC_MEDIGORON, RG_GIANTS_KNIFE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MEDIGORON), false, 200); + locationTable[RC_GC_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFB), "Deku Scrub Grotto Left", RHT_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT), false, 20); + locationTable[RC_GC_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFB), "Deku Scrub Grotto Right", RHT_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT), false, 40); + locationTable[RC_GC_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFB), "Deku Scrub Grotto Center", RHT_GC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER), false, 70); + locationTable[RC_GC_MEDIGORON] = Location::Base(RC_GC_MEDIGORON, RCQUEST_BOTH, RCTYPE_MERCHANT, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Medigoron", RHT_GC_MEDIGORON, RG_GIANTS_KNIFE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MEDIGORON), false, 200); // Death Mountain Crater locationTable[RC_DMC_UPPER_GROTTO_CHEST] = Location::Chest(RC_DMC_UPPER_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_BOX, SCENE_GROTTOS, 23802, 0x1A, "Upper Grotto Chest", RHT_DMC_UPPER_GROTTO_CHEST, RG_BOMBS_20); locationTable[RC_DMC_WALL_FREESTANDING_POH] = Location::Collectable(RC_DMC_WALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 518, 0x02, "Wall Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_DMC_VOLCANO_FREESTANDING_POH] = Location::Collectable(RC_DMC_VOLCANO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 2054, 0x08, "Volcano Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); - locationTable[RC_DMC_DEKU_SCRUB] = Location::Base(RC_DMC_DEKU_SCRUB, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DEATH_MOUNTAIN_CRATER, 0x05, "Deku Scrub", RHT_DMC_DEKU_SCRUB, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB), false, 40); - locationTable[RC_DMC_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xF9), "Deku Scrub Grotto Left", RHT_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT), false, 20); - locationTable[RC_DMC_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xF9), "Deku Scrub Grotto Right", RHT_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT), false, 40); - locationTable[RC_DMC_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF9), "Deku Scrub Grotto Center", RHT_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER), false, 70); + locationTable[RC_DMC_DEKU_SCRUB] = Location::Base(RC_DMC_DEKU_SCRUB, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DEATH_MOUNTAIN_CRATER, 0x05, "Deku Scrub", RHT_DMC_DEKU_SCRUB, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB), false, 40); + locationTable[RC_DMC_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xF9), "Deku Scrub Grotto Left", RHT_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT), false, 20); + locationTable[RC_DMC_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xF9), "Deku Scrub Grotto Right", RHT_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT), false, 40); + locationTable[RC_DMC_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF9), "Deku Scrub Grotto Center", RHT_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER), false, 70); // Zoras River locationTable[RC_ZR_OPEN_GROTTO_CHEST] = Location::Chest(RC_ZR_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_BOX, SCENE_GROTTOS, 22985, 0x09, "Open Grotto Chest", RHT_ZR_OPEN_GROTTO_CHEST, RG_RED_RUPEE); - locationTable[RC_ZR_MAGIC_BEAN_SALESMAN] = Location::Base(RC_ZR_MAGIC_BEAN_SALESMAN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_RIVER, 0x00, "Magic Bean Salesman", RHT_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN), true, 60); - locationTable[RC_ZR_FROGS_ZELDAS_LULLABY] = Location::Base(RC_ZR_FROGS_ZELDAS_LULLABY, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Zelda's Lullaby", RHT_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD1)); - locationTable[RC_ZR_FROGS_EPONAS_SONG] = Location::Base(RC_ZR_FROGS_EPONAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Epona's Song", RHT_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD2)); - locationTable[RC_ZR_FROGS_SARIAS_SONG] = Location::Base(RC_ZR_FROGS_SARIAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Saria's Song", RHT_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD4)); - locationTable[RC_ZR_FROGS_SUNS_SONG] = Location::Base(RC_ZR_FROGS_SUNS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Sun's Song", RHT_ZR_FROGS_SUNS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD3)); - locationTable[RC_ZR_FROGS_SONG_OF_TIME] = Location::Base(RC_ZR_FROGS_SONG_OF_TIME, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Song of Time", RHT_ZR_FROGS_SONG_OF_TIME, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD5)); - locationTable[RC_ZR_FROGS_IN_THE_RAIN] = Location::Base(RC_ZR_FROGS_IN_THE_RAIN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs in the Rain", RHT_ZR_FROGS_IN_THE_RAIN, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xD6), true); - locationTable[RC_ZR_FROGS_OCARINA_GAME] = Location::Base(RC_ZR_FROGS_OCARINA_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Ocarina Game", RHT_ZR_FROGS_OCARINA_GAME, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xD0), true); + locationTable[RC_ZR_MAGIC_BEAN_SALESMAN] = Location::Base(RC_ZR_MAGIC_BEAN_SALESMAN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_RIVER, 0x00, "Magic Bean Salesman", RHT_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN), true, 60); + locationTable[RC_ZR_FROGS_ZELDAS_LULLABY] = Location::Base(RC_ZR_FROGS_ZELDAS_LULLABY, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Zelda's Lullaby", RHT_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD1)); + locationTable[RC_ZR_FROGS_EPONAS_SONG] = Location::Base(RC_ZR_FROGS_EPONAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Epona's Song", RHT_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD2)); + locationTable[RC_ZR_FROGS_SARIAS_SONG] = Location::Base(RC_ZR_FROGS_SARIAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Saria's Song", RHT_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD4)); + locationTable[RC_ZR_FROGS_SUNS_SONG] = Location::Base(RC_ZR_FROGS_SUNS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Sun's Song", RHT_ZR_FROGS_SUNS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD3)); + locationTable[RC_ZR_FROGS_SONG_OF_TIME] = Location::Base(RC_ZR_FROGS_SONG_OF_TIME, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Song of Time", RHT_ZR_FROGS_SONG_OF_TIME, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD5)); + locationTable[RC_ZR_FROGS_IN_THE_RAIN] = Location::Base(RC_ZR_FROGS_IN_THE_RAIN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs in the Rain", RHT_ZR_FROGS_IN_THE_RAIN, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xD6), true); + locationTable[RC_ZR_FROGS_OCARINA_GAME] = Location::Base(RC_ZR_FROGS_OCARINA_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Ocarina Game", RHT_ZR_FROGS_OCARINA_GAME, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xD0), true); locationTable[RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 1030, 0x04, "Near Open Grotto Freestanding PoH", RHT_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_ZR_NEAR_DOMAIN_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 2822, 0x0B, "Near Domain Freestanding PoH", RHT_ZR_NEAR_DOMAIN_FREESTANDING_POH, RG_PIECE_OF_HEART, true); - locationTable[RC_ZR_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEB), "Deku Scrub Grotto Rear", RHT_ZR_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR), false, 40); - locationTable[RC_ZR_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEB), "Deku Scrub Grotto Front", RHT_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT), false, 40); + locationTable[RC_ZR_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEB), "Deku Scrub Grotto Rear", RHT_ZR_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR), false, 40); + locationTable[RC_ZR_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEB), "Deku Scrub Grotto Front", RHT_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT), false, 40); // Zoras Domain locationTable[RC_ZD_CHEST] = Location::Chest(RC_ZD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_ZORAS_DOMAIN, -18496, 0x00, "Chest", RHT_ZD_CHEST, RG_PIECE_OF_HEART, true); - locationTable[RC_ZD_DIVING_MINIGAME] = Location::Base(RC_ZD_DIVING_MINIGAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "Diving Minigame", RHT_ZD_DIVING_MINIGAME, RG_PROGRESSIVE_SCALE, SpoilerCollectionCheck::EventChkInf(0x38), true); - locationTable[RC_ZD_KING_ZORA_THAWED] = Location::Base(RC_ZD_KING_ZORA_THAWED, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "King Zora Thawed", RHT_ZD_KING_ZORA_THAWED, RG_ZORA_TUNIC, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KING_ZORA_THAWED), true); - locationTable[RC_ZD_TRADE_PRESCRIPTION] = Location::Base(RC_ZD_TRADE_PRESCRIPTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "Trade Prescription", RHT_ZD_TRADE_PRESCRIPTION, RG_EYEBALL_FROG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION), true); + locationTable[RC_ZD_DIVING_MINIGAME] = Location::Base(RC_ZD_DIVING_MINIGAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "Diving Minigame", RHT_ZD_DIVING_MINIGAME, RG_PROGRESSIVE_SCALE, SpoilerCollectionCheck::EventChkInf(0x38), true); + locationTable[RC_ZD_KING_ZORA_THAWED] = Location::Base(RC_ZD_KING_ZORA_THAWED, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "King Zora Thawed", RHT_ZD_KING_ZORA_THAWED, RG_ZORA_TUNIC, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KING_ZORA_THAWED), true); + locationTable[RC_ZD_TRADE_PRESCRIPTION] = Location::Base(RC_ZD_TRADE_PRESCRIPTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "Trade Prescription", RHT_ZD_TRADE_PRESCRIPTION, RG_EYEBALL_FROG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION), true); // Zora's Fountain - locationTable[RC_ZF_ICEBERC_FREESTANDING_POH] = Location::Collectable(RC_ZF_ICEBERC_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 262, 0x01, "Iceberg Freestanding PoH", RHT_ZF_ICEBERG_FREESTANDING_POH, RG_PIECE_OF_HEART, true); + locationTable[RC_ZF_ICEBERG_FREESTANDING_POH] = Location::Collectable(RC_ZF_ICEBERG_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 262, 0x01, "Iceberg Freestanding PoH", RHT_ZF_ICEBERG_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_ZF_BOTTOM_FREESTANDING_POH] = Location::Collectable(RC_ZF_BOTTOM_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, 5126, 0x14, "Bottom Freestanding PoH", RHT_ZF_BOTTOM_FREESTANDING_POH, RG_PIECE_OF_HEART, true); // Lon Lon Ranch - locationTable[RC_LLR_TALONS_CHICKENS] = Location::Base(RC_LLR_TALONS_CHICKENS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LON_LON_BUILDINGS, 0x00, "Talons Chickens", RHT_LLR_TALONS_CHICKENS, RG_BOTTLE_WITH_MILK, SpoilerCollectionCheck::ItemGetInf(2), true); + locationTable[RC_LLR_TALONS_CHICKENS] = Location::Base(RC_LLR_TALONS_CHICKENS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LON_LON_BUILDINGS, 0x00, "Talons Chickens", RHT_LLR_TALONS_CHICKENS, RG_BOTTLE_WITH_MILK, SpoilerCollectionCheck::ItemGetInf(2), true); locationTable[RC_LLR_FREESTANDING_POH] = Location::Collectable(RC_LLR_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_LON_LON_BUILDINGS, 262, 0x01, "Freestanding PoH", RHT_LLR_FREESTANDING_POH, RG_PIECE_OF_HEART, true); - locationTable[RC_LLR_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFC), "Deku Scrub Grotto Left", RHT_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT), false, 20); - locationTable[RC_LLR_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFC), "Deku Scrub Grotto Right", RHT_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT), false, 40); - locationTable[RC_LLR_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFC), "Deku Scrub Grotto Center", RHT_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER), false, 40); + locationTable[RC_LLR_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFC), "Deku Scrub Grotto Left", RHT_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT), false, 20); + locationTable[RC_LLR_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFC), "Deku Scrub Grotto Right", RHT_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT), false, 40); + locationTable[RC_LLR_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFC), "Deku Scrub Grotto Center", RHT_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER), false, 40); // Dungeons // Deku Tree Vanilla @@ -317,7 +334,7 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_DEKU_TREE_MQ_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31452, 0x04, "MQ Basement Chest", RHT_DEKU_TREE_MQ_BASEMENT_CHEST, RG_DEKU_SHIELD); locationTable[RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "MQ Before Spinning Log Chest", RHT_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RG_RECOVERY_HEART); locationTable[RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 23200, 0x00, "MQ After Spinning Log Chest", RHT_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RG_PURPLE_RUPEE); - locationTable[RC_DEKU_TREE_MQ_DEKU_SCRUB] = Location::Base(RC_DEKU_TREE_MQ_DEKU_SCRUB, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DEKU_TREE, 0x04, "MQ Deku Scrub", RHT_DEKU_TREE_MQ_DEKU_SCRUB, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB), false, 50); + locationTable[RC_DEKU_TREE_MQ_DEKU_SCRUB] = Location::Base(RC_DEKU_TREE_MQ_DEKU_SCRUB, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DEKU_TREE, 0x04, "MQ Deku Scrub", RHT_DEKU_TREE_MQ_DEKU_SCRUB, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB), false, 50); // Dodongo's Cavern Shared locationTable[RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN_BOSS, 20512, 0x00, "Boss Room Chest", RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RG_BOMBS_5); @@ -327,10 +344,10 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22982, 0x06, "Bomb Flower Platform Chest", RHT_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RG_RED_RUPEE); locationTable[RC_DODONGOS_CAVERN_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "Bomb Bag Chest", RHT_DODONGOS_CAVERN_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, true); locationTable[RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21802, 0x0A, "End Of Bridge Chest", RHT_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RG_DEKU_SHIELD); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x00, "Deku Scrub Near Bomb Bag Left", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT), false, 20); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, "Deku Scrub Side Room Near Dodongos", RHT_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS), false, 15); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, "Deku Scrub Near Bomb Bag Right", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT), false, 40); - locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, "Deku Scrub Lobby", RHT_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY), false, 50); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x00, "Deku Scrub Near Bomb Bag Left", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT), false, 20); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, "Deku Scrub Side Room Near Dodongos", RHT_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS), false, 15); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, "Deku Scrub Near Bomb Bag Right", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT), false, 40); + locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, "Deku Scrub Lobby", RHT_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY), false, 50); // Dodongo's Cavern MQ locationTable[RC_DODONGOS_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2080, 0x00, "MQ Map Chest", RHT_DODONGOS_CAVERN_MQ_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, true); locationTable[RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "MQ Bomb Bag Chest", RHT_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, true); @@ -338,16 +355,16 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 29986, 0x02, "MQ Larvae Room Chest", RHT_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RG_DEKU_SHIELD); locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22947, 0x03, "MQ Torch Puzzle Room Chest", RHT_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RG_BLUE_RUPEE); locationTable[RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21825, 0x01, "MQ Under Grave Chest", RHT_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RG_HYLIAN_SHIELD); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, "MQ Deku Scrub Lobby Rear", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR), false, 15); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, "MQ Deku Scrub Lobby Front", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT), false, 40); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, "MQ Deku Scrub Staircase", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE), false, 50); - locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x07, "MQ Deku Scrub Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS), false, 40); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, "MQ Deku Scrub Lobby Rear", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR), false, 15); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, "MQ Deku Scrub Lobby Front", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT), false, 40); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, "MQ Deku Scrub Staircase", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE), false, 50); + locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x07, "MQ Deku Scrub Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS), false, 40); // Jabu-Jabu's Belly Vanilla locationTable[RC_JABU_JABUS_BELLY_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_JABU_JABU, 6178, 0x02, "Map Chest", RHT_JABU_JABUS_BELLY_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, true); locationTable[RC_JABU_JABUS_BELLY_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_JABU_JABU, -18428, 0x04, "Compass Chest", RHT_JABU_JABUS_BELLY_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, true); locationTable[RC_JABU_JABUS_BELLY_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, 4289, 0x01, "Boomerang Chest", RHT_JABU_JABUS_BELLY_BOOMERANG_CHEST, RG_BOOMERANG, true); - locationTable[RC_JABU_JABUS_BELLY_DEKU_SCRUB] = Location::Base(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_JABU_JABU, 0x00, "Deku Scrub", RHT_JABU_JABUS_BELLY_DEKU_SCRUB, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB), false, 20); + locationTable[RC_JABU_JABUS_BELLY_DEKU_SCRUB] = Location::Base(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_JABU_JABU, 0x00, "Deku Scrub", RHT_JABU_JABUS_BELLY_DEKU_SCRUB, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB), false, 20); // Jabu-Jabu's Belly MQ locationTable[RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, -32699, 0x05, "MQ First Room Side Chest", RHT_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RG_DEKU_NUTS_5); locationTable[RC_JABU_JABUS_BELLY_MQ_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_JABU_JABU, -18397, 0x03, "MQ Map Chest", RHT_JABU_JABUS_BELLY_MQ_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, true); @@ -553,38 +570,38 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_ICE_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_ICE_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_ICE_CAVERN, -18399, 0x01, "MQ Map Chest", RHT_ICE_CAVERN_MQ_MAP_CHEST, RG_ICE_CAVERN_MAP, true); locationTable[RC_ICE_CAVERN_MQ_FREESTANDING_POH] = Location::Collectable(RC_ICE_CAVERN_MQ_FREESTANDING_POH, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, 262, 0x01, "MQ Freestanding PoH", RHT_ICE_CAVERN_MQ_FREESTANDING_POH, RG_PIECE_OF_HEART, true); - // Gerudo Training Grounds Vanilla + // Gerudo Training Ground Vanilla locationTable[RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30573, 0x13, "Lobby Left Chest", RHT_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, RG_BLUE_RUPEE); locationTable[RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30393, 0x07, "Lobby Right Chest", RHT_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, RG_ARROWS_10); - locationTable[RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30656, 0x00, "Stalfos Chest", RHT_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); - locationTable[RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "Beamos Chest", RHT_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); - locationTable[RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22603, 0x0B, "Hidden Ceiling Chest", RHT_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30656, 0x00, "Stalfos Chest", RHT_GERUDO_TRAINING_GROUND_STALFOS_CHEST, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "Beamos Chest", RHT_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22603, 0x0B, "Hidden Ceiling Chest", RHT_GERUDO_TRAINING_GROUND_HIDDEN_CEILING_CHEST, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23206, 0x06, "Maze Path First Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FIRST_CHEST, RG_PURPLE_RUPEE); locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22986, 0x0A, "Maze Path Second Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_SECOND_CHEST, RG_RED_RUPEE); locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22889, 0x09, "Maze Path Third Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_THIRD_CHEST, RG_ARROWS_30); locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, RCQUEST_VANILLA, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 2860, 0x0C, "Maze Path Final Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_PATH_FINAL_CHEST, RG_ICE_ARROWS, true); locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23877, 0x05, "Maze Right Central Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_CENTRAL_CHEST, RG_BOMBCHU_5); locationTable[RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22888, 0x08, "Maze Right Side Chest", RHT_GERUDO_TRAINING_GROUND_MAZE_RIGHT_SIDE_CHEST, RG_ARROWS_30); - locationTable[RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, 0x0D, "Underwater Silver Rupee Chest", RHT_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30643, 0x0D, "Underwater Silver Rupee Chest", RHT_GERUDO_TRAINING_GROUND_UNDERWATER_SILVER_RUPEE_CHEST, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31058, 0x12, "Hammer Room Clear Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_CLEAR_CHEST, RG_ARROWS_10); - locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22608, 0x10, "Hammer Room Switch Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); - locationTable[RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30653, 0x03, "Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); - locationTable[RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22596, 0x04, "Near Scarecrow Chest", RHT_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22608, 0x10, "Hammer Room Switch Chest", RHT_GERUDO_TRAINING_GROUND_HAMMER_ROOM_SWITCH_CHEST, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30653, 0x03, "Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_EYE_STATUE_CHEST, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22596, 0x04, "Near Scarecrow Chest", RHT_GERUDO_TRAINING_GROUND_NEAR_SCARECROW_CHEST, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); locationTable[RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31089, 0x11, "Before Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_BEFORE_HEAVY_BLOCK_CHEST, RG_ARROWS_30); locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31439, 0x0F, "Heavy Block First Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FIRST_CHEST, RG_HUGE_RUPEE); locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 30862, 0x0E, "Heavy Block Second Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_SECOND_CHEST, RG_BLUE_RUPEE); - locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 26708, 0x14, "Heavy Block Third Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 26708, 0x14, "Heavy Block Third Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_THIRD_CHEST, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); locationTable[RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 24450, 0x02, "Heavy Block Fourth Chest", RHT_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_FOURTH_CHEST, RG_ICE_TRAP); - locationTable[RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY] = Location::Collectable(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_GERUDO_TRAINING_GROUND, 273, 0x01, "Freestanding Key", RHT_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); - // Gerudo Training Grounds Master Quest + locationTable[RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY] = Location::Collectable(RC_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_GERUDO_TRAINING_GROUND, 273, 0x01, "Freestanding Key", RHT_GERUDO_TRAINING_GROUND_FREESTANDING_KEY, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); + // Gerudo Training Ground Master Quest locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 23879, 0x07, "MQ Lobby Right Chest", RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_CHEST, RG_BOMBCHU_5); locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22867, 0x13, "MQ Lobby Left Chest", RHT_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_CHEST, RG_ARROWS_10); locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30304, 0x00, "MQ First Iron Knuckle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FIRST_IRON_KNUCKLE_CHEST, RG_BLUE_RUPEE); locationTable[RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31057, 0x11, "MQ Before Heavy Block Chest", RHT_GERUDO_TRAINING_GROUND_MQ_BEFORE_HEAVY_BLOCK_CHEST, RG_ARROWS_10); locationTable[RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -32669, 0x03, "MQ Eye Statue Chest", RHT_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, RG_BOMBCHU_10); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30642, 0x0E, "MQ Flame Circle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30642, 0x0E, "MQ Flame Circle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); locationTable[RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 31058, 0x12, "MQ Second Iron Knuckle Chest", RHT_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, RG_ARROWS_10); - locationTable[RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "MQ Dinolfos Chest", RHT_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, true); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -30655, 0x01, "MQ Dinolfos Chest", RHT_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_CHEST, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, true); locationTable[RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, RCQUEST_MQ, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, -17628, 0x04, "MQ Ice Arrows Chest", RHT_GERUDO_TRAINING_GROUND_MQ_ICE_ARROWS_CHEST, RG_ICE_ARROWS, true); locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22661, 0x05, "MQ Maze Right Central Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT_CENTRAL_CHEST, RG_BLUE_RUPEE); locationTable[RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST] = Location::Chest(RC_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_TRAINING_GROUND, 22918, 0x06, "MQ Maze Path First Chest", RHT_GERUDO_TRAINING_GROUND_MQ_MAZE_PATH_FIRST_CHEST, RG_GREEN_RUPEE); @@ -613,10 +630,10 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24463, 0x0F, "Light Trial Third Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RG_ICE_TRAP); locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30800, 0x10, "Light Trial Invisible Enemies Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RG_GANONS_CASTLE_SMALL_KEY, true); locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30639, 0x11, "Light Trial Lullaby Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RG_GANONS_CASTLE_SMALL_KEY, true); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, "Deku Scrub Center-Left", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT), false, 40); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, "Deku Scrub Center-Right", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT), false, 70); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, "Deku Scrub Right", RHT_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT), false, 20); - locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, "Deku Scrub Left", RHT_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT), false, 40); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, "Deku Scrub Center-Left", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT), false, 40); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, "Deku Scrub Center-Right", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT), false, 70); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, "Deku Scrub Right", RHT_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT), false, 20); + locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, "Deku Scrub Left", RHT_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT), false, 40); // Ganon's Castle MQ locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22977, 0x01, "MQ Water Trial Chest", RHT_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RG_RED_RUPEE); locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30398, 0x02, "MQ Forest Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RG_ARROWS_10); @@ -631,275 +648,275 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 20586, 0x0A, "MQ Spirit Trial First Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RG_BOMBCHU_10); locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "MQ Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10); locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY] = Location::Collectable(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, 273, 0x01, "MQ Forest Trial Freestanding Key", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RG_GANONS_CASTLE_SMALL_KEY, true); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x00, "MQ Deku Scrub Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT), false, 20); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, "MQ Deku Scrub Center-Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT), false, 40); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, "MQ Deku Scrub Center", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER), false, 70); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, "MQ Deku Scrub Center-Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT), false, 40); - locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, "MQ Deku Scrub Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT), false, 40); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x00, "MQ Deku Scrub Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT), false, 20); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, "MQ Deku Scrub Center-Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT), false, 40); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, "MQ Deku Scrub Center", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER), false, 70); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, "MQ Deku Scrub Center-Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT), false, 40); + locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, "MQ Deku Scrub Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT), false, 40); // Gold Skulltula Tokens // Dungeons // Deku Tree - locationTable[RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8193, 0x01, "GS Basement Back Room", RHT_DEKU_TREE_GS_BASEMENT_BACK_ROOM); - locationTable[RC_DEKU_TREE_GS_BASEMENT_GATE] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_GATE, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8194, 0x02, "GS Basement Gate", RHT_DEKU_TREE_GS_BASEMENT_GATE); - locationTable[RC_DEKU_TREE_GS_BASEMENT_VINES] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_VINES, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8196, 0x04, "GS Basement Vines", RHT_DEKU_TREE_GS_BASEMENT_VINES); - locationTable[RC_DEKU_TREE_GS_COMPASS_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_COMPASS_ROOM, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8200, 0x08, "GS Compass Room", RHT_DEKU_TREE_GS_COMPASS_ROOM); - locationTable[RC_DEKU_TREE_MQ_GS_LOBBY] = Location::GSToken(RC_DEKU_TREE_MQ_GS_LOBBY, RCQUEST_MQ, SCENE_DEKU_TREE, 8194, 0x02, "MQ GS Lobby", RHT_DEKU_TREE_MQ_GS_LOBBY); - locationTable[RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES] = Location::GSToken(RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, RCQUEST_MQ, SCENE_DEKU_TREE, 8200, 0x08, "MQ GS Past Boulder Vines", RHT_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES); - locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, RCQUEST_MQ, SCENE_DEKU_TREE, 8196, 0x04, "MQ GS Basement Graves Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM); - locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, RCQUEST_MQ, SCENE_DEKU_TREE, 8193, 0x01, "MQ GS Basement Back Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM); + locationTable[RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_BACK_ROOM, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8193, 0x01, "GS Basement Back Room", RHT_DEKU_TREE_GS_BASEMENT_BACK_ROOM); + locationTable[RC_DEKU_TREE_GS_BASEMENT_GATE] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_GATE, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8194, 0x02, "GS Basement Gate", RHT_DEKU_TREE_GS_BASEMENT_GATE); + locationTable[RC_DEKU_TREE_GS_BASEMENT_VINES] = Location::GSToken(RC_DEKU_TREE_GS_BASEMENT_VINES, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8196, 0x04, "GS Basement Vines", RHT_DEKU_TREE_GS_BASEMENT_VINES); + locationTable[RC_DEKU_TREE_GS_COMPASS_ROOM] = Location::GSToken(RC_DEKU_TREE_GS_COMPASS_ROOM, RCQUEST_VANILLA, SCENE_DEKU_TREE, 8200, 0x08, "GS Compass Room", RHT_DEKU_TREE_GS_COMPASS_ROOM); + locationTable[RC_DEKU_TREE_MQ_GS_LOBBY] = Location::GSToken(RC_DEKU_TREE_MQ_GS_LOBBY, RCQUEST_MQ, SCENE_DEKU_TREE, 8194, 0x02, "MQ GS Lobby", RHT_DEKU_TREE_MQ_GS_LOBBY); + locationTable[RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES] = Location::GSToken(RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, RCQUEST_MQ, SCENE_DEKU_TREE, 8200, 0x08, "MQ GS Past Boulder Vines", RHT_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES); + locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, RCQUEST_MQ, SCENE_DEKU_TREE, 8196, 0x04, "MQ GS Basement Graves Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM); + locationTable[RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM] = Location::GSToken(RC_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM, RCQUEST_MQ, SCENE_DEKU_TREE, 8193, 0x01, "MQ GS Basement Back Room", RHT_DEKU_TREE_MQ_GS_BASEMENT_BACK_ROOM); // Dodongo's Cavern - locationTable[RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8449, 0x01, "GS Vines Above Stairs", RHT_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS); - locationTable[RC_DODONGOS_CAVERN_GS_SCARECROW] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SCARECROW, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8450, 0x02, "GS Scarecrow", RHT_DODONGOS_CAVERN_GS_SCARECROW); - locationTable[RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8452, 0x04, "GS Alcove Above Stairs", RHT_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS); - locationTable[RC_DODONGOS_CAVERN_GS_BACK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_GS_BACK_ROOM, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8456, 0x08, "GS Back Room", RHT_DODONGOS_CAVERN_GS_BACK_ROOM); - locationTable[RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8464, 0x10, "GS Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8450, 0x02, "MQ GS Scrub Room", RHT_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8456, 0x08, "MQ GS Song of Time Block Room", RHT_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8452, 0x04, "MQ GS Lizalfos Room", RHT_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8464, 0x10, "MQ GS Larvae Room", RHT_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM); - locationTable[RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8449, 0x01, "MQ GS Back Room", RHT_DODONGOS_CAVERN_MQ_GS_BACK_AREA); - locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, RCQUEST_VANILLA, SCENE_JABU_JABU, 8705, 0x01, "GS Lobby Basement Lower", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER); - locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, RCQUEST_VANILLA, SCENE_JABU_JABU, 8706, 0x02, "GS Lobby Basement Upper", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER); - locationTable[RC_JABU_JABUS_BELLY_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, RCQUEST_VANILLA, SCENE_JABU_JABU, 8708, 0x04, "GS Near Boss", RHT_JABU_JABUS_BELLY_GS_NEAR_BOSS); - locationTable[RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, RCQUEST_VANILLA, SCENE_JABU_JABU, 8712, 0x08, "GS Water Switch Room", RHT_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, RCQUEST_MQ, SCENE_JABU_JABU, 8708, 0x04, "MQ GS Tail Parasan Room", RHT_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, RCQUEST_MQ, SCENE_JABU_JABU, 8712, 0x08, "MQ GS Invisible Enemies Room", RHT_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, RCQUEST_MQ, SCENE_JABU_JABU, 8705, 0x01, "MQ GS Boomerang Chest Room", RHT_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM); - locationTable[RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, RCQUEST_MQ, SCENE_JABU_JABU, 8706, 0x02, "MQ GS Near Boss", RHT_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS); - locationTable[RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8961, 0x01, "GS Raised Island Courtyard", RHT_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD); - locationTable[RC_FOREST_TEMPLE_GS_FIRST_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_GS_FIRST_ROOM, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8962, 0x02, "GS First Room", RHT_FOREST_TEMPLE_GS_FIRST_ROOM); - locationTable[RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8964, 0x04, "GS Level Island Courtyard", RHT_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD); - locationTable[RC_FOREST_TEMPLE_GS_LOBBY] = Location::GSToken(RC_FOREST_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8968, 0x08, "GS Lobby", RHT_FOREST_TEMPLE_GS_LOBBY); - locationTable[RC_FOREST_TEMPLE_GS_BASEMENT] = Location::GSToken(RC_FOREST_TEMPLE_GS_BASEMENT, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8976, 0x10, "GS Basement", RHT_FOREST_TEMPLE_GS_BASEMENT); - locationTable[RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8962, 0x02, "MQ GS First Hallway", RHT_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY); - locationTable[RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8976, 0x10, "MQ GS Block Push Room", RHT_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM); - locationTable[RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8961, 0x01, "MQ GS Raised Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD); - locationTable[RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8964, 0x04, "MQ GS Level Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD); - locationTable[RC_FOREST_TEMPLE_MQ_GS_WELL] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_WELL, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8968, 0x08, "MQ GS Well", RHT_FOREST_TEMPLE_MQ_GS_WELL); + locationTable[RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8449, 0x01, "GS Vines Above Stairs", RHT_DODONGOS_CAVERN_GS_VINES_ABOVE_STAIRS); + locationTable[RC_DODONGOS_CAVERN_GS_SCARECROW] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SCARECROW, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8450, 0x02, "GS Scarecrow", RHT_DODONGOS_CAVERN_GS_SCARECROW); + locationTable[RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8452, 0x04, "GS Alcove Above Stairs", RHT_DODONGOS_CAVERN_GS_ALCOVE_ABOVE_STAIRS); + locationTable[RC_DODONGOS_CAVERN_GS_BACK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_GS_BACK_ROOM, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8456, 0x08, "GS Back Room", RHT_DODONGOS_CAVERN_GS_BACK_ROOM); + locationTable[RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::GSToken(RC_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 8464, 0x10, "GS Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_GS_SIDE_ROOM_NEAR_LOWER_LIZALFOS); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8450, 0x02, "MQ GS Scrub Room", RHT_DODONGOS_CAVERN_MQ_GS_SCRUB_ROOM); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8456, 0x08, "MQ GS Song of Time Block Room", RHT_DODONGOS_CAVERN_MQ_GS_SONG_OF_TIME_BLOCK_ROOM); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8452, 0x04, "MQ GS Lizalfos Room", RHT_DODONGOS_CAVERN_MQ_GS_LIZALFOS_ROOM); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8464, 0x10, "MQ GS Larvae Room", RHT_DODONGOS_CAVERN_MQ_GS_LARVAE_ROOM); + locationTable[RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA] = Location::GSToken(RC_DODONGOS_CAVERN_MQ_GS_BACK_AREA, RCQUEST_MQ, SCENE_DODONGOS_CAVERN, 8449, 0x01, "MQ GS Back Room", RHT_DODONGOS_CAVERN_MQ_GS_BACK_AREA); + locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER, RCQUEST_VANILLA, SCENE_JABU_JABU, 8705, 0x01, "GS Lobby Basement Lower", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_LOWER); + locationTable[RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER, RCQUEST_VANILLA, SCENE_JABU_JABU, 8706, 0x02, "GS Lobby Basement Upper", RHT_JABU_JABUS_BELLY_GS_LOBBY_BASEMENT_UPPER); + locationTable[RC_JABU_JABUS_BELLY_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_NEAR_BOSS, RCQUEST_VANILLA, SCENE_JABU_JABU, 8708, 0x04, "GS Near Boss", RHT_JABU_JABUS_BELLY_GS_NEAR_BOSS); + locationTable[RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM, RCQUEST_VANILLA, SCENE_JABU_JABU, 8712, 0x08, "GS Water Switch Room", RHT_JABU_JABUS_BELLY_GS_WATER_SWITCH_ROOM); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, RCQUEST_MQ, SCENE_JABU_JABU, 8708, 0x04, "MQ GS Tail Parasan Room", RHT_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM, RCQUEST_MQ, SCENE_JABU_JABU, 8712, 0x08, "MQ GS Invisible Enemies Room", RHT_JABU_JABUS_BELLY_MQ_GS_INVISIBLE_ENEMIES_ROOM); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM, RCQUEST_MQ, SCENE_JABU_JABU, 8705, 0x01, "MQ GS Boomerang Chest Room", RHT_JABU_JABUS_BELLY_MQ_GS_BOOMERANG_CHEST_ROOM); + locationTable[RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS, RCQUEST_MQ, SCENE_JABU_JABU, 8706, 0x02, "MQ GS Near Boss", RHT_JABU_JABUS_BELLY_MQ_GS_NEAR_BOSS); + locationTable[RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8961, 0x01, "GS Raised Island Courtyard", RHT_FOREST_TEMPLE_GS_RAISED_ISLAND_COURTYARD); + locationTable[RC_FOREST_TEMPLE_GS_FIRST_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_GS_FIRST_ROOM, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8962, 0x02, "GS First Room", RHT_FOREST_TEMPLE_GS_FIRST_ROOM); + locationTable[RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8964, 0x04, "GS Level Island Courtyard", RHT_FOREST_TEMPLE_GS_LEVEL_ISLAND_COURTYARD); + locationTable[RC_FOREST_TEMPLE_GS_LOBBY] = Location::GSToken(RC_FOREST_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8968, 0x08, "GS Lobby", RHT_FOREST_TEMPLE_GS_LOBBY); + locationTable[RC_FOREST_TEMPLE_GS_BASEMENT] = Location::GSToken(RC_FOREST_TEMPLE_GS_BASEMENT, RCQUEST_VANILLA, SCENE_FOREST_TEMPLE, 8976, 0x10, "GS Basement", RHT_FOREST_TEMPLE_GS_BASEMENT); + locationTable[RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8962, 0x02, "MQ GS First Hallway", RHT_FOREST_TEMPLE_MQ_GS_FIRST_HALLWAY); + locationTable[RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8976, 0x10, "MQ GS Block Push Room", RHT_FOREST_TEMPLE_MQ_GS_BLOCK_PUSH_ROOM); + locationTable[RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8961, 0x01, "MQ GS Raised Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD); + locationTable[RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8964, 0x04, "MQ GS Level Island Courtyard", RHT_FOREST_TEMPLE_MQ_GS_LEVEL_ISLAND_COURTYARD); + locationTable[RC_FOREST_TEMPLE_MQ_GS_WELL] = Location::GSToken(RC_FOREST_TEMPLE_MQ_GS_WELL, RCQUEST_MQ, SCENE_FOREST_TEMPLE, 8968, 0x08, "MQ GS Well", RHT_FOREST_TEMPLE_MQ_GS_WELL); // Fire Temple - locationTable[RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9217, 0x01, "GS Song of Time Room", RHT_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM); - locationTable[RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9218, 0x02, "GS Boss Key Loop", RHT_FIRE_TEMPLE_GS_BOSS_KEY_LOOP); - locationTable[RC_FIRE_TEMPLE_GS_BOULDER_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9220, 0x04, "GS Boulder Maze", RHT_FIRE_TEMPLE_GS_BOULDER_MAZE); - locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_TOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9224, 0x08, "GS Scarecrow Top", RHT_FIRE_TEMPLE_GS_SCARECROW_TOP); - locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9232, 0x10, "GS Scarecrow Climb", RHT_FIRE_TEMPLE_GS_SCARECROW_CLIMB); - locationTable[RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_MAZE, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9218, 0x02, "MQ GS Above Fire Wall Maze", RHT_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE); - locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9224, 0x08, "MQ GS Fire Wall Maze Center", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER); - locationTable[RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9217, 0x01, "MQ GS Big Lava Room Open Door", RHT_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR); - locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9232, 0x10, "MQ GS Fire Wall Maze Side Room", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM); - locationTable[RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9220, 0x04, "MQ GS Skull on Fire", RHT_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE); + locationTable[RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9217, 0x01, "GS Song of Time Room", RHT_FIRE_TEMPLE_GS_SONG_OF_TIME_ROOM); + locationTable[RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOSS_KEY_LOOP, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9218, 0x02, "GS Boss Key Loop", RHT_FIRE_TEMPLE_GS_BOSS_KEY_LOOP); + locationTable[RC_FIRE_TEMPLE_GS_BOULDER_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9220, 0x04, "GS Boulder Maze", RHT_FIRE_TEMPLE_GS_BOULDER_MAZE); + locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_TOP] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_TOP, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9224, 0x08, "GS Scarecrow Top", RHT_FIRE_TEMPLE_GS_SCARECROW_TOP); + locationTable[RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB] = Location::GSToken(RC_FIRE_TEMPLE_GS_SCARECROW_CLIMB, RCQUEST_VANILLA, SCENE_FIRE_TEMPLE, 9232, 0x10, "GS Scarecrow Climb", RHT_FIRE_TEMPLE_GS_SCARECROW_CLIMB); + locationTable[RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_MAZE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_MAZE, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9218, 0x02, "MQ GS Above Fire Wall Maze", RHT_FIRE_TEMPLE_MQ_GS_ABOVE_FIRE_WALL_MAZE); + locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9224, 0x08, "MQ GS Fire Wall Maze Center", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_CENTER); + locationTable[RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9217, 0x01, "MQ GS Big Lava Room Open Door", RHT_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR); + locationTable[RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9232, 0x10, "MQ GS Fire Wall Maze Side Room", RHT_FIRE_TEMPLE_MQ_GS_FIRE_WALL_MAZE_SIDE_ROOM); + locationTable[RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE] = Location::GSToken(RC_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE, RCQUEST_MQ, SCENE_FIRE_TEMPLE, 9220, 0x04, "MQ GS Skull on Fire", RHT_FIRE_TEMPLE_MQ_GS_SKULL_ON_FIRE); // Water Temple - locationTable[RC_WATER_TEMPLE_GS_BEHIND_GATE] = Location::GSToken(RC_WATER_TEMPLE_GS_BEHIND_GATE, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9473, 0x01, "GS Behind Gate", RHT_WATER_TEMPLE_GS_BEHIND_GATE); - locationTable[RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM] = Location::GSToken(RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9474, 0x02, "GS Falling Platform Room", RHT_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM); - locationTable[RC_WATER_TEMPLE_GS_CENTRAL_PILLAR] = Location::GSToken(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9476, 0x04, "GS Central Pillar", RHT_WATER_TEMPLE_GS_CENTRAL_PILLAR); - locationTable[RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST] = Location::GSToken(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9480, 0x08, "GS Near Boss Key Chest", RHT_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST); - locationTable[RC_WATER_TEMPLE_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_GS_RIVER, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9488, 0x10, "GS River", RHT_WATER_TEMPLE_GS_RIVER); - locationTable[RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9476, 0x04, "MQ GS Before Upper Water Switch", RHT_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH); - locationTable[RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9480, 0x08, "MQ GS Freestanding Key Area", RHT_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA); - locationTable[RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9473, 0x01, "MQ GS Lizalfos Hallway", RHT_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY); - locationTable[RC_WATER_TEMPLE_MQ_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_RIVER, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9474, 0x02, "MQ GS River", RHT_WATER_TEMPLE_MQ_GS_RIVER); - locationTable[RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9488, 0x10, "MQ GS Triple Wall Torch", RHT_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH); + locationTable[RC_WATER_TEMPLE_GS_BEHIND_GATE] = Location::GSToken(RC_WATER_TEMPLE_GS_BEHIND_GATE, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9473, 0x01, "GS Behind Gate", RHT_WATER_TEMPLE_GS_BEHIND_GATE); + locationTable[RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM] = Location::GSToken(RC_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9474, 0x02, "GS Falling Platform Room", RHT_WATER_TEMPLE_GS_FALLING_PLATFORM_ROOM); + locationTable[RC_WATER_TEMPLE_GS_CENTRAL_PILLAR] = Location::GSToken(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9476, 0x04, "GS Central Pillar", RHT_WATER_TEMPLE_GS_CENTRAL_PILLAR); + locationTable[RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST] = Location::GSToken(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9480, 0x08, "GS Near Boss Key Chest", RHT_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST); + locationTable[RC_WATER_TEMPLE_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_GS_RIVER, RCQUEST_VANILLA, SCENE_WATER_TEMPLE, 9488, 0x10, "GS River", RHT_WATER_TEMPLE_GS_RIVER); + locationTable[RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9476, 0x04, "MQ GS Before Upper Water Switch", RHT_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH); + locationTable[RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9480, 0x08, "MQ GS Freestanding Key Area", RHT_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA); + locationTable[RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9473, 0x01, "MQ GS Lizalfos Hallway", RHT_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY); + locationTable[RC_WATER_TEMPLE_MQ_GS_RIVER] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_RIVER, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9474, 0x02, "MQ GS River", RHT_WATER_TEMPLE_MQ_GS_RIVER); + locationTable[RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH] = Location::GSToken(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, RCQUEST_MQ, SCENE_WATER_TEMPLE, 9488, 0x10, "MQ GS Triple Wall Torch", RHT_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH); // Spirit Temple - locationTable[RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "GS Hall After Sun Block Room", RHT_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM); - locationTable[RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "GS Boulder Room", RHT_SPIRIT_TEMPLE_GS_BOULDER_ROOM); - locationTable[RC_SPIRIT_TEMPLE_GS_LOBBY] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "GS Lobby", RHT_SPIRIT_TEMPLE_GS_LOBBY); - locationTable[RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "GS Sun on Floor Room", RHT_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM); - locationTable[RC_SPIRIT_TEMPLE_GS_METAL_FENCE] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "GS Metal Fence", RHT_SPIRIT_TEMPLE_GS_METAL_FENCE); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "MQ GS Symphony Room", RHT_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "MQ GS Leever Room", RHT_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "MQ GS Nine Thrones Room West", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "MQ GS Nine Thrones Room North", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH); - locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "MQ GS Sun Block Room", RHT_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM); + locationTable[RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "GS Hall After Sun Block Room", RHT_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM); + locationTable[RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_BOULDER_ROOM, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "GS Boulder Room", RHT_SPIRIT_TEMPLE_GS_BOULDER_ROOM); + locationTable[RC_SPIRIT_TEMPLE_GS_LOBBY] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_LOBBY, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "GS Lobby", RHT_SPIRIT_TEMPLE_GS_LOBBY); + locationTable[RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "GS Sun on Floor Room", RHT_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM); + locationTable[RC_SPIRIT_TEMPLE_GS_METAL_FENCE] = Location::GSToken(RC_SPIRIT_TEMPLE_GS_METAL_FENCE, RCQUEST_VANILLA, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "GS Metal Fence", RHT_SPIRIT_TEMPLE_GS_METAL_FENCE); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9736, 0x08, "MQ GS Symphony Room", RHT_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9730, 0x02, "MQ GS Leever Room", RHT_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9732, 0x04, "MQ GS Nine Thrones Room West", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9744, 0x10, "MQ GS Nine Thrones Room North", RHT_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH); + locationTable[RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM] = Location::GSToken(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, RCQUEST_MQ, SCENE_SPIRIT_TEMPLE, 9729, 0x01, "MQ GS Sun Block Room", RHT_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM); // Shadow Temple - locationTable[RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9985, 0x01, "GS Single Giant Pot", RHT_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT); - locationTable[RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9986, 0x02, "GS Falling Spikes Room", RHT_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM); - locationTable[RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9988, 0x04, "GS Triple Giant Pot", RHT_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT); - locationTable[RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9992, 0x08, "GS Like Like Room", RHT_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM); - locationTable[RC_SHADOW_TEMPLE_GS_NEAR_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 10000, 0x10, "GS Near Ship", RHT_SHADOW_TEMPLE_GS_NEAR_SHIP); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9986, 0x02, "MQ GS Falling Spikes Room", RHT_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9985, 0x01, "MQ GS Wind Hint Room", RHT_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9992, 0x08, "MQ GS After Wind", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_WIND); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 10000, 0x10, "MQ GS After Ship", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP); - locationTable[RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9988, 0x04, "MQ GS Near Boss", RHT_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS); + locationTable[RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9985, 0x01, "GS Single Giant Pot", RHT_SHADOW_TEMPLE_GS_SINGLE_GIANT_POT); + locationTable[RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9986, 0x02, "GS Falling Spikes Room", RHT_SHADOW_TEMPLE_GS_FALLING_SPIKES_ROOM); + locationTable[RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT] = Location::GSToken(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9988, 0x04, "GS Triple Giant Pot", RHT_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT); + locationTable[RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 9992, 0x08, "GS Like Like Room", RHT_SHADOW_TEMPLE_GS_LIKE_LIKE_ROOM); + locationTable[RC_SHADOW_TEMPLE_GS_NEAR_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, RCQUEST_VANILLA, SCENE_SHADOW_TEMPLE, 10000, 0x10, "GS Near Ship", RHT_SHADOW_TEMPLE_GS_NEAR_SHIP); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9986, 0x02, "MQ GS Falling Spikes Room", RHT_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9985, 0x01, "MQ GS Wind Hint Room", RHT_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9992, 0x08, "MQ GS After Wind", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_WIND); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 10000, 0x10, "MQ GS After Ship", RHT_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP); + locationTable[RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS] = Location::GSToken(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, RCQUEST_MQ, SCENE_SHADOW_TEMPLE, 9988, 0x04, "MQ GS Near Boss", RHT_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS); // Bottom of the Well - locationTable[RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, RCQUEST_VANILLA, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "GS Like Like Cage", RHT_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE); - locationTable[RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, RCQUEST_VANILLA, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "GS East Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM); - locationTable[RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, RCQUEST_VANILLA, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, RCQUEST_MQ, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "MQ GS Basement", RHT_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, RCQUEST_MQ, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "MQ GS Coffin Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM); - locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, RCQUEST_MQ, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "MQ GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM); + locationTable[RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE, RCQUEST_VANILLA, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "GS Like Like Cage", RHT_BOTTOM_OF_THE_WELL_GS_LIKE_LIKE_CAGE); + locationTable[RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, RCQUEST_VANILLA, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "GS East Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM); + locationTable[RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, RCQUEST_VANILLA, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT, RCQUEST_MQ, SCENE_BOTTOM_OF_THE_WELL, 10241, 0x01, "MQ GS Basement", RHT_BOTTOM_OF_THE_WELL_MQ_GS_BASEMENT); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM, RCQUEST_MQ, SCENE_BOTTOM_OF_THE_WELL, 10244, 0x04, "MQ GS Coffin Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_COFFIN_ROOM); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM] = Location::GSToken(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, RCQUEST_MQ, SCENE_BOTTOM_OF_THE_WELL, 10242, 0x02, "MQ GS West Inner Room", RHT_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM); // Ice Cavern - locationTable[RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, RCQUEST_VANILLA, SCENE_ICE_CAVERN, 10497, 0x01, "GS Push Block Room", RHT_ICE_CAVERN_GS_PUSH_BLOCK_ROOM); - locationTable[RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, RCQUEST_VANILLA, SCENE_ICE_CAVERN, 10498, 0x02, "GS Spinning Scythe Room", RHT_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM); - locationTable[RC_ICE_CAVERN_GS_HEART_PIECE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, RCQUEST_VANILLA, SCENE_ICE_CAVERN, 10500, 0x04, "GS Heart Piece Room", RHT_ICE_CAVERN_GS_HEART_PIECE_ROOM); - locationTable[RC_ICE_CAVERN_MQ_GS_SCARECROW] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_SCARECROW, RCQUEST_MQ, SCENE_ICE_CAVERN, 10497, 0x01, "MQ GS Scarecrow", RHT_ICE_CAVERN_MQ_GS_SCARECROW); - locationTable[RC_ICE_CAVERN_MQ_GS_ICE_BLOCK] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, RCQUEST_MQ, SCENE_ICE_CAVERN, 10500, 0x04, "MQ GS Ice Block", RHT_ICE_CAVERN_MQ_GS_ICE_BLOCK); - locationTable[RC_ICE_CAVERN_MQ_GS_RED_ICE] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_RED_ICE, RCQUEST_MQ, SCENE_ICE_CAVERN, 10498, 0x02, "MQ GS Red Ice", RHT_ICE_CAVERN_MQ_GS_RED_ICE); + locationTable[RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_PUSH_BLOCK_ROOM, RCQUEST_VANILLA, SCENE_ICE_CAVERN, 10497, 0x01, "GS Push Block Room", RHT_ICE_CAVERN_GS_PUSH_BLOCK_ROOM); + locationTable[RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, RCQUEST_VANILLA, SCENE_ICE_CAVERN, 10498, 0x02, "GS Spinning Scythe Room", RHT_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM); + locationTable[RC_ICE_CAVERN_GS_HEART_PIECE_ROOM] = Location::GSToken(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, RCQUEST_VANILLA, SCENE_ICE_CAVERN, 10500, 0x04, "GS Heart Piece Room", RHT_ICE_CAVERN_GS_HEART_PIECE_ROOM); + locationTable[RC_ICE_CAVERN_MQ_GS_SCARECROW] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_SCARECROW, RCQUEST_MQ, SCENE_ICE_CAVERN, 10497, 0x01, "MQ GS Scarecrow", RHT_ICE_CAVERN_MQ_GS_SCARECROW); + locationTable[RC_ICE_CAVERN_MQ_GS_ICE_BLOCK] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_ICE_BLOCK, RCQUEST_MQ, SCENE_ICE_CAVERN, 10500, 0x04, "MQ GS Ice Block", RHT_ICE_CAVERN_MQ_GS_ICE_BLOCK); + locationTable[RC_ICE_CAVERN_MQ_GS_RED_ICE] = Location::GSToken(RC_ICE_CAVERN_MQ_GS_RED_ICE, RCQUEST_MQ, SCENE_ICE_CAVERN, 10498, 0x02, "MQ GS Red Ice", RHT_ICE_CAVERN_MQ_GS_RED_ICE); // Overworld // Kokiri Forest - locationTable[RC_KF_GS_BEAN_PATCH] = Location::GSToken(RC_KF_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 27649, 0x01, "GS Bean Patch", RHT_KF_GS_BEAN_PATCH, 0x0C); - locationTable[RC_KF_GS_KNOW_IT_ALL_HOUSE] = Location::GSToken(RC_KF_GS_KNOW_IT_ALL_HOUSE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 19458, 0x02, "GS Know It All House", RHT_KF_GS_KNOW_IT_ALL_HOUSE, 0x0C); - locationTable[RC_KF_GS_HOUSE_OF_TWINS] = Location::GSToken(RC_KF_GS_HOUSE_OF_TWINS, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 19460, 0x04, "GS House of Twins", RHT_KF_GS_HOUSE_OF_TWINS, 0x0C); + locationTable[RC_KF_GS_BEAN_PATCH] = Location::GSToken(RC_KF_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 27649, 0x01, "GS Bean Patch", RHT_KF_GS_BEAN_PATCH, 0x0C); + locationTable[RC_KF_GS_KNOW_IT_ALL_HOUSE] = Location::GSToken(RC_KF_GS_KNOW_IT_ALL_HOUSE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 19458, 0x02, "GS Know It All House", RHT_KF_GS_KNOW_IT_ALL_HOUSE, 0x0C); + locationTable[RC_KF_GS_HOUSE_OF_TWINS] = Location::GSToken(RC_KF_GS_HOUSE_OF_TWINS, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 19460, 0x04, "GS House of Twins", RHT_KF_GS_HOUSE_OF_TWINS, 0x0C); // Lost Woods - locationTable[RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, RCQUEST_BOTH, SCENE_LOST_WOODS, 27905, 0x01, "GS Bean Patch Near Bridge", RHT_LW_GS_BEAN_PATCH_NEAR_BRIDGE, 0x0D); - locationTable[RC_LW_GS_BEAN_PATCH_NEAR_THEATER] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, RCQUEST_BOTH, SCENE_LOST_WOODS, 27906, 0x02, "GS Bean Patch Near Theater", RHT_LW_GS_BEAN_PATCH_NEAR_THEATER, 0x0D); - locationTable[RC_LW_GS_ABOVE_THEATER] = Location::GSToken(RC_LW_GS_ABOVE_THEATER, RCQUEST_BOTH, SCENE_LOST_WOODS, 19716, 0x04, "GS Above Theater", RHT_LW_GS_ABOVE_THEATER, 0x0D); - locationTable[RC_SFM_GS] = Location::GSToken(RC_SFM_GS, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 19720, 0x08, "GS", RHT_SFM_GS, 0x0D); + locationTable[RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, RCQUEST_BOTH, SCENE_LOST_WOODS, 27905, 0x01, "GS Bean Patch Near Bridge", RHT_LW_GS_BEAN_PATCH_NEAR_BRIDGE, 0x0D); + locationTable[RC_LW_GS_BEAN_PATCH_NEAR_THEATER] = Location::GSToken(RC_LW_GS_BEAN_PATCH_NEAR_THEATER, RCQUEST_BOTH, SCENE_LOST_WOODS, 27906, 0x02, "GS Bean Patch Near Theater", RHT_LW_GS_BEAN_PATCH_NEAR_THEATER, 0x0D); + locationTable[RC_LW_GS_ABOVE_THEATER] = Location::GSToken(RC_LW_GS_ABOVE_THEATER, RCQUEST_BOTH, SCENE_LOST_WOODS, 19716, 0x04, "GS Above Theater", RHT_LW_GS_ABOVE_THEATER, 0x0D); + locationTable[RC_SFM_GS] = Location::GSToken(RC_SFM_GS, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 19720, 0x08, "GS", RHT_SFM_GS, 0x0D); // Hyrule Field - locationTable[RC_HF_GS_COW_GROTTO] = Location::GSToken(RC_HF_GS_COW_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10753, 0x01, "GS Cow Grotto", RHT_HF_GS_COW_GROTTO, 0x0A); - locationTable[RC_HF_GS_NEAR_KAK_GROTTO] = Location::GSToken(RC_HF_GS_NEAR_KAK_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10754, 0x02, "GS Near Kak Grotto", RHT_HF_GS_NEAR_KAK_GROTTO, 0x0A); + locationTable[RC_HF_GS_COW_GROTTO] = Location::GSToken(RC_HF_GS_COW_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10753, 0x01, "GS Cow Grotto", RHT_HF_GS_COW_GROTTO, 0x0A); + locationTable[RC_HF_GS_NEAR_KAK_GROTTO] = Location::GSToken(RC_HF_GS_NEAR_KAK_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 10754, 0x02, "GS Near Kak Grotto", RHT_HF_GS_NEAR_KAK_GROTTO, 0x0A); // Lake Hylia - locationTable[RC_LH_GS_BEAN_PATCH] = Location::GSToken(RC_LH_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 29185, 0x01, "GS Bean Patch", RHT_LH_GS_BEAN_PATCH, 0x12); - locationTable[RC_LH_GS_SMALL_ISLAND] = Location::GSToken(RC_LH_GS_SMALL_ISLAND, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 20994, 0x02, "GS Small Island", RHT_LH_GS_SMALL_ISLAND, 0x12); - locationTable[RC_LH_GS_LAB_WALL] = Location::GSToken(RC_LH_GS_LAB_WALL, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 20996, 0x04, "GS Lab Wall", RHT_LH_GS_LAB_WALL, 0x12); - locationTable[RC_LH_GS_LAB_CRATE] = Location::GSToken(RC_LH_GS_LAB_CRATE, RCQUEST_BOTH, SCENE_LAKESIDE_LABORATORY, -28152, 0x08, "GS Lab Crate", RHT_LH_GS_LAB_CRATE, 0x12); - locationTable[RC_LH_GS_TREE] = Location::GSToken(RC_LH_GS_TREE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 21008, 0x10, "GS Tree", RHT_LH_GS_TREE, 0x12); + locationTable[RC_LH_GS_BEAN_PATCH] = Location::GSToken(RC_LH_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 29185, 0x01, "GS Bean Patch", RHT_LH_GS_BEAN_PATCH, 0x12); + locationTable[RC_LH_GS_SMALL_ISLAND] = Location::GSToken(RC_LH_GS_SMALL_ISLAND, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 20994, 0x02, "GS Small Island", RHT_LH_GS_SMALL_ISLAND, 0x12); + locationTable[RC_LH_GS_LAB_WALL] = Location::GSToken(RC_LH_GS_LAB_WALL, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 20996, 0x04, "GS Lab Wall", RHT_LH_GS_LAB_WALL, 0x12); + locationTable[RC_LH_GS_LAB_CRATE] = Location::GSToken(RC_LH_GS_LAB_CRATE, RCQUEST_BOTH, SCENE_LAKESIDE_LABORATORY, -28152, 0x08, "GS Lab Crate", RHT_LH_GS_LAB_CRATE, 0x12); + locationTable[RC_LH_GS_TREE] = Location::GSToken(RC_LH_GS_TREE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 21008, 0x10, "GS Tree", RHT_LH_GS_TREE, 0x12); // Gerudo Valley - locationTable[RC_GV_GS_BEAN_PATCH] = Location::GSToken(RC_GV_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 29441, 0x01, "GS Bean Patch", RHT_GV_GS_BEAN_PATCH, 0x13); - locationTable[RC_GV_GS_SMALL_BRIDGE] = Location::GSToken(RC_GV_GS_SMALL_BRIDGE, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21250, 0x02, "GS Small Bridge", RHT_GV_GS_SMALL_BRIDGE, 0x13); - locationTable[RC_GV_GS_PILLAR] = Location::GSToken(RC_GV_GS_PILLAR, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21252, 0x04, "GS Pillar", RHT_GV_GS_PILLAR, 0x13); - locationTable[RC_GV_GS_BEHIND_TENT] = Location::GSToken(RC_GV_GS_BEHIND_TENT, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21256, 0x08, "GS Behind Tent", RHT_GV_GS_BEHIND_TENT, 0x13); + locationTable[RC_GV_GS_BEAN_PATCH] = Location::GSToken(RC_GV_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 29441, 0x01, "GS Bean Patch", RHT_GV_GS_BEAN_PATCH, 0x13); + locationTable[RC_GV_GS_SMALL_BRIDGE] = Location::GSToken(RC_GV_GS_SMALL_BRIDGE, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21250, 0x02, "GS Small Bridge", RHT_GV_GS_SMALL_BRIDGE, 0x13); + locationTable[RC_GV_GS_PILLAR] = Location::GSToken(RC_GV_GS_PILLAR, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21252, 0x04, "GS Pillar", RHT_GV_GS_PILLAR, 0x13); + locationTable[RC_GV_GS_BEHIND_TENT] = Location::GSToken(RC_GV_GS_BEHIND_TENT, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 21256, 0x08, "GS Behind Tent", RHT_GV_GS_BEHIND_TENT, 0x13); // Gerudo Fortress - locationTable[RC_GF_GS_ARCHERY_RANGE] = Location::GSToken(RC_GF_GS_ARCHERY_RANGE, RCQUEST_BOTH, SCENE_GERUDOS_FORTRESS, 21505, 0x01, "GS Archery Range", RHT_GF_GS_ARCHERY_RANGE, 0x14); - locationTable[RC_GF_GS_TOP_FLOOR] = Location::GSToken(RC_GF_GS_TOP_FLOOR, RCQUEST_BOTH, SCENE_GERUDOS_FORTRESS, 21506, 0x02, "GS Top Floor", RHT_GF_GS_TOP_FLOOR, 0x14); + locationTable[RC_GF_GS_ARCHERY_RANGE] = Location::GSToken(RC_GF_GS_ARCHERY_RANGE, RCQUEST_BOTH, SCENE_GERUDOS_FORTRESS, 21505, 0x01, "GS Archery Range", RHT_GF_GS_ARCHERY_RANGE, 0x14); + locationTable[RC_GF_GS_TOP_FLOOR] = Location::GSToken(RC_GF_GS_TOP_FLOOR, RCQUEST_BOTH, SCENE_GERUDOS_FORTRESS, 21506, 0x02, "GS Top Floor", RHT_GF_GS_TOP_FLOOR, 0x14); // Wasteland & Desert Colossus - locationTable[RC_WASTELAND_GS] = Location::GSToken(RC_WASTELAND_GS, RCQUEST_BOTH, SCENE_HAUNTED_WASTELAND, 13570, 0x02, "GS", RHT_WASTELAND_GS, 0x15); - locationTable[RC_COLOSSUS_GS_BEAN_PATCH] = Location::GSToken(RC_COLOSSUS_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 29953, 0x01, "GS Bean Patch", RHT_COLOSSUS_GS_BEAN_PATCH, 0x15); - locationTable[RC_COLOSSUS_GS_HILL] = Location::GSToken(RC_COLOSSUS_GS_HILL, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 21764, 0x04, "GS Hill", RHT_COLOSSUS_GS_HILL, 0x15); - locationTable[RC_COLOSSUS_GS_TREE] = Location::GSToken(RC_COLOSSUS_GS_TREE, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 21768, 0x08, "GS Tree", RHT_COLOSSUS_GS_TREE, 0x15); + locationTable[RC_WASTELAND_GS] = Location::GSToken(RC_WASTELAND_GS, RCQUEST_BOTH, SCENE_HAUNTED_WASTELAND, 13570, 0x02, "GS", RHT_WASTELAND_GS, 0x15); + locationTable[RC_COLOSSUS_GS_BEAN_PATCH] = Location::GSToken(RC_COLOSSUS_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 29953, 0x01, "GS Bean Patch", RHT_COLOSSUS_GS_BEAN_PATCH, 0x15); + locationTable[RC_COLOSSUS_GS_HILL] = Location::GSToken(RC_COLOSSUS_GS_HILL, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 21764, 0x04, "GS Hill", RHT_COLOSSUS_GS_HILL, 0x15); + locationTable[RC_COLOSSUS_GS_TREE] = Location::GSToken(RC_COLOSSUS_GS_TREE, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 21768, 0x08, "GS Tree", RHT_COLOSSUS_GS_TREE, 0x15); // Hyrule Castle, Market, and Outside Ganon's Castle - locationTable[RC_OGC_GS] = Location::GSToken(RC_OGC_GS, RCQUEST_BOTH, SCENE_OUTSIDE_GANONS_CASTLE, 11777, 0x01, "OGC GS", RHT_OGC_GS, 0x0E); - locationTable[RC_HC_GS_STORMS_GROTTO] = Location::GSToken(RC_HC_GS_STORMS_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 11778, 0x02, "GS Storms Grotto", RHT_HC_GS_STORMS_GROTTO, 0x0E); - locationTable[RC_HC_GS_TREE] = Location::GSToken(RC_HC_GS_TREE, RCQUEST_BOTH, SCENE_HYRULE_CASTLE, -29180, 0x04, "GS Tree", RHT_HC_GS_TREE, 0x0E); - locationTable[RC_MARKET_GS_GUARD_HOUSE] = Location::GSToken(RC_MARKET_GS_GUARD_HOUSE, RCQUEST_BOTH, SCENE_MARKET_GUARD_HOUSE, -29176, 0x08, "Market GS Guard House", RHT_MARKET_GS_GUARD_HOUSE, 0x0E); + locationTable[RC_OGC_GS] = Location::GSToken(RC_OGC_GS, RCQUEST_BOTH, SCENE_OUTSIDE_GANONS_CASTLE, 11777, 0x01, "OGC GS", RHT_OGC_GS, 0x0E); + locationTable[RC_HC_GS_STORMS_GROTTO] = Location::GSToken(RC_HC_GS_STORMS_GROTTO, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 11778, 0x02, "GS Storms Grotto", RHT_HC_GS_STORMS_GROTTO, 0x0E); + locationTable[RC_HC_GS_TREE] = Location::GSToken(RC_HC_GS_TREE, RCQUEST_BOTH, SCENE_HYRULE_CASTLE, -29180, 0x04, "GS Tree", RHT_HC_GS_TREE, 0x0E); + locationTable[RC_MARKET_GS_GUARD_HOUSE] = Location::GSToken(RC_MARKET_GS_GUARD_HOUSE, RCQUEST_BOTH, SCENE_MARKET_GUARD_HOUSE, -29176, 0x08, "Market GS Guard House", RHT_MARKET_GS_GUARD_HOUSE, 0x0E); // Kakariko - locationTable[RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION] = Location::GSToken(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20488, 0x08, "GS House Under Construction", RHT_KAK_GS_HOUSE_UNDER_CONSTRUCTION, 0x10); - locationTable[RC_KAK_GS_SKULLTULA_HOUSE] = Location::GSToken(RC_KAK_GS_SKULLTULA_HOUSE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20496, 0x10, "GS Skulltula House", RHT_KAK_GS_SKULLTULA_HOUSE, 0x10); - locationTable[RC_KAK_GS_GUARDS_HOUSE] = Location::GSToken(RC_KAK_GS_GUARDS_HOUSE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20482, 0x02, "GS Guards House", RHT_KAK_GS_GUARDS_HOUSE, 0x10); - locationTable[RC_KAK_GS_TREE] = Location::GSToken(RC_KAK_GS_TREE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, -28640, 0x20, "GS Tree", RHT_KAK_GS_TREE, 0x10); - locationTable[RC_KAK_GS_WATCHTOWER] = Location::GSToken(RC_KAK_GS_WATCHTOWER, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20484, 0x04, "GS Watchtower", RHT_KAK_GS_WATCHTOWER, 0x10); - locationTable[RC_KAK_GS_ABOVE_IMPAS_HOUSE] = Location::GSToken(RC_KAK_GS_ABOVE_IMPAS_HOUSE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20544, 0x40, "GS Above Impas House", RHT_KAK_GS_ABOVE_IMPAS_HOUSE, 0x10); + locationTable[RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION] = Location::GSToken(RC_KAK_GS_HOUSE_UNDER_CONSTRUCTION, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20488, 0x08, "GS House Under Construction", RHT_KAK_GS_HOUSE_UNDER_CONSTRUCTION, 0x10); + locationTable[RC_KAK_GS_SKULLTULA_HOUSE] = Location::GSToken(RC_KAK_GS_SKULLTULA_HOUSE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20496, 0x10, "GS Skulltula House", RHT_KAK_GS_SKULLTULA_HOUSE, 0x10); + locationTable[RC_KAK_GS_GUARDS_HOUSE] = Location::GSToken(RC_KAK_GS_GUARDS_HOUSE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20482, 0x02, "GS Guards House", RHT_KAK_GS_GUARDS_HOUSE, 0x10); + locationTable[RC_KAK_GS_TREE] = Location::GSToken(RC_KAK_GS_TREE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, -28640, 0x20, "GS Tree", RHT_KAK_GS_TREE, 0x10); + locationTable[RC_KAK_GS_WATCHTOWER] = Location::GSToken(RC_KAK_GS_WATCHTOWER, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20484, 0x04, "GS Watchtower", RHT_KAK_GS_WATCHTOWER, 0x10); + locationTable[RC_KAK_GS_ABOVE_IMPAS_HOUSE] = Location::GSToken(RC_KAK_GS_ABOVE_IMPAS_HOUSE, RCQUEST_BOTH, SCENE_KAKARIKO_VILLAGE, 20544, 0x40, "GS Above Impas House", RHT_KAK_GS_ABOVE_IMPAS_HOUSE, 0x10); // Graveyard - locationTable[RC_GRAVEYARD_GS_WALL] = Location::GSToken(RC_GRAVEYARD_GS_WALL, RCQUEST_BOTH, SCENE_GRAVEYARD, 20608, 0x80, "GS Wall", RHT_GRAVEYARD_GS_WALL, 0x10); - locationTable[RC_GRAVEYARD_GS_BEAN_PATCH] = Location::GSToken(RC_GRAVEYARD_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_GRAVEYARD, 28673, 0x01, "GS Bean Patch", RHT_GRAVEYARD_GS_BEAN_PATCH, 0x10); + locationTable[RC_GRAVEYARD_GS_WALL] = Location::GSToken(RC_GRAVEYARD_GS_WALL, RCQUEST_BOTH, SCENE_GRAVEYARD, 20608, 0x80, "GS Wall", RHT_GRAVEYARD_GS_WALL, 0x10); + locationTable[RC_GRAVEYARD_GS_BEAN_PATCH] = Location::GSToken(RC_GRAVEYARD_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_GRAVEYARD, 28673, 0x01, "GS Bean Patch", RHT_GRAVEYARD_GS_BEAN_PATCH, 0x10); // Death Mountain - locationTable[RC_DMC_GS_BEAN_PATCH] = Location::GSToken(RC_DMC_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_CRATER, 28417, 0x01, "GS Bean Patch", RHT_DMC_GS_BEAN_PATCH, 0x0F); - locationTable[RC_DMC_GS_CRATE] = Location::GSToken(RC_DMC_GS_CRATE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_CRATER, -28800, 0x80, "GS Crate", RHT_DMC_GS_CRATE, 0x0F); - locationTable[RC_DMT_GS_BEAN_PATCH] = Location::GSToken(RC_DMT_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 28418, 0x02, "GS Bean Patch", RHT_DMT_GS_BEAN_PATCH, 0x0F); - locationTable[RC_DMT_GS_NEAR_KAK] = Location::GSToken(RC_DMT_GS_NEAR_KAK, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 12036, 0x04, "GS Near Kak", RHT_DMT_GS_NEAR_KAK, 0x0F); - locationTable[RC_DMT_GS_ABOVE_DODONGOS_CAVERN] = Location::GSToken(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 20232, 0x08, "GS Above Dodongos Cavern", RHT_DMT_GS_ABOVE_DODONGOS_CAVERN, 0x0F); - locationTable[RC_DMT_GS_FALLING_ROCKS_PATH] = Location::GSToken(RC_DMT_GS_FALLING_ROCKS_PATH, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 20240, 0x10, "GS Falling Rocks Path", RHT_DMT_GS_FALLING_ROCKS_PATH, 0x0F); - locationTable[RC_GC_GS_CENTER_PLATFORM] = Location::GSToken(RC_GC_GS_CENTER_PLATFORM, RCQUEST_BOTH, SCENE_GORON_CITY, 12064, 0x20, "GS Center Platform", RHT_GC_GS_CENTER_PLATFORM, 0x0F); - locationTable[RC_GC_GS_BOULDER_MAZE] = Location::GSToken(RC_GC_GS_BOULDER_MAZE, RCQUEST_BOTH, SCENE_GORON_CITY, -28864, 0x40, "GS Boulder Maze", RHT_GC_GS_BOULDER_MAZE, 0x0F); + locationTable[RC_DMC_GS_BEAN_PATCH] = Location::GSToken(RC_DMC_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_CRATER, 28417, 0x01, "GS Bean Patch", RHT_DMC_GS_BEAN_PATCH, 0x0F); + locationTable[RC_DMC_GS_CRATE] = Location::GSToken(RC_DMC_GS_CRATE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_CRATER, -28800, 0x80, "GS Crate", RHT_DMC_GS_CRATE, 0x0F); + locationTable[RC_DMT_GS_BEAN_PATCH] = Location::GSToken(RC_DMT_GS_BEAN_PATCH, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 28418, 0x02, "GS Bean Patch", RHT_DMT_GS_BEAN_PATCH, 0x0F); + locationTable[RC_DMT_GS_NEAR_KAK] = Location::GSToken(RC_DMT_GS_NEAR_KAK, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 12036, 0x04, "GS Near Kak", RHT_DMT_GS_NEAR_KAK, 0x0F); + locationTable[RC_DMT_GS_ABOVE_DODONGOS_CAVERN] = Location::GSToken(RC_DMT_GS_ABOVE_DODONGOS_CAVERN, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 20232, 0x08, "GS Above Dodongos Cavern", RHT_DMT_GS_ABOVE_DODONGOS_CAVERN, 0x0F); + locationTable[RC_DMT_GS_FALLING_ROCKS_PATH] = Location::GSToken(RC_DMT_GS_FALLING_ROCKS_PATH, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 20240, 0x10, "GS Falling Rocks Path", RHT_DMT_GS_FALLING_ROCKS_PATH, 0x0F); + locationTable[RC_GC_GS_CENTER_PLATFORM] = Location::GSToken(RC_GC_GS_CENTER_PLATFORM, RCQUEST_BOTH, SCENE_GORON_CITY, 12064, 0x20, "GS Center Platform", RHT_GC_GS_CENTER_PLATFORM, 0x0F); + locationTable[RC_GC_GS_BOULDER_MAZE] = Location::GSToken(RC_GC_GS_BOULDER_MAZE, RCQUEST_BOTH, SCENE_GORON_CITY, -28864, 0x40, "GS Boulder Maze", RHT_GC_GS_BOULDER_MAZE, 0x0F); // Zora's River, Domain, and Fountain - locationTable[RC_ZR_GS_LADDER] = Location::GSToken(RC_ZR_GS_LADDER, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 20737, 0x01, "GS Ladder", RHT_ZR_GS_LADDER, 0x11); - locationTable[RC_ZR_GS_TREE] = Location::GSToken(RC_ZR_GS_TREE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, -28414, 0x02, "GS Tree", RHT_ZR_GS_TREE, 0x11); - locationTable[RC_ZR_GS_ABOVE_BRIDGE] = Location::GSToken(RC_ZR_GS_ABOVE_BRIDGE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 20744, 0x08, "GS Above Bridge", RHT_ZR_GS_ABOVE_BRIDGE, 0x11); - locationTable[RC_ZR_GS_NEAR_RAISED_GROTTOS] = Location::GSToken(RC_ZR_GS_NEAR_RAISED_GROTTOS, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 20752, 0x10, "GS Near Raised Grottos", RHT_ZR_GS_NEAR_RAISED_GROTTOS, 0x11); - locationTable[RC_ZD_GS_FROZEN_WATERFALL] = Location::GSToken(RC_ZD_GS_FROZEN_WATERFALL, RCQUEST_BOTH, SCENE_ZORAS_DOMAIN, 20800, 0x40, "GS Frozen Waterfall", RHT_ZD_GS_FROZEN_WATERFALL, 0x11); - locationTable[RC_ZF_GS_ABOVE_THE_LOG] = Location::GSToken(RC_ZF_GS_ABOVE_THE_LOG, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 20740, 0x04, "GS Above The Log", RHT_ZF_GS_ABOVE_THE_LOG, 0x11); - locationTable[RC_ZF_GS_HIDDEN_CAVE] = Location::GSToken(RC_ZF_GS_HIDDEN_CAVE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 20768, 0x20, "GS Hidden Cave", RHT_ZF_GS_HIDDEN_CAVE, 0x11); - locationTable[RC_ZF_GS_TREE] = Location::GSToken(RC_ZF_GS_TREE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, -28288, 0x80, "GS Tree", RHT_ZF_GS_TREE, 0x11); + locationTable[RC_ZR_GS_LADDER] = Location::GSToken(RC_ZR_GS_LADDER, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 20737, 0x01, "GS Ladder", RHT_ZR_GS_LADDER, 0x11); + locationTable[RC_ZR_GS_TREE] = Location::GSToken(RC_ZR_GS_TREE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, -28414, 0x02, "GS Tree", RHT_ZR_GS_TREE, 0x11); + locationTable[RC_ZR_GS_ABOVE_BRIDGE] = Location::GSToken(RC_ZR_GS_ABOVE_BRIDGE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 20744, 0x08, "GS Above Bridge", RHT_ZR_GS_ABOVE_BRIDGE, 0x11); + locationTable[RC_ZR_GS_NEAR_RAISED_GROTTOS] = Location::GSToken(RC_ZR_GS_NEAR_RAISED_GROTTOS, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 20752, 0x10, "GS Near Raised Grottos", RHT_ZR_GS_NEAR_RAISED_GROTTOS, 0x11); + locationTable[RC_ZD_GS_FROZEN_WATERFALL] = Location::GSToken(RC_ZD_GS_FROZEN_WATERFALL, RCQUEST_BOTH, SCENE_ZORAS_DOMAIN, 20800, 0x40, "GS Frozen Waterfall", RHT_ZD_GS_FROZEN_WATERFALL, 0x11); + locationTable[RC_ZF_GS_ABOVE_THE_LOG] = Location::GSToken(RC_ZF_GS_ABOVE_THE_LOG, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 20740, 0x04, "GS Above The Log", RHT_ZF_GS_ABOVE_THE_LOG, 0x11); + locationTable[RC_ZF_GS_HIDDEN_CAVE] = Location::GSToken(RC_ZF_GS_HIDDEN_CAVE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 20768, 0x20, "GS Hidden Cave", RHT_ZF_GS_HIDDEN_CAVE, 0x11); + locationTable[RC_ZF_GS_TREE] = Location::GSToken(RC_ZF_GS_TREE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, -28288, 0x80, "GS Tree", RHT_ZF_GS_TREE, 0x11); // Lon Lon Ranch - locationTable[RC_LLR_GS_BACK_WALL] = Location::GSToken(RC_LLR_GS_BACK_WALL, RCQUEST_BOTH, SCENE_LON_LON_RANCH, 11009, 0x01, "GS Back Wall", RHT_LLR_GS_BACK_WALL, 0x0B); - locationTable[RC_LLR_GS_RAIN_SHED] = Location::GSToken(RC_LLR_GS_RAIN_SHED, RCQUEST_BOTH, SCENE_LON_LON_RANCH, 11010, 0x02, "GS Rain Shed", RHT_LLR_GS_RAIN_SHED, 0x0B); - locationTable[RC_LLR_GS_HOUSE_WINDOW] = Location::GSToken(RC_LLR_GS_HOUSE_WINDOW, RCQUEST_BOTH, SCENE_LON_LON_RANCH, 11012, 0x04, "GS House Window", RHT_LLR_GS_HOUSE_WINDOW, 0x0B); - locationTable[RC_LLR_GS_TREE] = Location::GSToken(RC_LLR_GS_TREE, RCQUEST_BOTH, SCENE_LON_LON_RANCH, -29944, 0x08, "GS Tree", RHT_LLR_GS_TREE, 0x0B); + locationTable[RC_LLR_GS_BACK_WALL] = Location::GSToken(RC_LLR_GS_BACK_WALL, RCQUEST_BOTH, SCENE_LON_LON_RANCH, 11009, 0x01, "GS Back Wall", RHT_LLR_GS_BACK_WALL, 0x0B); + locationTable[RC_LLR_GS_RAIN_SHED] = Location::GSToken(RC_LLR_GS_RAIN_SHED, RCQUEST_BOTH, SCENE_LON_LON_RANCH, 11010, 0x02, "GS Rain Shed", RHT_LLR_GS_RAIN_SHED, 0x0B); + locationTable[RC_LLR_GS_HOUSE_WINDOW] = Location::GSToken(RC_LLR_GS_HOUSE_WINDOW, RCQUEST_BOTH, SCENE_LON_LON_RANCH, 11012, 0x04, "GS House Window", RHT_LLR_GS_HOUSE_WINDOW, 0x0B); + locationTable[RC_LLR_GS_TREE] = Location::GSToken(RC_LLR_GS_TREE, RCQUEST_BOTH, SCENE_LON_LON_RANCH, -29944, 0x08, "GS Tree", RHT_LLR_GS_TREE, 0x0B); // Bosses - locationTable[RC_LINKS_POCKET] = Location::Base(RC_LINKS_POCKET, RCQUEST_BOTH, RCTYPE_LINKS_POCKET, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Link's Pocket", "Link's Pocket", RHT_LINKS_POCKET, RG_NONE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LINKS_POCKET), true); - locationTable[RC_QUEEN_GOHMA] = Location::Base(RC_QUEEN_GOHMA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_DEKU_TREE_BOSS, 0x00, "Queen Gohma", "Queen Gohma", RHT_QUEEN_GOHMA, RG_KOKIRI_EMERALD, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP), true); - locationTable[RC_KING_DODONGO] = Location::Base(RC_KING_DODONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_DODONGOS_CAVERN_BOSS, 0x00, "King Dodongo", "King Dodongo", RHT_KING_DODONGO, RG_GORON_RUBY, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP), true); - locationTable[RC_BARINADE] = Location::Base(RC_BARINADE, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_JABU_JABU_BOSS, 0x00, "Barinade", "Barinade", RHT_BARINADE, RG_ZORA_SAPPHIRE, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP), true); - locationTable[RC_PHANTOM_GANON] = Location::Base(RC_PHANTOM_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_FOREST_TEMPLE_BOSS, 0x00, "Phantom Ganon", "Phantom Ganon", RHT_PHANTOM_GANON, RG_FOREST_MEDALLION, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), true); - locationTable[RC_VOLVAGIA] = Location::Base(RC_VOLVAGIA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_FIRE_TEMPLE_BOSS, 0x00, "Volvagia", "Volvagia", RHT_VOLVAGIA, RG_FIRE_MEDALLION, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP), true); - locationTable[RC_MORPHA] = Location::Base(RC_MORPHA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_WATER_TEMPLE_BOSS, 0x00, "Morpha", "Morpha", RHT_MORPHA, RG_WATER_MEDALLION, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP), true); - locationTable[RC_TWINROVA] = Location::Base(RC_TWINROVA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, "Twinrova", "Twinrova", RHT_TWINROVA, RG_SPIRIT_MEDALLION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE), true); - locationTable[RC_BONGO_BONGO] = Location::Base(RC_BONGO_BONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_SHADOW_TEMPLE_BOSS, 0x00, "Bongo Bongo", "Bongo Bongo", RHT_BONGO_BONGO, RG_SHADOW_MEDALLION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE), true); + locationTable[RC_LINKS_POCKET] = Location::Base(RC_LINKS_POCKET, RCQUEST_BOTH, RCTYPE_LINKS_POCKET, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Link's Pocket", "Link's Pocket", RHT_LINKS_POCKET, RG_NONE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LINKS_POCKET), true); + locationTable[RC_QUEEN_GOHMA] = Location::Base(RC_QUEEN_GOHMA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_DEKU_TREE_BOSS, 0x00, "Queen Gohma", "Queen Gohma", RHT_QUEEN_GOHMA, RG_KOKIRI_EMERALD, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP), true); + locationTable[RC_KING_DODONGO] = Location::Base(RC_KING_DODONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_DODONGOS_CAVERN_BOSS, 0x00, "King Dodongo", "King Dodongo", RHT_KING_DODONGO, RG_GORON_RUBY, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP), true); + locationTable[RC_BARINADE] = Location::Base(RC_BARINADE, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_JABU_JABU_BOSS, 0x00, "Barinade", "Barinade", RHT_BARINADE, RG_ZORA_SAPPHIRE, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP), true); + locationTable[RC_PHANTOM_GANON] = Location::Base(RC_PHANTOM_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_FOREST_TEMPLE_BOSS, 0x00, "Phantom Ganon", "Phantom Ganon", RHT_PHANTOM_GANON, RG_FOREST_MEDALLION, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP), true); + locationTable[RC_VOLVAGIA] = Location::Base(RC_VOLVAGIA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_FIRE_TEMPLE_BOSS, 0x00, "Volvagia", "Volvagia", RHT_VOLVAGIA, RG_FIRE_MEDALLION, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP), true); + locationTable[RC_MORPHA] = Location::Base(RC_MORPHA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_WATER_TEMPLE_BOSS, 0x00, "Morpha", "Morpha", RHT_MORPHA, RG_WATER_MEDALLION, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP), true); + locationTable[RC_TWINROVA] = Location::Base(RC_TWINROVA, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, "Twinrova", "Twinrova", RHT_TWINROVA, RG_SPIRIT_MEDALLION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE), true); + locationTable[RC_BONGO_BONGO] = Location::Base(RC_BONGO_BONGO, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_SHADOW_TEMPLE_BOSS, 0x00, "Bongo Bongo", "Bongo Bongo", RHT_BONGO_BONGO, RG_SHADOW_MEDALLION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE), true); locationTable[RC_GANON] = Location::Base(RC_GANON, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, ACTOR_DOOR_WARP1, SCENE_GANON_BOSS, 0x00, "Ganon", "Ganon", RHT_NONE, RG_TRIFORCE); - locationTable[RC_GIFT_FROM_SAGES] = Location::Base(RC_GIFT_FROM_SAGES, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Gift from Raoru", "Gift from Raoru", RHT_NONE, RG_LIGHT_MEDALLION, SpoilerCollectionCheck::EventChkInf(0xC9), true); + locationTable[RC_GIFT_FROM_RAURU] = Location::Base(RC_GIFT_FROM_RAURU, RCQUEST_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Gift from Rauru", "Gift from Rauru", RHT_GIFT_FROM_RAURU, RG_LIGHT_MEDALLION, SpoilerCollectionCheck::EventChkInf(0xC9), true); // Heart Containers - locationTable[RC_DEKU_TREE_QUEEN_GOHMA_HEART] = Location::Base(RC_DEKU_TREE_QUEEN_GOHMA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_DEKU_TREE_BOSS, 0x00, "Queen Gohma Heart Container", RHT_DEKU_TREE_QUEEN_GOHMA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x11, 0x1F), true); - locationTable[RC_DODONGOS_CAVERN_KING_DODONGO_HEART] = Location::Base(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_DODONGOS_CAVERN_BOSS, 0x00, "King Dodongo Heart Container", RHT_DODONGOS_CAVERN_KING_DODONGO_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x12, 0x1F), true); - locationTable[RC_JABU_JABUS_BELLY_BARINADE_HEART] = Location::Base(RC_JABU_JABUS_BELLY_BARINADE_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_JABU_JABU_BOSS, 0x00, "Barinade Heart Container", RHT_JABU_JABUS_BELLY_BARINADE_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x13, 0x1F), true); - locationTable[RC_FOREST_TEMPLE_PHANTOM_GANON_HEART] = Location::Base(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_FOREST_TEMPLE_BOSS, 0x00, "Phantom Ganon Heart Container", RHT_FOREST_TEMPLE_PHANTOM_GANON_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x14, 0x1F), true); - locationTable[RC_FIRE_TEMPLE_VOLVAGIA_HEART] = Location::Base(RC_FIRE_TEMPLE_VOLVAGIA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_FIRE_TEMPLE_BOSS, 0x00, "Volvagia Heart Container", RHT_FIRE_TEMPLE_VOLVAGIA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x15, 0x1F), true); - locationTable[RC_WATER_TEMPLE_MORPHA_HEART] = Location::Base(RC_WATER_TEMPLE_MORPHA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_WATER_TEMPLE_BOSS, 0x00, "Morpha Heart Container", RHT_WATER_TEMPLE_MORPHA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x16, 0x1F), true); - locationTable[RC_SPIRIT_TEMPLE_TWINROVA_HEART] = Location::Base(RC_SPIRIT_TEMPLE_TWINROVA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, "Twinrova Heart Container", RHT_SPIRIT_TEMPLE_TWINROVA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x17, 0x1F), true); - locationTable[RC_SHADOW_TEMPLE_BONGO_BONGO_HEART] = Location::Base(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_SHADOW_TEMPLE_BOSS, 0x00, "Bongo Bongo Heart Container", RHT_SHADOW_TEMPLE_BONGO_BONGO_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x18, 0x1F), true); + locationTable[RC_DEKU_TREE_QUEEN_GOHMA_HEART] = Location::Base(RC_DEKU_TREE_QUEEN_GOHMA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_DEKU_TREE_BOSS, 0x00, "Queen Gohma Heart Container", RHT_DEKU_TREE_QUEEN_GOHMA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x11, 0x1F), true); + locationTable[RC_DODONGOS_CAVERN_KING_DODONGO_HEART] = Location::Base(RC_DODONGOS_CAVERN_KING_DODONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_DODONGOS_CAVERN_BOSS, 0x00, "King Dodongo Heart Container", RHT_DODONGOS_CAVERN_KING_DODONGO_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x12, 0x1F), true); + locationTable[RC_JABU_JABUS_BELLY_BARINADE_HEART] = Location::Base(RC_JABU_JABUS_BELLY_BARINADE_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_JABU_JABU_BOSS, 0x00, "Barinade Heart Container", RHT_JABU_JABUS_BELLY_BARINADE_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x13, 0x1F), true); + locationTable[RC_FOREST_TEMPLE_PHANTOM_GANON_HEART] = Location::Base(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_FOREST_TEMPLE_BOSS, 0x00, "Phantom Ganon Heart Container", RHT_FOREST_TEMPLE_PHANTOM_GANON_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x14, 0x1F), true); + locationTable[RC_FIRE_TEMPLE_VOLVAGIA_HEART] = Location::Base(RC_FIRE_TEMPLE_VOLVAGIA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_FIRE_TEMPLE_BOSS, 0x00, "Volvagia Heart Container", RHT_FIRE_TEMPLE_VOLVAGIA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x15, 0x1F), true); + locationTable[RC_WATER_TEMPLE_MORPHA_HEART] = Location::Base(RC_WATER_TEMPLE_MORPHA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_WATER_TEMPLE_BOSS, 0x00, "Morpha Heart Container", RHT_WATER_TEMPLE_MORPHA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x16, 0x1F), true); + locationTable[RC_SPIRIT_TEMPLE_TWINROVA_HEART] = Location::Base(RC_SPIRIT_TEMPLE_TWINROVA_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_SPIRIT_TEMPLE_BOSS, 0x00, "Twinrova Heart Container", RHT_SPIRIT_TEMPLE_TWINROVA_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x17, 0x1F), true); + locationTable[RC_SHADOW_TEMPLE_BONGO_BONGO_HEART] = Location::Base(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, RCQUEST_BOTH, RCTYPE_BOSS_HEART_OR_OTHER_REWARD, ACTOR_ITEM_B_HEART, SCENE_SHADOW_TEMPLE_BOSS, 0x00, "Bongo Bongo Heart Container", RHT_SHADOW_TEMPLE_BONGO_BONGO_HEART, RG_HEART_CONTAINER, SpoilerCollectionCheck::Collectable(0x18, 0x1F), true); // Cutscenes - locationTable[RC_TOT_MASTER_SWORD] = Location::Base(RC_TOT_MASTER_SWORD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, 0x00, "ToT Master Sword", RHT_TOT_MASTER_SWORD, RG_MASTER_SWORD, SpoilerCollectionCheck::EventChkInf(0x45), true); - locationTable[RC_TOT_LIGHT_ARROWS_CUTSCENE] = Location::Base(RC_TOT_LIGHT_ARROWS_CUTSCENE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, 0x00, "ToT Light Arrow Cutscene", RHT_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS, SpoilerCollectionCheck::EventChkInf(0xC4), true); - locationTable[RC_LW_GIFT_FROM_SARIA] = Location::Base(RC_LW_GIFT_FROM_SARIA, RCQUEST_BOTH, RCTYPE_OCARINA, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Gift From Saria", RHT_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, SpoilerCollectionCheck::EventChkInf(0xC1), true); - locationTable[RC_ZF_GREAT_FAIRY_REWARD] = Location::Base(RC_ZF_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, "Great Fairy Reward", RHT_ZF_GREAT_FAIRY_REWARD, RG_FARORES_WIND, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_GREAT_FAIRY_REWARD), true); - locationTable[RC_HC_GREAT_FAIRY_REWARD] = Location::Base(RC_HC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, "Great Fairy Reward", RHT_HC_GREAT_FAIRY_REWARD, RG_DINS_FIRE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_GREAT_FAIRY_REWARD), true); - locationTable[RC_COLOSSUS_GREAT_FAIRY_REWARD] = Location::Base(RC_COLOSSUS_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 3, "Great Fairy Reward", RHT_COLOSSUS_GREAT_FAIRY_REWARD, RG_NAYRUS_LOVE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD), true); - locationTable[RC_DMT_GREAT_FAIRY_REWARD] = Location::Base(RC_DMT_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, "Great Fairy Reward", RHT_DMT_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GREAT_FAIRY_REWARD), true); - locationTable[RC_DMC_GREAT_FAIRY_REWARD] = Location::Base(RC_DMC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, "Great Fairy Reward", RHT_DMC_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GREAT_FAIRY_REWARD), true); - locationTable[RC_OGC_GREAT_FAIRY_REWARD] = Location::Base(RC_OGC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, "OGC Great Fairy Reward", "OGC Great Fairy Reward", RHT_OGC_GREAT_FAIRY_REWARD, RG_DOUBLE_DEFENSE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_GREAT_FAIRY_REWARD), true); + locationTable[RC_TOT_MASTER_SWORD] = Location::Base(RC_TOT_MASTER_SWORD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, 0x00, "ToT Master Sword", RHT_TOT_MASTER_SWORD, RG_MASTER_SWORD, SpoilerCollectionCheck::EventChkInf(0x45), true); + locationTable[RC_TOT_LIGHT_ARROWS_CUTSCENE] = Location::Base(RC_TOT_LIGHT_ARROWS_CUTSCENE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, 0x00, "ToT Light Arrow Cutscene", RHT_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS, SpoilerCollectionCheck::EventChkInf(0xC4), true); + locationTable[RC_LW_GIFT_FROM_SARIA] = Location::Base(RC_LW_GIFT_FROM_SARIA, RCQUEST_BOTH, RCTYPE_OCARINA, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Gift From Saria", RHT_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, SpoilerCollectionCheck::EventChkInf(0xC1), true); + locationTable[RC_ZF_GREAT_FAIRY_REWARD] = Location::Base(RC_ZF_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_FOUNTAIN, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 1, "Great Fairy Reward", RHT_ZF_GREAT_FAIRY_REWARD, RG_FARORES_WIND, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_GREAT_FAIRY_REWARD), true); + locationTable[RC_HC_GREAT_FAIRY_REWARD] = Location::Base(RC_HC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 2, "Great Fairy Reward", RHT_HC_GREAT_FAIRY_REWARD, RG_DINS_FIRE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_GREAT_FAIRY_REWARD), true); + locationTable[RC_COLOSSUS_GREAT_FAIRY_REWARD] = Location::Base(RC_COLOSSUS_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DESERT_COLOSSUS, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 3, "Great Fairy Reward", RHT_COLOSSUS_GREAT_FAIRY_REWARD, RG_NAYRUS_LOVE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD), true); + locationTable[RC_DMT_GREAT_FAIRY_REWARD] = Location::Base(RC_DMT_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 1, "Great Fairy Reward", RHT_DMT_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GREAT_FAIRY_REWARD), true); + locationTable[RC_DMC_GREAT_FAIRY_REWARD] = Location::Base(RC_DMC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 2, "Great Fairy Reward", RHT_DMC_GREAT_FAIRY_REWARD, RG_PROGRESSIVE_MAGIC_METER, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GREAT_FAIRY_REWARD), true); + locationTable[RC_OGC_GREAT_FAIRY_REWARD] = Location::Base(RC_OGC_GREAT_FAIRY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_CASTLE, ACTOR_BG_DY_YOSEIZO, SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 3, "OGC Great Fairy Reward", "OGC Great Fairy Reward", RHT_OGC_GREAT_FAIRY_REWARD, RG_DOUBLE_DEFENSE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_OGC_GREAT_FAIRY_REWARD), true); // Songs - locationTable[RC_SHEIK_IN_FOREST] = Location::Base(RC_SHEIK_IN_FOREST, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, "Sheik in Forest", "Sheik in Forest", RHT_SHEIK_IN_FOREST, RG_MINUET_OF_FOREST, SpoilerCollectionCheck::EventChkInf(0x50), true); - locationTable[RC_SHEIK_IN_CRATER] = Location::Base(RC_SHEIK_IN_CRATER, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_CRATER, 0x00, "Sheik in Crater", "Sheik in Crater", RHT_SHEIK_IN_CRATER, RG_BOLERO_OF_FIRE, SpoilerCollectionCheck::EventChkInf(0x51), true); - locationTable[RC_SHEIK_IN_ICE_CAVERN] = Location::Base(RC_SHEIK_IN_ICE_CAVERN, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_ICE_CAVERN, 0x00, "Sheik in Ice Cavern", "Sheik in Ice Cavern", RHT_SHEIK_IN_ICE_CAVERN, RG_SERENADE_OF_WATER, SpoilerCollectionCheck::EventChkInf(0x52), true); - locationTable[RC_SHEIK_AT_COLOSSUS] = Location::Base(RC_SHEIK_AT_COLOSSUS, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_DESERT_COLOSSUS, 0x00, "Sheik at Colossus", "Sheik at Colossus", RHT_SHEIK_AT_COLOSSUS, RG_REQUIEM_OF_SPIRIT, SpoilerCollectionCheck::EventChkInf(0xAC), true); - locationTable[RC_SHEIK_IN_KAKARIKO] = Location::Base(RC_SHEIK_IN_KAKARIKO, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Sheik in Kakariko", "Sheik in Kakariko", RHT_SHEIK_IN_KAKARIKO, RG_NOCTURNE_OF_SHADOW, SpoilerCollectionCheck::EventChkInf(0xAA), true); - locationTable[RC_SHEIK_AT_TEMPLE] = Location::Base(RC_SHEIK_AT_TEMPLE, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, 0x00, "Sheik at Temple", "Sheik at Temple", RHT_SHEIK_AT_TEMPLE, RG_PRELUDE_OF_LIGHT, SpoilerCollectionCheck::EventChkInf(0x55), true); - locationTable[RC_SONG_FROM_IMPA] = Location::Base(RC_SONG_FROM_IMPA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Song from Impa", "Song from Impa", RHT_SONG_FROM_IMPA, RG_ZELDAS_LULLABY, SpoilerCollectionCheck::EventChkInf(0x59), true); - locationTable[RC_SONG_FROM_MALON] = Location::Base(RC_SONG_FROM_MALON, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_LON_LON_RANCH, 0x00, "Song from Malon", "Song from Malon", RHT_SONG_FROM_MALON, RG_EPONAS_SONG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LEARNED_EPONA_SONG), true); - locationTable[RC_SONG_FROM_SARIA] = Location::Base(RC_SONG_FROM_SARIA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, "Song from Saria", "Song from Saria", RHT_SONG_FROM_SARIA, RG_SARIAS_SONG, SpoilerCollectionCheck::EventChkInf(0x57), true); - locationTable[RC_SONG_FROM_ROYAL_FAMILYS_TOMB] = Location::Base(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_ROYAL_FAMILYS_TOMB, 0x00, "Song from Composers Grave", "Song from Composers Grave", RHT_SONG_FROM_ROYAL_FAMILYS_TOMB, RG_SUNS_SONG, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SUNS_SONG), true); - locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Base(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, SpoilerCollectionCheck::EventChkInf(0xA9), true); - locationTable[RC_SONG_FROM_WINDMILL] = Location::Base(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0x00, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS), true); + locationTable[RC_SHEIK_IN_FOREST] = Location::Base(RC_SHEIK_IN_FOREST, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, "Sheik in Forest", "Sheik in Forest", RHT_SHEIK_IN_FOREST, RG_MINUET_OF_FOREST, SpoilerCollectionCheck::EventChkInf(0x50), true); + locationTable[RC_SHEIK_IN_CRATER] = Location::Base(RC_SHEIK_IN_CRATER, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_DEATH_MOUNTAIN_CRATER, 0x00, "Sheik in Crater", "Sheik in Crater", RHT_SHEIK_IN_CRATER, RG_BOLERO_OF_FIRE, SpoilerCollectionCheck::EventChkInf(0x51), true); + locationTable[RC_SHEIK_IN_ICE_CAVERN] = Location::Base(RC_SHEIK_IN_ICE_CAVERN, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_ICE_CAVERN, 0x00, "Sheik in Ice Cavern", "Sheik in Ice Cavern", RHT_SHEIK_IN_ICE_CAVERN, RG_SERENADE_OF_WATER, SpoilerCollectionCheck::EventChkInf(0x52), true); + locationTable[RC_SHEIK_AT_COLOSSUS] = Location::Base(RC_SHEIK_AT_COLOSSUS, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_DESERT_COLOSSUS, 0x00, "Sheik at Colossus", "Sheik at Colossus", RHT_SHEIK_AT_COLOSSUS, RG_REQUIEM_OF_SPIRIT, SpoilerCollectionCheck::EventChkInf(0xAC), true); + locationTable[RC_SHEIK_IN_KAKARIKO] = Location::Base(RC_SHEIK_IN_KAKARIKO, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Sheik in Kakariko", "Sheik in Kakariko", RHT_SHEIK_IN_KAKARIKO, RG_NOCTURNE_OF_SHADOW, SpoilerCollectionCheck::EventChkInf(0xAA), true); + locationTable[RC_SHEIK_AT_TEMPLE] = Location::Base(RC_SHEIK_AT_TEMPLE, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, 0x00, "Sheik at Temple", "Sheik at Temple", RHT_SHEIK_AT_TEMPLE, RG_PRELUDE_OF_LIGHT, SpoilerCollectionCheck::EventChkInf(0x55), true); + locationTable[RC_SONG_FROM_IMPA] = Location::Base(RC_SONG_FROM_IMPA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_HYRULE_CASTLE, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Song from Impa", "Song from Impa", RHT_SONG_FROM_IMPA, RG_ZELDAS_LULLABY, SpoilerCollectionCheck::EventChkInf(0x59), true); + locationTable[RC_SONG_FROM_MALON] = Location::Base(RC_SONG_FROM_MALON, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_LON_LON_RANCH, 0x00, "Song from Malon", "Song from Malon", RHT_SONG_FROM_MALON, RG_EPONAS_SONG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LEARNED_EPONA_SONG), true); + locationTable[RC_SONG_FROM_SARIA] = Location::Base(RC_SONG_FROM_SARIA, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_SACRED_FOREST_MEADOW, 0x00, "Song from Saria", "Song from Saria", RHT_SONG_FROM_SARIA, RG_SARIAS_SONG, SpoilerCollectionCheck::EventChkInf(0x57), true); + locationTable[RC_SONG_FROM_ROYAL_FAMILYS_TOMB] = Location::Base(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_ROYAL_FAMILYS_TOMB, 0x00, "Song from Composers Grave", "Song from Composers Grave", RHT_SONG_FROM_ROYAL_FAMILYS_TOMB, RG_SUNS_SONG, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SUNS_SONG), true); + locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Base(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, SpoilerCollectionCheck::EventChkInf(0xA9), true); + locationTable[RC_SONG_FROM_WINDMILL] = Location::Base(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0x00, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS), true); //Beehives - locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT)); - locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x2C), "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT)); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x14), "Near Shortcuts Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT)); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x14), "Near Shortcuts Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT)); - locationTable[RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(747, 0xF5), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO)); - locationTable[RC_SFM_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_SFM_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_SACRED_FOREST_MEADOW, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEE), "Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_SFM_STORMS_GROTTO)); - locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x00), "Near Market Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT)); - locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x00), "Near Market Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT)); - locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x03), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT)); - locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x03), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT)); - locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x22), "Southeast Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT)); - locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x22), "Southeast Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT)); - locationTable[RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE] = Location::Base(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1410, 0xE6), "Inside Fence Grotto Beehive", RHT_BEEHIVE_LONELY_SCRUB_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO)); - locationTable[RC_LLR_GROTTO_BEEHIVE] = Location::Base(RC_LLR_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LON_LON_RANCH, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFC), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LLR_GROTTO)); - locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x28), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT)); - locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x28), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT)); - locationTable[RC_DMT_COW_GROTTO_BEEHIVE] = Location::Base(RC_DMT_COW_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2617, 0xF8), "Cow Grotto Beehive", RHT_BEEHIVE_COW_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_COW_GROTTO)); - locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x57), "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT)); - locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x57), "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT)); - locationTable[RC_GC_GROTTO_BEEHIVE] = Location::Base(RC_GC_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GORON_CITY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFB), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GC_GROTTO)); - locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x7A), "Upper Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT)); - locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x7A), "Upper Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT)); - locationTable[RC_DMC_HAMMER_GROTTO_BEEHIVE] = Location::Base(RC_DMC_HAMMER_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xF9), "Hammer Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO)); - locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x29), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT)); - locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x29), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT)); - locationTable[RC_ZR_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_ZR_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEB), "Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_STORMS_GROTTO)); - locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(382, 0x00), "In Front of King Zora Beehive Left", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT)); - locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(948, 0x00), "In Front of King Zora Beehive Right", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT)); - locationTable[RC_ZD_BEHIND_KING_ZORA_BEEHIVE] = Location::Base(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(701, 0x00), "Behind King Zora Beehive", RHT_BEEHIVE_BEHIND_KING_ZORA, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA)); - locationTable[RC_LH_GROTTO_BEEHIVE] = Location::Base(RC_LH_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LAKE_HYLIA, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xEF), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LH_GROTTO)); - locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO)); - locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), "Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_COLOSSUS_GROTTO)); + locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT)); + locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x2C), "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT)); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x14), "Near Shortcuts Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT)); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x14), "Near Shortcuts Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT)); + locationTable[RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(747, 0xF5), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO)); + locationTable[RC_SFM_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_SFM_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_SACRED_FOREST_MEADOW, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEE), "Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_SFM_STORMS_GROTTO)); + locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x00), "Near Market Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT)); + locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x00), "Near Market Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT)); + locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x03), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT)); + locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x03), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT)); + locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x22), "Southeast Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT)); + locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x22), "Southeast Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT)); + locationTable[RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE] = Location::Base(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1410, 0xE6), "Inside Fence Grotto Beehive", RHT_BEEHIVE_LONELY_SCRUB_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO)); + locationTable[RC_LLR_GROTTO_BEEHIVE] = Location::Base(RC_LLR_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LON_LON_RANCH, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFC), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LLR_GROTTO)); + locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x28), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT)); + locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x28), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT)); + locationTable[RC_DMT_COW_GROTTO_BEEHIVE] = Location::Base(RC_DMT_COW_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2617, 0xF8), "Cow Grotto Beehive", RHT_BEEHIVE_COW_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_COW_GROTTO)); + locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x57), "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT)); + locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x57), "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT)); + locationTable[RC_GC_GROTTO_BEEHIVE] = Location::Base(RC_GC_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GORON_CITY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFB), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GC_GROTTO)); + locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x7A), "Upper Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT)); + locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x7A), "Upper Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT)); + locationTable[RC_DMC_HAMMER_GROTTO_BEEHIVE] = Location::Base(RC_DMC_HAMMER_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xF9), "Hammer Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO)); + locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x29), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT)); + locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x29), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT)); + locationTable[RC_ZR_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_ZR_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEB), "Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_STORMS_GROTTO)); + locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(382, 0x00), "In Front of King Zora Beehive Left", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT)); + locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(948, 0x00), "In Front of King Zora Beehive Right", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT)); + locationTable[RC_ZD_BEHIND_KING_ZORA_BEEHIVE] = Location::Base(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(701, 0x00), "Behind King Zora Beehive", RHT_BEEHIVE_BEHIND_KING_ZORA, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA)); + locationTable[RC_LH_GROTTO_BEEHIVE] = Location::Base(RC_LH_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LAKE_HYLIA, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xEF), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LH_GROTTO)); + locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO)); + locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), "Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_COLOSSUS_GROTTO)); // Cows - locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, "Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW)); - locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), "Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW)); - locationTable[RC_LLR_STABLES_LEFT_COW] = Location::Base(RC_LLR_STABLES_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(-122, -254), "Stables Left Cow", RHT_LLR_STABLES_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW)); - locationTable[RC_LLR_STABLES_RIGHT_COW] = Location::Base(RC_LLR_STABLES_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(116, -254), "Stables Right Cow", RHT_LLR_STABLES_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW)); - locationTable[RC_LLR_TOWER_LEFT_COW] = Location::Base(RC_LLR_TOWER_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229, 157), "Tower Left Cow", RHT_LLR_TOWER_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW)); - locationTable[RC_LLR_TOWER_RIGHT_COW] = Location::Base(RC_LLR_TOWER_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142, -140), "Tower Right Cow", RHT_LLR_TOWER_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW)); - locationTable[RC_KAK_IMPAS_HOUSE_COW] = Location::Base(RC_KAK_IMPAS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_IMPAS_HOUSE, 0x00, "Impas House Cow", RHT_KAK_IMPAS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW)); - locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), "Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW)); - locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, "Cow", RHT_GV_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_GV_COW)); - locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, "MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW)); + locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, "Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW)); + locationTable[RC_HF_COW_GROTTO_COW] = Location::Base(RC_HF_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_HYRULE_FIELD, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3485, -291), "Cow Grotto Cow", RHT_HF_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW)); + locationTable[RC_LLR_STABLES_LEFT_COW] = Location::Base(RC_LLR_STABLES_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(-122, -254), "Stables Left Cow", RHT_LLR_STABLES_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW)); + locationTable[RC_LLR_STABLES_RIGHT_COW] = Location::Base(RC_LLR_STABLES_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_STABLE, TWO_ACTOR_PARAMS(116, -254), "Stables Right Cow", RHT_LLR_STABLES_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW)); + locationTable[RC_LLR_TOWER_LEFT_COW] = Location::Base(RC_LLR_TOWER_LEFT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-229, 157), "Tower Left Cow", RHT_LLR_TOWER_LEFT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW)); + locationTable[RC_LLR_TOWER_RIGHT_COW] = Location::Base(RC_LLR_TOWER_RIGHT_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(-142, -140), "Tower Right Cow", RHT_LLR_TOWER_RIGHT_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW)); + locationTable[RC_KAK_IMPAS_HOUSE_COW] = Location::Base(RC_KAK_IMPAS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_IMPAS_HOUSE, 0x00, "Impas House Cow", RHT_KAK_IMPAS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW)); + locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), "Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW)); + locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, "Cow", RHT_GV_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_GV_COW)); + locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, "MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW)); /*------------------------------- --- SHOPS --- @@ -1020,15 +1037,15 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_LH_ADULT_FISH_15] = Location::Fish(RC_LH_ADULT_FISH_15, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 114, RAND_INF_ADULT_FISH_15, "Adult Pond Fish 15", RHT_LH_POND_FISH, RG_NONE); locationTable[RC_LH_ADULT_LOACH] = Location::Fish(RC_LH_ADULT_LOACH, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, 115, RAND_INF_ADULT_LOACH, "Adult Pond Loach", RHT_LH_HYRULE_LOACH, RG_NONE); // Grotto fish - locationTable[RC_KF_STORMS_GROTTO_FISH] = Location::GrottoFish(RC_KF_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, 0x12C, RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO, "Storms Grotto Fish", RHT_KF_STORMS_GROTTO_FISH); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_FISH] = Location::GrottoFish(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RCQUEST_BOTH, RCAREA_LOST_WOODS, 0x114, RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO, "Near Shortcuts Grotto Fish", RHT_LW_NEAR_SHORTCUTS_GROTTO_FISH); - locationTable[RC_HF_SOUTHEAST_GROTTO_FISH] = Location::GrottoFish(RC_HF_SOUTHEAST_GROTTO_FISH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, 0x122, RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO, "Southeast Grotto Fish", RHT_HF_SOUTHEAST_GROTTO_FISH); - locationTable[RC_HF_OPEN_GROTTO_FISH] = Location::GrottoFish(RC_HF_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, 0x103, RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO, "Open Grotto Fish", RHT_HF_OPEN_GROTTO_FISH); - locationTable[RC_HF_NEAR_MARKET_GROTTO_FISH] = Location::GrottoFish(RC_HF_NEAR_MARKET_GROTTO_FISH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, 0x100, RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO, "Near Market Grotto Fish", RHT_HF_NEAR_MARKET_GROTTO_FISH); - locationTable[RC_KAK_OPEN_GROTTO_FISH] = Location::GrottoFish(RC_KAK_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, 0x128, RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO, "Open Grotto Fish", RHT_KAK_OPEN_GROTTO_FISH); - locationTable[RC_DMT_STORMS_GROTTO_FISH] = Location::GrottoFish(RC_DMT_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, 0x157, RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO, "Storms Grotto Fish", RHT_DMT_STORMS_GROTTO_FISH); - locationTable[RC_DMC_UPPER_GROTTO_FISH] = Location::GrottoFish(RC_DMC_UPPER_GROTTO_FISH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, 0x17A, RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO, "Upper Grotto Fish", RHT_DMC_UPPER_GROTTO_FISH); - locationTable[RC_ZR_OPEN_GROTTO_FISH] = Location::GrottoFish(RC_ZR_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, 0x129, RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO, "Open Grotto Fish", RHT_ZR_OPEN_GROTTO_FISH); + locationTable[RC_KF_STORMS_GROTTO_FISH] = Location::GrottoFish(RC_KF_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, 0x12C, RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO, "Storms Grotto Fish", RHT_KF_STORMS_GROTTO_FISH); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_FISH] = Location::GrottoFish(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RCQUEST_BOTH, RCAREA_LOST_WOODS, 0x114, RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO, "Near Shortcuts Grotto Fish", RHT_LW_NEAR_SHORTCUTS_GROTTO_FISH); + locationTable[RC_HF_SOUTHEAST_GROTTO_FISH] = Location::GrottoFish(RC_HF_SOUTHEAST_GROTTO_FISH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, 0x122, RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO, "Southeast Grotto Fish", RHT_HF_SOUTHEAST_GROTTO_FISH); + locationTable[RC_HF_OPEN_GROTTO_FISH] = Location::GrottoFish(RC_HF_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, 0x103, RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO, "Open Grotto Fish", RHT_HF_OPEN_GROTTO_FISH); + locationTable[RC_HF_NEAR_MARKET_GROTTO_FISH] = Location::GrottoFish(RC_HF_NEAR_MARKET_GROTTO_FISH, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, 0x100, RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO, "Near Market Grotto Fish", RHT_HF_NEAR_MARKET_GROTTO_FISH); + locationTable[RC_KAK_OPEN_GROTTO_FISH] = Location::GrottoFish(RC_KAK_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, 0x128, RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO, "Open Grotto Fish", RHT_KAK_OPEN_GROTTO_FISH); + locationTable[RC_DMT_STORMS_GROTTO_FISH] = Location::GrottoFish(RC_DMT_STORMS_GROTTO_FISH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, 0x157, RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO, "Storms Grotto Fish", RHT_DMT_STORMS_GROTTO_FISH); + locationTable[RC_DMC_UPPER_GROTTO_FISH] = Location::GrottoFish(RC_DMC_UPPER_GROTTO_FISH, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, 0x17A, RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO, "Upper Grotto Fish", RHT_DMC_UPPER_GROTTO_FISH); + locationTable[RC_ZR_OPEN_GROTTO_FISH] = Location::GrottoFish(RC_ZR_OPEN_GROTTO_FISH, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, 0x129, RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO, "Open Grotto Fish", RHT_ZR_OPEN_GROTTO_FISH); // Zora's Domain fish locationTable[RC_ZD_FISH_1] = Location::Fish(RC_ZD_FISH_1, RCQUEST_BOTH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 0, RAND_INF_ZD_FISH_1, "Fish 1", RHT_ZD_FISH, RG_FISH); locationTable[RC_ZD_FISH_2] = Location::Fish(RC_ZD_FISH_2, RCQUEST_BOTH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 1, RAND_INF_ZD_FISH_2, "Fish 2", RHT_ZD_FISH, RG_FISH); @@ -1036,62 +1053,1066 @@ void Rando::StaticData::InitLocationTable() { // locationTable[RC_ZD_FISH_4] = Location::Fish(RC_ZD_FISH_4, RCQUEST_BOTH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 3, RAND_INF_ZD_FISH_4, "Fish 4", RHT_ZD_FISH, RG_FISH); locationTable[RC_ZD_FISH_5] = Location::Fish(RC_ZD_FISH_5, RCQUEST_BOTH, ACTOR_EN_FISH, SCENE_ZORAS_DOMAIN, -1 ^ 4, RAND_INF_ZD_FISH_5, "Fish 5", RHT_ZD_FISH, RG_FISH); + + /* +----------------+ + | SHUFFLE POTS | + +----------------+ */ + + // Overworld Pots + // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Spoiler Name Hint Text Key Vanilla Spoiler Collection Check + locationTable[RC_KF_LINKS_HOUSE_POT] = Location::Pot(RC_KF_LINKS_HOUSE_POT, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_LINKS_HOUSE, TWO_ACTOR_PARAMS(-118, 51), "Links House Pot", "KF Links House Pot", RHT_POT_KOKIRI_FOREST, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_LINKS_HOUSE_POT)); + locationTable[RC_KF_TWINS_HOUSE_POT_2] = Location::Pot(RC_KF_TWINS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_TWINS_HOUSE, TWO_ACTOR_PARAMS(35, 57), "Twins House Pot 2", "KF Twins House Pot 2", RHT_POT_KOKIRI_FOREST, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_TWINS_HOUSE_POT_2)); + locationTable[RC_KF_TWINS_HOUSE_POT_1] = Location::Pot(RC_KF_TWINS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_TWINS_HOUSE, TWO_ACTOR_PARAMS(33, -55), "Twins House Pot 1", "KF Twins House Pot 1", RHT_POT_KOKIRI_FOREST, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_TWINS_HOUSE_POT_1)); + locationTable[RC_KF_BROTHERS_HOUSE_POT_1] = Location::Pot(RC_KF_BROTHERS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KNOW_IT_ALL_BROS_HOUSE, TWO_ACTOR_PARAMS(-134, -29), "Brothers House Pot 1", "KF Brothers House Pot 1", RHT_POT_KOKIRI_FOREST, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BROTHERS_HOUSE_POT_1)); + locationTable[RC_KF_BROTHERS_HOUSE_POT_2] = Location::Pot(RC_KF_BROTHERS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KNOW_IT_ALL_BROS_HOUSE, TWO_ACTOR_PARAMS(-68, 114), "Brothers House Pot 2", "KF Brothers House Pot 2", RHT_POT_KOKIRI_FOREST, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BROTHERS_HOUSE_POT_2)); + locationTable[RC_GF_BREAK_ROOM_POT_1] = Location::Pot(RC_GF_BREAK_ROOM_POT_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1438, -3629), "Break Room Pot 1", "GF Break Room Pot 1", RHT_POT_GERUDO_FORTRESS, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_BREAK_ROOM_POT_1)); + locationTable[RC_GF_BREAK_ROOM_POT_2] = Location::Pot(RC_GF_BREAK_ROOM_POT_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1403, -3679), "Break Room Pot 2", "GF Break Room Pot 2", RHT_POT_GERUDO_FORTRESS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_BREAK_ROOM_POT_2)); + locationTable[RC_GF_KITCHEN_POT_1] = Location::Pot(RC_GF_KITCHEN_POT_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1908, -789), "Kitchen Pot 1", "GF Kitchen Pot 1", RHT_POT_GERUDO_FORTRESS, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_KITCHEN_POT_1)); + locationTable[RC_GF_KITCHEN_POT_2] = Location::Pot(RC_GF_KITCHEN_POT_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1951, -850), "Kitchen Pot 2", "GF Kitchen Pot 2", RHT_POT_GERUDO_FORTRESS, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_KITCHEN_POT_2)); + locationTable[RC_GF_NORTH_F1_CARPENTER_POT_1] = Location::Pot(RC_GF_NORTH_F1_CARPENTER_POT_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-475, -2622), "North F1 Carpenter Pot 1", "GF North F1 Carpenter Pot 1", RHT_POT_GERUDO_FORTRESS, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTH_F1_CARPENTER_POT_1)); + locationTable[RC_GF_NORTH_F1_CARPENTER_POT_2] = Location::Pot(RC_GF_NORTH_F1_CARPENTER_POT_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-512, -2621), "North F1 Carpenter Pot 2", "GF North F1 Carpenter Pot 2", RHT_POT_GERUDO_FORTRESS, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTH_F1_CARPENTER_POT_2)); + locationTable[RC_GF_NORTH_F1_CARPENTER_POT_3] = Location::Pot(RC_GF_NORTH_F1_CARPENTER_POT_3, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-511, -2582), "North F1 Carpenter Pot 3", "GF North F1 Carpenter Pot 3", RHT_POT_GERUDO_FORTRESS, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTH_F1_CARPENTER_POT_3)); + locationTable[RC_GF_NORTH_F2_CARPENTER_POT_1] = Location::Pot(RC_GF_NORTH_F2_CARPENTER_POT_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(67, -1975), "North F2 Carpenter Pot 1", "GF North F2 Carpenter Pot 1", RHT_POT_GERUDO_FORTRESS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTH_F2_CARPENTER_POT_1)); + locationTable[RC_GF_NORTH_F2_CARPENTER_POT_2] = Location::Pot(RC_GF_NORTH_F2_CARPENTER_POT_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(39, -1943), "North F2 Carpenter Pot 2", "GF North F2 Carpenter Pot 2", RHT_POT_GERUDO_FORTRESS, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTH_F2_CARPENTER_POT_2)); + locationTable[RC_GF_SOUTH_F1_CARPENTER_POT_1] = Location::Pot(RC_GF_SOUTH_F1_CARPENTER_POT_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(691, 48), "South F1 Carpenter Pot 1", "GF South F1 Carpenter Pot 1", RHT_POT_GERUDO_FORTRESS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1)); + locationTable[RC_GF_SOUTH_F1_CARPENTER_POT_2] = Location::Pot(RC_GF_SOUTH_F1_CARPENTER_POT_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(691, 16), "South F1 Carpenter Pot 2", "GF South F1 Carpenter Pot 2", RHT_POT_GERUDO_FORTRESS, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2)); + locationTable[RC_GF_SOUTH_F1_CARPENTER_POT_3] = Location::Pot(RC_GF_SOUTH_F1_CARPENTER_POT_3, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(661, 16), "South F1 Carpenter Pot 3", "GF South F1 Carpenter Pot 3", RHT_POT_GERUDO_FORTRESS, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3)); + locationTable[RC_GF_SOUTH_F1_CARPENTER_CELL_POT_1] = Location::Pot(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(26, 524), "South F1 Carpenter Cell Pot 1", "GF South F1 Carpenter Cell Pot 1", RHT_POT_GERUDO_FORTRESS, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1)); + locationTable[RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2] = Location::Pot(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(61, 549), "South F1 Carpenter Cell Pot 2", "GF South F1 Carpenter Cell Pot 2", RHT_POT_GERUDO_FORTRESS, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2)); + locationTable[RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3] = Location::Pot(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(215, 549), "South F1 Carpenter Cell Pot 3", "GF South F1 Carpenter Cell Pot 3", RHT_POT_GERUDO_FORTRESS, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3)); + locationTable[RC_GF_SOUTH_F1_CARPENTER_CELL_POT_4] = Location::Pot(RC_GF_SOUTH_F1_CARPENTER_CELL_POT_4, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(254, 529), "South F1 Carpenter Cell Pot 4", "GF South F1 Carpenter Cell Pot 4", RHT_POT_GERUDO_FORTRESS, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4)); + locationTable[RC_WASTELAND_NEAR_GS_POT_1] = Location::Pot(RC_WASTELAND_NEAR_GS_POT_1, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(488, -2424), "Near GS Pot 1", "Wasteland Near GS Pot 1", RHT_POT_GERUDO_FORTRESS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WASTELAND_NEAR_GS_POT_1)); + locationTable[RC_WASTELAND_NEAR_GS_POT_2] = Location::Pot(RC_WASTELAND_NEAR_GS_POT_2, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(485, -2463), "Near GS Pot 2", "Wasteland Near GS Pot 2", RHT_POT_GERUDO_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WASTELAND_NEAR_GS_POT_2)); + locationTable[RC_WASTELAND_NEAR_GS_POT_3] = Location::Pot(RC_WASTELAND_NEAR_GS_POT_3, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(806, -2426), "Near GS Pot 3", "Wasteland Near GS Pot 3", RHT_POT_GERUDO_FORTRESS, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WASTELAND_NEAR_GS_POT_3)); + locationTable[RC_WASTELAND_NEAR_GS_POT_4] = Location::Pot(RC_WASTELAND_NEAR_GS_POT_4, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(801, -2460), "Near GS Pot 4", "Wasteland Near GS Pot 4", RHT_POT_GERUDO_FORTRESS, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WASTELAND_NEAR_GS_POT_4)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_1] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-60, 27), "Guard House Child Pot 1", "MK Guard House Child Pot 1", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_2] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-89, 28), "Guard House Child Pot 2", "MK Guard House Child Pot 2", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_3] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_3, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-110, 6), "Guard House Child Pot 3", "MK Guard House Child Pot 3", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_4] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_4, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-58, -7), "Guard House Child Pot 4", "MK Guard House Child Pot 4", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_5] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_5, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-80, -7), "Guard House Child Pot 5", "MK Guard House Child Pot 5", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_6] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_6, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-65, -45), "Guard House Child Pot 6", "MK Guard House Child Pot 6", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_7] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_7, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-85, -41), "Guard House Child Pot 7", "MK Guard House Child Pot 7", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_8] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_8, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-107, -45), "Guard House Child Pot 8", "MK Guard House Child Pot 8", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_9] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_9, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-66, -79), "Guard House Child Pot 9", "MK Guard House Child Pot 9", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_10] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_10, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-88, -84), "Guard House Child Pot 10", "MK Guard House Child Pot 10", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_11] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_11, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(70, 215), "Guard House Child Pot 11", "MK Guard House Child Pot 11", RHT_POT_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_12] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_12, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(68, 148), "Guard House Child Pot 12", "MK Guard House Child Pot 12", RHT_POT_MARKET, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_13] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_13, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(73, 117), "Guard House Child Pot 13", "MK Guard House Child Pot 13", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_14] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_14, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(40, 123), "Guard House Child Pot 14", "MK Guard House Child Pot 14", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_15] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_15, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(43, 89), "Guard House Child Pot 15", "MK Guard House Child Pot 15", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_16] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_16, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(68, 81), "Guard House Child Pot 16", "MK Guard House Child Pot 16", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_17] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_17, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(21, 73), "Guard House Child Pot 17", "MK Guard House Child Pot 17", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_18] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_18, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(64, 45), "Guard House Child Pot 18", "MK Guard House Child Pot 18", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_19] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_19, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(84, 31), "Guard House Child Pot 19", "MK Guard House Child Pot 19", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_20] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_20, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(42, 26), "Guard House Child Pot 20", "MK Guard House Child Pot 20", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_21] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_21, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(20, 34), "Guard House Child Pot 21", "MK Guard House Child Pot 21", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_22] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_22, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(89, -2), "Guard House Child Pot 22", "MK Guard House Child Pot 22", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_23] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_23, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(70, -12), "Guard House Child Pot 23", "MK Guard House Child Pot 23", RHT_POT_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_24] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_24, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(42, -5), "Guard House Child Pot 24", "MK Guard House Child Pot 24", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_25] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_25, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(16, -6), "Guard House Child Pot 25", "MK Guard House Child Pot 25", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_26] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_26, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(68, -44), "Guard House Child Pot 26", "MK Guard House Child Pot 26", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_27] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_27, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(37, -40), "Guard House Child Pot 27", "MK Guard House Child Pot 27", RHT_POT_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_28] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_28, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(70, -80), "Guard House Child Pot 28", "MK Guard House Child Pot 28", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_29] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_29, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(50, -74), "Guard House Child Pot 29", "MK Guard House Child Pot 29", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_30] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_30, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(28, -79), "Guard House Child Pot 30", "MK Guard House Child Pot 30", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_31] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_31, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(39, -111), "Guard House Child Pot 31", "MK Guard House Child Pot 31", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_32] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_32, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(169, 216), "Guard House Child Pot 32", "MK Guard House Child Pot 32", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_33] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_33, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(168, 166), "Guard House Child Pot 33", "MK Guard House Child Pot 33", RHT_POT_MARKET, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_34] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_34, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, 120), "Guard House Child Pot 34", "MK Guard House Child Pot 34", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_35] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_35, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(177, 85), "Guard House Child Pot 35", "MK Guard House Child Pot 35", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_36] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_36, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(155, 39), "Guard House Child Pot 36", "MK Guard House Child Pot 36", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_37] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_37, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(184, 13), "Guard House Child Pot 37", "MK Guard House Child Pot 37", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_38] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_38, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(156, -1), "Guard House Child Pot 38", "MK Guard House Child Pot 38", RHT_POT_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_39] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_39, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(181, -33), "Guard House Child Pot 39", "MK Guard House Child Pot 39", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_40] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_40, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(156, -45), "Guard House Child Pot 40", "MK Guard House Child Pot 40", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_41] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_41, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(172, -82), "Guard House Child Pot 41", "MK Guard House Child Pot 41", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_42] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_42, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, -120), "Guard House Child Pot 42", "MK Guard House Child Pot 42", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_43] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_43, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, -166), "Guard House Child Pot 43", "MK Guard House Child Pot 43", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43)); + locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_44] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_44, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, -216), "Guard House Child Pot 44", "MK Guard House Child Pot 44", RHT_POT_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_1] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(61, 204), "Guard House Adult Pot 1", "MK Guard House Adult Pot 1", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_2] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(71, 132), "Guard House Adult Pot 2", "MK Guard House Adult Pot 2", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_3] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_3, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(74, 23), "Guard House Adult Pot 3", "MK Guard House Adult Pot 3", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_4] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_4, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(40, 4), "Guard House Adult Pot 4", "MK Guard House Adult Pot 4", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_5] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_5, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(71, -22), "Guard House Adult Pot 5", "MK Guard House Adult Pot 5", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_6] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_6, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(44, -151), "Guard House Adult Pot 6", "MK Guard House Adult Pot 6", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_7] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_7, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(79, -182), "Guard House Adult Pot 7", "MK Guard House Adult Pot 7", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_8] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_8, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(44, -198), "Guard House Adult Pot 8", "MK Guard House Adult Pot 8", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_9] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_9, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(168, 210), "Guard House Adult Pot 9", "MK Guard House Adult Pot 9", RHT_POT_MARKET, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_10] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_10, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(167, -122), "Guard House Adult Pot 10", "MK Guard House Adult Pot 10", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10)); + locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_11] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_11, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(167, -210), "Guard House Adult Pot 11", "MK Guard House Adult Pot 11", RHT_POT_MARKET, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11)); + locationTable[RC_MK_BACK_ALLEY_HOUSE_POT_1] = Location::Pot(RC_MK_BACK_ALLEY_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_BACK_ALLEY_HOUSE, TWO_ACTOR_PARAMS(100, 45), "Back Alley House Pot 1", "MK Back Alley House Pot 1", RHT_POT_MARKET, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1)); + locationTable[RC_MK_BACK_ALLEY_HOUSE_POT_2] = Location::Pot(RC_MK_BACK_ALLEY_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_BACK_ALLEY_HOUSE, TWO_ACTOR_PARAMS(12, -180), "Back Alley House Pot 2", "MK Back Alley House Pot 2", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2)); + locationTable[RC_MK_BACK_ALLEY_HOUSE_POT_3] = Location::Pot(RC_MK_BACK_ALLEY_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_MARKET, SCENE_BACK_ALLEY_HOUSE, TWO_ACTOR_PARAMS(-54, -180), "Back Alley House Pot 3", "MK Back Alley House Pot 3", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3)); + locationTable[RC_KAK_NEAR_POTION_SHOP_POT_1] = Location::Pot(RC_KAK_NEAR_POTION_SHOP_POT_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(222, -377), "Near Potion Shop Pot 1", "Kak Near Potion Shop Pot 1", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_POTION_SHOP_POT_1)); + locationTable[RC_KAK_NEAR_POTION_SHOP_POT_2] = Location::Pot(RC_KAK_NEAR_POTION_SHOP_POT_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(255, -366), "Near Potion Shop Pot 2", "Kak Near Potion Shop Pot 2", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_POTION_SHOP_POT_2)); + locationTable[RC_KAK_NEAR_POTION_SHOP_POT_3] = Location::Pot(RC_KAK_NEAR_POTION_SHOP_POT_3, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(284, -356), "Near Potion Shop Pot 3", "Kak Near Potion Shop Pot 3", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_POTION_SHOP_POT_3)); + locationTable[RC_KAK_NEAR_IMPAS_HOUSE_POT_1] = Location::Pot(RC_KAK_NEAR_IMPAS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-384, 1568), "Near Impas House Pot 1", "Kak Near Impas House Pot 1", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1)); + locationTable[RC_KAK_NEAR_IMPAS_HOUSE_POT_2] = Location::Pot(RC_KAK_NEAR_IMPAS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-384, 1539), "Near Impas House Pot 2", "Kak Near Impas House Pot 2", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2)); + locationTable[RC_KAK_NEAR_IMPAS_HOUSE_POT_3] = Location::Pot(RC_KAK_NEAR_IMPAS_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-384, 1510), "Near Impas House Pot 3", "Kak Near Impas House Pot 3", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3)); + locationTable[RC_KAK_NEAR_GUARDS_HOUSE_POT_1] = Location::Pot(RC_KAK_NEAR_GUARDS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-392, -870), "Near Guards House Pot 1", "Kak Near Guards House Pot 1", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1)); + locationTable[RC_KAK_NEAR_GUARDS_HOUSE_POT_2] = Location::Pot(RC_KAK_NEAR_GUARDS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-422, -883), "Near Guards House Pot 2", "Kak Near Guards House Pot 2", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2)); + locationTable[RC_KAK_NEAR_GUARDS_HOUSE_POT_3] = Location::Pot(RC_KAK_NEAR_GUARDS_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-450, -895), "Near Guards House Pot 3", "Kak Near Guards House Pot 3", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3)); + locationTable[RC_KAK_NEAR_MEDICINE_SHOP_POT_1] = Location::Pot(RC_KAK_NEAR_MEDICINE_SHOP_POT_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(781, 89), "Near Medicine Shop Pot 1", "Kak Near Medicine Shop Pot 1", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1)); + locationTable[RC_KAK_NEAR_MEDICINE_SHOP_POT_2] = Location::Pot(RC_KAK_NEAR_MEDICINE_SHOP_POT_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(815, 89), "Near Medicine Shop Pot 2", "Kak Near Medicine Shop Pot 2", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2)); + locationTable[RC_GY_DAMPES_GRAVE_POT_1] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(-319, -1542), "Dampes Grave Pot 1", "GY Dampes Grave Pot 1", RHT_POT_GRAVEYARD, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_1)); + locationTable[RC_GY_DAMPES_GRAVE_POT_2] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(-319, -1600), "Dampes Grave Pot 2", "GY Dampes Grave Pot 2", RHT_POT_GRAVEYARD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_2)); + locationTable[RC_GY_DAMPES_GRAVE_POT_3] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(-364, -1571), "Dampes Grave Pot 3", "GY Dampes Grave Pot 3", RHT_POT_GRAVEYARD, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_3)); + locationTable[RC_GY_DAMPES_GRAVE_POT_4] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_4, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(198, -1540), "Dampes Grave Pot 4", "GY Dampes Grave Pot 4", RHT_POT_GRAVEYARD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_4)); + locationTable[RC_GY_DAMPES_GRAVE_POT_5] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_5, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(198, -1608), "Dampes Grave Pot 5", "GY Dampes Grave Pot 5", RHT_POT_GRAVEYARD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_5)); + locationTable[RC_GY_DAMPES_GRAVE_POT_6] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_6, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(239, -1577), "Dampes Grave Pot 6", "GY Dampes Grave Pot 6", RHT_POT_GRAVEYARD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_6)); + locationTable[RC_GC_LOWER_STAIRCASE_POT_1] = Location::Pot(RC_GC_LOWER_STAIRCASE_POT_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-189, 866), "Lower Staircase Pot 1", "GC Lower Staircase Pot 1", RHT_POT_GORON_CITY, RG_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_LOWER_STAIRCASE_POT_1)); + locationTable[RC_GC_LOWER_STAIRCASE_POT_2] = Location::Pot(RC_GC_LOWER_STAIRCASE_POT_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-271, 825), "Lower Staircase Pot 2", "GC Lower Staircase Pot 2", RHT_POT_GORON_CITY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_LOWER_STAIRCASE_POT_2)); + locationTable[RC_GC_UPPER_STAIRCASE_POT_1] = Location::Pot(RC_GC_UPPER_STAIRCASE_POT_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1170, 60), "Upper Staircase Pot 1", "GC Upper Staircase Pot 1", RHT_POT_GORON_CITY, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_UPPER_STAIRCASE_POT_1)); + locationTable[RC_GC_UPPER_STAIRCASE_POT_2] = Location::Pot(RC_GC_UPPER_STAIRCASE_POT_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1185, 95), "Upper Staircase Pot 2", "GC Upper Staircase Pot 2", RHT_POT_GORON_CITY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_UPPER_STAIRCASE_POT_2)); + locationTable[RC_GC_UPPER_STAIRCASE_POT_3] = Location::Pot(RC_GC_UPPER_STAIRCASE_POT_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1200, 63), "Upper Staircase Pot 3", "GC Upper Staircase Pot 3", RHT_POT_GORON_CITY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_UPPER_STAIRCASE_POT_3)); + locationTable[RC_GC_MEDIGORON_POT_1] = Location::Pot(RC_GC_MEDIGORON_POT_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-694, 1196), "Medigoron Pot 1", "GC Medigoron Pot 1", RHT_POT_GORON_CITY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_POT_1)); + locationTable[RC_GC_DARUNIA_POT_1] = Location::Pot(RC_GC_DARUNIA_POT_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(262, -1210), "Darunia Pot 1", "GC Darunia Pot 1", RHT_POT_GORON_CITY, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_DARUNIA_POT_1)); + locationTable[RC_GC_DARUNIA_POT_2] = Location::Pot(RC_GC_DARUNIA_POT_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(261, -1254), "Darunia Pot 2", "GC Darunia Pot 2", RHT_POT_GORON_CITY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_DARUNIA_POT_2)); + locationTable[RC_GC_DARUNIA_POT_3] = Location::Pot(RC_GC_DARUNIA_POT_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(262, -1386), "Darunia Pot 3", "GC Darunia Pot 3", RHT_POT_GORON_CITY, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_DARUNIA_POT_3)); + locationTable[RC_DMC_NEAR_GC_POT_2] = Location::Pot(RC_DMC_NEAR_GC_POT_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1546, 141), "Near GC Pot 2", "DMC Near GC Pot 2", RHT_POT_DEATH_MOUNTAIN_CRATER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_NEAR_GC_POT_2)); + locationTable[RC_DMC_NEAR_GC_POT_3] = Location::Pot(RC_DMC_NEAR_GC_POT_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1641, -127), "Near GC Pot 3", "DMC Near GC Pot 3", RHT_POT_DEATH_MOUNTAIN_CRATER, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_NEAR_GC_POT_3)); + locationTable[RC_DMC_NEAR_GC_POT_1] = Location::Pot(RC_DMC_NEAR_GC_POT_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1590, 132), "Near GC Pot 1", "DMC Near GC Pot 1", RHT_POT_DEATH_MOUNTAIN_CRATER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_NEAR_GC_POT_1)); + locationTable[RC_DMC_NEAR_GC_POT_4] = Location::Pot(RC_DMC_NEAR_GC_POT_4, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1606, -166), "Near GC Pot 4", "DMC Near GC Pot 4", RHT_POT_DEATH_MOUNTAIN_CRATER, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_NEAR_GC_POT_4)); + locationTable[RC_ZD_NEAR_SHOP_POT_1] = Location::Pot(RC_ZD_NEAR_SHOP_POT_1, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(676, 377), "Near Shop Pot 1", "ZD Near Shop Pot 1", RHT_POT_ZORAS_DOMAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_1)); + locationTable[RC_ZD_NEAR_SHOP_POT_2] = Location::Pot(RC_ZD_NEAR_SHOP_POT_2, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(614, 419), "Near Shop Pot 2", "ZD Near Shop Pot 2", RHT_POT_ZORAS_DOMAIN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_2)); + locationTable[RC_ZD_NEAR_SHOP_POT_3] = Location::Pot(RC_ZD_NEAR_SHOP_POT_3, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(289, 415), "Near Shop Pot 3", "ZD Near Shop Pot 3", RHT_POT_ZORAS_DOMAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_3)); + locationTable[RC_ZD_NEAR_SHOP_POT_4] = Location::Pot(RC_ZD_NEAR_SHOP_POT_4, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(289, 289), "Near Shop Pot 4", "ZD Near Shop Pot 4", RHT_POT_ZORAS_DOMAIN, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_4)); + locationTable[RC_ZD_NEAR_SHOP_POT_5] = Location::Pot(RC_ZD_NEAR_SHOP_POT_5, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(220, 384), "Near Shop Pot 5", "ZD Near Shop Pot 5", RHT_POT_ZORAS_DOMAIN, RG_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_5)); + locationTable[RC_ZF_HIDDEN_CAVE_POT_1] = Location::Pot(RC_ZF_HIDDEN_CAVE_POT_1, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(385, 2587), "Hidden Cave Pot 1", "ZF Hidden Cave Pot 1", RHT_POT_ZORAS_FOUNTAIN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_HIDDEN_CAVE_POT_1)); + locationTable[RC_ZF_HIDDEN_CAVE_POT_2] = Location::Pot(RC_ZF_HIDDEN_CAVE_POT_2, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(418, 2609), "Hidden Cave Pot 2", "ZF Hidden Cave Pot 2", RHT_POT_ZORAS_FOUNTAIN, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_HIDDEN_CAVE_POT_2)); + locationTable[RC_ZF_HIDDEN_CAVE_POT_3] = Location::Pot(RC_ZF_HIDDEN_CAVE_POT_3, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(430, 2568), "Hidden Cave Pot 3", "ZF Hidden Cave Pot 3", RHT_POT_ZORAS_FOUNTAIN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_HIDDEN_CAVE_POT_3)); + locationTable[RC_ZF_NEAR_JABU_POT_1] = Location::Pot(RC_ZF_NEAR_JABU_POT_1, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1630, 170), "Near Jabu Pot 1", "ZF Near Jabu Pot 1", RHT_POT_ZORAS_FOUNTAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_1)); + locationTable[RC_ZF_NEAR_JABU_POT_2] = Location::Pot(RC_ZF_NEAR_JABU_POT_2, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1550, 170), "Near Jabu Pot 2", "ZF Near Jabu Pot 2", RHT_POT_ZORAS_FOUNTAIN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_2)); + locationTable[RC_ZF_NEAR_JABU_POT_3] = Location::Pot(RC_ZF_NEAR_JABU_POT_3, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1630, -260), "Near Jabu Pot 3", "ZF Near Jabu Pot 3", RHT_POT_ZORAS_FOUNTAIN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_3)); + locationTable[RC_ZF_NEAR_JABU_POT_4] = Location::Pot(RC_ZF_NEAR_JABU_POT_4, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1550, -260), "Near Jabu Pot 4", "ZF Near Jabu Pot 4", RHT_POT_ZORAS_FOUNTAIN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_4)); + locationTable[RC_LLR_FRONT_POT_1] = Location::Pot(RC_LLR_FRONT_POT_1, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3218), "Front Pot 1", "LLR Front Pot 1", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_1)); + locationTable[RC_LLR_FRONT_POT_2] = Location::Pot(RC_LLR_FRONT_POT_2, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3186), "Front Pot 2", "LLR Front Pot 2", RHT_POT_LON_LON_RANCH, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_2)); + locationTable[RC_LLR_FRONT_POT_3] = Location::Pot(RC_LLR_FRONT_POT_3, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3154), "Front Pot 3", "LLR Front Pot 3", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_3)); + locationTable[RC_LLR_FRONT_POT_4] = Location::Pot(RC_LLR_FRONT_POT_4, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3122), "Front Pot 4", "LLR Front Pot 4", RHT_POT_LON_LON_RANCH, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_4)); + locationTable[RC_LLR_RAIN_SHED_POT_1] = Location::Pot(RC_LLR_RAIN_SHED_POT_1, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(852, 172), "Rain Shed Pot 1", "LLR Rain Shed Pot 1", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_RAIN_SHED_POT_1)); + locationTable[RC_LLR_RAIN_SHED_POT_2] = Location::Pot(RC_LLR_RAIN_SHED_POT_2, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(840, 212), "Rain Shed Pot 2", "LLR Rain Shed Pot 2", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_RAIN_SHED_POT_2)); + locationTable[RC_LLR_RAIN_SHED_POT_3] = Location::Pot(RC_LLR_RAIN_SHED_POT_3, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(872, 219), "Rain Shed Pot 3", "LLR Rain Shed Pot 3", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_RAIN_SHED_POT_3)); + locationTable[RC_LLR_TALONS_HOUSE_POT_1] = Location::Pot(RC_LLR_TALONS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(1255, 47), "Talons House Pot 1", "LLR Talons House Pot 1", RHT_POT_LON_LON_RANCH, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TALONS_HOUSE_POT_1)); + locationTable[RC_LLR_TALONS_HOUSE_POT_2] = Location::Pot(RC_LLR_TALONS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(1256, -51), "Talons House Pot 2", "LLR Talons House Pot 2", RHT_POT_LON_LON_RANCH, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TALONS_HOUSE_POT_2)); + locationTable[RC_LLR_TALONS_HOUSE_POT_3] = Location::Pot(RC_LLR_TALONS_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(1256, -78), "Talons House Pot 3", "LLR Talons House Pot 3", RHT_POT_LON_LON_RANCH, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TALONS_HOUSE_POT_3)); + locationTable[RC_HF_COW_GROTTO_POT_1] = Location::Pot(RC_HF_COW_GROTTO_POT_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3410, -223), "Cow Grotto Pot 1", "HF Cow Grotto Pot 1", RHT_POT_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_POT_1)); + locationTable[RC_HF_COW_GROTTO_POT_2] = Location::Pot(RC_HF_COW_GROTTO_POT_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3390, -258), "Cow Grotto Pot 2", "HF Cow Grotto Pot 2", RHT_POT_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_POT_2)); + locationTable[RC_HC_STORMS_GROTTO_POT_1] = Location::Pot(RC_HC_STORMS_GROTTO_POT_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1843, 1014), "Storms Grotto Pot 1", "HC Storms Grotto Pot 1", RHT_POT_HYRULE_CASTLE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_1)); + locationTable[RC_HC_STORMS_GROTTO_POT_2] = Location::Pot(RC_HC_STORMS_GROTTO_POT_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1769, 954), "Storms Grotto Pot 2", "HC Storms Grotto Pot 2", RHT_POT_HYRULE_CASTLE, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_2)); + locationTable[RC_HC_STORMS_GROTTO_POT_3] = Location::Pot(RC_HC_STORMS_GROTTO_POT_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1857, 897), "Storms Grotto Pot 3", "HC Storms Grotto Pot 3", RHT_POT_HYRULE_CASTLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_3)); + locationTable[RC_HC_STORMS_GROTTO_POT_4] = Location::Pot(RC_HC_STORMS_GROTTO_POT_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1764, 847), "Storms Grotto Pot 4", "HC Storms Grotto Pot 4", RHT_POT_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_4)); + + // Dungeon Pots + // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Spoiler Name Hint Text Key Vanilla Spoiler Collection Check + locationTable[RC_DODONGOS_CAVERN_LIZALFOS_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_LIZALFOS_POT_3, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2673, -2060), "Lizalfos Pot 3", "Dodongos Cavern Lizalfos Pot 3", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3)); + locationTable[RC_DODONGOS_CAVERN_LIZALFOS_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_LIZALFOS_POT_2, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3526, -2574), "Lizalfos Pot 2", "Dodongos Cavern Lizalfos Pot 2", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2)); + locationTable[RC_DODONGOS_CAVERN_LIZALFOS_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_LIZALFOS_POT_1, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3579, -2574), "Lizalfos Pot 1", "Dodongos Cavern Lizalfos Pot 1", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1)); + locationTable[RC_DODONGOS_CAVERN_LIZALFOS_POT_4] = Location::Pot(RC_DODONGOS_CAVERN_LIZALFOS_POT_4, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2653, -2031), "Lizalfos Pot 4", "Dodongos Cavern Lizalfos Pot 4", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4)); + locationTable[RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1708, -471), "Side Room Pot 1", "Dodongos Cavern Side Room Pot 1", RHT_POT_DODONGOS_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1)); + locationTable[RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1746, -424), "Side Room Pot 2", "Dodongos Cavern Side Room Pot 2", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2)); + locationTable[RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2573, -489), "Side Room Pot 3", "Dodongos Cavern Side Room Pot 3", RHT_POT_DODONGOS_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3)); + locationTable[RC_DODONGOS_CAVERN_SIDE_ROOM_POT_4] = Location::Pot(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_4, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2622, -489), "Side Room Pot 4", "Dodongos Cavern Side Room Pot 4", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4)); + locationTable[RC_DODONGOS_CAVERN_SIDE_ROOM_POT_5] = Location::Pot(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_5, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3507, -964), "Side Room Pot 5", "Dodongos Cavern Side Room Pot 5", RHT_POT_DODONGOS_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5)); + locationTable[RC_DODONGOS_CAVERN_SIDE_ROOM_POT_6] = Location::Pot(RC_DODONGOS_CAVERN_SIDE_ROOM_POT_6, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3617, -911), "Side Room Pot 6", "Dodongos Cavern Side Room Pot 6", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6)); + locationTable[RC_DODONGOS_CAVERN_TORCH_ROOM_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_TORCH_ROOM_POT_1, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1846, -1879), "Torch Room Pot 1", "Dodongos Cavern Torch Room Pot 1", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1)); + locationTable[RC_DODONGOS_CAVERN_TORCH_ROOM_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_TORCH_ROOM_POT_2, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2050, -1964), "Torch Room Pot 2", "Dodongos Cavern Torch Room Pot 2", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2)); + locationTable[RC_DODONGOS_CAVERN_TORCH_ROOM_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_TORCH_ROOM_POT_3, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2281, -1799), "Torch Room Pot 3", "Dodongos Cavern Torch Room Pot 3", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3)); + locationTable[RC_DODONGOS_CAVERN_TORCH_ROOM_POT_4] = Location::Pot(RC_DODONGOS_CAVERN_TORCH_ROOM_POT_4, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1836, -1239), "Torch Room Pot 4", "Dodongos Cavern Torch Room Pot 4", RHT_POT_DODONGOS_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4)); + locationTable[RC_DODONGOS_CAVERN_STAIRCASE_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_STAIRCASE_POT_1, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-2414, -1823), "Staircase Pot 1", "Dodongos Cavern Staircase Pot 1", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1)); + locationTable[RC_DODONGOS_CAVERN_STAIRCASE_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_STAIRCASE_POT_2, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-2368, -1827), "Staircase Pot 2", "Dodongos Cavern Staircase Pot 2", RHT_POT_DODONGOS_CAVERN, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2)); + locationTable[RC_DODONGOS_CAVERN_STAIRCASE_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_STAIRCASE_POT_3, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-1574, -1831), "Staircase Pot 3", "Dodongos Cavern Staircase Pot 3", RHT_POT_DODONGOS_CAVERN, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3)); + locationTable[RC_DODONGOS_CAVERN_STAIRCASE_POT_4] = Location::Pot(RC_DODONGOS_CAVERN_STAIRCASE_POT_4, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-1528, -1827), "Staircase Pot 4", "Dodongos Cavern Staircase Pot 4", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4)); + locationTable[RC_DODONGOS_CAVERN_SINGLE_EYE_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_SINGLE_EYE_POT_1, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2704, -483), "Single Eye Pot 1", "Dodongos Cavern Single Eye Pot 1", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1)); + locationTable[RC_DODONGOS_CAVERN_SINGLE_EYE_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_SINGLE_EYE_POT_2, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3195, -155), "Single Eye Pot 2", "Dodongos Cavern Single Eye Pot 2", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2)); + locationTable[RC_DODONGOS_CAVERN_BLADE_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_BLADE_POT_1, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1656, -531), "Blade Pot 1", "Dodongos Cavern Blade Pot 1", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_BLADE_POT_1)); + locationTable[RC_DODONGOS_CAVERN_BLADE_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_BLADE_POT_2, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1831, -593), "Blade Pot 2", "Dodongos Cavern Blade Pot 2", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_BLADE_POT_2)); + locationTable[RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3329, -753), "Double Eye Pot 1", "Dodongos Cavern Double Eye Pot 1", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1)); + locationTable[RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2705, -1086), "Double Eye Pot 2", "Dodongos Cavern Double Eye Pot 2", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2)); + locationTable[RC_DODONGOS_CAVERN_BACK_ROOM_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_BACK_ROOM_POT_1, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1027, -3704), "Back Room Pot 1", "Dodongos Cavern Back Room Pot 1", RHT_POT_DODONGOS_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1)); + locationTable[RC_DODONGOS_CAVERN_BACK_ROOM_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_BACK_ROOM_POT_2, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(966, -3704), "Back Room Pot 2", "Dodongos Cavern Back Room Pot 2", RHT_POT_DODONGOS_CAVERN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2)); + locationTable[RC_DODONGOS_CAVERN_BACK_ROOM_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_BACK_ROOM_POT_3, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(125, -3854), "Back Room Pot 3", "Dodongos Cavern Back Room Pot 3", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3)); + locationTable[RC_DODONGOS_CAVERN_BACK_ROOM_POT_4] = Location::Pot(RC_DODONGOS_CAVERN_BACK_ROOM_POT_4, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(78, -3835), "Back Room Pot 4", "Dodongos Cavern Back Room Pot 4", RHT_POT_DODONGOS_CAVERN, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4)); + locationTable[RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1] = Location::Pot(RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1295, -3612), "Above Big Octo Pot 1", "Jabu Jabus Belly Above Big Octo Pot 1", RHT_POT_JABU_JABUS_BELLY, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1)); + locationTable[RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2] = Location::Pot(RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1355, -3612), "Above Big Octo Pot 2", "Jabu Jabus Belly Above Big Octo Pot 2", RHT_POT_JABU_JABUS_BELLY, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2)); + locationTable[RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3] = Location::Pot(RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1422, -3612), "Above Big Octo Pot 3", "Jabu Jabus Belly Above Big Octo Pot 3", RHT_POT_JABU_JABUS_BELLY, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3)); + locationTable[RC_JABU_JABUS_BELLY_BARINADE_POT_1] = Location::Pot(RC_JABU_JABUS_BELLY_BARINADE_POT_1, RCQUEST_BOTH, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU_BOSS, TWO_ACTOR_PARAMS(-551, 33), "Barinade Pot 1", "Jabu Jabus Belly Barinade Pot 1", RHT_POT_JABU_JABUS_BELLY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1)); + locationTable[RC_JABU_JABUS_BELLY_BARINADE_POT_2] = Location::Pot(RC_JABU_JABUS_BELLY_BARINADE_POT_2, RCQUEST_BOTH, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU_BOSS, TWO_ACTOR_PARAMS(551, 36), "Barinade Pot 2", "Jabu Jabus Belly Barinade Pot 2", RHT_POT_JABU_JABUS_BELLY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2)); + locationTable[RC_JABU_JABUS_BELLY_BARINADE_POT_3] = Location::Pot(RC_JABU_JABUS_BELLY_BARINADE_POT_3, RCQUEST_BOTH, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU_BOSS, TWO_ACTOR_PARAMS(554, -493), "Barinade Pot 3", "Jabu Jabus Belly Barinade Pot 3", RHT_POT_JABU_JABUS_BELLY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3)); + locationTable[RC_JABU_JABUS_BELLY_BARINADE_POT_4] = Location::Pot(RC_JABU_JABUS_BELLY_BARINADE_POT_4, RCQUEST_BOTH, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU_BOSS, TWO_ACTOR_PARAMS(-543, -496), "Barinade Pot 4", "Jabu Jabus Belly Barinade Pot 4", RHT_POT_JABU_JABUS_BELLY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4)); + locationTable[RC_JABU_JABUS_BELLY_BARINADE_POT_5] = Location::Pot(RC_JABU_JABUS_BELLY_BARINADE_POT_5, RCQUEST_BOTH, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU_BOSS, TWO_ACTOR_PARAMS(-268, -786), "Barinade Pot 5", "Jabu Jabus Belly Barinade Pot 5", RHT_POT_JABU_JABUS_BELLY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5)); + locationTable[RC_JABU_JABUS_BELLY_BARINADE_POT_6] = Location::Pot(RC_JABU_JABUS_BELLY_BARINADE_POT_6, RCQUEST_BOTH, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU_BOSS, TWO_ACTOR_PARAMS(279, -761), "Barinade Pot 6", "Jabu Jabus Belly Barinade Pot 6", RHT_POT_JABU_JABUS_BELLY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6)); + locationTable[RC_JABU_JABUS_BELLY_BASEMENT_POT_1] = Location::Pot(RC_JABU_JABUS_BELLY_BASEMENT_POT_1, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(703, -2371), "Basement Pot 1", "Jabu Jabus Belly Basement Pot 1", RHT_POT_JABU_JABUS_BELLY, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1)); + locationTable[RC_JABU_JABUS_BELLY_BASEMENT_POT_2] = Location::Pot(RC_JABU_JABUS_BELLY_BASEMENT_POT_2, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(645, -2408), "Basement Pot 2", "Jabu Jabus Belly Basement Pot 2", RHT_POT_JABU_JABUS_BELLY, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2)); + locationTable[RC_JABU_JABUS_BELLY_BASEMENT_POT_3] = Location::Pot(RC_JABU_JABUS_BELLY_BASEMENT_POT_3, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(650, -2344), "Basement Pot 3", "Jabu Jabus Belly Basement Pot 3", RHT_POT_JABU_JABUS_BELLY, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3)); + locationTable[RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1] = Location::Pot(RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1127, -2271), "Two Octorok Pot 1", "Jabu Jabus Belly Two Octorok Pot 1", RHT_POT_JABU_JABUS_BELLY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1)); + locationTable[RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2] = Location::Pot(RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1178, -2272), "Two Octorok Pot 2", "Jabu Jabus Belly Two Octorok Pot 2", RHT_POT_JABU_JABUS_BELLY, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2)); + locationTable[RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3] = Location::Pot(RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1150, -2248), "Two Octorok Pot 3", "Jabu Jabus Belly Two Octorok Pot 3", RHT_POT_JABU_JABUS_BELLY, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3)); + locationTable[RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4] = Location::Pot(RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1131, -2221), "Two Octorok Pot 4", "Jabu Jabus Belly Two Octorok Pot 4", RHT_POT_JABU_JABUS_BELLY, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4)); + locationTable[RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5] = Location::Pot(RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, RCQUEST_VANILLA, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1173, -2227), "Two Octorok Pot 5", "Jabu Jabus Belly Two Octorok Pot 5", RHT_POT_JABU_JABUS_BELLY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5)); + locationTable[RC_FOREST_TEMPLE_LOBBY_POT_1] = Location::Pot(RC_FOREST_TEMPLE_LOBBY_POT_1, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(720, -1037), "Lobby Pot 1", "Forest Temple Lobby Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_LOBBY_POT_1)); + locationTable[RC_FOREST_TEMPLE_LOBBY_POT_2] = Location::Pot(RC_FOREST_TEMPLE_LOBBY_POT_2, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(675, -989), "Lobby Pot 2", "Forest Temple Lobby Pot 2", RHT_POT_FOREST_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_LOBBY_POT_2)); + locationTable[RC_FOREST_TEMPLE_LOBBY_POT_3] = Location::Pot(RC_FOREST_TEMPLE_LOBBY_POT_3, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(630, -943), "Lobby Pot 3", "Forest Temple Lobby Pot 3", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_LOBBY_POT_3)); + locationTable[RC_FOREST_TEMPLE_LOBBY_POT_4] = Location::Pot(RC_FOREST_TEMPLE_LOBBY_POT_4, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-384, -937), "Lobby Pot 4", "Forest Temple Lobby Pot 4", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_LOBBY_POT_4)); + locationTable[RC_FOREST_TEMPLE_LOBBY_POT_5] = Location::Pot(RC_FOREST_TEMPLE_LOBBY_POT_5, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-429, -981), "Lobby Pot 5", "Forest Temple Lobby Pot 5", RHT_POT_FOREST_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_LOBBY_POT_5)); + locationTable[RC_FOREST_TEMPLE_LOBBY_POT_6] = Location::Pot(RC_FOREST_TEMPLE_LOBBY_POT_6, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-477, -1034), "Lobby Pot 6", "Forest Temple Lobby Pot 6", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_LOBBY_POT_6)); + locationTable[RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1] = Location::Pot(RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(90, -3583), "Lower Stalfos Pot 1", "Forest Temple Lower Stalfos Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1)); + locationTable[RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2] = Location::Pot(RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(142, -3583), "Lower Stalfos Pot 2", "Forest Temple Lower Stalfos Pot 2", RHT_POT_FOREST_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2)); + locationTable[RC_FOREST_TEMPLE_GREEN_POE_POT_1] = Location::Pot(RC_FOREST_TEMPLE_GREEN_POE_POT_1, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(1647, -1529), "Green Poe Pot 1", "Forest Temple Green Poe Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1)); + locationTable[RC_FOREST_TEMPLE_GREEN_POE_POT_2] = Location::Pot(RC_FOREST_TEMPLE_GREEN_POE_POT_2, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(1645, -1588), "Green Poe Pot 2", "Forest Temple Green Poe Pot 2", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2)); + locationTable[RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1] = Location::Pot(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(32, -3012), "Upper Stalfos Pot 1", "Forest Temple Upper Stalfos Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1)); + locationTable[RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2] = Location::Pot(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(202, -3012), "Upper Stalfos Pot 2", "Forest Temple Upper Stalfos Pot 2", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2)); + locationTable[RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3] = Location::Pot(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(30, -3631), "Upper Stalfos Pot 3", "Forest Temple Upper Stalfos Pot 3", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3)); + locationTable[RC_FOREST_TEMPLE_UPPER_STALFOS_POT_4] = Location::Pot(RC_FOREST_TEMPLE_UPPER_STALFOS_POT_4, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(206, -3631), "Upper Stalfos Pot 4", "Forest Temple Upper Stalfos Pot 4", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4)); + locationTable[RC_FOREST_TEMPLE_BLUE_POE_POT_1] = Location::Pot(RC_FOREST_TEMPLE_BLUE_POE_POT_1, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(830, -3639), "Blue Poe Pot 1", "Forest Temple Blue Poe Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1)); + locationTable[RC_FOREST_TEMPLE_BLUE_POE_POT_2] = Location::Pot(RC_FOREST_TEMPLE_BLUE_POE_POT_2, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(883, -3640), "Blue Poe Pot 2", "Forest Temple Blue Poe Pot 2", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2)); + locationTable[RC_FOREST_TEMPLE_BLUE_POE_POT_3] = Location::Pot(RC_FOREST_TEMPLE_BLUE_POE_POT_3, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(941, -3640), "Blue Poe Pot 3", "Forest Temple Blue Poe Pot 3", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3)); + locationTable[RC_FOREST_TEMPLE_FROZEN_EYE_POT_1] = Location::Pot(RC_FOREST_TEMPLE_FROZEN_EYE_POT_1, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(2312, -874), "Frozen Eye Pot 1", "Forest Temple Frozen Eye Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1)); + locationTable[RC_FOREST_TEMPLE_FROZEN_EYE_POT_2] = Location::Pot(RC_FOREST_TEMPLE_FROZEN_EYE_POT_2, RCQUEST_VANILLA, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(2364, -873), "Frozen Eye Pot 2", "Forest Temple Frozen Eye Pot 2", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2)); + locationTable[RC_FIRE_TEMPLE_NEAR_BOSS_POT_1] = Location::Pot(RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-1086, -714), "Near Boss Pot 1", "Fire Temple Near Boss Pot 1", RHT_POT_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1)); + locationTable[RC_FIRE_TEMPLE_NEAR_BOSS_POT_2] = Location::Pot(RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-1138, -713), "Near Boss Pot 2", "Fire Temple Near Boss Pot 2", RHT_POT_FIRE_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2)); + locationTable[RC_FIRE_TEMPLE_NEAR_BOSS_POT_3] = Location::Pot(RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-1087, -765), "Near Boss Pot 3", "Fire Temple Near Boss Pot 3", RHT_POT_FIRE_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3)); + locationTable[RC_FIRE_TEMPLE_NEAR_BOSS_POT_4] = Location::Pot(RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-1139, -766), "Near Boss Pot 4", "Fire Temple Near Boss Pot 4", RHT_POT_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4)); + locationTable[RC_FIRE_TEMPLE_BIG_LAVA_POT_1] = Location::Pot(RC_FIRE_TEMPLE_BIG_LAVA_POT_1, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(2226, -754), "Big Lava Pot 1", "Fire Temple Big Lava Pot 1", RHT_POT_FIRE_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1)); + locationTable[RC_FIRE_TEMPLE_BIG_LAVA_POT_2] = Location::Pot(RC_FIRE_TEMPLE_BIG_LAVA_POT_2, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(2226, -809), "Big Lava Pot 2", "Fire Temple Big Lava Pot 2", RHT_POT_FIRE_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2)); + locationTable[RC_FIRE_TEMPLE_BIG_LAVA_POT_3] = Location::Pot(RC_FIRE_TEMPLE_BIG_LAVA_POT_3, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(2227, -862), "Big Lava Pot 3", "Fire Temple Big Lava Pot 3", RHT_POT_FIRE_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3)); + locationTable[RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1] = Location::Pot(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2388, 953), "Flame Maze Left Pot 1", "Fire Temple Flame Maze Left Pot 1", RHT_POT_FIRE_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1)); + locationTable[RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2] = Location::Pot(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2423, 920), "Flame Maze Left Pot 2", "Fire Temple Flame Maze Left Pot 2", RHT_POT_FIRE_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2)); + locationTable[RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3] = Location::Pot(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2442, 715), "Flame Maze Left Pot 3", "Fire Temple Flame Maze Left Pot 3", RHT_POT_FIRE_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3)); + locationTable[RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4] = Location::Pot(RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2408, 680), "Flame Maze Left Pot 4", "Fire Temple Flame Maze Left Pot 4", RHT_POT_FIRE_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4)); + locationTable[RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1] = Location::Pot(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2208, -168), "Flame Maze Right Pot 1", "Fire Temple Flame Maze Right Pot 1", RHT_POT_FIRE_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1)); + locationTable[RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2] = Location::Pot(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2253, -167), "Flame Maze Right Pot 2", "Fire Temple Flame Maze Right Pot 2", RHT_POT_FIRE_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2)); + locationTable[RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3] = Location::Pot(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2657, -591), "Flame Maze Right Pot 3", "Fire Temple Flame Maze Right Pot 3", RHT_POT_FIRE_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3)); + locationTable[RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4] = Location::Pot(RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2657, -635), "Flame Maze Right Pot 4", "Fire Temple Flame Maze Right Pot 4", RHT_POT_FIRE_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4)); + locationTable[RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1] = Location::Pot(RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(330, -198), "Main Level 2 Pot 1", "Water Temple Main Level 2 Pot 1", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1)); + locationTable[RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2] = Location::Pot(RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(331, -168), "Main Level 2 Pot 2", "Water Temple Main Level 2 Pot 2", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2)); + locationTable[RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1] = Location::Pot(RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-241, -1193), "Main Level 1 Pot 1", "Water Temple Main Level 1 Pot 1", RHT_POT_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1)); + locationTable[RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_2] = Location::Pot(RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-117, -1192), "Main Level 1 Pot 2", "Water Temple Main Level 1 Pot 2", RHT_POT_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2)); + locationTable[RC_WATER_TEMPLE_TORCH_POT_1] = Location::Pot(RC_WATER_TEMPLE_TORCH_POT_1, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(1123, 62), "Torch Pot 1", "Water Temple Torch Pot 1", RHT_POT_WATER_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_TORCH_POT_1)); + locationTable[RC_WATER_TEMPLE_TORCH_POT_2] = Location::Pot(RC_WATER_TEMPLE_TORCH_POT_2, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(1123, 293), "Torch Pot 2", "Water Temple Torch Pot 2", RHT_POT_WATER_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_TORCH_POT_2)); + locationTable[RC_WATER_TEMPLE_NEAR_COMPASS_POT_1] = Location::Pot(RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(1222, -617), "Near Compass Pot 1", "Water Temple Near Compass Pot 1", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1)); + locationTable[RC_WATER_TEMPLE_NEAR_COMPASS_POT_2] = Location::Pot(RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(1172, -617), "Near Compass Pot 2", "Water Temple Near Compass Pot 2", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2)); + locationTable[RC_WATER_TEMPLE_NEAR_COMPASS_POT_3] = Location::Pot(RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(1122, -617), "Near Compass Pot 3", "Water Temple Near Compass Pot 3", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3)); + locationTable[RC_WATER_TEMPLE_CENTRAL_BOW_POT_1] = Location::Pot(RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(688, 1008), "Central Bow Pot 1", "Water Temple Central Bow Pot 1", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1)); + locationTable[RC_WATER_TEMPLE_CENTRAL_BOW_POT_2] = Location::Pot(RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(631, 1008), "Central Bow Pot 2", "Water Temple Central Bow Pot 2", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2)); + locationTable[RC_WATER_TEMPLE_BEHIND_GATE_POT_1] = Location::Pot(RC_WATER_TEMPLE_BEHIND_GATE_POT_1, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2313, 944), "Behind Gate Pot 1", "Water Temple Behind Gate Pot 1", RHT_POT_WATER_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1)); + locationTable[RC_WATER_TEMPLE_BEHIND_GATE_POT_2] = Location::Pot(RC_WATER_TEMPLE_BEHIND_GATE_POT_2, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2313, 905), "Behind Gate Pot 2", "Water Temple Behind Gate Pot 2", RHT_POT_WATER_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2)); + locationTable[RC_WATER_TEMPLE_BEHIND_GATE_POT_3] = Location::Pot(RC_WATER_TEMPLE_BEHIND_GATE_POT_3, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2314, 808), "Behind Gate Pot 3", "Water Temple Behind Gate Pot 3", RHT_POT_WATER_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3)); + locationTable[RC_WATER_TEMPLE_BEHIND_GATE_POT_4] = Location::Pot(RC_WATER_TEMPLE_BEHIND_GATE_POT_4, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2314, 770), "Behind Gate Pot 4", "Water Temple Behind Gate Pot 4", RHT_POT_WATER_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4)); + locationTable[RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1] = Location::Pot(RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-28, -3817), "Basement Block Puzzle Pot 1", "Water Temple Basement Block Puzzle Pot 1", RHT_POT_WATER_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1)); + locationTable[RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2] = Location::Pot(RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(28, -3817), "Basement Block Puzzle Pot 2", "Water Temple Basement Block Puzzle Pot 2", RHT_POT_WATER_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2)); + locationTable[RC_WATER_TEMPLE_RIVER_POT_1] = Location::Pot(RC_WATER_TEMPLE_RIVER_POT_1, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2226, -2487), "River Pot 1", "Water Temple River Pot 1", RHT_POT_WATER_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_RIVER_POT_1)); + locationTable[RC_WATER_TEMPLE_RIVER_POT_2] = Location::Pot(RC_WATER_TEMPLE_RIVER_POT_2, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2184, -2456), "River Pot 2", "Water Temple River Pot 2", RHT_POT_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_RIVER_POT_2)); + locationTable[RC_WATER_TEMPLE_LIKE_LIKE_POT_1] = Location::Pot(RC_WATER_TEMPLE_LIKE_LIKE_POT_1, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-3188, -1628), "Like Like Pot 1", "Water Temple Like Like Pot 1", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1)); + locationTable[RC_WATER_TEMPLE_LIKE_LIKE_POT_2] = Location::Pot(RC_WATER_TEMPLE_LIKE_LIKE_POT_2, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-3056, -1626), "Like Like Pot 2", "Water Temple Like Like Pot 2", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2)); + locationTable[RC_WATER_TEMPLE_BOSS_KEY_POT_1] = Location::Pot(RC_WATER_TEMPLE_BOSS_KEY_POT_1, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-1150, -3031), "Boss Key Pot 1", "Water Temple Boss Key Pot 1", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1)); + locationTable[RC_WATER_TEMPLE_BOSS_KEY_POT_2] = Location::Pot(RC_WATER_TEMPLE_BOSS_KEY_POT_2, RCQUEST_VANILLA, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-1417, -3025), "Boss Key Pot 2", "Water Temple Boss Key Pot 2", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2)); + locationTable[RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-1806, -344), "Near Dead Hand Pot 1", "Shadow Temple Near Dead Hand Pot 1", RHT_POT_SHADOW_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1)); + locationTable[RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-1721, 61), "Whispering Walls Pot 1", "Shadow Temple Whispering Walls Pot 1", RHT_POT_SHADOW_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1)); + locationTable[RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2] = Location::Pot(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-1407, 61), "Whispering Walls Pot 2", "Shadow Temple Whispering Walls Pot 2", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2)); + locationTable[RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3] = Location::Pot(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-1614, 61), "Whispering Walls Pot 3", "Shadow Temple Whispering Walls Pot 3", RHT_POT_SHADOW_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3)); + locationTable[RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4] = Location::Pot(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-1055, -257), "Whispering Walls Pot 4", "Shadow Temple Whispering Walls Pot 4", RHT_POT_SHADOW_TEMPLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4)); + locationTable[RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5] = Location::Pot(RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-1050, -130), "Whispering Walls Pot 5", "Shadow Temple Whispering Walls Pot 5", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5)); + locationTable[RC_SHADOW_TEMPLE_MAP_CHEST_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-665, -760), "Map Chest Pot 1", "Shadow Temple Map Chest Pot 1", RHT_POT_SHADOW_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1)); + locationTable[RC_SHADOW_TEMPLE_MAP_CHEST_POT_2] = Location::Pot(RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-929, -748), "Map Chest Pot 2", "Shadow Temple Map Chest Pot 2", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2)); + locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(614, 3579), "Falling Spikes Pot 1", "Shadow Temple Falling Spikes Pot 1", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1)); + locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2] = Location::Pot(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(798, 3574), "Falling Spikes Pot 2", "Shadow Temple Falling Spikes Pot 2", RHT_POT_SHADOW_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2)); + locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3] = Location::Pot(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(1173, 3707), "Falling Spikes Pot 3", "Shadow Temple Falling Spikes Pot 3", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3)); + locationTable[RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4] = Location::Pot(RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(1173, 3605), "Falling Spikes Pot 4", "Shadow Temple Falling Spikes Pot 4", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4)); + locationTable[RC_SHADOW_TEMPLE_AFTER_WIND_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(4222, -916), "After Wind Pot 1", "Shadow Temple After Wind Pot 1", RHT_POT_SHADOW_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1)); + locationTable[RC_SHADOW_TEMPLE_AFTER_WIND_POT_2] = Location::Pot(RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(4549, -922), "After Wind Pot 2", "Shadow Temple After Wind Pot 2", RHT_POT_SHADOW_TEMPLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2)); + locationTable[RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-4303, -2657), "Spike Walls Pot 1", "Shadow Temple Spike Walls Pot 1", RHT_POT_SHADOW_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1)); + locationTable[RC_SHADOW_TEMPLE_FLOORMASTER_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-4575, -811), "Floormaster Pot 1", "Shadow Temple Floormaster Pot 1", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1)); + locationTable[RC_SHADOW_TEMPLE_FLOORMASTER_POT_2] = Location::Pot(RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-4036, -811), "Floormaster Pot 2", "Shadow Temple Floormaster Pot 2", RHT_POT_SHADOW_TEMPLE, RG_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2)); + locationTable[RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-2400, -1470), "After Boat Pot 1", "Shadow Temple After Boat Pot 1", RHT_POT_SHADOW_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1)); + locationTable[RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2] = Location::Pot(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-2230, -1470), "After Boat Pot 2", "Shadow Temple After Boat Pot 2", RHT_POT_SHADOW_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2)); + locationTable[RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3] = Location::Pot(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-2859, -497), "After Boat Pot 3", "Shadow Temple After Boat Pot 3", RHT_POT_SHADOW_TEMPLE, RG_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3)); + locationTable[RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4] = Location::Pot(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, RCQUEST_VANILLA, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-2624, -492), "After Boat Pot 4", "Shadow Temple After Boat Pot 4", RHT_POT_SHADOW_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4)); + locationTable[RC_SPIRIT_TEMPLE_LOBBY_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_LOBBY_POT_1, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-181, 233), "Lobby Pot 1", "Spirit Temple Lobby Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_LOBBY_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_LOBBY_POT_2, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(184, 231), "Lobby Pot 2", "Spirit Temple Lobby Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_ANUBIS_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_ANUBIS_POT_1, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-975, -1751), "Anubis Pot 1", "Spirit Temple Anubis Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_ANUBIS_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_ANUBIS_POT_2, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-928, -1827), "Anubis Pot 2", "Spirit Temple Anubis Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_ANUBIS_POT_3] = Location::Pot(RC_SPIRIT_TEMPLE_ANUBIS_POT_3, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1211, -1530), "Anubis Pot 3", "Spirit Temple Anubis Pot 3", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3)); + locationTable[RC_SPIRIT_TEMPLE_ANUBIS_POT_4] = Location::Pot(RC_SPIRIT_TEMPLE_ANUBIS_POT_4, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1055, -1680), "Anubis Pot 4", "Spirit Temple Anubis Pot 4", RHT_POT_SPIRIT_TEMPLE, RG_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4)); + locationTable[RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1101, -1305), "Child Climb Pot 1", "Spirit Temple Child Climb Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1781, 830), "After Sun Block Pot 1", "Spirit Temple After Sun Block Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1617, 830), "After Sun Block Pot 2", "Spirit Temple After Sun Block Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-600, -1213), "Central Chamber Pot 1", "Spirit Temple Central Chamber Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-564, -1180), "Central Chamber Pot 2", "Spirit Temple Central Chamber Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3] = Location::Pot(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-526, -1213), "Central Chamber Pot 3", "Spirit Temple Central Chamber Pot 3", RHT_POT_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3)); + locationTable[RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4] = Location::Pot(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(639, -1224), "Central Chamber Pot 4", "Spirit Temple Central Chamber Pot 4", RHT_POT_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4)); + locationTable[RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5] = Location::Pot(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(671, -1179), "Central Chamber Pot 5", "Spirit Temple Central Chamber Pot 5", RHT_POT_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5)); + locationTable[RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6] = Location::Pot(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(704, -1224), "Central Chamber Pot 6", "Spirit Temple Central Chamber Pot 6", RHT_POT_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6)); + locationTable[RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(819, -333), "Beamos Hall Pot 1", "Spirit Temple Beamos Hall Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_BOMBS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1)); + locationTable[RC_GANONS_CASTLE_FOREST_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1725, 2336), "Forest Trial Pot 1", "Ganons Castle Forest Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_FOREST_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1892, 2241), "Forest Trial Pot 2", "Ganons Castle Forest Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_FIRE_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1898, -3942), "Fire Trial Pot 2", "Ganons Castle Fire Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_FIRE_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2051, -3855), "Fire Trial Pot 1", "Ganons Castle Fire Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_WATER_TRIAL_POT_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(3558, -920), "Water Trial Pot 1", "Ganons Castle Water Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_WATER_TRIAL_POT_2, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(3558, -761), "Water Trial Pot 2", "Ganons Castle Water Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_WATER_TRIAL_POT_3] = Location::Pot(RC_GANONS_CASTLE_WATER_TRIAL_POT_3, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2822, -507), "Water Trial Pot 3", "Ganons Castle Water Trial Pot 3", RHT_POT_GANONS_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3)); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1234, -3418), "Shadow Trial Pot 1", "Ganons Castle Shadow Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1621, -3203), "Shadow Trial Pot 2", "Ganons Castle Shadow Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3] = Location::Pot(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2067, -4592), "Shadow Trial Pot 3", "Ganons Castle Shadow Trial Pot 3", RHT_POT_GANONS_CASTLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3)); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4] = Location::Pot(RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2224, -4506), "Shadow Trial Pot 4", "Ganons Castle Shadow Trial Pot 4", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4)); + locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1398, 1402), "Spirit Trial Pot 1", "Ganons Castle Spirit Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1237, 1494), "Spirit Trial Pot 2", "Ganons Castle Spirit Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1] = Location::Pot(RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2581, -839), "Light Trial Boulder Pot 1", "Ganons Castle Light Trial Boulder Pot 1", RHT_POT_GANONS_CASTLE, RG_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1)); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-3840, -923), "Light Trial Pot 1", "Ganons Castle Light Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, RCQUEST_VANILLA, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-3840, -755), "Light Trial Pot 2", "Ganons Castle Light Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_1] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_1, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(-422, -258), "Ganons Tower Pot 1", "Ganons Castle Ganons Tower Pot 1", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_2] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_2, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(-382, -300), "Ganons Tower Pot 2", "Ganons Castle Ganons Tower Pot 2", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_3] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_3, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(-342, -341), "Ganons Tower Pot 3", "Ganons Castle Ganons Tower Pot 3", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_4] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_4, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(-298, -383), "Ganons Tower Pot 4", "Ganons Castle Ganons Tower Pot 4", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_5] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_5, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(-257, -424), "Ganons Tower Pot 5", "Ganons Castle Ganons Tower Pot 5", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_6] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_6, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(-382, -259), "Ganons Tower Pot 6", "Ganons Castle Ganons Tower Pot 6", RHT_POT_GANONS_CASTLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_7] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_7, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(-342, -300), "Ganons Tower Pot 7", "Ganons Castle Ganons Tower Pot 7", RHT_POT_GANONS_CASTLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_8] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_8, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(-301, -341), "Ganons Tower Pot 8", "Ganons Castle Ganons Tower Pot 8", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_9] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_9, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(-258, -383), "Ganons Tower Pot 9", "Ganons Castle Ganons Tower Pot 9", RHT_POT_GANONS_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_10] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_10, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(418, -261), "Ganons Tower Pot 10", "Ganons Castle Ganons Tower Pot 10", RHT_POT_GANONS_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_11] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_11, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(377, -301), "Ganons Tower Pot 11", "Ganons Castle Ganons Tower Pot 11", RHT_POT_GANONS_CASTLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_12] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_12, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(338, -340), "Ganons Tower Pot 12", "Ganons Castle Ganons Tower Pot 12", RHT_POT_GANONS_CASTLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_13] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_13, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(300, -380), "Ganons Tower Pot 13", "Ganons Castle Ganons Tower Pot 13", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_14] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_14, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(260, -420), "Ganons Tower Pot 14", "Ganons Castle Ganons Tower Pot 14", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_15] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_15, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(378, -261), "Ganons Tower Pot 15", "Ganons Castle Ganons Tower Pot 15", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_16] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_16, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(337, -300), "Ganons Tower Pot 16", "Ganons Castle Ganons Tower Pot 16", RHT_POT_GANONS_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_17] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_17, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(299, -340), "Ganons Tower Pot 17", "Ganons Castle Ganons Tower Pot 17", RHT_POT_GANONS_CASTLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17)); + locationTable[RC_GANONS_CASTLE_GANONS_TOWER_POT_18] = Location::Pot(RC_GANONS_CASTLE_GANONS_TOWER_POT_18, RCQUEST_BOTH, RCAREA_GANONS_CASTLE, SCENE_GANONS_TOWER, TWO_ACTOR_PARAMS(260, -380), "Ganons Tower Pot 18", "Ganons Castle Ganons Tower Pot 18", RHT_POT_GANONS_CASTLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-95, -673), "Basement Pot 1", "Bottom Of The Well Basement Pot 1", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(75, -598), "Basement Pot 2", "Bottom Of The Well Basement Pot 2", RHT_POT_BOTTOM_OF_THE_WELL, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(270, -1151), "Basement Pot 3", "Bottom Of The Well Basement Pot 3", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(566, -1254), "Basement Pot 4", "Bottom Of The Well Basement Pot 4", RHT_POT_BOTTOM_OF_THE_WELL, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(378, -1089), "Basement Pot 5", "Bottom Of The Well Basement Pot 5", RHT_POT_BOTTOM_OF_THE_WELL, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(665, -1252), "Basement Pot 6", "Bottom Of The Well Basement Pot 6", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(566, -1345), "Basement Pot 7", "Bottom Of The Well Basement Pot 7", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(562, -1304), "Basement Pot 8", "Bottom Of The Well Basement Pot 8", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(313, -1086), "Basement Pot 9", "Bottom Of The Well Basement Pot 9", RHT_POT_BOTTOM_OF_THE_WELL, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(618, -1254), "Basement Pot 10", "Bottom Of The Well Basement Pot 10", RHT_POT_BOTTOM_OF_THE_WELL, RG_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(257, -1099), "Basement Pot 11", "Bottom Of The Well Basement Pot 11", RHT_POT_BOTTOM_OF_THE_WELL, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12] = Location::Pot(RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(296, -1206), "Basement Pot 12", "Bottom Of The Well Basement Pot 12", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12)); + locationTable[RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1] = Location::Pot(RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-969, 55), "Left Side Pot 1", "Bottom Of The Well Left Side Pot 1", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1)); + locationTable[RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2] = Location::Pot(RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-966, 9), "Left Side Pot 2", "Bottom Of The Well Left Side Pot 2", RHT_POT_BOTTOM_OF_THE_WELL, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2)); + locationTable[RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3] = Location::Pot(RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-965, -32), "Left Side Pot 3", "Bottom Of The Well Left Side Pot 3", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3)); + locationTable[RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1] = Location::Pot(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-41, 389), "Near Entrance Pot 1", "Bottom Of The Well Near Entrance Pot 1", RHT_POT_BOTTOM_OF_THE_WELL, RG_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1)); + locationTable[RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2] = Location::Pot(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(36, 389), "Near Entrance Pot 2", "Bottom Of The Well Near Entrance Pot 2", RHT_POT_BOTTOM_OF_THE_WELL, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2)); + locationTable[RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1] = Location::Pot(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(874, -1294), "Fire Keese Pot 1", "Bottom Of The Well Fire Keese Pot 1", RHT_POT_BOTTOM_OF_THE_WELL, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1)); + locationTable[RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT] = Location::Pot(RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(3, -1641), "Underwater Pot", "Bottom Of The Well Underwater Pot", RHT_POT_BOTTOM_OF_THE_WELL, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT)); + locationTable[RC_ICE_CAVERN_HALL_POT_1] = Location::Pot(RC_ICE_CAVERN_HALL_POT_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-206, 449), "Hall Pot 1", "Ice Cavern Hall Pot 1", RHT_POT_ICE_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HALL_POT_1)); + locationTable[RC_ICE_CAVERN_HALL_POT_2] = Location::Pot(RC_ICE_CAVERN_HALL_POT_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-203, 492), "Hall Pot 2", "Ice Cavern Hall Pot 2", RHT_POT_ICE_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_HALL_POT_2)); + locationTable[RC_ICE_CAVERN_SPINNING_BLADE_POT_1] = Location::Pot(RC_ICE_CAVERN_SPINNING_BLADE_POT_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(433, -732), "Spinning Blade Pot 1", "Ice Cavern Spinning Blade Pot 1", RHT_POT_ICE_CAVERN, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1)); + locationTable[RC_ICE_CAVERN_SPINNING_BLADE_POT_2] = Location::Pot(RC_ICE_CAVERN_SPINNING_BLADE_POT_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(569, -175), "Spinning Blade Pot 2", "Ice Cavern Spinning Blade Pot 2", RHT_POT_ICE_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2)); + locationTable[RC_ICE_CAVERN_SPINNING_BLADE_POT_3] = Location::Pot(RC_ICE_CAVERN_SPINNING_BLADE_POT_3, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(521, -131), "Spinning Blade Pot 3", "Ice Cavern Spinning Blade Pot 3", RHT_POT_ICE_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3)); + locationTable[RC_ICE_CAVERN_NEAR_END_POT_1] = Location::Pot(RC_ICE_CAVERN_NEAR_END_POT_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1422, 586), "Near End Pot 1", "Ice Cavern Near End Pot 1", RHT_POT_ICE_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_POT_1)); + locationTable[RC_ICE_CAVERN_NEAR_END_POT_2] = Location::Pot(RC_ICE_CAVERN_NEAR_END_POT_2, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1488, 676), "Near End Pot 2", "Ice Cavern Near End Pot 2", RHT_POT_ICE_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_NEAR_END_POT_2)); + locationTable[RC_ICE_CAVERN_FROZEN_POT_1] = Location::Pot(RC_ICE_CAVERN_FROZEN_POT_1, RCQUEST_VANILLA, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(366, -2036), "Frozen Pot 1", "Ice Cavern Frozen Pot 1", RHT_POT_ICE_CAVERN, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_FROZEN_POT_1)); + + // MQ Dungeon Pots + // Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Spoiler Name Hint Text Key Vanilla Spoiler Collection Check + locationTable[RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-2391, -1804), "MQ Staircase Pot 1", "Dodongos Cavern MQ Staircase Pot 1", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-2361, -1161), "MQ Staircase Pot 2", "Dodongos Cavern MQ Staircase Pot 2", RHT_POT_DODONGOS_CAVERN, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-1525, -1800), "MQ Staircase Pot 3", "Dodongos Cavern MQ Staircase Pot 3", RHT_POT_DODONGOS_CAVERN, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3)); + locationTable[RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4] = Location::Pot(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-1558, -1169), "MQ Staircase Pot 4", "Dodongos Cavern MQ Staircase Pot 4", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4)); + locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT] = Location::Pot(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1532, -1225), "MQ Torch Puzzle Middle Pot", "Dodongos Cavern MQ Torch Puzzle Middle Pot", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3195, -155), "MQ Big Block Pot 1", "Dodongos Cavern MQ Big Block Pot 1", RHT_POT_DODONGOS_CAVERN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2704, -483), "MQ Big Block Pot 2", "Dodongos Cavern MQ Big Block Pot 2", RHT_POT_DODONGOS_CAVERN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3869, -811), "MQ Upper Lizalfos Pot 1", "Dodongos Cavern MQ Upper Lizalfos Pot 1", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3867, -969), "MQ Upper Lizalfos Pot 2", "Dodongos Cavern MQ Upper Lizalfos Pot 2", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4687, -1071), "MQ Upper Lizalfos Pot 3", "Dodongos Cavern MQ Upper Lizalfos Pot 3", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3)); + locationTable[RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4] = Location::Pot(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4693, -1194), "MQ Upper Lizalfos Pot 4", "Dodongos Cavern MQ Upper Lizalfos Pot 4", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4)); + locationTable[RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3327, -805), "MQ Two Flames Pot 1", "Dodongos Cavern MQ Two Flames Pot 1", RHT_POT_DODONGOS_CAVERN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3326, -753), "MQ Two Flames Pot 2", "Dodongos Cavern MQ Two Flames Pot 2", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT] = Location::Pot(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1827, -587), "MQ Torch Puzzle Corner Pot", "Dodongos Cavern MQ Torch Puzzle Corner Pot", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1727, -151), "MQ Right Side Pot 1", "Dodongos Cavern MQ Right Side Pot 1", RHT_POT_DODONGOS_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1815, -154), "MQ Right Side Pot 2", "Dodongos Cavern MQ Right Side Pot 2", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3442, -469), "MQ Right Side Pot 3", "Dodongos Cavern MQ Right Side Pot 3", RHT_POT_DODONGOS_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3)); + locationTable[RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4] = Location::Pot(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3682, -466), "MQ Right Side Pot 4", "Dodongos Cavern MQ Right Side Pot 4", RHT_POT_DODONGOS_CAVERN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4)); + locationTable[RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1844, -1867), "MQ Poe Room Pot 1", "Dodongos Cavern MQ Poe Room Pot 1", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2272, -2213), "MQ Poe Room Pot 2", "Dodongos Cavern MQ Poe Room Pot 2", RHT_POT_DODONGOS_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2240, -1369), "MQ Poe Room Pot 3", "Dodongos Cavern MQ Poe Room Pot 3", RHT_POT_DODONGOS_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3)); + locationTable[RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4] = Location::Pot(RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1535, -1299), "MQ Poe Room Pot 4", "Dodongos Cavern MQ Poe Room Pot 4", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4)); + locationTable[RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT] = Location::Pot(RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(258, -3055), "MQ Before Boss SW Pot", "Dodongos Cavern MQ Before Boss SW Pot", RHT_POT_DODONGOS_CAVERN, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT] = Location::Pot(RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(-265, -2499), "MQ Before Boss NE Pot", "Dodongos Cavern MQ Before Boss NE Pot", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT] = Location::Pot(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1758, -3194), "MQ Armos Room SE Pot", "Dodongos Cavern MQ Armos SE Pot", RHT_POT_DODONGOS_CAVERN, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3)); + locationTable[RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SW_POT] = Location::Pot(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SW_POT, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1223, -3197), "MQ Armos Room SW Pot", "Dodongos Cavern MQ Armos SW Pot", RHT_POT_DODONGOS_CAVERN, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4)); + locationTable[RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1] = Location::Pot(RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1663, -4311), "MQ Backroom Pot 1", "Dodongos Cavern MQ Backroom Pot 1", RHT_POT_DODONGOS_CAVERN, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2] = Location::Pot(RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1648, -4694), "MQ Backroom Pot 2", "Dodongos Cavern MQ Backroom Pot 2", RHT_POT_DODONGOS_CAVERN, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2)); + locationTable[RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT] = Location::Pot(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1005, -3711), "MQ Armos Room NW Pot", "Dodongos Cavern MQ Armos NW Pot", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1)); + locationTable[RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT] = Location::Pot(RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1066, -3711), "MQ Armos Room NE Pot", "Dodongos Cavern MQ Armos NE Pot", RHT_POT_DODONGOS_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1] = Location::Pot(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-183, -449), "MQ Entrance Pot 1", "Jabu Jabus Belly MQ Entrance Pot 1", RHT_POT_JABU_JABUS_BELLY, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2] = Location::Pot(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(202, -62), "MQ Entrance Pot 2", "Jabu Jabus Belly MQ Entrance Pot 2", RHT_POT_JABU_JABUS_BELLY, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1] = Location::Pot(RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-689, -1800), "MQ Geyser Pot 1", "Jabu Jabus Belly MQ Geyser Pot 1", RHT_POT_JABU_JABUS_BELLY, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2] = Location::Pot(RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-693, -1614), "MQ Geyser Pot 2", "Jabu Jabus Belly MQ Geyser Pot 2", RHT_POT_JABU_JABUS_BELLY, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1] = Location::Pot(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(697, -2318), "MQ Time Block Pot 1", "Jabu Jabus Belly MQ Time Block Pot 1", RHT_POT_JABU_JABUS_BELLY, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2] = Location::Pot(RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(699, -2445), "MQ Time Block Pot 2", "Jabu Jabus Belly MQ Time Block Pot 2", RHT_POT_JABU_JABUS_BELLY, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1] = Location::Pot(RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(612, -5932), "MQ Like Likes Pot 1", "Jabu Jabus Belly MQ Like Likes Pot 1", RHT_POT_JABU_JABUS_BELLY, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2] = Location::Pot(RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(718, -5929), "MQ Like Likes Pot 2", "Jabu Jabus Belly MQ Like Likes Pot 2", RHT_POT_JABU_JABUS_BELLY, RG_BOMBS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1] = Location::Pot(RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(1305, -2005), "MQ Before Boss Pot 1", "Jabu Jabus Belly MQ Before Boss Pot 1", RHT_POT_JABU_JABUS_BELLY, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1)); + locationTable[RC_FOREST_TEMPLE_MQ_LOBBY_POT_1] = Location::Pot(RC_FOREST_TEMPLE_MQ_LOBBY_POT_1, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(675, -989), "MQ Lobby Pot 1", "Forest Temple MQ Lobby Pot 1", RHT_POT_FOREST_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1)); + locationTable[RC_FOREST_TEMPLE_MQ_LOBBY_POT_2] = Location::Pot(RC_FOREST_TEMPLE_MQ_LOBBY_POT_2, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-429, -981), "MQ Lobby Pot 2", "Forest Temple MQ Lobby Pot 2", RHT_POT_FOREST_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2)); + locationTable[RC_FOREST_TEMPLE_MQ_LOBBY_POT_3] = Location::Pot(RC_FOREST_TEMPLE_MQ_LOBBY_POT_3, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(720, -1037), "MQ Lobby Pot 3", "Forest Temple MQ Lobby Pot 3", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3)); + locationTable[RC_FOREST_TEMPLE_MQ_LOBBY_POT_4] = Location::Pot(RC_FOREST_TEMPLE_MQ_LOBBY_POT_4, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-477, -1034), "MQ Lobby Pot 4", "Forest Temple MQ Lobby Pot 4", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4)); + locationTable[RC_FOREST_TEMPLE_MQ_LOBBY_POT_5] = Location::Pot(RC_FOREST_TEMPLE_MQ_LOBBY_POT_5, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(630, -943), "MQ Lobby Pot 5", "Forest Temple MQ Lobby Pot 5", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5)); + locationTable[RC_FOREST_TEMPLE_MQ_LOBBY_POT_6] = Location::Pot(RC_FOREST_TEMPLE_MQ_LOBBY_POT_6, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-384, -937), "MQ Lobby Pot 6", "Forest Temple MQ Lobby Pot 6", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6)); + locationTable[RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1] = Location::Pot(RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(90, -3583), "MQ Wolfos Pot 1", "Forest Temple MQ Wolfos Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1)); + locationTable[RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2] = Location::Pot(RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(142, -3583), "MQ Wolfos Pot 2", "Forest Temple MQ Wolfos Pot 2", RHT_POT_FOREST_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2)); + locationTable[RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1] = Location::Pot(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(206, -3631), "MQ Upper Stalfos Pot 1", "Forest Temple MQ Upper Stalfos Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1)); + locationTable[RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2] = Location::Pot(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(32, -3012), "MQ Upper Stalfos Pot 2", "Forest Temple MQ Upper Stalfos Pot 2", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2)); + locationTable[RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3] = Location::Pot(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(30, -3631), "MQ Upper Stalfos Pot 3", "Forest Temple MQ Upper Stalfos Pot 3", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3)); + locationTable[RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4] = Location::Pot(RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(202, -3012), "MQ Upper Stalfos Pot 4", "Forest Temple MQ Upper Stalfos Pot 4", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4)); + locationTable[RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1] = Location::Pot(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(830, -3639), "MQ Blue Poe Pot 1", "Forest Temple MQ Blue Poe Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1)); + locationTable[RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2] = Location::Pot(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(941, -3640), "MQ Blue Poe Pot 2", "Forest Temple MQ Blue Poe Pot 2", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2)); + locationTable[RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3] = Location::Pot(RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(883, -3640), "MQ Blue Poe Pot 3", "Forest Temple MQ Blue Poe Pot 3", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3)); + locationTable[RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1] = Location::Pot(RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(1647, -1529), "MQ Green Poe Pot 1", "Forest Temple MQ Green Poe Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1)); + locationTable[RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2] = Location::Pot(RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(1645, -1588), "MQ Green Poe Pot 2", "Forest Temple MQ Green Poe Pot 2", RHT_POT_FOREST_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2)); + locationTable[RC_FOREST_TEMPLE_MQ_BASEMENT_POT_1] = Location::Pot(RC_FOREST_TEMPLE_MQ_BASEMENT_POT_1, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-461, -1095), "MQ Basement Pot 1", "Forest Temple MQ Basement Pot 1", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1)); + locationTable[RC_FOREST_TEMPLE_MQ_BASEMENT_POT_2] = Location::Pot(RC_FOREST_TEMPLE_MQ_BASEMENT_POT_2, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-351, -979), "MQ Basement Pot 2", "Forest Temple MQ Basement Pot 2", RHT_POT_FOREST_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2)); + locationTable[RC_FOREST_TEMPLE_MQ_BASEMENT_POT_3] = Location::Pot(RC_FOREST_TEMPLE_MQ_BASEMENT_POT_3, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-387, -1018), "MQ Basement Pot 3", "Forest Temple MQ Basement Pot 3", RHT_POT_FOREST_TEMPLE, RG_BOMBS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3)); + locationTable[RC_FOREST_TEMPLE_MQ_BASEMENT_POT_4] = Location::Pot(RC_FOREST_TEMPLE_MQ_BASEMENT_POT_4, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-424, -1057), "MQ Basement Pot 4", "Forest Temple MQ Basement Pot 4", RHT_POT_FOREST_TEMPLE, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4)); + locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1873, 2252), "MQ Forest Trial Pot 1", "Ganons Castle MQ Forest Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1726, 2326), "MQ Forest Trial Pot 2", "Ganons Castle MQ Forest Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(3544, -931), "MQ Water Trial Pot 1", "Ganons Castle MQ Water Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(3541, -755), "MQ Water Trial Pot 2", "Ganons Castle MQ Water Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2073, -4592), "MQ Shadow Trial Pot 1", "Ganons Castle MQ Shadow Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(2217, -4516), "MQ Shadow Trial Pot 2", "Ganons Castle MQ Shadow Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1918, -3957), "MQ Fire Trial Pot 1", "Ganons Castle MQ Fire Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2052, -3888), "MQ Fire Trial Pot 2", "Ganons Castle MQ Fire Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-3842, -759), "MQ Light Trial Pot 1", "Ganons Castle MQ Light Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-3845, -933), "MQ Light Trial Pot 2", "Ganons Castle MQ Light Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2)); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1] = Location::Pot(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1402, 1414), "MQ Spirit Trial Pot 1", "Ganons Castle MQ Spirit Trial Pot 1", RHT_POT_GANONS_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1)); + locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2] = Location::Pot(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1256, 1500), "MQ Spirit Trial Pot 2", "Ganons Castle MQ Spirit Trial Pot 2", RHT_POT_GANONS_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2)); + locationTable[RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-1045, -130), "MQ Whispering Walls Pot 1", "Shadow Temple MQ Whispering Walls Pot 1", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1)); + locationTable[RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2] = Location::Pot(RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-1045, -240), "MQ Whispering Walls Pot 2", "Shadow Temple MQ Whispering Walls Pot 2", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2)); + locationTable[RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-657, -949), "MQ Entrance Redead Pot 1", "Shadow Temple MQ Entrance Redead Pot 1", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1)); + locationTable[RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2] = Location::Pot(RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-713, -1016), "MQ Entrance Redead Pot 2", "Shadow Temple MQ Entrance Redead Pot 2", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2)); + locationTable[RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT] = Location::Pot(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(614, 3579), "MQ Lower Umbrella W Pot", "Shadow Temple MQ Stone Umbrella Lower West Pot", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1)); + locationTable[RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT] = Location::Pot(RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(798, 3574), "MQ Lower Umbrella E Pot", "Shadow Temple MQ Stone Umbrella Lower East Pot", RHT_POT_SHADOW_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2)); + locationTable[RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT] = Location::Pot(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(1173, 3707), "MQ Upper Umbrella S Pot", "Shadow Temple MQ Stone Umbrella Upper South Pot", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3)); + locationTable[RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT] = Location::Pot(RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(1173, 3605), "MQ Upper Umbrella N Pot", "Shadow Temple MQ Stone Umbrella Upper North Pot", RHT_POT_SHADOW_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4)); + locationTable[RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(4222, -916), "MQ Before Boat Pot 1", "Shadow Temple MQ Before Boat Pot 1", RHT_POT_SHADOW_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1)); + locationTable[RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2] = Location::Pot(RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(4549, -922), "MQ Before Boat Pot 2", "Shadow Temple MQ Before Boat Pot 2", RHT_POT_SHADOW_TEMPLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2)); + locationTable[RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT] = Location::Pot(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-2400, -1470), "MQ Before Chasm W Pot", "Shadow Temple MQ Before Chasm West Pot", RHT_POT_SHADOW_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1)); + locationTable[RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT] = Location::Pot(RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-2230, -1470), "MQ Before Chasm E Pot", "Shadow Temple MQ Before Chasm East Pot", RHT_POT_SHADOW_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2)); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT] = Location::Pot(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-2859, -497), "MQ After Chasm W Pot", "Shadow Temple MQ After Chasm West Pot", RHT_POT_SHADOW_TEMPLE, RG_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3)); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT] = Location::Pot(RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-2624, -492), "MQ After Chasm E Pot", "Shadow Temple MQ After Chasm East Pot", RHT_POT_SHADOW_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4)); + locationTable[RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT] = Location::Pot(RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-4303, -2657), "MQ Spike Baricade Pot", "Shadow Temple MQ Spike Baricade Pot", RHT_POT_SHADOW_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT)); + locationTable[RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1] = Location::Pot(RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-4575, -811), "MQ Dead Hand Pot 1", "Shadow Temple MQ Dead Hand Pot 1", RHT_POT_SHADOW_TEMPLE, RG_BOMBS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1)); + locationTable[RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2] = Location::Pot(RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-4036, -811), "MQ Dead Hand Pot 2", "Shadow Temple MQ Dead Hand Pot 2", RHT_POT_SHADOW_TEMPLE, RG_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1] = Location::Pot(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(339, -377), "MQ Inner Lobby Pot 1", "Bottom Of The Well MQ Inner Lobby Pot 1", RHT_POT_BOTTOM_OF_THE_WELL, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2] = Location::Pot(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(416, -377), "MQ Inner Lobby Pot 2", "Bottom Of The Well MQ Inner Lobby Pot 2", RHT_POT_BOTTOM_OF_THE_WELL, RG_BOMBS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3] = Location::Pot(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(269, -376), "MQ Inner Lobby Pot 3", "Bottom Of The Well MQ Inner Lobby Pot 3", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT] = Location::Pot(RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(421, -174), "MQ Outer Lobby Pot", "Bottom Of The Well MQ Outer Lobby Pot", RHT_POT_BOTTOM_OF_THE_WELL, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1] = Location::Pot(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(288, -1240), "MQ East Inner Pot 1", "Bottom Of The Well MQ East Inner Room Pot 1", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2] = Location::Pot(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(438, -1234), "MQ East Inner Pot 2", "Bottom Of The Well MQ East Inner Room Pot 2", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3] = Location::Pot(RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(444, -1114), "MQ East Inner Pot 3", "Bottom Of The Well MQ East Inner Room Pot 3", RHT_POT_BOTTOM_OF_THE_WELL, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3)); + locationTable[RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1] = Location::Pot(RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-357, 957), "MQ Entrance Pot 1", "Fire Temple MQ Entrance Pot 1", RHT_POT_FIRE_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1)); + locationTable[RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2] = Location::Pot(RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(356, 959), "MQ Entrance Pot 2", "Fire Temple MQ Entrance Pot 2", RHT_POT_FIRE_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2)); + locationTable[RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1] = Location::Pot(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(187, -1449), "MQ Before Mini Boss Pot 1", "Fire Temple MQ Before Mini Boss Pot 1", RHT_POT_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1)); + locationTable[RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2] = Location::Pot(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(188, -1514), "MQ Before Mini Boss Pot 2", "Fire Temple MQ Before Mini Boss Pot 2", RHT_POT_FIRE_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2)); + locationTable[RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3] = Location::Pot(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(487, -1450), "MQ Before Mini Boss Pot 3", "Fire Temple MQ Before Mini Boss Pot 3", RHT_POT_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3)); + locationTable[RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4] = Location::Pot(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(486, -1515), "MQ Before Mini Boss Pot 4", "Fire Temple MQ Before Mini Boss Pot 4", RHT_POT_FIRE_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4)); + locationTable[RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5] = Location::Pot(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(38, -1179), "MQ Before Mini Boss Pot 5", "Fire Temple MQ Before Mini Boss Pot 5", RHT_POT_FIRE_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5)); + locationTable[RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6] = Location::Pot(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(42, -1298), "MQ Before Mini Boss Pot 6", "Fire Temple MQ Before Mini Boss Pot 6", RHT_POT_FIRE_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6)); + locationTable[RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7] = Location::Pot(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(520, -943), "MQ Before Mini Boss Pot 7", "Fire Temple MQ Before Mini Boss Pot 7", RHT_POT_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7)); + locationTable[RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8] = Location::Pot(RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(35, -946), "MQ Before Mini Boss Pot 8", "Fire Temple MQ Before Mini Boss Pot 8", RHT_POT_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8)); + locationTable[RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1] = Location::Pot(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-1426, -711), "MQ Outside Boss Pot 1", "Fire Temple MQ Outside Boss Pot 1", RHT_POT_FIRE_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1)); + locationTable[RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2] = Location::Pot(RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-1425, -660), "MQ Outside Boss Pot 2", "Fire Temple MQ Outside Boss Pot 2", RHT_POT_FIRE_TEMPLE, RG_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2)); + locationTable[RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT] = Location::Pot(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1646, -1260), "MQ Lava Room North Pot", "Fire Temple MQ Lava Room North Pot", RHT_POT_FIRE_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1)); + locationTable[RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT] = Location::Pot(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(2226, -809), "MQ Lava Room High Pot", "Fire Temple MQ Lava Room High Pot", RHT_POT_FIRE_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2)); + locationTable[RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT] = Location::Pot(RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1634, 1475), "MQ Lava Room South Pot", "Fire Temple MQ Lava Room South Pot", RHT_POT_FIRE_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3)); + locationTable[RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1] = Location::Pot(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(845, -1591), "MQ Lava Torch Pot 1", "Fire Temple MQ Lava Torch Pot 1", RHT_POT_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1)); + locationTable[RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2] = Location::Pot(RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(901, -1593), "MQ Lava Torch Pot 2", "Fire Temple MQ Lava Torch Pot 2", RHT_POT_FIRE_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2)); + locationTable[RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1] = Location::Pot(RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1756, -155), "MQ Above Lava Pot 1", "Fire Temple MQ Above Lava Pot 1", RHT_POT_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1)); + locationTable[RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2] = Location::Pot(RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1819, -82), "MQ Above Lava Pot 2", "Fire Temple MQ Above Lava Pot 2", RHT_POT_FIRE_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2)); + locationTable[RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3] = Location::Pot(RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1789, -122), "MQ Above Lava Pot 3", "Fire Temple MQ Above Lava Pot 3", RHT_POT_FIRE_TEMPLE, RG_BOMBS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3)); + locationTable[RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1] = Location::Pot(RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1493, 386), "MQ Flame Wall Pot 1", "Fire Temple MQ Flame Wall Pot 1", RHT_POT_FIRE_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1)); + locationTable[RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2] = Location::Pot(RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1445, 445), "MQ Flame Wall Pot 2", "Fire Temple MQ Flame Wall Pot 2", RHT_POT_FIRE_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2)); + locationTable[RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT] = Location::Pot(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2217, -163), "MQ Past Fire Maze North Pot", "Fire Temple MQ Past Fire Maze North Pot", RHT_POT_FIRE_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1)); + locationTable[RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT] = Location::Pot(RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2657, -591), "MQ Past Fire Maze South Pot", "Fire Temple MQ Past Fire Maze South Pot", RHT_POT_FIRE_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2)); + locationTable[RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT] = Location::Pot(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-1849, -1114), "MQ Fire Maze Northmost Pot", "Fire Temple MQ Fire Maze Northmost Pot", RHT_POT_FIRE_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3)); + locationTable[RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT] = Location::Pot(RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2110, -646), "MQ Fire Maze North West Pot", "Fire Temple MQ Fire Maze North West Pot", RHT_POT_FIRE_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4)); + locationTable[RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT] = Location::Pot(RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2319, 838), "MQ South Fire Maze W Pot", "Fire Temple MQ South Fire Maze West Pot", RHT_POT_FIRE_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5)); + locationTable[RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT] = Location::Pot(RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(-2285, 803), "MQ South Fire Maze E Pot", "Fire Temple MQ South Fire Maze East Pot", RHT_POT_FIRE_TEMPLE, RG_BOMBS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6)); + locationTable[RC_ICE_CAVERN_MQ_ENTRANCE_POT] = Location::Pot(RC_ICE_CAVERN_MQ_ENTRANCE_POT, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(248, 2287), "MQ Entrance Pot", "Ice Cavern MQ Entrance Pot", RHT_POT_ICE_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT)); + locationTable[RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1] = Location::Pot(RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(51, 718), "MQ First Crystal Pot 1", "Ice Cavern MQ First Crystal Pot 1", RHT_POT_ICE_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1)); + locationTable[RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2] = Location::Pot(RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(52, 768), "MQ First Crystal Pot 2", "Ice Cavern MQ First Crystal Pot 2", RHT_POT_ICE_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2)); + locationTable[RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1] = Location::Pot(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(433, -732), "MQ Early Wolfos Pot 1", "Ice Cavern MQ Early Wolfos Pot 1", RHT_POT_ICE_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1)); + locationTable[RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2] = Location::Pot(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(569, -175), "MQ Early Wolfos Pot 2", "Ice Cavern MQ Early Wolfos Pot 2", RHT_POT_ICE_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2)); + locationTable[RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3] = Location::Pot(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(521, -131), "MQ Early Wolfos Pot 3", "Ice Cavern MQ Early Wolfos Pot 3", RHT_POT_ICE_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3)); + locationTable[RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4] = Location::Pot(RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(138, -672), "MQ Early Wolfos Pot 4", "Ice Cavern MQ Early Wolfos Pot 4", RHT_POT_ICE_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4)); + locationTable[RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1] = Location::Pot(RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1352, 639), "MQ Push Block Pot 1", "Ice Cavern MQ Push Block Pot 1", RHT_POT_ICE_CAVERN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1)); + locationTable[RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2] = Location::Pot(RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1396, 596), "MQ Push Block Pot 2", "Ice Cavern MQ Push Block Pot 2", RHT_POT_ICE_CAVERN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2)); + locationTable[RC_ICE_CAVERN_MQ_COMPASS_POT_1] = Location::Pot(RC_ICE_CAVERN_MQ_COMPASS_POT_1, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(902, -2720), "MQ Compass Pot 1", "Ice Cavern MQ Compass Pot 1", RHT_POT_ICE_CAVERN, RG_BOMBS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1)); + locationTable[RC_ICE_CAVERN_MQ_COMPASS_POT_2] = Location::Pot(RC_ICE_CAVERN_MQ_COMPASS_POT_2, RCQUEST_MQ, RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(451, -2726), "MQ Compass Pot 2", "Ice Cavern MQ Compass Pot 2", RHT_POT_ICE_CAVERN, RG_BOMBS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-255, 742), "MQ Entrance Pot 1", "Spirit Temple MQ Entrance Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(306, 682), "MQ Entrance Pot 2", "Spirit Temple MQ Entrance Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-297, 687), "MQ Entrance Pot 3", "Spirit Temple MQ Entrance Pot 3", RHT_POT_SPIRIT_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3)); + locationTable[RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(260, 735), "MQ Entrance Pot 4", "Spirit Temple MQ Entrance Pot 4", RHT_POT_SPIRIT_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-894, -50), "MQ Child Slugma Pot", "Spirit Temple MQ Child Slugma Pot", RHT_POT_SPIRIT_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-382, -1256), "MQ Child Gibdo Pot 1", "Spirit Temple MQ Child Gibdo Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-381, -1207), "MQ Child Gibdo Pot 2", "Spirit Temple MQ Child Gibdo Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1035, -1240), "MQ Child Like Like Pot", "Spirit Temple MQ Child Like Like Pot", RHT_POT_SPIRIT_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1166, -1931), "MQ Child Stalfos Pot 1", "Spirit Temple MQ Child Stalfos Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-959, -1930), "MQ Child Stalfos Pot 2", "Spirit Temple MQ Child Stalfos Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-853, -1837), "MQ Child Stalfos Pot 3", "Spirit Temple MQ Child Stalfos Pot 3", RHT_POT_SPIRIT_TEMPLE, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1250, -1852), "MQ Child Stalfos Pot 4", "Spirit Temple MQ Child Stalfos Pot 4", RHT_POT_SPIRIT_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4)); + locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(639, -1224), "MQ Statue Room 2F CE Pot", "Spirit Temple MQ Statue 2F Center East Pot", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-521, -1576), "MQ Statue Room 3F E Pot", "Spirit Temple MQ Statue Room 3F East Pot", RHT_POT_SPIRIT_TEMPLE, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-595, -1576), "MQ Statue Room 3F W Pot", "Spirit Temple MQ Statue Room 3F West Pot", RHT_POT_SPIRIT_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3)); + locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-559, -1209), "MQ Statue Room 2F W Pot", "Spirit Temple MQ Statue 2F West Pot", RHT_POT_SPIRIT_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4)); + locationTable[RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(704, -1224), "MQ Statue Room 2F E Pot", "Spirit Temple MQ Statue 2F Eastmost Pot", RHT_POT_SPIRIT_TEMPLE, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5)); + locationTable[RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1276, 432), "MQ Sun Blocks Pot 1", "Spirit Temple MQ Sun Blocks Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1635, -446), "MQ Sun Blocks Pot 2", "Spirit Temple MQ Sun Blocks Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(829, 250), "MQ Long Climb Pot 1", "Spirit Temple MQ Long Climb Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(531, 249), "MQ Long Climb Pot 2", "Spirit Temple MQ Long Climb Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(244, -893), "MQ Big Mirror Pot 1", "Spirit Temple MQ Big Mirror Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-122, -741), "MQ Big Mirror Pot 2", "Spirit Temple MQ Big Mirror Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(250, -741), "MQ Big Mirror Pot 3", "Spirit Temple MQ Big Mirror Pot 3", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3)); + locationTable[RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-123, -892), "MQ Big Mirror Pot 4", "Spirit Temple MQ Big Mirror Pot 4", RHT_POT_SPIRIT_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4)); + locationTable[RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(781, -841), "MQ Before Mirror Pot 1", "Spirit Temple MQ Before Mirror Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(587, -844), "MQ Before Mirror Pot 2", "Spirit Temple MQ Before Mirror Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2)); + locationTable[RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(1204, -910), "MQ Early Adult Pot 1", "Spirit Temple MQ Early Adult Pot 1", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1)); + locationTable[RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2] = Location::Pot(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(1204, -1028), "MQ Early Adult Pot 2", "Spirit Temple MQ Early Adult Pot 2", RHT_POT_SPIRIT_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2)); + locationTable[RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1] = Location::Pot(RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(1123, 62), "MQ Lower Torches Pot 1", "Water Temple MQ Lower Torches Pot 1", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1)); + locationTable[RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(1123, 293), "MQ Lower Torches Pot 2", "Water Temple MQ Lower Torches Pot 2", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2)); + locationTable[RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1] = Location::Pot(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(1222, -617), "MQ Storage Room A Pot 1", "Water Temple MQ Storage Room A Pot 1", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1)); + locationTable[RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(1122, -617), "MQ Storage Room A Pot 2", "Water Temple MQ Storage Room A Pot 2", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2)); + locationTable[RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3] = Location::Pot(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(1172, -617), "MQ Storage Room A Pot 3", "Water Temple MQ Storage Room A Pot 3", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3)); + locationTable[RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1] = Location::Pot(RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-989, 255), "MQ GS Storage Room Pot 1", "Water Temple MQ GS Storage Room Pot 1", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1)); + locationTable[RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-1026, 257), "MQ GS Storage Room Pot 2", "Water Temple MQ GS Storage Room Pot 2", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2)); + locationTable[RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3] = Location::Pot(RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-1062, 256), "MQ GS Storage Room Pot 3", "Water Temple MQ GS Storage Room Pot 3", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3)); + locationTable[RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_WEST_POT] = Location::Pot(RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_WEST_POT, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(512, 579), "MQ Lizalfos Hall W Pot", "Water Temple MQ Lizalfos Hallway West Pot", RHT_POT_WATER_TEMPLE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1)); + locationTable[RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SOUTH_POT] = Location::Pot(RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SOUTH_POT, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(602, 1022), "MQ Lizalfos Hall S Pot", "Water Temple MQ Lizalfos Hallway South Pot", RHT_POT_WATER_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2)); + locationTable[RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SE_POT] = Location::Pot(RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SE_POT, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(789, 947), "MQ Lizalfos Hall SE Pot", "Water Temple MQ Lizalfos Hallway SE Pot", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3)); + locationTable[RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_SOUTH_POT] = Location::Pot(RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_SOUTH_POT, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(768, 565), "MQ Lizalfos Cage N Pot", "Water Temple MQ Lizalfos Cage North Pot", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4)); + locationTable[RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_NORTH_POT] = Location::Pot(RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_NORTH_POT, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(767, 517), "MQ Lizalfos Cage S Pot", "Water Temple MQ Lizalfos Cage South Pot", RHT_POT_WATER_TEMPLE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5)); + locationTable[RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT] = Location::Pot(RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-3500, -751), "MQ Stalfos Pit Middle Pot", "Water Temple MQ Stalfos Pit Middle Pot", RHT_POT_WATER_TEMPLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3)); + locationTable[RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT] = Location::Pot(RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-3500, -686), "MQ Stalfos Pit South Pot", "Water Temple MQ Stalfos Pit South Pot", RHT_POT_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4)); + locationTable[RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT] = Location::Pot(RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-3500, -810), "MQ Stalfos Pit North Pot", "Water Temple MQ Stalfos Pit North Pot", RHT_POT_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5)); + locationTable[RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1] = Location::Pot(RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-3188, -1628), "MQ Before Dark Link Pot 1", "Water Temple MQ Before Dark Link Pot 1", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1)); + locationTable[RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-3056, -1626), "MQ Before Dark Link Pot 2", "Water Temple MQ Before Dark Link Pot 2", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2)); + locationTable[RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1] = Location::Pot(RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-3072, -4024), "MQ After Dark Link Pot 1", "Water Temple MQ After Dark Link Pot 1", RHT_POT_WATER_TEMPLE, RG_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1)); + locationTable[RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-3169, -4023), "MQ After Dark Link Pot 2", "Water Temple MQ After Dark Link Pot 2", RHT_POT_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2)); + locationTable[RC_WATER_TEMPLE_MQ_RIVER_POT_1] = Location::Pot(RC_WATER_TEMPLE_MQ_RIVER_POT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2226, -2487), "MQ River Pot 1", "Water Temple MQ River Pot 1", RHT_POT_WATER_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1)); + locationTable[RC_WATER_TEMPLE_MQ_RIVER_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_RIVER_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2184, -2456), "MQ River Pot 2", "Water Temple MQ River Pot 2", RHT_POT_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2)); + locationTable[RC_WATER_TEMPLE_MQ_BOSS_KEY_POT] = Location::Pot(RC_WATER_TEMPLE_MQ_BOSS_KEY_POT, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-1033, -1569), "MQ Boss Key Pot", "Water Temple MQ Boss Key Pot", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT)); + locationTable[RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_1] = Location::Pot(RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2314, 770), "MQ Lowest GS Pot 1", "Water Temple MQ Lowest GS Pot 1", RHT_POT_WATER_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1)); + locationTable[RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2314, 808), "MQ Lowest GS Pot 2", "Water Temple MQ Lowest GS Pot 2", RHT_POT_WATER_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2)); + locationTable[RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_3] = Location::Pot(RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2313, 944), "MQ Lowest GS Pot 3", "Water Temple MQ Lowest GS Pot 3", RHT_POT_WATER_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3)); + locationTable[RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_4] = Location::Pot(RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2313, 905), "MQ Lowest GS Pot 4", "Water Temple MQ Lowest GS Pot 4", RHT_POT_WATER_TEMPLE, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4)); + locationTable[RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1] = Location::Pot(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-1417, -3025), "MQ Storage Room B Pot 1", "Water Temple MQ Storage Room B Pot 1", RHT_POT_WATER_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1)); + locationTable[RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-1150, -3031), "MQ Storage Room B Pot 2", "Water Temple MQ Storage Room B Pot 2", RHT_POT_WATER_TEMPLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2)); + locationTable[RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1] = Location::Pot(RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(28, -3817), "MQ Mini Dodongo Pot 1", "Water Temple MQ Mini Dodongo Pot 1", RHT_POT_WATER_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1)); + locationTable[RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2] = Location::Pot(RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-28, -3817), "MQ Mini Dodongo Pot 2", "Water Temple MQ Mini Dodongo Pot 2", RHT_POT_WATER_TEMPLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-324, -72), "MQ Lobby Left Pot 1", "Gerudo Training Ground MQ Lobby Left Pot 1", RHT_POT_GERUDO_TRAINING_GROUND, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(-324, -177), "MQ Lobby Left Pot 2", "Gerudo Training Ground MQ Lobby Left Pot 2", RHT_POT_GERUDO_TRAINING_GROUND, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(199, -79), "MQ Lobby Right Pot 1", "Gerudo Training Ground MQ Lobby Right Pot 1", RHT_POT_GERUDO_TRAINING_GROUND, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1)); + locationTable[RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2] = Location::Pot(RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, RCQUEST_MQ, RCAREA_GERUDO_TRAINING_GROUND, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(197, -179), "MQ Lobby Right Pot 2", "Gerudo Training Ground MQ Lobby Right Pot 2", RHT_POT_GERUDO_TRAINING_GROUND, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2)); + + // Fairies + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1800, "Grotto Fairy 1", "SFM Grotto Fairy 1", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1801, "Grotto Fairy 2", "SFM Grotto Fairy 2", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1802, "Grotto Fairy 3", "SFM Grotto Fairy 3", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1803, "Grotto Fairy 4", "SFM Grotto Fairy 4", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1804, "Grotto Fairy 5", "SFM Grotto Fairy 5", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1805, "Grotto Fairy 6", "SFM Grotto Fairy 6", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1806, "Grotto Fairy 7", "SFM Grotto Fairy 7", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7)); + locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1807, "Grotto Fairy 8", "SFM Grotto Fairy 8", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0300, "Grotto Fairy 1", "ZR Grotto Fairy 1", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0301, "Grotto Fairy 2", "ZR Grotto Fairy 2", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0302, "Grotto Fairy 3", "ZR Grotto Fairy 3", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0303, "Grotto Fairy 4", "ZR Grotto Fairy 4", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0304, "Grotto Fairy 5", "ZR Grotto Fairy 5", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0305, "Grotto Fairy 6", "ZR Grotto Fairy 6", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0306, "Grotto Fairy 7", "ZR Grotto Fairy 7", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7)); + locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0307, "Grotto Fairy 8", "ZR Grotto Fairy 8", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F00, "Grotto Fairy 1", "HF Grotto Fairy 1", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_1)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F01, "Grotto Fairy 2", "HF Grotto Fairy 2", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_2)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F02, "Grotto Fairy 3", "HF Grotto Fairy 3", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_3)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F03, "Grotto Fairy 4", "HF Grotto Fairy 4", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_4)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F04, "Grotto Fairy 5", "HF Grotto Fairy 5", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_5)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F05, "Grotto Fairy 6", "HF Grotto Fairy 6", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_6)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F06, "Grotto Fairy 7", "HF Grotto Fairy 7", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_7)); + locationTable[RC_HF_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F07, "Grotto Fairy 8", "HF Grotto Fairy 8", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_8)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C00, "Grotto Fairy 1", "ZD Grotto Fairy 1", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C01, "Grotto Fairy 2", "ZD Grotto Fairy 2", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C02, "Grotto Fairy 3", "ZD Grotto Fairy 3", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C03, "Grotto Fairy 4", "ZD Grotto Fairy 4", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C04, "Grotto Fairy 5", "ZD Grotto Fairy 5", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C05, "Grotto Fairy 6", "ZD Grotto Fairy 6", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C06, "Grotto Fairy 7", "ZD Grotto Fairy 7", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7)); + locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C07, "Grotto Fairy 8", "ZD Grotto Fairy 8", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D00, "Grotto Fairy 1", "GF Grotto Fairy 1", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_1)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D01, "Grotto Fairy 2", "GF Grotto Fairy 2", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_2)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D02, "Grotto Fairy 3", "GF Grotto Fairy 3", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_3)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D03, "Grotto Fairy 4", "GF Grotto Fairy 4", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_4)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D04, "Grotto Fairy 5", "GF Grotto Fairy 5", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_5)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D05, "Grotto Fairy 6", "GF Grotto Fairy 6", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_6)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D06, "Grotto Fairy 7", "GF Grotto Fairy 7", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_7)); + locationTable[RC_GF_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D07, "Grotto Fairy 8", "GF Grotto Fairy 8", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_8)); + + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x00, "Shield Grave Fairy 1", "Shield Grave Fairy 1", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x01, "Shield Grave Fairy 2", "Shield Grave Fairy 2", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x02, "Shield Grave Fairy 3", "Shield Grave Fairy 3", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x03, "Shield Grave Fairy 4", "Shield Grave Fairy 4", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x04, "Shield Grave Fairy 5", "Shield Grave Fairy 5", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x05, "Shield Grave Fairy 6", "Shield Grave Fairy 6", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x06, "Shield Grave Fairy 7", "Shield Grave Fairy 7", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7)); + locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x07, "Shield Grave Fairy 8", "Shield Grave Fairy 8", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_1] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_1, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x00, "Scrubs Fairy 1", "Scrubs Fairy 1", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_2] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_2, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x01, "Scrubs Fairy 2", "Scrubs Fairy 2", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_3] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_3, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x02, "Scrubs Fairy 3", "Scrubs Fairy 3", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_4] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_4, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x03, "Scrubs Fairy 4", "Scrubs Fairy 4", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_5] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_5, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x04, "Scrubs Fairy 5", "Scrubs Fairy 5", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_6] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_6, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x05, "Scrubs Fairy 6", "Scrubs Fairy 6", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_7] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_7, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x06, "Scrubs Fairy 7", "Scrubs Fairy 7", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7)); + locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_8] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x07, "Scrubs Fairy 8", "Scrubs Fairy 8", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x00, "MQ Scrubs Fairy 1", "MQ Scrubs Fairy 1", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x01, "MQ Scrubs Fairy 2", "MQ Scrubs Fairy 2", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x02, "MQ Scrubs Fairy 3", "MQ Scrubs Fairy 3", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x03, "MQ Scrubs Fairy 4", "MQ Scrubs Fairy 4", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x04, "MQ Scrubs Fairy 5", "MQ Scrubs Fairy 5", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x05, "MQ Scrubs Fairy 6", "MQ Scrubs Fairy 6", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x06, "MQ Scrubs Fairy 7", "MQ Scrubs Fairy 7", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7)); + locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x07, "MQ Scrubs Fairy 8", "MQ Scrubs Fairy 8", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_1] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x00, "Oasis Fairy 1", "Oasis Fairy 1", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_1)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_2] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x01, "Oasis Fairy 2", "Oasis Fairy 2", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_2)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_3] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x02, "Oasis Fairy 3", "Oasis Fairy 3", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_3)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_4] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_4, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x03, "Oasis Fairy 4", "Oasis Fairy 4", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_4)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_5] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_5, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x04, "Oasis Fairy 5", "Oasis Fairy 5", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_5)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_6] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_6, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x05, "Oasis Fairy 6", "Oasis Fairy 6", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_6)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_7] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_7, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x06, "Oasis Fairy 7", "Oasis Fairy 7", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_7)); + locationTable[RC_COLOSSUS_OASIS_FAIRY_8] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_8, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x07, "Oasis Fairy 8", "Oasis Fairy 8", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_8)); + + locationTable[RC_ZR_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_ZR_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0300, "Bean Sprout Fairy 1", "ZR Bean Sprout Fairy 1", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_ZR_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_ZR_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0301, "Bean Sprout Fairy 2", "ZR Bean Sprout Fairy 2", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_ZR_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_ZR_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0302, "Bean Sprout Fairy 3", "ZR Bean Sprout Fairy 3", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_KF_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_KF_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0900, "Bean Sprout Fairy 1", "KF Bean Sprout Fairy 1", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_KF_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_KF_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0901, "Bean Sprout Fairy 2", "KF Bean Sprout Fairy 2", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_KF_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_KF_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0902, "Bean Sprout Fairy 3", "KF Bean Sprout Fairy 3", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0400, "Bean Sprout Near Bridge Fairy 1", "LW Bean Sprout Near Bridge Fairy 1", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0401, "Bean Sprout Near Bridge Fairy 2", "LW Bean Sprout Near Bridge Fairy 2", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0402, "Bean Sprout Near Bridge Fairy 3", "LW Bean Sprout Near Bridge Fairy 3", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1200, "Bean Sprout Near Theatre Fairy 1", "LW Bean Sprout Near Theatre Fairy 1", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1201, "Bean Sprout Near Theatre Fairy 2", "LW Bean Sprout Near Theatre Fairy 2", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2)); + locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1202, "Bean Sprout Near Theatre Fairy 3", "LW Bean Sprout Near Theatre Fairy 3", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3)); + locationTable[RC_LH_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_LH_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0100, "Bean Sprout Fairy 1", "LH Bean Sprout Fairy 1", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_LH_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_LH_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0101, "Bean Sprout Fairy 2", "LH Bean Sprout Fairy 2", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_LH_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_LH_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0102, "Bean Sprout Fairy 3", "LH Bean Sprout Fairy 3", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_GV_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_GV_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0300, "Bean Sprout Fairy 1", "GV Bean Sprout Fairy 1", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_GV_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_GV_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0301, "Bean Sprout Fairy 2", "GV Bean Sprout Fairy 2", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_GV_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_GV_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0302, "Bean Sprout Fairy 3", "GV Bean Sprout Fairy 3", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1800, "Bean Sprout Fairy 1", "Col Bean Sprout Fairy 1", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1801, "Bean Sprout Fairy 2", "Col Bean Sprout Fairy 2", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1802, "Bean Sprout Fairy 3", "Col Bean Sprout Fairy 3", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0300, "Bean Sprout Fairy 1", "GY Bean Sprout Fairy 1", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0301, "Bean Sprout Fairy 2", "GY Bean Sprout Fairy 2", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0302, "Bean Sprout Fairy 3", "GY Bean Sprout Fairy 3", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_DMC_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_DMC_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0300, "Bean Sprout Fairy 1", "DMC Bean Sprout Fairy 1", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_DMC_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_DMC_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0301, "Bean Sprout Fairy 2", "DMC Bean Sprout Fairy 2", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_DMC_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_DMC_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0302, "Bean Sprout Fairy 3", "DMC Bean Sprout Fairy 3", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_3)); + locationTable[RC_DMT_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_DMT_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0600, "Bean Sprout Fairy 1", "DMT Bean Sprout Fairy 1", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_1)); + locationTable[RC_DMT_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_DMT_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0601, "Bean Sprout Fairy 2", "DMT Bean Sprout Fairy 2", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_2)); + locationTable[RC_DMT_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_DMT_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0602, "Bean Sprout Fairy 3", "DMT Bean Sprout Fairy 3", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_3)); + + locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -680), "ToT Left Gossip Stone Fairy", "ToT Left Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY)); + locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -680), "ToT Left Gossip Stone Big Fairy", "ToT Left Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -615), "ToT Left Center Gossip Stone Fairy", "ToT Left Center Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY)); + locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -615), "ToT Left Center Gossip Stone Big Fairy", "ToT Left Center Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -550), "ToT Right Center Gossip Stone Fairy", "ToT Right Center Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY)); + locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -550), "ToT Right Center Gossip Stone Big Fairy", "ToT Right Center Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -485), "ToT Right Gossip Stone Fairy", "ToT Right Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY)); + locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -485), "ToT Right Gossip Stone Big Fairy", "ToT Right Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DMC_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMC_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS( 0, 1656), "Gossip Stone Fairy", "DMC Gossip Stone Fairy", RHT_DMC_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_STONE_FAIRY)); + locationTable[RC_DMC_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMC_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(0x1000, 1656), "Gossip Stone Big Fairy", "DMC Gossip Stone Big Fairy", RHT_DMC_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DMT_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS( 0, -3935), "Gossip Stone Fairy", "DMT Gossip Stone Fairy", RHT_DMT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GOSSIP_STONE_FAIRY)); + locationTable[RC_DMT_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, -3935), "Gossip Stone Big Fairy", "DMT Gossip Stone Big Fairy", RHT_DMT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_COLOSSUS_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_COLOSSUS_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS( 0, 1320), "Gossip Stone Fairy", "Col Gossip Stone Fairy", RHT_COLOSSUS_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY)); + locationTable[RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(0x1000, 1320), "Gossip Stone Big Fairy", "Col Gossip Stone Big Fairy", RHT_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, RCQUEST_VANILLA,RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS( 0, -1520), "Gossip Stone Fairy", "DC Gossip Stone Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY)); + locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, RCQUEST_VANILLA,RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(0x1000, -1520), "Gossip Stone Big Fairy", "DC Gossip Stone Big Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS( 0, -916), "MQ Gossip Stone Fairy", "DC MQ Gossip Stone Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY)); + locationTable[RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(0x1000, -916), "MQ Gossip Stone Big Fairy", "DC MQ Gossip Stone Big Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_GV_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GV_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS( 0, -2340), "Gossip Stone Fairy", "GV Gossip Stone Fairy", RHT_GV_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_GOSSIP_STONE_FAIRY)); + locationTable[RC_GV_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GV_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(0x1000, -2340), "Gossip Stone Big Fairy", "GV Gossip Stone Big Fairy", RHT_GV_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_GC_MAZE_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GC_MAZE_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS( 0, -1265), "Maze Gossip Stone Fairy", "GC Maze Gossip Stone Fairy", RHT_GC_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY)); + locationTable[RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(0x1000, -1265), "Maze Gossip Stone Big Fairy", "GC Maze Gossip Stone Big Fairy", RHT_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS( 0, 1496), "Medigoron Gossip Stone Fairy", "GC Medigoron Gossip Stone Fairy", RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY)); + locationTable[RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(0x1000, 1496), "Medigoron Gossip Stone Big Fairy", "GC Medigoron Gossip Stone Big Fairy", RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_GRAVEYARD_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GRAVEYARD_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS( 0, -75), "Gossip Stone Fairy", "GY Gossip Stone Fairy", RHT_GRAVEYARD_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY)); + locationTable[RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(0x1000, -75), "Gossip Stone Big Fairy", "GY Gossip Stone Big Fairy", RHT_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HC_MALON_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HC_MALON_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS( 0, 3445), "Malon Gossip Stone Fairy", "HC Malon Gossip Stone Fairy", RHT_HC_MALON_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY)); + locationTable[RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(0x1000, 3445), "Malon Gossip Stone Big Fairy", "HC Malon Gossip Stone Big Fairy", RHT_HC_MALON_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS( 0, 1041), "Rock Wall Gossip Stone Fairy", "HC Rock Wall Gossip Stone Fairy", RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY)); + locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(0x1000, 1041), "Rock Wall Gossip Stone Big Fairy", "HC Rock Wall Gossip Stone Big Fairy", RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0xC, 735), "Storms Grotto Gossip Stone Fairy", "HC Storms Grotto Gossip Stone Fairy", RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x100C, 735), "Storms Grotto Gossip Stone Big Fairy", "HC Storms Grotto Gossip Stone Big Fairy", RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -2230), "Deku Tree Left Gossip Stone Fairy", "KF Deku Tree Left Gossip Stone Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY)); + locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -2230), "Deku Tree Left Gossip Stone Big Fairy", "KF Deku Tree Left Gossip Stone Big Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -700), "Deku Tree Right Gossip Stone Fairy", "KF Deku Tree Right Gossip Stone Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY)); + locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -700), "Deku Tree Right Gossip Stone Big Fairy", "KF Deku Tree Right Gossip Stone Big Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_KF_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -1223), "Gossip Stone Fairy", "KF Gossip Stone Fairy", RHT_KF_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_GOSSIP_STONE_FAIRY)); + locationTable[RC_KF_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -1223), "Gossip Stone Big Fairy", "KF Gossip Stone Big Fairy", RHT_KF_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x1B, -236), "Storms Gossip Stone Fairy", "KF Storms Gossip Stone Fairy", RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x101B, -236), "Storms Gossip Stone Big Fairy", "KF Storms Gossip Stone Big Fairy", RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_LH_LAB_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LH_LAB_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 3212), "Lab Gossip Stone Fairy", "LH Lab Gossip Stone Fairy", RHT_LH_LAB_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY)); + locationTable[RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 3212), "Lab Gossip Stone Big Fairy", "LH Lab Gossip Stone Big Fairy", RHT_LH_LAB_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 8395), "Southeast Gossip Stone Fairy", "LH Southeast Gossip Stone Fairy", RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY)); + locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 8395), "Southeast Gossip Stone Big Fairy", "LH Southeast Gossip Stone Big Fairy", RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 7984), "Southwest Gossip Stone Fairy", "LH Southwest Gossip Stone Fairy", RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY)); + locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 7984), "Southwest Gossip Stone Big Fairy", "LH Southwest Gossip Stone Big Fairy", RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_LW_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LW_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS( 0, 2300), "Gossip Stone Fairy", "LW Gossip Stone Fairy", RHT_LW_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_GOSSIP_STONE_FAIRY)); + locationTable[RC_LW_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LW_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, 2300), "Gossip Stone Big Fairy", "LW Gossip Stone Big Fairy", RHT_LW_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, 1370), "Maze Lower Gossip Stone Fairy", "SFM Maze Lower Gossip Stone Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY)); + locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, 1370), "Maze Lower Gossip Stone Big Fairy", "SFM Maze Lower Gossip Stone Big Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, 740), "Maze Upper Gossip Stone Fairy", "SFM Maze Upper Gossip Stone Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY)); + locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, 740), "Maze Upper Gossip Stone Big Fairy", "SFM Maze Upper Gossip Stone Big Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_SFM_SARIA_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, -2300), "Saria Gossip Stone Fairy", "SFM Saria Gossip Stone Fairy", RHT_SFM_SARIA_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY)); + locationTable[RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, -2300), "Saria Gossip Stone Big Fairy", "SFM Saria Gossip Stone Big Fairy", RHT_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZD_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZD_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS( 0, -1600), "Gossip Stone Fairy", "ZD Gossip Stone Fairy", RHT_ZD_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZD_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZD_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(0x1000, -1600), "Gossip Stone Big Fairy", "ZD Gossip Stone Big Fairy", RHT_ZD_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZF_FAIRY_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS( 0, 2205), "Fairy Gossip Stone Fairy", "ZF Fairy Gossip Stone Fairy", RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(0x1000, 2205), "Fairy Gossip Stone Big Fairy", "ZF Fairy Gossip Stone Big Fairy", RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZF_JABU_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZF_JABU_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS( 0, -985), "Jabu Gossip Stone Fairy", "ZF Jabu Gossip Stone Fairy", RHT_ZF_JABU_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(0x1000, -985), "Jabu Gossip Stone Big Fairy", "ZF Jabu Gossip Stone Big Fairy", RHT_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS( 0, -1070), "Near Grottos Gossip Stone Fairy", "ZR Near Grottos Gossip Stone Fairy", RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(0x1000, -1070), "Near Grottos Gossip Stone Big Fairy", "ZR Near Grottos Gossip Stone Big Fairy", RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS( 0, -1650), "Near Domain Gossip Stone Fairy", "ZR Near Domain Gossip Stone Fairy", RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(0x1000, -1650), "Near Domain Gossip Stone Big Fairy", "ZR Near Domain Gossip Stone Big Fairy", RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x11, -357), "Cow Grotto Gossip Stone Fairy", "HF Cow Grotto Gossip Stone Fairy", RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1011, -357), "Cow Grotto Gossip Stone Big Fairy", "HF Cow Grotto Gossip Stone Big Fairy", RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x10, -236), "Near Market Gossip Stone Fairy", "HF Near Market Gossip Stone Fairy", RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1010, -236), "Near Market Gossip Stone Big Fairy", "HF Near Market Gossip Stone Big Fairy", RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x14, -236), "Southeast Gossip Stone Fairy", "HF Southeast Gossip Stone Fairy", RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1014, -236), "Southeast Gossip Stone Big Fairy", "HF Southeast Gossip Stone Big Fairy", RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x13, -236), "Open Grotto Gossip Stone Fairy", "HF Open Grotto Gossip Stone Fairy", RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1013, -236), "Open Grotto Gossip Stone Big Fairy", "HF Open Grotto Gossip Stone Big Fairy", RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0xA, -236), "Open Grotto Gossip Stone Fairy", "Kak Open Grotto Gossip Stone Fairy", RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x100A, -236), "Open Grotto Gossip Stone Big Fairy", "Kak Open Grotto Gossip Stone Big Fairy", RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x4, -236), "Open Grotto Gossip Stone Fairy", "ZR Open Grotto Gossip Stone Fairy", RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1004, -236), "Open Grotto Gossip Stone Big Fairy", "ZR Open Grotto Gossip Stone Big Fairy", RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x1A, -236), "Near Shortcuts Gossip Stone Fairy", "LW Near Shortcuts Gossip Stone Fairy", RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x101A, -236), "Near Shortcuts Gossip Stone Big Fairy", "LW Near Shortcuts Gossip Stone Big Fairy", RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x8, -236), "Storms Grotto Gossip Stone Fairy", "DMT Storms Grotto Gossip Stone Fairy", RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1008, -236), "Storms Grotto Gossip Stone Big Fairy", "DMT Storms Grotto Gossip Stone Big Fairy", RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x6, -236), "Upper Grotto Gossip Stone Fairy", "DMC Upper Grotto Gossip Stone Fairy", RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY)); + locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1006, -236), "Upper Grotto Gossip Stone Big Fairy", "DMC Upper Grotto Gossip Stone Big Fairy", RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG)); + + locationTable[RC_LH_ISLAND_SUN_FAIRY] = Location::Fairy(RC_LH_ISLAND_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 7319), "Island Sun's Song Fairy", "Island Sun's Song Fairy", RHT_LH_ISLAND_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_ISLAND_SUN_FAIRY)); + locationTable[RC_HF_POND_STORMS_FAIRY] = Location::Fairy(RC_HF_POND_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(0x1000, 5012), "Pond Song of Storms Fairy", "Pond Song of Storms Fairy", RHT_HF_POND_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_POND_STORMS_FAIRY)); + locationTable[RC_HF_FENCE_GROTTO_STORMS_FAIRY] = Location::Fairy(RC_HF_FENCE_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1012, -308), "Inside Fence Storms Fairy", "Inside Fence Storms Fairy", RHT_HF_FENCE_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RHT_HF_FENCE_GROTTO_STORMS_FAIRY)); + locationTable[RC_DMT_FLAG_SUN_FAIRY] = Location::Fairy(RC_DMT_FLAG_SUN_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, 464), "Flag Sun's Song Fairy", "Flag Sun's Song Fairy", RHT_DMT_FLAG_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_FLAG_SUN_FAIRY)); + locationTable[RC_LW_SHORTCUT_STORMS_FAIRY] = Location::Fairy(RC_LW_SHORTCUT_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, -795), "Shortcuts Song of Storms Fairy", "Shortcuts Song of Storms Fairy", RHT_LW_SHORTCUT_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_STORMS_FAIRY)); + locationTable[RC_GF_KITCHEN_SUN_FAIRY] = Location::Fairy(RC_GF_KITCHEN_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(0x1000, -621), "Kitchen Sun's Song Fairy", "Kitchen Sun's Song Fairy", RHT_GF_KITCHEN_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_KITCHEN_SUN_FAIRY)); + + locationTable[RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1896), "After Boulder Room Sun's Song Fairy", "After Boulder Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY)); + locationTable[RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "Four Armos Room Sun's Song Fairy", "Four Armos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 54), "Beamos Song of Storms Fairy", "Beamos Song of Storms Fairy", RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_PIT_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 3339), "Pit Room Song of Storms Fairy", "Pit Room Song of Storms Fairy", RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -127), "Wind Hint Sun's Song Fairy", "Wind Hint Sun's Song Fairy", RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY] = Location::Fairy(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1531), "Basement Sun's Song Fairy", "Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY)); + locationTable[RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY] = Location::Fairy(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, RCQUEST_VANILLA,RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(0x1000, 1186), "Entrance Song of Storms Fairy", "Ice Cavern Entrance Song of Storms Fairy", RHT_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY)); + locationTable[RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY] = Location::Fairy(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, RCQUEST_VANILLA,RCAREA_GERUDO_TRAINING_GROUND,SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(0x1000, -445), "Entrance Song of Storms Fairy", "GTG Entrance Song of Storms Fairy", RHT_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY)); + locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY] = Location::Fairy(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(0x1000, 587), "Spirit Trial Beamos Sun's Song Fairy", "Spirit Trial Beamos Sun's Song Fairy", RHT_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY)); + + locationTable[RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY] = Location::Fairy(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -551), "MQ Lower Loop Stalfos Room Sun's Song Fairy", "MQ Lower Loop Stalfos Room Sun's Song Fairy", RHT_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY)); + locationTable[RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY] = Location::Fairy(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1563), "MQ Lower Loop Behind Iron Knuckle Sun's Song Fairy", "MQ Lower Loop Behind Iron Knuckle Sun's Song Fairy", RHT_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY)); + locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY] = Location::Fairy(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -540), "MQ Before Dark Link Pilar Sun's Song Fairy", "MQ Before Dark Link Pilar Sun's Song Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY)); + locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY] = Location::Fairy(RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1501), "MQ Before Dark Link Left Song of Storms Fairy", "MQ Before Dark Link Left Song of Storms Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY)); + locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY] = Location::Fairy(RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1504), "MQ Before Dark Link Right Sun's Song Fairy", "MQ Before Dark Link Right Sun's Song Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY)); + locationTable[RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "MQ Dinalfos Room Sun's Song Fairy", "MQ Dinalfos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 55), "MQ Beamos Song of Storms Fairy", "MQ Beamos Song of Storms Fairy", RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 3342), "MQ Pit Room Song of Storms Fairy", "MQ Pit Room Song of Storms Fairy", RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY)); + locationTable[RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -127), "MQ Wind Hint Sun's Song Fairy", "MQ Wind Hint Sun's Song Fairy", RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY] = Location::Fairy(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -437), "MQ East Cell Sun's Song Fairy", "MQ East Cell Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY] = Location::Fairy(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1458), "MQ Basement Sun's Song Fairy", "MQ Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY)); + + // Freestanding Hearts and Rupees + locationTable[RC_KF_BOULDER_RUPEE_2] = Location::Collectable(RC_KF_BOULDER_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-712, 1857), "Boulder Maze Second Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BOULDER_RUPEE_2)); + locationTable[RC_KF_BOULDER_RUPEE_1] = Location::Collectable(RC_KF_BOULDER_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-1009, 1556), "Boulder Maze First Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BOULDER_RUPEE_1)); + locationTable[RC_KF_BRIDGE_RUPEE] = Location::Collectable(RC_KF_BRIDGE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(2, -45), "Bridge Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BRIDGE_RUPEE)); + locationTable[RC_KF_BEHIND_MIDOS_RUPEE] = Location::Collectable(RC_KF_BEHIND_MIDOS_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-364, -783), "Behind Mido's House Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEHIND_MIDOS_RUPEE)); + locationTable[RC_KF_SARIAS_ROOF_WEST_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_WEST_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(451, 810), "Saria's Roof West Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_ROOF_WEST_HEART)); + locationTable[RC_KF_SARIAS_ROOF_EAST_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_EAST_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(567, 819), "Saria's Roof East Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_ROOF_EAST_HEART)); + locationTable[RC_KF_SARIAS_ROOF_NORTH_HEART] = Location::Collectable(RC_KF_SARIAS_ROOF_NORTH_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(509, 725), "Saria's Roof North Heart", RHT_KOKIRI_FOREST_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_ROOF_NORTH_HEART)); + locationTable[RC_KF_SOUTH_GRASS_WEST_RUPEE] = Location::Collectable(RC_KF_SOUTH_GRASS_WEST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-537, 194), "South Grass West Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE)); + locationTable[RC_KF_NORTH_GRASS_WEST_RUPEE] = Location::Collectable(RC_KF_NORTH_GRASS_WEST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(35, -418), "North Grass West Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_NORTH_GRASS_WEST_RUPEE)); + locationTable[RC_KF_NORTH_GRASS_EAST_RUPEE] = Location::Collectable(RC_KF_NORTH_GRASS_EAST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(107, -418), "North Grass East Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_NORTH_GRASS_EAST_RUPEE)); + locationTable[RC_KF_SOUTH_GRASS_EAST_RUPEE] = Location::Collectable(RC_KF_SOUTH_GRASS_EAST_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-459, 181), "South Grass East Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE)); + locationTable[RC_KF_SARIAS_TOP_LEFT_HEART] = Location::Collectable(RC_KF_SARIAS_TOP_LEFT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SARIAS_HOUSE, TWO_ACTOR_PARAMS(45, -52), "Saria's House Top Left Heart", RHT_SARIAS_HOUSE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_TOP_LEFT_HEART)); + locationTable[RC_KF_SARIAS_TOP_RIGHT_HEART] = Location::Collectable(RC_KF_SARIAS_TOP_RIGHT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SARIAS_HOUSE, TWO_ACTOR_PARAMS(46, 56), "Saria's House Top Right Heart", RHT_SARIAS_HOUSE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_TOP_RIGHT_HEART)); + locationTable[RC_KF_SARIAS_BOTTOM_LEFT_HEART] = Location::Collectable(RC_KF_SARIAS_BOTTOM_LEFT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SARIAS_HOUSE, TWO_ACTOR_PARAMS(-46, -51), "Saria's House Bottom Left Heart", RHT_SARIAS_HOUSE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART)); + locationTable[RC_KF_SARIAS_BOTTOM_RIGHT_HEART] = Location::Collectable(RC_KF_SARIAS_BOTTOM_RIGHT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SARIAS_HOUSE, TWO_ACTOR_PARAMS(-46, 57), "Saria's House Bottom Right Heart", RHT_SARIAS_HOUSE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART)); + + locationTable[RC_KF_BEAN_RUPEE_1] = Location::Collectable(RC_KF_BEAN_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1269, -528), "Bean Platform Rupee 1", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_1)); + locationTable[RC_KF_BEAN_RUPEE_2] = Location::Collectable(RC_KF_BEAN_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1269, -567), "Bean Platform Rupee 2", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_2)); + locationTable[RC_KF_BEAN_RUPEE_3] = Location::Collectable(RC_KF_BEAN_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1304, -588), "Bean Platform Rupee 3", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_3)); + locationTable[RC_KF_BEAN_RUPEE_4] = Location::Collectable(RC_KF_BEAN_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1338, -567), "Bean Platform Rupee 4", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_4)); + locationTable[RC_KF_BEAN_RUPEE_5] = Location::Collectable(RC_KF_BEAN_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1338, -528), "Bean Platform Rupee 5", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_5)); + locationTable[RC_KF_BEAN_RUPEE_6] = Location::Collectable(RC_KF_BEAN_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1304, -508), "Bean Platform Rupee 6", RHT_KOKIRI_FOREST_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RUPEE_6)); + locationTable[RC_KF_BEAN_RED_RUPEE] = Location::Collectable(RC_KF_BEAN_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(1304, -548), "Bean Platform Red Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_RED_RUPEE)); + + locationTable[RC_LW_BOULDER_RUPEE] = Location::Collectable(RC_LW_BOULDER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(1720, -2510), 0x13, "Boulder Rupee", RHT_LOST_WOODS_RUPEE, RG_BLUE_RUPEE); + locationTable[RC_LW_SHORTCUT_RUPEE_1] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2215, -850), "Underwater Shortcut Rupee 1", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_1)); + locationTable[RC_LW_SHORTCUT_RUPEE_2] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2164, -850), "Underwater Shortcut Rupee 2", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_2)); + locationTable[RC_LW_SHORTCUT_RUPEE_3] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2113, -850), "Underwater Shortcut Rupee 3", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_3)); + locationTable[RC_LW_SHORTCUT_RUPEE_4] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2061, -853), "Underwater Shortcut Rupee 4", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_4)); + locationTable[RC_LW_SHORTCUT_RUPEE_5] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2194, -895), "Underwater Shortcut Rupee 5", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_5)); + locationTable[RC_LW_SHORTCUT_RUPEE_6] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2156, -937), "Underwater Shortcut Rupee 6", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_6)); + locationTable[RC_LW_SHORTCUT_RUPEE_7] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_7, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2193, -813), "Underwater Shortcut Rupee 7", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_7)); + locationTable[RC_LW_SHORTCUT_RUPEE_8] = Location::Collectable(RC_LW_SHORTCUT_RUPEE_8, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(2153, -779), "Underwater Shortcut Rupee 8", RHT_LOST_WOODS_SHORTCUT_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_RUPEE_8)); + + locationTable[RC_LH_FRONT_RUPEE] = Location::Collectable(RC_LH_FRONT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-940, 3968), "Underwater Front Rupee", RHT_LAKE_HYLIA_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_FRONT_RUPEE)); + locationTable[RC_LH_MIDDLE_RUPEE] = Location::Collectable(RC_LH_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-868, 4090), "Underwater Middle Rupee", RHT_LAKE_HYLIA_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_MIDDLE_RUPEE)); + locationTable[RC_LH_BACK_RUPEE] = Location::Collectable(RC_LH_BACK_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(-861, 4212), "Underwater Back Rupee", RHT_LAKE_HYLIA_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BACK_RUPEE)); + locationTable[RC_LH_LAB_FRONT_RUPEE] = Location::Collectable(RC_LH_LAB_FRONT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(68, -207), "Lab Front Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_FRONT_RUPEE)); + locationTable[RC_LH_LAB_LEFT_RUPEE] = Location::Collectable(RC_LH_LAB_LEFT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(-52, -32), "Lab Left Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_LEFT_RUPEE)); + locationTable[RC_LH_LAB_RIGHT_RUPEE] = Location::Collectable(RC_LH_LAB_RIGHT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_LAKESIDE_LABORATORY, TWO_ACTOR_PARAMS(-169, -124), "Lab Right Rupee", RHT_LABORATORY_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_RIGHT_RUPEE)); + + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_1] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(385, -2766), "Dampe's Grave Rupee 1", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_2] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(528, -3216), "Dampe's Grave Rupee 2", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_3] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(753, -4828), "Dampe's Grave Rupee 3", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_4] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(570, -5599), "Dampe's Grave Rupee 4", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_5] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(1461, -5736), "Dampe's Grave Rupee 5", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_6] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(2376, -4647), "Dampe's Grave Rupee 6", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_7] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_7, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(2573, -3758), "Dampe's Grave Rupee 7", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7)); + locationTable[RC_GRAVEYARD_DAMPE_RACE_RUPEE_8] = Location::Collectable(RC_GRAVEYARD_DAMPE_RACE_RUPEE_8, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(1511, -3118), "Dampe's Grave Rupee 8", RHT_DAMPES_GRAVE_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8)); + + locationTable[RC_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-42, 880), "Octorok Grotto Front Left Blue Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(58, 803), "Octorok Grotto Back Blue Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(90, 910), "Octorok Grotto Front Right Blue Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-68, 959), "Octorok Grotto Front Left Green Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(132, 961), "Octorok Grotto Front Right Green Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-38, 768), "Octorok Grotto Back Left Green Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 784), "Octorok Grotto Back Right Green Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE)); + locationTable[RC_GV_OCTOROK_GROTTO_RED_RUPEE] = Location::Collectable(RC_GV_OCTOROK_GROTTO_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_GERUDO_VALLEY, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(32, 852), "Octorok Grotto Red Rupee", RHT_GERUDO_VALLEY_GROTTO_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE)); + + locationTable[RC_DMT_RED_RUPEE] = Location::Collectable(RC_DMT_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-625, -55), "Red Rupee Under Boulder", RHT_DEATH_MOUNTAIN_TRAIL_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_RED_RUPEE)); + locationTable[RC_DMT_BLUE_RUPEE] = Location::Collectable(RC_DMT_BLUE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(-1060, -51), "Blue Rupee Under Boulder", RHT_DEATH_MOUNTAIN_TRAIL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BLUE_RUPEE)); + locationTable[RC_DMT_COW_GROTTO_LEFT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_LEFT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2287, -412), "Cow Grotto Left Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_LEFT_HEART)); + locationTable[RC_DMT_COW_GROTTO_MIDDLE_LEFT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2371, -532), "Cow Grotto Middle Left Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART)); + locationTable[RC_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2449, -534), "Cow Grotto Middle Right Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART)); + locationTable[RC_DMT_COW_GROTTO_RIGHT_HEART] = Location::Collectable(RC_DMT_COW_GROTTO_RIGHT_HEART, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2569, -432), "Cow Grotto Right Heart", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RIGHT_HEART)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_1] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2390, -100), "Cow Grotto Rupee 1", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_1)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_2] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2390, -139), "Cow Grotto Rupee 2", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_2)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_3] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2425, -160), "Cow Grotto Rupee 3", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_3)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_4] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2459, -139), "Cow Grotto Rupee 4", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_4)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_5] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2459, -100), "Cow Grotto Rupee 5", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_5)); + locationTable[RC_DMT_COW_GROTTO_RUPEE_6] = Location::Collectable(RC_DMT_COW_GROTTO_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2425, -80), "Cow Grotto Rupee 6", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RUPEE_6)); + locationTable[RC_DMT_COW_GROTTO_RED_RUPEE] = Location::Collectable(RC_DMT_COW_GROTTO_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_ITEM00, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2425, -120), "Cow Grotto Red Rupee", RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_RED_RUPEE)); + + locationTable[RC_DMC_NEAR_PLATFORM_RED_RUPEE] = Location::Collectable(RC_DMC_NEAR_PLATFORM_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(675, -718), "Near Warp Platform Red Rupee", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE)); + locationTable[RC_DMC_MIDDLE_PLATFORM_RED_RUPEE] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1117, -185), "Middle Platform Red Rupee", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1117, -248), "Middle Platform Blue Rupee 1", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1116, -128), "Middle Platform Blue Rupee 2", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1159, -162), "Middle Platform Blue Rupee 3", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1158, -227), "Middle Platform Blue Rupee 4", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1078, -226), "Middle Platform Blue Rupee 5", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5)); + locationTable[RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6] = Location::Collectable(RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1078, -164), "Middle Platform Blue Rupee 6", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_1] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_1, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1087, 454), "Distant Platform Rupee 1", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_2] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1087, 415), "Distant Platform Rupee 2", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_3] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_3, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1122, 395), "Distant Platform Rupee 3", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_4] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_4, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1156, 415), "Distant Platform Rupee 4", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_5] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_5, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1156, 454), "Distant Platform Rupee 5", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5)); + locationTable[RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_6] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_6, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1122, 475), "Distant Platform Rupee 6", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6)); + locationTable[RC_DMC_DISTANT_PLATFORM_RED_RUPEE] = Location::Collectable(RC_DMC_DISTANT_PLATFORM_RED_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(1122, 435), "Distant Platform Red Rupee", RHT_DEATH_MOUNTAIN_CRATER_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE)); + + locationTable[RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE] = Location::Collectable(RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(4216, -1464), "Beneath Domain Red Left Rupee", RHT_ZORAS_RIVER_WATERFALL_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE)); + locationTable[RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE] = Location::Collectable(RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(4171, -1436), "Beneath Domain Red Middle Left Rupee", RHT_ZORAS_RIVER_WATERFALL_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE)); + locationTable[RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE] = Location::Collectable(RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(4171, -1376), "Beneath Domain Red Middle Right Rupee", RHT_ZORAS_RIVER_WATERFALL_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE)); + locationTable[RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE] = Location::Collectable(RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(4224, -1339), "Beneath Domain Red Right Rupee", RHT_ZORAS_RIVER_WATERFALL_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE)); + + locationTable[RC_ZF_BOTTOM_NORTH_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTH_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(68, -166), "Bottom North Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(172, -35), "Bottom Northeast Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(137, 130), "Bottom Southeast Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTH_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTH_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-76, 172), "Bottom South Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-207, 47), "Bottom Southwest Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHWEST_INNER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-173, -132), "Bottom Northwest Inner Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTH_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(242, -576), "Bottom North Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(540, -124), "Bottom Northeast Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(397, 318), "Bottom Southeast Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-166, 428), "Bottom South Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-574, 163), "Bottom Southwest Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-464, -389), "Bottom Northwest Middle Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTH_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTH_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(353, -934), "Bottom North Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(1032, -254), "Bottom Northeast Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(603, 466), "Bottom Southeast Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTH_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTH_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-227, 696), "Bottom South Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE)); + locationTable[RC_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-847, 206), "Bottom Southwest Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE)); + locationTable[RC_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE] = Location::Collectable(RC_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-857, -654), "Bottom Northwest Outer Rupee", RHT_ZORAS_FOUNTAIN_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE)); + + locationTable[RC_DEKU_TREE_LOBBY_LOWER_HEART] = Location::Collectable(RC_DEKU_TREE_LOBBY_LOWER_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-25, -81), "Lobby Lower Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART)); + locationTable[RC_DEKU_TREE_LOBBY_UPPER_HEART] = Location::Collectable(RC_DEKU_TREE_LOBBY_UPPER_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(87, -16), "Lobby Upper Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART)); + locationTable[RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART] = Location::Collectable(RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-885, -185), "Final Room Left Front Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART)); + locationTable[RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART] = Location::Collectable(RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-820, -76), "Final Room Left Back Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART)); + locationTable[RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART] = Location::Collectable(RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-354, -206), "Final Room Right Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART)); + + locationTable[RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4266, -1575), "Lower Lizalfos Room Lavafall Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART)); + locationTable[RC_DODONGOS_CAVERN_BLADE_ROOM_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2039, -317), "Blade Room Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART)); + locationTable[RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3553, -1962), "Upper Lizalfos Room Left Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART)); + locationTable[RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(3580, -2004), "Upper Lizalfos Room Right Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART)); + + locationTable[RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART] = Location::Collectable(RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-1124, -2855), "West Courtyard Right Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART)); + locationTable[RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART] = Location::Collectable(RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-1165, -2788), "West Courtyard Left Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART)); + locationTable[RC_FOREST_TEMPLE_WELL_WEST_HEART] = Location::Collectable(RC_FOREST_TEMPLE_WELL_WEST_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(307, -1734), "Well East Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART)); + locationTable[RC_FOREST_TEMPLE_WELL_EAST_HEART] = Location::Collectable(RC_FOREST_TEMPLE_WELL_EAST_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(251, -1735), "Well West Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART)); + + locationTable[RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3476, -359), "Fire Pillar Room Left Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART)); + locationTable[RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3476, -295), "Fire Pillar Room Right Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART)); + locationTable[RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3526, -339), "Fire Pillar Room Back Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART)); + locationTable[RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1753, -136), "East Central Room Left Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART)); + locationTable[RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1813, -37), "East Central Room Right Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART)); + locationTable[RC_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART] = Location::Collectable(RC_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1783, -91), "East Central Room Middle Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART)); + locationTable[RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(862, -169), "Fire Wall Chase East Pillar Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART)); + locationTable[RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(603, -190), "Fire Wall Chase West Pillar Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART)); + locationTable[RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(1381, -1120), "Fire Wall Chase Exit Platform Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART)); + + locationTable[RC_WATER_TEMPLE_RIVER_HEART_1] = Location::Collectable(RC_WATER_TEMPLE_RIVER_HEART_1, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2781, -2515), "River Heart 1", RHT_WATER_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_RIVER_HEART_1)); + locationTable[RC_WATER_TEMPLE_RIVER_HEART_2] = Location::Collectable(RC_WATER_TEMPLE_RIVER_HEART_2, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2528, -2727), "River Heart 2", RHT_WATER_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_RIVER_HEART_2)); + locationTable[RC_WATER_TEMPLE_RIVER_HEART_3] = Location::Collectable(RC_WATER_TEMPLE_RIVER_HEART_3, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2436, -3348), "River Heart 3", RHT_WATER_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_RIVER_HEART_3)); + locationTable[RC_WATER_TEMPLE_RIVER_HEART_4] = Location::Collectable(RC_WATER_TEMPLE_RIVER_HEART_4, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(-2021, -2937), "River Heart 4", RHT_WATER_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_RIVER_HEART_4)); + + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5676, 1565), "Invisible Blades Left Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART)); + locationTable[RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5695, 1589), "Invisible Blades Right Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART)); + locationTable[RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3971, -1716), "Scarecrow Near Ship North Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART)); + locationTable[RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3970, -1560), "Scarecrow Near Ship South Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART)); + locationTable[RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3471, -884), "After Ship Upper Left Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART)); + locationTable[RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3473, -927), "After Ship Upper Right Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART)); + locationTable[RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3164, -646), "After Ship Lower Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART)); + + locationTable[RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(708, 227), "Adult Climb Left Heart", RHT_SPIRIT_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART)); + locationTable[RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(661, 227), "Adult Climb Right Heart", RHT_SPIRIT_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART)); + + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-67, -748), "Basement Platform Left Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-19, -828), "Basement Platform Back Left Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(47, -805), "Basement Platform Middle Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(94, -762), "Basement Platform Back Right Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE)); + locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-85, -710), "Basement Platform Right Rupee", RHT_BOTTOM_OF_THE_WELL_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE)); + locationTable[RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-1947, -625), "Coffin Room Front Left Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-2144, -859), "Coffin Room Middle Right Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART)); + + locationTable[RC_ICE_CAVERN_LOBBY_RUPEE] = Location::Collectable(RC_ICE_CAVERN_LOBBY_RUPEE, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-105, 854), "Lobby Rupee", RHT_ICE_CAVERN_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_LOBBY_RUPEE)); + locationTable[RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART] = Location::Collectable(RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1171, -2258), "Map Room Left Heart", RHT_ICE_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART)); + locationTable[RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART] = Location::Collectable(RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1212, -2213), "Map Room Middle Heart", RHT_ICE_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART)); + locationTable[RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART] = Location::Collectable(RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(1166, -2173), "Map Room Right Heart", RHT_ICE_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART)); + locationTable[RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1] = Location::Collectable(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1699, -697), "Sliding Block Room Rupee 1", RHT_ICE_CAVERN_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1)); + locationTable[RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2] = Location::Collectable(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1648, -715), "Sliding Block Room Rupee 2", RHT_ICE_CAVERN_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2)); + locationTable[RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3] = Location::Collectable(RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(-1648, -677), "Sliding Block Room Rupee 3", RHT_ICE_CAVERN_RUPEE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3)); + + locationTable[RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART] = Location::Collectable(RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1486, 204), "Beamos South Heart", RHT_GERUDO_TRAINING_GROUNDS_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART)); + locationTable[RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART] = Location::Collectable(RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(1858, -183), "Beamos East Heart", RHT_GERUDO_TRAINING_GROUNDS_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART)); + + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1] = Location::Collectable(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1855, -3953), "Shadow Trial Heart 1", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1)); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2] = Location::Collectable(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1844, -4038), "Shadow Trial Heart 2", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2)); + locationTable[RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3] = Location::Collectable(RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1827, -4106), "Shadow Trial Heart 3", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3)); + locationTable[RC_GANONS_CASTLE_FIRE_TRIAL_HEART] = Location::Collectable(RC_GANONS_CASTLE_FIRE_TRIAL_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-1636, -3069), "Fire Trial Heart", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART)); + locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART] = Location::Collectable(RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, RCQUEST_VANILLA, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-517, 592), "Spirit Trial Heart", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART)); + + locationTable[RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-1128, 1571), "MQ Compass Room Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART)); + locationTable[RC_DEKU_TREE_MQ_DEKU_BABA_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_DEKU_BABA_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-594, 840), "MQ Deku Baba Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART)); + locationTable[RC_DEKU_TREE_MQ_LOBBY_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_LOBBY_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-22, -88), "MQ Lobby Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_LOBBY_HEART)); + locationTable[RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-1165, 325), "MQ Slingshot Room Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART)); + locationTable[RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-885, -185), "MQ Final Room Left Front Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART)); + locationTable[RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-820, -76), "MQ Final Room Left Back Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART)); + locationTable[RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART] = Location::Collectable(RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DEKU_TREE, TWO_ACTOR_PARAMS(-354, -206), "MQ Final Room Right Heart", RHT_DEKU_TREE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART)); + + locationTable[RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(4266, -1575), "MQ Lizalfos Room Lavafall Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART)); + locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART] = Location::Collectable(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(1955, -596), "MQ Torch Room Invisible Heart", RHT_DODONGOS_CAVERN_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART)); + + locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-390, -1695), "MQ Lift Room Underwater Rupee 1", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-487, -1701), "MQ Lift Room Underwater Rupee 2", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-549, -1709), "MQ Lift Room Underwater Rupee 3", RHT_JABU_JABU_RUPEE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3)); + locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-217, -1620), "MQ Lift Room Heart 1", RHT_JABU_JABU_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2] = Location::Collectable(RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-206, -1797), "MQ Lift Room Heart 2", RHT_JABU_JABU_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2)); + + locationTable[RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-1124, -2855), "MQ West Courtyard Right Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART)); + locationTable[RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-1157, -2798), "MQ West Courtyard Middle Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART)); + locationTable[RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(-1184, -2744), "MQ West Courtyard Left Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART)); + locationTable[RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(115, -1755), "MQ Well Middle Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART)); + locationTable[RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(15, -1755), "MQ Well West Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART)); + locationTable[RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART] = Location::Collectable(RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(215, -1755), "MQ Well East Heart", RHT_FOREST_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART)); + + locationTable[RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3476, -331), "MQ Fire Pillar Room Left Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART)); + locationTable[RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART] = Location::Collectable(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3502, 320), "MQ Fire Pillar Room Right Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART)); + locationTable[RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART] = Location::Collectable(RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(3307, 180), "MQ Fire Pillar Room Lower Heart", RHT_FIRE_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART)); + + locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5676, 1565), "MQ Invisible Blades Left Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(5695, 1589), "MQ Invisible Blades Right Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3971, -1716), "MQ Scarecrow Near Ship North Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(3970, -1560), "MQ Scarecrow Near Ship South Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3471, -884), "MQ After Ship Upper Left Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3473, -927), "MQ After Ship Upper Right Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART)); + locationTable[RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART] = Location::Collectable(RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(-3164, -646), "MQ After Ship Lower Heart", RHT_SHADOW_TEMPLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART)); + + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1151, -535), "MQ Child Early Left Heart", RHT_SPIRIT_TEMPLE_MQ_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART)); + locationTable[RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART] = Location::Collectable(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-976, -535), "MQ Child Early Right Heart", RHT_SPIRIT_TEMPLE_MQ_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART)); + + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-1945, -863), "MQ Coffin Room Front Right Invisible Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-83, -350), "MQ Bomb Alcove Left Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-83, -274), "MQ Bomb Alcove Right Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(-2143, -621), "MQ Coffin Room Middle Left Invisible Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(1083, -1174), "MQ Basement Hallway Front Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(1044, -1223), "MQ Basement Hallway Left Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART)); + locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART] = Location::Collectable(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(1114, -1223), "MQ Basement Hallway Right Heart", RHT_BOTTOM_OF_THE_WELL_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART)); + + locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART] = Location::Collectable(RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(1743, -528), "MQ Water Trial Heart", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART)); + locationTable[RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART] = Location::Collectable(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2506, -1096), "MQ Light Trial Right Heart", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART)); + locationTable[RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART] = Location::Collectable(RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, RCQUEST_MQ, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(-2655, -549), "MQ Light Trial Left Heart", RHT_GANONS_CASTLE_HEART, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART)); + // Gossip Stones - locationTable[RC_DMC_GOSSIP_STONE] = Location::HintStone(RC_DMC_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_CRATER, 14341, "Gossip Stone"); - locationTable[RC_DMT_GOSSIP_STONE] = Location::HintStone(RC_DMT_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 14340, "Gossip Stone"); - locationTable[RC_COLOSSUS_GOSSIP_STONE] = Location::HintStone(RC_COLOSSUS_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 14362, "Gossip Stone"); - locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE] = Location::HintStone(RC_DODONGOS_CAVERN_GOSSIP_STONE, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 4372, "Gossip Stone"); - locationTable[RC_GV_GOSSIP_STONE] = Location::HintStone(RC_GV_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 14353, "Gossip Stone"); - locationTable[RC_GC_MAZE_GOSSIP_STONE] = Location::HintStone(RC_GC_MAZE_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GORON_CITY, 14357, "Maze Gossip Stone"); - locationTable[RC_GC_MEDIGORON_GOSSIP_STONE] = Location::HintStone(RC_GC_MEDIGORON_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GORON_CITY, 14873, "Medigoron Gossip Stone"); - locationTable[RC_GRAVEYARD_GOSSIP_STONE] = Location::HintStone(RC_GRAVEYARD_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GRAVEYARD, 14346, "Gossip Stone"); - locationTable[RC_HC_MALON_GOSSIP_STONE] = Location::HintStone(RC_HC_MALON_GOSSIP_STONE, RCQUEST_BOTH, SCENE_HYRULE_CASTLE, 14610, "Malon Gossip Stone"); - locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE] = Location::HintStone(RC_HC_ROCK_WALL_GOSSIP_STONE, RCQUEST_BOTH, SCENE_HYRULE_CASTLE, 14347, "Rock Wall Gossip Stone"); - locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HC_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 14355, "Storms Grotto Gossip Stone"); - locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 14623, "Deku Tree Left Gossip Stone"); - locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 14880, "Deku Tree Right Gossip Stone"); - locationTable[RC_KF_GOSSIP_STONE] = Location::HintStone(RC_KF_GOSSIP_STONE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 14366, "Gossip Stone"); - locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KF_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, -22988, "Storms Gossip Stone"); - locationTable[RC_LH_LAB_GOSSIP_STONE] = Location::HintStone(RC_LH_LAB_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 14339, "Lab Gossip Stone"); - locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 14863, "Southeast Gossip Stone"); - locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHWEST_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 14600, "Southwest Gossip Stone"); - locationTable[RC_LW_GOSSIP_STONE] = Location::HintStone(RC_LW_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LOST_WOODS, 14365, "Gossip Stone"); - locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_LOWER_GOSSIP_STONE, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 14358, "Maze Lower Gossip Stone"); - locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_UPPER_GOSSIP_STONE, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 14615, "Maze Upper Gossip Stone"); - locationTable[RC_SFM_SARIA_GOSSIP_STONE] = Location::HintStone(RC_SFM_SARIA_GOSSIP_STONE, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 14876, "Saria Gossip Stone"); - locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFTMOST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Left Gossip Stone"); - locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHTMOST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Right Gossip Stone"); - locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Right Center Gossip Stone"); - locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Left Center Gossip Stone"); - locationTable[RC_ZD_GOSSIP_STONE] = Location::HintStone(RC_ZD_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_DOMAIN, 14345, "Gossip Stone"); - locationTable[RC_ZF_FAIRY_GOSSIP_STONE] = Location::HintStone(RC_ZF_FAIRY_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 0x00, "Fairy Gossip Stone"); - locationTable[RC_ZF_JABU_GOSSIP_STONE] = Location::HintStone(RC_ZF_JABU_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 0x00, "Jabu Gossip Stone"); - locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 14605, "Near Grottos Gossip Stone"); - locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 14860, "Near Domain Gossip Stone"); - locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_COW_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 14363, "Cow Grotto Gossip Stone"); - locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22944, "Near Market Gossip Stone"); - locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22978, "Southeast Gossip Stone"); - locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22947, "Open Grotto Gossip Stone"); - locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, -22984, "Open Grotto Gossip Stone"); - locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, -22985, "Open Grotto Gossip Stone"); - locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, -22964, "Near Shortcuts Gossip Stone"); - locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, -23255, "Storms Grotto Gossip Stone"); - locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, -23802, "Upper Grotto Gossip Stone"); + locationTable[RC_DMC_GOSSIP_STONE] = Location::HintStone(RC_DMC_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_CRATER, 14341, "Gossip Stone"); + locationTable[RC_DMT_GOSSIP_STONE] = Location::HintStone(RC_DMT_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DEATH_MOUNTAIN_TRAIL, 14340, "Gossip Stone"); + locationTable[RC_COLOSSUS_GOSSIP_STONE] = Location::HintStone(RC_COLOSSUS_GOSSIP_STONE, RCQUEST_BOTH, SCENE_DESERT_COLOSSUS, 14362, "Gossip Stone"); + locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE] = Location::HintStone(RC_DODONGOS_CAVERN_GOSSIP_STONE, RCQUEST_VANILLA, SCENE_DODONGOS_CAVERN, 4372, "Gossip Stone"); + locationTable[RC_GV_GOSSIP_STONE] = Location::HintStone(RC_GV_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GERUDO_VALLEY, 14353, "Gossip Stone"); + locationTable[RC_GC_MAZE_GOSSIP_STONE] = Location::HintStone(RC_GC_MAZE_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GORON_CITY, 14357, "Maze Gossip Stone"); + locationTable[RC_GC_MEDIGORON_GOSSIP_STONE] = Location::HintStone(RC_GC_MEDIGORON_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GORON_CITY, 14873, "Medigoron Gossip Stone"); + locationTable[RC_GRAVEYARD_GOSSIP_STONE] = Location::HintStone(RC_GRAVEYARD_GOSSIP_STONE, RCQUEST_BOTH, SCENE_GRAVEYARD, 14346, "Gossip Stone"); + locationTable[RC_HC_MALON_GOSSIP_STONE] = Location::HintStone(RC_HC_MALON_GOSSIP_STONE, RCQUEST_BOTH, SCENE_HYRULE_CASTLE, 14610, "Malon Gossip Stone"); + locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE] = Location::HintStone(RC_HC_ROCK_WALL_GOSSIP_STONE, RCQUEST_BOTH, SCENE_HYRULE_CASTLE, 14347, "Rock Wall Gossip Stone"); + locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HC_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, 14355, "Storms Grotto Gossip Stone"); + locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 14623, "Deku Tree Left Gossip Stone"); + locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE] = Location::HintStone(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 14880, "Deku Tree Right Gossip Stone"); + locationTable[RC_KF_GOSSIP_STONE] = Location::HintStone(RC_KF_GOSSIP_STONE, RCQUEST_BOTH, SCENE_KOKIRI_FOREST, 14366, "Gossip Stone"); + locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KF_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, -22988, "Storms Gossip Stone"); + locationTable[RC_LH_LAB_GOSSIP_STONE] = Location::HintStone(RC_LH_LAB_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 14339, "Lab Gossip Stone"); + locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHEAST_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 14863, "Southeast Gossip Stone"); + locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE] = Location::HintStone(RC_LH_SOUTHWEST_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LAKE_HYLIA, 14600, "Southwest Gossip Stone"); + locationTable[RC_LW_GOSSIP_STONE] = Location::HintStone(RC_LW_GOSSIP_STONE, RCQUEST_BOTH, SCENE_LOST_WOODS, 14365, "Gossip Stone"); + locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_LOWER_GOSSIP_STONE, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 14358, "Maze Lower Gossip Stone"); + locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE] = Location::HintStone(RC_SFM_MAZE_UPPER_GOSSIP_STONE, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 14615, "Maze Upper Gossip Stone"); + locationTable[RC_SFM_SARIA_GOSSIP_STONE] = Location::HintStone(RC_SFM_SARIA_GOSSIP_STONE, RCQUEST_BOTH, SCENE_SACRED_FOREST_MEADOW, 14876, "Saria Gossip Stone"); + locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFTMOST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Left Gossip Stone"); + locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHTMOST_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Right Gossip Stone"); + locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Right Center Gossip Stone"); + locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE] = Location::HintStone(RC_TOT_LEFT_CENTER_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_ID_MAX, 0x00, "ToT Left Center Gossip Stone"); + locationTable[RC_ZD_GOSSIP_STONE] = Location::HintStone(RC_ZD_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_DOMAIN, 14345, "Gossip Stone"); + locationTable[RC_ZF_FAIRY_GOSSIP_STONE] = Location::HintStone(RC_ZF_FAIRY_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 0x00, "Fairy Gossip Stone"); + locationTable[RC_ZF_JABU_GOSSIP_STONE] = Location::HintStone(RC_ZF_JABU_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_FOUNTAIN, 0x00, "Jabu Gossip Stone"); + locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 14605, "Near Grottos Gossip Stone"); + locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE] = Location::HintStone(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, RCQUEST_BOTH, SCENE_ZORAS_RIVER, 14860, "Near Domain Gossip Stone"); + locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_COW_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, 14363, "Cow Grotto Gossip Stone"); + locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22944, "Near Market Gossip Stone"); + locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22978, "Southeast Gossip Stone"); + locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22947, "Open Grotto Gossip Stone"); + locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, -22984, "Open Grotto Gossip Stone"); + locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, -22985, "Open Grotto Gossip Stone"); + locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, -22964, "Near Shortcuts Gossip Stone"); + locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, -23255, "Storms Grotto Gossip Stone"); + locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, -23802, "Upper Grotto Gossip Stone"); // Other Hints - locationTable[RC_GANONDORF_HINT] = Location::OtherHint(RC_GANONDORF_HINT, RCQUEST_BOTH, ACTOR_EN_GANON_MANT, SCENE_GANON_BOSS, "Ganondorf Hint"); - locationTable[RC_SHEIK_HINT_GC] = Location::OtherHint(RC_SHEIK_HINT_GC, RCQUEST_VANILLA, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint"); - locationTable[RC_SHEIK_HINT_MQ_GC] = Location::OtherHint(RC_SHEIK_HINT_MQ_GC, RCQUEST_MQ, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint"); - locationTable[RC_DAMPE_HINT] = Location::OtherHint(RC_DAMPE_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_GRAVEKEEPERS_HUT, "Diary Hint"); - locationTable[RC_GREG_HINT] = Location::OtherHint(RC_GREG_HINT, RCQUEST_BOTH, RCAREA_MARKET, ACTOR_EN_TAKARA_MAN, SCENE_TREASURE_BOX_SHOP, "Greg Hint"); - locationTable[RC_SARIA_SONG_HINT] = Location::OtherHint(RC_SARIA_SONG_HINT, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, "Sarias Song Hint", "Magic Hint Via Saria's Song"); - locationTable[RC_ALTAR_HINT_CHILD] = Location::OtherHint(RC_ALTAR_HINT_CHILD, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Child Altar Hint"); - locationTable[RC_ALTAR_HINT_ADULT] = Location::OtherHint(RC_ALTAR_HINT_ADULT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Adult Altar Hint"); - locationTable[RC_FISHING_POLE_HINT] = Location::OtherHint(RC_FISHING_POLE_HINT, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, "Fishing Pole Hint"); - locationTable[RC_TOT_SHEIK_HINT] = Location::OtherHint(RC_TOT_SHEIK_HINT, RCQUEST_BOTH, ACTOR_EN_XC, SCENE_TEMPLE_OF_TIME, "Ocarina of Time Hint"); - locationTable[RC_MASK_SHOP_HINT] = Location::OtherHint(RC_MASK_SHOP_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_HAPPY_MASK_SHOP, "Mask Shop Hint"); + locationTable[RC_GANONDORF_HINT] = Location::OtherHint(RC_GANONDORF_HINT, RCQUEST_BOTH, ACTOR_EN_GANON_MANT, SCENE_GANON_BOSS, "Ganondorf Hint"); + locationTable[RC_SHEIK_HINT_GC] = Location::OtherHint(RC_SHEIK_HINT_GC, RCQUEST_VANILLA, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint"); + locationTable[RC_SHEIK_HINT_MQ_GC] = Location::OtherHint(RC_SHEIK_HINT_MQ_GC, RCQUEST_MQ, ACTOR_EN_XC, SCENE_INSIDE_GANONS_CASTLE, "Sheik Hint"); + locationTable[RC_DAMPE_HINT] = Location::OtherHint(RC_DAMPE_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_GRAVEKEEPERS_HUT, "Diary Hint"); + locationTable[RC_GREG_HINT] = Location::OtherHint(RC_GREG_HINT, RCQUEST_BOTH, RCAREA_MARKET, ACTOR_EN_TAKARA_MAN, SCENE_TREASURE_BOX_SHOP, "Greg Hint"); + locationTable[RC_SARIA_SONG_HINT] = Location::OtherHint(RC_SARIA_SONG_HINT, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, ACTOR_ID_MAX, SCENE_ID_MAX, "Sarias Song Hint", "Magic Hint Via Saria's Song"); + locationTable[RC_ALTAR_HINT_CHILD] = Location::OtherHint(RC_ALTAR_HINT_CHILD, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Child Altar Hint"); + locationTable[RC_ALTAR_HINT_ADULT] = Location::OtherHint(RC_ALTAR_HINT_ADULT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_TEMPLE_OF_TIME, "ToT Adult Altar Hint"); + locationTable[RC_FISHING_POLE_HINT] = Location::OtherHint(RC_FISHING_POLE_HINT, RCQUEST_BOTH, ACTOR_FISHING, SCENE_FISHING_POND, "Fishing Pole Hint"); + locationTable[RC_TOT_SHEIK_HINT] = Location::OtherHint(RC_TOT_SHEIK_HINT, RCQUEST_BOTH, ACTOR_EN_XC, SCENE_TEMPLE_OF_TIME, "Ocarina of Time Hint"); + locationTable[RC_MASK_SHOP_HINT] = Location::OtherHint(RC_MASK_SHOP_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_HAPPY_MASK_SHOP, "Mask Shop Hint"); - locationTable[RC_TRIFORCE_COMPLETED] = Location::Base(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE); + locationTable[RC_TRIFORCE_COMPLETED] = Location::Base(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE); // clang-format on // Init locationNameToEnum diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 4870fbc38..1ebca00f9 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -59,10 +59,13 @@ namespace Rando { case RG_PROGRESSIVE_NUT_UPGRADE: case RG_NUTS: return CurrentUpgrade(UPG_NUTS); + //RANDOTODO handle cases where the scarecrow is persistent between age better when OI is added case RG_SCARECROW: return ScarecrowsSong() && CanUse(RG_HOOKSHOT); case RG_DISTANT_SCARECROW: return ScarecrowsSong() && CanUse(RG_LONGSHOT); + case RG_MAGIC_BEAN: + return GetAmmo(ITEM_BEAN) > 0; case RG_KOKIRI_SWORD: case RG_DEKU_SHIELD: case RG_GORON_TUNIC: @@ -303,6 +306,8 @@ namespace Rando { case RG_WEIRD_EGG: case RG_RUTOS_LETTER: return IsChild; + case RG_MAGIC_BEAN: + return IsChild; // Songs case RG_ZELDAS_LULLABY: @@ -336,7 +341,7 @@ namespace Rando { return BugShrub || WanderingBugs || BugRock || GetInLogic(LOGIC_BUGS_ACCESS); case RG_BOTTLE_WITH_FISH: return LoneFish || FishGroup || GetInLogic(LOGIC_FISH_ACCESS); //is there any need to care about lone vs group? - case RG_BOTTLE_WITH_BLUE_FIRE: //RANDOTODO should probably be better named to + case RG_BOTTLE_WITH_BLUE_FIRE: //RANDOTODO should probably be better named return BlueFireAccess || GetInLogic(LOGIC_BLUE_FIRE_ACCESS); case RG_BOTTLE_WITH_FAIRY: return FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond || GetInLogic(LOGIC_FAIRY_ACCESS); @@ -410,10 +415,42 @@ namespace Rando { //RANDOTODO quantity is a placeholder for proper ammo use calculation logic. in time will want updating to account for ammo capacity //Can we kill this enemy - bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wallOrFloor, uint8_t quantity) { + bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wallOrFloor, uint8_t quantity, bool timer, bool inWater) { bool killed = false; switch(enemy) { case RE_GOLD_SKULLTULA: + switch (distance){ + case ED_CLOSE: + //hammer jumpslash cannot damage these, but hammer swing can + killed = CanUse(RG_MEGATON_HAMMER); + [[fallthrough]]; + case ED_SHORT_JUMPSLASH: + killed = killed || CanUse(RG_KOKIRI_SWORD); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + killed = killed || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); + [[fallthrough]]; + case ED_BOMB_THROW: + killed = killed || CanUse(RG_BOMB_BAG); + [[fallthrough]]; + case ED_BOOMERANG: + killed = killed || CanUse(RG_BOOMERANG) || CanUse(RG_DINS_FIRE); + [[fallthrough]]; + case ED_HOOKSHOT: + //RANDOTODO test dins and chu range in a practical example + killed = killed || CanUse(RG_HOOKSHOT); + [[fallthrough]]; + case ED_LONGSHOT: + killed = killed || CanUse(RG_LONGSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); + [[fallthrough]]; + case ED_FAR: + killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + break; + } + return killed; case RE_GOHMA_LARVA: case RE_MAD_SCRUB: case RE_DEKU_BABA: @@ -422,30 +459,73 @@ namespace Rando { switch (distance){ case ED_CLOSE: //hammer jumpslash cannot damage these, but hammer swing can - killed = killed || CanUse(RG_MEGATON_HAMMER); + killed = CanUse(RG_MEGATON_HAMMER); + [[fallthrough]]; + case ED_SHORT_JUMPSLASH: + killed = killed || CanUse(RG_KOKIRI_SWORD); [[fallthrough]]; - case ED_HAMMER_JUMPSLASH: case ED_MASTER_SWORD_JUMPSLASH: - killed = killed || CanJumpslashExceptHammer(); + killed = killed || CanUse(RG_MASTER_SWORD); [[fallthrough]]; - case ED_RANG_OR_HOOKSHOT: - //RANDOTODO test dins, bomb and chu range in a practical example - killed = killed || CanUse(RG_HOOKSHOT) || CanUse(RG_BOMB_BAG) || (wallOrFloor && CanUse(RG_BOMBCHU_5)) || CanUse(RG_DINS_FIRE); + case ED_LONG_JUMPSLASH: + killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); + [[fallthrough]]; + case ED_BOMB_THROW: + killed = killed || CanUse(RG_BOMB_BAG); + [[fallthrough]]; + case ED_BOOMERANG: + //RANDOTODO test dins and chu range in a practical example + killed = killed || CanUse(RG_DINS_FIRE); + [[fallthrough]]; + case ED_HOOKSHOT: + //RANDOTODO test dins and chu range in a practical example + killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); [[fallthrough]]; case ED_LONGSHOT: killed = killed || CanUse(RG_LONGSHOT); [[fallthrough]]; case ED_FAR: - killed = CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); break; } return killed; case RE_DODONGO: + return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || (quantity <= 5 && CanUse(RG_STICKS)) || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); case RE_LIZALFOS: return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); case RE_KEESE: case RE_FIRE_KEESE: - return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); + switch (distance){ + case ED_CLOSE: + case ED_SHORT_JUMPSLASH: + killed = CanUse(RG_MEGATON_HAMMER) || CanUse(RG_KOKIRI_SWORD); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + killed = killed || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); + [[fallthrough]]; + case ED_BOMB_THROW: + //RANDOTODO test dins and chu range in a practical example + killed = killed || (!inWater && CanUse(RG_BOMB_BAG)); + [[fallthrough]]; + case ED_BOOMERANG: + //RANDOTODO test dins and chu range in a practical example + killed = killed || CanUse(RG_BOOMERANG); + [[fallthrough]]; + case ED_HOOKSHOT: + //RANDOTODO test dins, bomb and chu range in a practical example + killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); + [[fallthrough]]; + case ED_LONGSHOT: + killed = killed || CanUse(RG_LONGSHOT); + [[fallthrough]]; + case ED_FAR: + killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + break; + } + return killed; case RE_BLUE_BUBBLE: //RANDOTODO Trick to use shield hylian shield as child to stun these guys //RANDOTODO check hammer damage @@ -460,8 +540,31 @@ namespace Rando { return CanDamage(); case RE_STALFOS: //RANDOTODO Add trick to kill stalfos with sticks, and a second one for bombs without stunning. Higher ammo logic for bombs is also plausible - return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_FAIRY_BOW) || CanUse(RG_BOMBCHU_5) || - (quantity <= 2 && (CanUse(RG_NUTS) || HookshotOrBoomerang()) && CanUse(RG_BOMB_BAG)) || (quantity <= 1 && CanUse(RG_STICKS)); + switch (distance){ + case ED_CLOSE: + case ED_SHORT_JUMPSLASH: + killed = CanUse(RG_MEGATON_HAMMER) || CanUse(RG_KOKIRI_SWORD); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + killed = killed || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + killed = killed || CanUse(RG_BIGGORON_SWORD) || (quantity <= 1 && CanUse(RG_STICKS)); + [[fallthrough]]; + case ED_BOMB_THROW: + killed = killed || (quantity <= 2 && !timer && !inWater && (CanUse(RG_NUTS) || HookshotOrBoomerang()) && CanUse(RG_BOMB_BAG)); + [[fallthrough]]; + case ED_BOOMERANG: + case ED_HOOKSHOT: + //RANDOTODO test dins and chu range in a practical example + killed = killed || (wallOrFloor && CanUse(RG_BOMBCHU_5)); + [[fallthrough]]; + case ED_LONGSHOT: + case ED_FAR: + killed = killed || CanUse(RG_FAIRY_BOW); + break; + } + return killed; //Needs 16 bombs, but is in default logic in N64, probably because getting the hits is quite easy. //bow and sling can wake them and damage after they shed their armour, so could reduce ammo requirements for explosives to 10. //requires 8 sticks to kill so would be a trick unless we apply higher stick bag logic @@ -474,7 +577,12 @@ namespace Rando { case RE_FLARE_DANCER: return CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || (HasExplosives() && (CanJumpslashExceptHammer() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG))); case RE_WOLFOS: - return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5) || (CanUse(RG_BOMB_BAG) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG))); + case RE_WHITE_WOLFOS: + case RE_WALLMASTER: + return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5) || CanUse(RG_DINS_FIRE) || (CanUse(RG_BOMB_BAG) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG))); + case RE_GERUDO_WARRIOR: + return CanJumpslash() || CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON) && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5))); + case RE_GIBDO: case RE_REDEAD: return CanJumpslash() || CanUse(RG_DINS_FIRE); case RE_MEG: @@ -487,9 +595,78 @@ namespace Rando { return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || HasExplosives()/* || (CanUse(RG_DINS_FIRE) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG)))*/; case RE_DINOLFOS: //stunning + bombs is possible but painful, as it loves to dodge the bombs and hookshot. it also dodges chus but if you cook it so it detonates under the dodge it usually gets caught on landing - return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_BOMBCHU_5) || CanUse(RG_FAIRY_SLINGSHOT); + return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || (!timer && CanUse(RG_BOMBCHU_5)); case RE_TORCH_SLUG: return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_BOW); + case RE_FREEZARD: + return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_STICKS) || HasExplosives() || CanUse(RG_HOOKSHOT) || CanUse(RG_DINS_FIRE) || CanUse(RG_FIRE_ARROWS); + case RE_SPIKE: + return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_STICKS) || HasExplosives() || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_DINS_FIRE); + case RE_STINGER: + switch (distance){ + case ED_CLOSE: + case ED_SHORT_JUMPSLASH: + killed = CanUse(RG_MEGATON_HAMMER) || CanUse(RG_KOKIRI_SWORD); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + killed = killed || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); + [[fallthrough]]; + case ED_BOMB_THROW: + //RANDOTODO test dins and chu range in a practical example + killed = killed || (!inWater && CanUse(RG_BOMB_BAG)); + [[fallthrough]]; + case ED_BOOMERANG: + case ED_HOOKSHOT: + //RANDOTODO test dins, bomb and chu range in a practical example + killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); + [[fallthrough]]; + case ED_LONGSHOT: + killed = killed || CanUse(RG_LONGSHOT); + [[fallthrough]]; + case ED_FAR: + killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + break; + } + return killed; + case RE_BIG_OCTO: + //If chasing octo is annoying but with rolls you can catch him, and you need rang to get into this room without shenanigains anyway. Bunny makes it free + return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_STICKS) || CanUse(RG_MASTER_SWORD); + case RE_GANONDORF: + // RANDOTODO: Trick to use hammer (no jumpslash) or stick (only jumpslash) instead of a sword to reflect the energy ball + // and either of them regardless of jumpslashing to damage and kill ganondorf + + // Bottle is not taken into account since a sword, hammer or stick are required + // for killing ganondorf and all of those can reflect the energy ball + // This will not be the case once ammo logic in taken into account as + // sticks are limited and using a bottle might become a requirement in that case + return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_LIGHT_ARROWS) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)); + case RE_GANON: + return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_MASTER_SWORD); + case RE_DARK_LINK: + //RANDOTODO Dark link is buggy right now, retest when he is not + return CanJumpslash() || CanUse(RG_FAIRY_BOW); + case RE_ANUBIS: + //there's a restoration that allows beating them with mirror shield + some way to trigger thier attack + return HasFireSource(); + case RE_BEAMOS: + return HasExplosives(); + case RE_PURPLE_LEEVER: + //dies on it's own, so this is the conditions to spawn it (killing 10 normal leevers) + //Sticks and Ice arrows work but will need ammo capacity logic + //other methods can damage them but not kill them, and they run when hit, making them impractical + return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD); + case RE_TENTACLE: + return CanUse(RG_BOOMERANG); + case RE_BARI: + return HookshotOrBoomerang() || CanUse(RG_FAIRY_BOW) || HasExplosives() || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_STICKS) || CanUse(RG_DINS_FIRE) || (TakeDamage() && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD))); + case RE_SHABOM: + //RANDOTODO when you add better damage logic, you can kill this by taking hits + return CanUse(RG_BOOMERANG) || CanUse(RG_NUTS) || CanJumpslash() || CanUse(RG_DINS_FIRE) || CanUse(RG_ICE_ARROWS); + case RE_OCTOROK: + return CanReflectNuts() || HookshotOrBoomerang() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMB_BAG) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); default: SPDLOG_ERROR("CanKillEnemy reached `default`."); assert(false); @@ -519,19 +696,29 @@ namespace Rando { case RE_STALFOS: case RE_FLARE_DANCER: case RE_WOLFOS: + case RE_WHITE_WOLFOS: case RE_FLOORMASTER: case RE_MEG: case RE_ARMOS: + case RE_FREEZARD: + case RE_SPIKE: + case RE_DARK_LINK: + case RE_ANUBIS: + case RE_WALLMASTER: + case RE_PURPLE_LEEVER: + case RE_OCTOROK: return true; case RE_BIG_SKULLTULA: //hammer jumpslash can pass, but only on flat land where you can kill with hammer swing return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG); case RE_LIKE_LIKE: return CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); + case RE_GIBDO: case RE_REDEAD: // we need a way to check if suns won't force a reload return CanUse(RG_HOOKSHOT) || CanUse(RG_SUNS_SONG); case RE_IRON_KNUCKLE: + case RE_BIG_OCTO: return false; case RE_GREEN_BUBBLE: return TakeDamage() || CanUse(RG_NUTS) || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT); @@ -543,42 +730,56 @@ namespace Rando { } //Can we avoid this enemy while climbing up a wall, or doing a difficult platforming challenge? - bool Logic::CanAvoidEnemy(RandomizerEnemy enemy) { - if (CanKillEnemy(enemy)){ - return true; - } - switch(enemy) { - case RE_GOLD_SKULLTULA: - case RE_GOHMA_LARVA: - case RE_LIZALFOS: - case RE_DODONGO: //RANDOTODO do dodongos block the way in tight corridors? - case RE_BIG_SKULLTULA: - case RE_DEAD_HAND: - case RE_DEKU_BABA: - case RE_WITHERED_DEKU_BABA: - case RE_LIKE_LIKE: - case RE_STALFOS: - case RE_IRON_KNUCKLE: - case RE_FLARE_DANCER: - case RE_WOLFOS: - case RE_FLOORMASTER: - case RE_REDEAD: - case RE_MEG: - case RE_ARMOS: - case RE_GREEN_BUBBLE: - return true; - case RE_MAD_SCRUB: - case RE_KEESE: - case RE_FIRE_KEESE: - return CanUse(RG_NUTS); - case RE_BLUE_BUBBLE: - //RANDOTODO Trick to use shield hylian shield as child to stun these guys - return CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield(); - default: - SPDLOG_ERROR("CanPassEnemy reached `default`."); - assert(false); - return false; - } +//use grounded if the challenge is such that the enemy interfears even if it cannot hit link out of the air + bool Logic::CanAvoidEnemy(RandomizerEnemy enemy, bool grounded, uint8_t quantity) { + //DISTANCE AND WALL ASSUMED, add more arguments later if needed + if (CanKillEnemy(enemy, ED_CLOSE, true, quantity)){ + return true; + } + switch(enemy) { + case RE_GOLD_SKULLTULA: + case RE_GOHMA_LARVA: + case RE_LIZALFOS: + case RE_DODONGO: + case RE_BIG_SKULLTULA: + case RE_DEAD_HAND: + case RE_DEKU_BABA: + case RE_WITHERED_DEKU_BABA: + case RE_LIKE_LIKE: + case RE_STALFOS: + case RE_IRON_KNUCKLE: + case RE_FLARE_DANCER: + case RE_WOLFOS: + case RE_WHITE_WOLFOS: + case RE_FLOORMASTER: + case RE_REDEAD: + case RE_MEG: + case RE_ARMOS: + case RE_GREEN_BUBBLE: + case RE_FREEZARD: + case RE_SPIKE: + case RE_BIG_OCTO: + case RE_GIBDO: + case RE_DARK_LINK: + case RE_WALLMASTER: + case RE_ANUBIS: + case RE_PURPLE_LEEVER: + return true; + case RE_BEAMOS: + return !grounded || CanUse(RG_NUTS) || (quantity == 1 && (CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT))); + case RE_MAD_SCRUB: + return !grounded || CanUse(RG_NUTS); + case RE_KEESE: + case RE_FIRE_KEESE: + return CanUse(RG_NUTS); + case RE_BLUE_BUBBLE: + //RANDOTODO Trick to use shield hylian shield as child to stun these guys + return !grounded || CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield(); + default: + SPDLOG_ERROR("CanPassEnemy reached `default`."); + assert(false); + return false; + } } bool Logic::CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance, bool aboveLink) { @@ -588,15 +789,35 @@ namespace Rando { if (distance <= ED_MASTER_SWORD_JUMPSLASH){ return true; } + bool drop = false; switch(enemy) { case RE_GOLD_SKULLTULA: - //RANDOTODO double check all jumpslash kills that might be out of jump/backflip range - return distance <= ED_HAMMER_JUMPSLASH || (distance <= ED_RANG_OR_HOOKSHOT && (CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG))) || (distance == ED_LONGSHOT && CanUse(RG_LONGSHOT)); + switch(distance){ + case ED_CLOSE: + case ED_SHORT_JUMPSLASH: + case ED_MASTER_SWORD_JUMPSLASH: + case ED_LONG_JUMPSLASH: + case ED_BOMB_THROW: + case ED_BOOMERANG: + drop = drop || CanUse(RG_BOOMERANG); + [[fallthrough]]; + case ED_HOOKSHOT: + drop = drop || CanUse(RG_HOOKSHOT); + [[fallthrough]]; + case ED_LONGSHOT: + drop = drop || CanUse(RG_LONGSHOT); + [[fallthrough]]; + case ED_FAR: + break; + //RANDOTODO double check all jumpslash kills that might be out of jump/backflip range + } + return drop; + break; case RE_KEESE: case RE_FIRE_KEESE: return true; default: - return aboveLink || (distance <= ED_RANG_OR_HOOKSHOT && CanUse(RG_BOOMERANG)); + return aboveLink || (distance <= ED_BOOMERANG && CanUse(RG_BOOMERANG)); } } @@ -625,6 +846,35 @@ namespace Rando { return CanDetonateBombFlowers() || HasItem(RG_GORONS_BRACELET); } + bool Logic::MQWaterLevel(RandoWaterLevel level) { + //For ease of reading, I will call the triforce emblem that sets the water to WL_LOW the "Low Emblem", the one that sets it to WL_MID the "Mid Emblem", and the one that sets it to WL_HIGH the "High Emblem" + switch(level){ + //While you have to go through WL_LOW to get to Mid, the requirements for WL_LOW are stricter than WL_MID because you can always go up to WL_MID and then could need to go back to WL_HIGH to reach the Low Emblem again + //Thanks to this caveat you need to be able to reach and play ZL to both the High and Low Emblems to have WL_LOW in logic. + //Alternativly a way to reach WL_LOW from WL_MID could exist, but all glitchless methods need you to do a Low-locked action + case WL_LOW: + return (CanWaterTempleHigh && CanWaterTempleLowFromHigh) || (CanWaterTempleLowFromMid && CanWaterTempleLowFromHigh); + case WL_LOW_OR_MID: + return (CanWaterTempleHigh && CanWaterTempleLowFromHigh) || (CanWaterTempleLowFromHigh && CanWaterTempleMiddle) || (CanWaterTempleLowFromMid && CanWaterTempleLowFromHigh); + //If we can set it to High out of logic we can just repeat what we did to lower the water in the first place as High is the default. + //Because of this you only need to be able to use the Low and Mid Emblems, WL_LOW could be skipped if it was ever possible to play ZL underwater. + case WL_MID: + return CanWaterTempleLowFromHigh && CanWaterTempleMiddle; + //Despite being the initial state of water temple, WL_HIGH has the extra requirement of making sure that, if we were to lower the water out of logic, we could put it back to WL_HIGH + //However because it is the default state, we do not need to check if we can actually change the water level, only to make sure we can return to WL_HIGH if we found the means to play ZL out of logic. + //There are 2 methods to lock yourself out after playing ZL already: Not being able to reach the High Emblem and being unable to replay ZL. (I will be ignoring other-age-access shenanigains) + //The former check would simply be a check to see if we can reach High Emblem, but we assume the water is WL_MID (as if we can set it to WL_LOW, we can set it to WL_MID, as Mid Emblem has no requirements) + //The latter check can be assumed for now but will want a revisit once OI tricks are added. + case WL_HIGH: + return ReachedWaterHighEmblem; + case WL_HIGH_OR_MID: + return ReachedWaterHighEmblem || (CanWaterTempleLowFromHigh && CanWaterTempleMiddle); + } + SPDLOG_ERROR("MQWaterLevel reached `return false;`. Missing case for a Water Level"); + assert(false); + return false; + } + Logic::Logic() { } @@ -660,8 +910,37 @@ namespace Rando { return CanJumpslashExceptHammer() || CanUse(RG_MEGATON_HAMMER); } - bool Logic::CanHitSwitch() { - return CanUse(RG_FAIRY_SLINGSHOT) || CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_BOW) || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT); + bool Logic::CanHitSwitch(EnemyDistance distance, bool inWater) { + bool hit = false; + switch (distance){ + case ED_CLOSE: + case ED_SHORT_JUMPSLASH: + hit = CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MEGATON_HAMMER); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + hit = hit || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + hit = hit || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); + [[fallthrough]]; + case ED_BOMB_THROW: + hit = hit || (!inWater && CanUse(RG_BOMB_BAG)); + [[fallthrough]]; + case ED_BOOMERANG: + hit = hit || CanUse(RG_BOOMERANG); + [[fallthrough]]; + case ED_HOOKSHOT: + //RANDOTODO test chu range in a practical example + hit = hit || CanUse(RG_HOOKSHOT) || CanUse(RG_BOMBCHU_5) ; + [[fallthrough]]; + case ED_LONGSHOT: + hit = hit || CanUse(RG_LONGSHOT); + [[fallthrough]]; + case ED_FAR: + hit = hit || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + break; + } + return hit; } bool Logic::CanDamage() { @@ -694,6 +973,10 @@ namespace Rando { return CanUse(RG_BOTTLE_WITH_BLUE_FIRE) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS)); } + bool Logic::CanBreakPots(){ + return true; + } + bool Logic::HasExplosives(){ return CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5); } @@ -719,7 +1002,7 @@ namespace Rando { } bool Logic::CanLeaveForest(){ - return ctx->GetOption(RSK_FOREST).IsNot(RO_FOREST_CLOSED) || IsAdult || DekuTreeClear || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES); + return ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || IsAdult || DekuTreeClear || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES); } bool Logic::CallGossipFairyExceptSuns(){ @@ -743,7 +1026,7 @@ namespace Rando { 10 for OHKO. This is the number of shifts to apply, not a real multiplier */ - uint8_t Multiplier = (ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Value() < 6) ? ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Value() : 10; + uint8_t Multiplier = (ctx->GetOption(RSK_DAMAGE_MULTIPLIER).GetContextOptionIndex() < 6) ? ctx->GetOption(RSK_DAMAGE_MULTIPLIER).GetContextOptionIndex() : 10; //(Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) is quarter hearts after DD //>> Multiplier halves on normal and does nothing on half, meaning we're working with half hearts on normal damage return ((Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) >> Multiplier) + @@ -772,6 +1055,7 @@ namespace Rando { return CanUse(RG_GORON_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts() * 8) : 0; } + //Tunic is not required if you are using irons to do something that a simple gold scale dive could do, and you are not in water temple. (celing swimming and long walks through water do not count) uint8_t Logic::WaterTimer(){ return CanUse(RG_ZORA_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts() * 8) : 0; } @@ -789,7 +1073,7 @@ namespace Rando { } bool Logic::CanGetNightTimeGS(){ - return CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG); + return AtNight && (CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG)); } bool Logic::CanBreakUpperBeehives(){ @@ -852,9 +1136,9 @@ namespace Rando { } bool Logic::CanFinishGerudoFortress(){ - return (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_NORMAL) && SmallKeys(RR_GERUDO_FORTRESS, 4) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && (HasItem(RG_GERUDO_MEMBERSHIP_CARD) || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) || - (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST) && SmallKeys(RR_GERUDO_FORTRESS, 1) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD))) || - ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_OPEN); + return (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && SmallKeys(RR_GERUDO_FORTRESS, 4) && CanKillEnemy(RE_GERUDO_WARRIOR) && (HasItem(RG_GERUDO_MEMBERSHIP_CARD) || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) || + (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST) && SmallKeys(RR_GERUDO_FORTRESS, 1) && CanKillEnemy(RE_GERUDO_WARRIOR)) || + ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE); } bool Logic::CanStandingShield(){ @@ -866,27 +1150,27 @@ namespace Rando { } bool Logic::CanUseProjectile(){ - return HasExplosives() || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG); + return HasExplosives() || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG); } bool Logic::CanBuildRainbowBridge(){ return ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_ALWAYS_OPEN) || (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_VANILLA) && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION) && CanUse(RG_LIGHT_ARROWS)) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES) && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Value()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS) && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Value()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS) && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Value()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Value()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) && GetGSCount() >= ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Value()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES) && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).GetContextOptionIndex()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS) && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).GetContextOptionIndex()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS) && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).GetContextOptionIndex()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).GetContextOptionIndex()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) && GetGSCount() >= ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).GetContextOptionIndex()) || (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG) && HasItem(RG_GREG_RUPEE)); } bool Logic::CanTriggerLACS(){ return (ctx->GetSettings()->LACSCondition() == RO_LACS_VANILLA && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION)) || - (ctx->GetSettings()->LACSCondition() == RO_LACS_STONES && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_STONE_COUNT).Value()) || - (ctx->GetSettings()->LACSCondition() == RO_LACS_MEDALLIONS && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Value()) || - (ctx->GetSettings()->LACSCondition() == RO_LACS_REWARDS && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_REWARD_COUNT).Value()) || - (ctx->GetSettings()->LACSCondition() == RO_LACS_DUNGEONS && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Value()) || - (ctx->GetSettings()->LACSCondition() == RO_LACS_TOKENS && GetGSCount() >= ctx->GetOption(RSK_LACS_TOKEN_COUNT).Value()); + (ctx->GetSettings()->LACSCondition() == RO_LACS_STONES && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_STONE_COUNT).GetContextOptionIndex()) || + (ctx->GetSettings()->LACSCondition() == RO_LACS_MEDALLIONS && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_MEDALLION_COUNT).GetContextOptionIndex()) || + (ctx->GetSettings()->LACSCondition() == RO_LACS_REWARDS && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_REWARD_COUNT).GetContextOptionIndex()) || + (ctx->GetSettings()->LACSCondition() == RO_LACS_DUNGEONS && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_DUNGEON_COUNT).GetContextOptionIndex()) || + (ctx->GetSettings()->LACSCondition() == RO_LACS_TOKENS && GetGSCount() >= ctx->GetOption(RSK_LACS_TOKEN_COUNT).GetContextOptionIndex()); } bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount) { @@ -935,7 +1219,7 @@ namespace Rando { }*/ return GetSmallKeyCount(SCENE_BOTTOM_OF_THE_WELL) >= requiredAmountGlitchless; - case RR_GERUDO_TRAINING_GROUNDS: + case RR_GERUDO_TRAINING_GROUND: /*if (IsGlitched && (false)) { return GerudoTrainingGroundsKeys >= requiredAmountGlitched; }*/ @@ -1007,7 +1291,7 @@ namespace Rando { { RG_SPIRIT_TEMPLE_SMALL_KEY, SCENE_SPIRIT_TEMPLE }, { RG_SHADOW_TEMPLE_SMALL_KEY, SCENE_SHADOW_TEMPLE }, { RG_BOTTOM_OF_THE_WELL_SMALL_KEY, SCENE_BOTTOM_OF_THE_WELL }, - { RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, SCENE_GERUDO_TRAINING_GROUND }, + { RG_GERUDO_TRAINING_GROUND_SMALL_KEY, SCENE_GERUDO_TRAINING_GROUND }, { RG_GERUDO_FORTRESS_SMALL_KEY, SCENE_THIEVES_HIDEOUT }, { RG_GANONS_CASTLE_SMALL_KEY, SCENE_INSIDE_GANONS_CASTLE }, { RG_FOREST_TEMPLE_KEY_RING, SCENE_FOREST_TEMPLE }, @@ -1016,7 +1300,7 @@ namespace Rando { { RG_SPIRIT_TEMPLE_KEY_RING, SCENE_SPIRIT_TEMPLE }, { RG_SHADOW_TEMPLE_KEY_RING, SCENE_SHADOW_TEMPLE }, { RG_BOTTOM_OF_THE_WELL_KEY_RING, SCENE_BOTTOM_OF_THE_WELL }, - { RG_GERUDO_TRAINING_GROUNDS_KEY_RING, SCENE_GERUDO_TRAINING_GROUND }, + { RG_GERUDO_TRAINING_GROUND_KEY_RING, SCENE_GERUDO_TRAINING_GROUND }, { RG_GERUDO_FORTRESS_KEY_RING, SCENE_THIEVES_HIDEOUT }, { RG_GANONS_CASTLE_KEY_RING, SCENE_INSIDE_GANONS_CASTLE }, { RG_FOREST_TEMPLE_BOSS_KEY, SCENE_FOREST_TEMPLE }, @@ -1349,6 +1633,8 @@ namespace Rando { case RG_BOMBCHU_20: SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); break; + default: + break; } } break; @@ -1447,6 +1733,8 @@ namespace Rando { case RG_BOMBCHU_20: SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); break; + default: + break; } } break; } @@ -1854,7 +2142,7 @@ namespace Rando { //CanPlantBean = false; BigPoeKill = false; - BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).Value() + 1; + BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).GetContextOptionIndex() + 1; //Bridge Requirements @@ -1876,9 +2164,10 @@ namespace Rando { GCWoodsWarpOpen = false; GCDaruniasDoorOpenChild = false; StopGCRollingGoronAsAdult = false; - WaterTempleLow = false; - WaterTempleMiddle = false; - WaterTempleHigh = false; + CanWaterTempleLowFromHigh = false; + CanWaterTempleLowFromMid = false; + CanWaterTempleMiddle = false; + CanWaterTempleHigh = false; KakarikoVillageGateOpen = false; KingZoraThawed = false; ForestTempleJoelle = false; @@ -1905,6 +2194,27 @@ namespace Rando { ForestClearBelowBowChest = false; ForestOpenBossCorridor = false; ShadowTrialFirstChest = false; + MQGTGMazeSwitch = false; + GTGPlatformSilverRupees = false; + MQJabuHolesRoomDoor = false; + JabuWestTentacle = false; + JabuEastTentacle = false; + JabuNorthTentacle = false; + LoweredJabuPath = false; + MQJabuLiftRoomCow = false; + MQShadowFloorSpikeRupees = false; + ShadowShortcutBlock = false; + MQWaterStalfosPit = false; + MQWaterDragonTorches = false; + MQWaterB1Switch = false; + //MQWaterPillarSoTBlock = false; + MQWaterOpenedPillarB1 = false; + MQSpiritCrawlBoulder = false; + MQSpiritMapRoomEnemies = false; + MQSpirit3SunsEnemies = false; + Spirit1FSilverRupees = false; + JabuRutoInB1 = false; + JabuRutoIn1F = false; StopPerformanceTimer(PT_LOGIC_RESET); } diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 8d07dbb5b..ec4b29899 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -118,9 +118,13 @@ class Logic { bool GCWoodsWarpOpen = false; bool GCDaruniasDoorOpenChild = false; bool StopGCRollingGoronAsAdult = false; - bool WaterTempleLow = false; - bool WaterTempleMiddle = false; - bool WaterTempleHigh = false; + bool CanWaterTempleLowFromHigh = false; + bool CanWaterTempleMiddle = false; + bool CanWaterTempleHigh = false; + bool CanWaterTempleLowFromMid = false; + bool CouldWaterTempleLow = false; + bool CouldWaterTempleMiddle = false; + bool ReachedWaterHighEmblem = false; bool KakarikoVillageGateOpen = false; bool KingZoraThawed = false; bool ForestTempleJoelle = false; @@ -147,6 +151,29 @@ class Logic { bool ForestClearBelowBowChest = false; //a better name that covers both versions would be nice bool ForestOpenBossCorridor = false; bool ShadowTrialFirstChest = false; + bool MQGTGMazeSwitch = false; + bool MQGTGRightSideSwitch = false; + bool GTGPlatformSilverRupees = false; + bool MQJabuHolesRoomDoor = false; + bool JabuWestTentacle = false; + bool JabuEastTentacle = false; + bool JabuNorthTentacle = false; + bool LoweredJabuPath = false; + bool MQJabuLiftRoomCow = false; + bool MQShadowFloorSpikeRupees = false; + bool ShadowShortcutBlock = false; + bool MQWaterStalfosPit = false; + bool MQWaterDragonTorches = false; + bool MQWaterB1Switch = false; + //bool MQWaterPillarSoTBlock = false; should be irrelevant. SHOULD. + bool MQWaterOpenedPillarB1 = false; + bool MQSpiritCrawlBoulder = false; + bool MQSpiritMapRoomEnemies = false; + bool MQSpiritTimeTravelChest = false; + bool MQSpirit3SunsEnemies = false; + bool Spirit1FSilverRupees = false; + bool JabuRutoInB1 = false; + bool JabuRutoIn1F = false; /* --- END OF HELPERS AND LOCATION ACCESS --- */ @@ -160,9 +187,9 @@ class Logic { bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched); bool CanDoGlitch(GlitchType glitch); bool CanEquipSwap(RandomizerGet itemName); - bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true, uint8_t quantity = 1); + bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true, uint8_t quantity = 1, bool timer = false, bool inWater = false); bool CanPassEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true); - bool CanAvoidEnemy(RandomizerEnemy enemy); + bool CanAvoidEnemy(RandomizerEnemy enemy, bool grounded = false, uint8_t quantity = 1); bool CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool aboveLink = false); bool CanBreakMudWalls(); bool CanGetDekuBabaSticks(); @@ -170,12 +197,13 @@ class Logic { bool CanHitEyeTargets(); bool CanDetonateBombFlowers(); bool CanDetonateUprightBombFlower(); + bool MQWaterLevel(RandoWaterLevel level); uint8_t BottleCount(); uint8_t OcarinaButtons(); bool HasBottle(); bool CanJumpslashExceptHammer(); bool CanJumpslash(); - bool CanHitSwitch(); + bool CanHitSwitch(EnemyDistance distance = ED_CLOSE, bool inWater = false); bool CanDamage(); bool CanAttack(); bool BombchusEnabled(); @@ -205,6 +233,7 @@ class Logic { bool CanGetNightTimeGS(); bool CanBreakUpperBeehives(); bool CanBreakLowerBeehives(); + bool CanBreakPots(); bool HasFireSource(); bool HasFireSourceWithTorch(); bool TradeQuestStep(RandomizerGet rg); diff --git a/soh/soh/Enhancements/randomizer/option.cpp b/soh/soh/Enhancements/randomizer/option.cpp index af7ba150e..d7ff94121 100644 --- a/soh/soh/Enhancements/randomizer/option.cpp +++ b/soh/soh/Enhancements/randomizer/option.cpp @@ -31,10 +31,7 @@ Option Option::LogicTrick(std::string name_) { } Option::operator bool() const { - if (std::holds_alternative(var)) { - return Value(); - } - return Value() != 0; + return contextSelection != 0; } size_t Option::GetOptionCount() const { @@ -49,12 +46,16 @@ const std::string& Option::GetDescription() const { return description; } -uint8_t Option::GetSelectedOptionIndex() const { - return selectedOption; +uint8_t Option::GetMenuOptionIndex() const { + return menuSelection; +} + +uint8_t Option::GetContextOptionIndex() const { + return contextSelection; } const std::string& Option::GetSelectedOptionText() const { - return options[selectedOption]; + return options[contextSelection]; } const std::string& Option::GetCVarName() const { @@ -63,39 +64,45 @@ const std::string& Option::GetCVarName() const { void Option::SetVariable() { if (std::holds_alternative(var)) { - var.emplace(selectedOption != 0); + var.emplace(menuSelection != 0); } else { - var.emplace(selectedOption); + var.emplace(menuSelection); } } -void Option::SetCVar() const { +void Option::SaveCVar() const { if (!cvarName.empty()) { - CVarSetInteger(cvarName.c_str(), GetSelectedOptionIndex()); + CVarSetInteger(cvarName.c_str(), GetMenuOptionIndex()); } } void Option::SetFromCVar() { if (!cvarName.empty()) { - SetSelectedIndex(CVarGetInteger(cvarName.c_str(), defaultOption)); + SetMenuIndex(CVarGetInteger(cvarName.c_str(), defaultOption)); } } void Option::SetDelayedOption() { - delayedOption = selectedOption; + delayedSelection = contextSelection; } void Option::RestoreDelayedOption() { - selectedOption = delayedOption; + contextSelection = delayedSelection; +} + +void Option::SetMenuIndex(size_t idx) { + menuSelection = idx; + if (menuSelection > options.size() - 1) { + menuSelection = options.size() - 1; + } SetVariable(); } -void Option::SetSelectedIndex(size_t idx) { - selectedOption = idx; - if (selectedOption > options.size() - 1) { - selectedOption = options.size() - 1; +void Option::SetContextIndex(size_t idx) { + contextSelection = idx; + if (contextSelection > options.size() - 1) { + contextSelection = options.size() - 1; } - SetVariable(); } void Option::Hide() { @@ -111,8 +118,8 @@ bool Option::IsHidden() const { } void Option::ChangeOptions(std::vector opts) { - if (selectedOption >= opts.size()) { - selectedOption = opts.size() - 1; + if (menuSelection >= opts.size()) { + menuSelection = opts.size() - 1; } options = std::move(opts); } @@ -171,14 +178,24 @@ void Option::RemoveFlag(const int imFlag_) { imFlags &= ~imFlag_; } +void Option::SetContextIndexFromText(const std::string text) { + if (optionsTextToVar.contains(text)){ + SetContextIndex(optionsTextToVar[text]); + } else { + SPDLOG_ERROR("Option {} does not have a var named {}.", name, text); + assert(false); + } +} + Option::Option(uint8_t var_, std::string name_, std::vector options_, OptionCategory category_, std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_, bool defaultHidden_, int imFlags_) : var(var_), name(std::move(name_)), options(std::move(options_)), category(category_), cvarName(std::move(cvarName_)), description(std::move(description_)), widgetType(widgetType_), defaultOption(defaultOption_), defaultHidden(defaultHidden_), imFlags(imFlags_) { - selectedOption = defaultOption; + menuSelection = contextSelection = defaultOption; hidden = defaultHidden; + PopulateTextToNum(); SetFromCVar(); } Option::Option(bool var_, std::string name_, std::vector options_, const OptionCategory category_, @@ -187,8 +204,9 @@ Option::Option(bool var_, std::string name_, std::vector options_, : var(var_), name(std::move(name_)), options(std::move(options_)), category(category_), cvarName(std::move(cvarName_)), description(std::move(description_)), widgetType(widgetType_), defaultOption(defaultOption_), defaultHidden(defaultHidden_), imFlags(imFlags_) { - selectedOption = defaultOption; + menuSelection = contextSelection = defaultOption; hidden = defaultHidden; + PopulateTextToNum(); SetFromCVar(); } @@ -201,7 +219,7 @@ bool Option::RenderCheckbox() { if (CustomCheckbox(name.c_str(), &val, disabled, disabledGraphic)) { CVarSetInteger(cvarName.c_str(), val); changed = true; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (!description.empty()) { UIWidgets::InsertHelpHoverText(description.c_str()); @@ -221,7 +239,7 @@ bool Option::RenderTristateCheckbox() { if (CustomCheckboxTristate(name.c_str(), &val, disabled, disabledGraphic)) { CVarSetInteger(cvarName.c_str(), val); changed = true; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (!description.empty()) { UIWidgets::InsertHelpHoverText(description.c_str()); @@ -243,7 +261,7 @@ bool Option::RenderCombobox() { selected = options.size(); CVarSetInteger(cvarName.c_str(), selected); changed = true; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (!description.empty()) { UIWidgets::InsertHelpHoverText(description.c_str()); @@ -256,7 +274,7 @@ bool Option::RenderCombobox() { CVarSetInteger(cvarName.c_str(), static_cast(i)); changed = true; selected = i; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } } @@ -270,7 +288,7 @@ bool Option::RenderCombobox() { bool Option::RenderSlider() { bool changed = false; - int val = GetSelectedOptionIndex(); + int val = GetMenuOptionIndex(); if (val > options.size() - 1) { val = options.size() - 1; CVarSetInteger(cvarName.c_str(), val); @@ -321,18 +339,24 @@ bool Option::RenderSlider() { if (changed) { CVarSetInteger(cvarName.c_str(), val); SetFromCVar(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } return changed; } -TrickOption::TrickOption(const RandomizerCheckQuest quest_, const RandomizerArea area_, std::set tags_, const bool glitch_, const std::string& name_, std::string description_) : +void Option::PopulateTextToNum(){ + for (uint8_t count = 0; count < options.size(); count++){ + optionsTextToVar[options[count]] = count; + } +} + +TrickOption::TrickOption(const RandomizerCheckQuest quest_, const RandomizerArea area_, std::set tags_, const std::string& name_, std::string description_) : Option(false, name_, {"Disabled", "Enabled"}, OptionCategory::Setting, "", std::move(description_), WidgetType::Checkbox, 0, false, IMFLAG_NONE), - mQuest(quest_), mArea(area_), mTags(std::move(tags_)), mGlitch(glitch_) {} + mQuest(quest_), mArea(area_), mTags(std::move(tags_)) {} -TrickOption TrickOption::LogicTrick(RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, bool glitch_, const std::string& name_, std::string description_) { - return {quest_, area_, std::move(tags_), glitch_, name_, std::move(description_)}; +TrickOption TrickOption::LogicTrick(RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, const std::string& name_, std::string description_) { + return {quest_, area_, std::move(tags_), name_, std::move(description_)}; } RandomizerCheckQuest TrickOption::GetQuest() const { @@ -343,10 +367,6 @@ RandomizerArea TrickOption::GetArea() const { return mArea; } -bool TrickOption::IsGlitch() const { - return mGlitch; -} - bool TrickOption::HasTag(const Tricks::Tag tag) const { return mTags.contains(tag); } @@ -356,26 +376,26 @@ const std::set& TrickOption::GetTags() const { } OptionGroup::OptionGroup(std::string name, std::vector options, const OptionGroupType groupType, - const bool printInSpoiler, const WidgetContainerType containerType, std::string description) - : mName(std::move(name)), mOptions(std::move(options)), mGroupType(groupType), mPrintInSpoiler(printInSpoiler), + const WidgetContainerType containerType, std::string description) + : mName(std::move(name)), mOptions(std::move(options)), mGroupType(groupType), mContainerType(containerType), mDescription(std::move(description)) { } OptionGroup::OptionGroup(std::string name, std::vector subGroups, const OptionGroupType groupType, - const bool printInSpoiler, const WidgetContainerType containerType, std::string description) - : mName(std::move(name)), mSubGroups(std::move(subGroups)), mGroupType(groupType), mPrintInSpoiler(printInSpoiler), + const WidgetContainerType containerType, std::string description) + : mName(std::move(name)), mSubGroups(std::move(subGroups)), mGroupType(groupType), mContainsType(OptionGroupType::SUBGROUP), mContainerType(containerType), mDescription(std::move(description)) { } -OptionGroup OptionGroup::SubGroup(std::string name, std::vector options, const bool printInSpoiler, +OptionGroup OptionGroup::SubGroup(std::string name, std::vector options, const WidgetContainerType containerType, std::string description) { - return {std::move(name), std::move(options), OptionGroupType::SUBGROUP, printInSpoiler, containerType, + return {std::move(name), std::move(options), OptionGroupType::SUBGROUP, containerType, std::move(description)}; } -OptionGroup OptionGroup::SubGroup(std::string name, std::vector subGroups, const bool printInSpoiler, +OptionGroup OptionGroup::SubGroup(std::string name, std::vector subGroups, const WidgetContainerType containerType, std::string description) { - return {std::move(name), std::move(subGroups), OptionGroupType::SUBGROUP, printInSpoiler, containerType, + return {std::move(name), std::move(subGroups), OptionGroupType::SUBGROUP, containerType, std::move(description)}; } @@ -391,10 +411,6 @@ const std::vector& OptionGroup::GetSubGroups() const { return mSubGroups; } -bool OptionGroup::PrintInSpoiler() const { - return mPrintInSpoiler; -} - OptionGroupType OptionGroup::GetGroupType() const { return mGroupType; } @@ -479,7 +495,7 @@ bool OptionGroup::RenderImGui() const { // NOLINT(*-no-recursion) ImGui::Unindent(); } if (option->HasFlag(IMFLAG_SEPARATOR_BOTTOM)) { - UIWidgets::PaddedSeparator(); + UIWidgets::PaddedSeparator(false, true); } } } diff --git a/soh/soh/Enhancements/randomizer/option.h b/soh/soh/Enhancements/randomizer/option.h index 1bb979ebc..e1e5a3a78 100644 --- a/soh/soh/Enhancements/randomizer/option.h +++ b/soh/soh/Enhancements/randomizer/option.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -56,9 +57,9 @@ class Option { * @param options_ A vector of value names for this Option. This vector should have a size of 2. * The name corresponding to the selected index for this option will be printed to the spoiler/patch file. * @param category_ The desired `OptionCategory` for this option. - * @param cvarName_ The name ofthe CVar this option should correspond with. Set as an empty string to not + * @param cvarName_ The name of the CVar this option should correspond with. Set as an empty string to not * link to any Cvar. - * @param description_ A description of what this option affects. Will be rendered in a toolip in ImGui. + * @param description_ A description of what this option affects. Will be rendered in a tooltip in ImGui. * Can be left as an empty string if desired, no tooltip will be rendered. * @param widgetType_ What type of widget should be rendered. Should probably be `Checkbox` but technically * `Combobox` or `Slider` would render and function correctly. @@ -126,42 +127,25 @@ class Option { */ static Option LogicTrick(std::string name_); - /** - * @brief Gets the selected index or boolean value of the Option. - * - * @tparam T uint8_t or bool, depending on how the option was constructed. - * @return T - */ - template T Value() const { - return std::get(var); - } - /** * @brief Determines if the value/selected index of this Option matches the provided value. * - * @tparam T uint8_t, bool, or an enum (which will be cast to uint8_t). * @param other The value to compare. * @return true * @return false */ - template bool Is(T other) const { - static_assert(std::is_integral_v || std::is_enum_v, "T must be an integral type or an enum."); - if constexpr ((std::is_integral_v && !std::is_same_v) || std::is_enum_v) { - return Value() == static_cast(other); - } else { - return Value() == static_cast(other); - } + bool Is(uint32_t other) const { + return contextSelection == other; } /** * @brief Determines if the value/selected index of this Option does not match the provided value. * - * @tparam T uint8_t, book, or an enum (which will be cast to uint8_t). * @param other The value to compare. * @return true * @return false */ - template bool IsNot(T other) const { + bool IsNot(uint32_t other) const { return !Is(other); } @@ -203,11 +187,18 @@ class Option { const std::string& GetCVarName() const; /** - * @brief Get the selected index for this Option. + * @brief Get the menu index for this Option. * * @return uint8_t */ - uint8_t GetSelectedOptionIndex() const; + uint8_t GetMenuOptionIndex() const; + + /** + * @brief Get the rando context index for this Option. + * + * @return uint8_t + */ + uint8_t GetContextOptionIndex() const; /** * @brief Sets the variable to the currently selected index for this Option. @@ -218,7 +209,7 @@ class Option { * @brief Sets the CVar corresponding to the property `cvarName` equal to the value * of the property `selectedValue`. */ - void SetCVar() const; + void SaveCVar() const; /** * @brief Sets the value of property `selectedValue` equal to the CVar corresponding @@ -237,11 +228,18 @@ class Option { void RestoreDelayedOption(); /** - * @brief Set the selected index for this Option. Also calls `SetVariable()`. + * @brief Set the menu index for this Option. Also calls `SetVariable()`. * * @param idx the index to set as the selected index. */ - void SetSelectedIndex(size_t idx); + void SetMenuIndex(size_t idx); + + /** + * @brief Set the rando context index for this Option. Also calls `SetVariable()`. + * + * @param idx the index to set as the selected index. + */ + void SetContextIndex(size_t idx); /** * @brief Hides this Option in the menu. (Not currently being used afaik, we prefer to @@ -308,6 +306,8 @@ class Option { void SetFlag(int imFlag_); void RemoveFlag(int imFlag_); + void SetContextIndexFromText(std::string text); + protected: Option(uint8_t var_, std::string name_, std::vector options_, OptionCategory category_, std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_, @@ -321,11 +321,13 @@ protected: bool RenderTristateCheckbox(); bool RenderCombobox(); bool RenderSlider(); + void PopulateTextToNum(); std::variant var; std::string name; std::vector options; - uint8_t selectedOption = 0; - uint8_t delayedOption = 0; + uint8_t menuSelection = 0; + uint8_t contextSelection = 0; + uint8_t delayedSelection = 0; bool hidden = false; OptionCategory category = OptionCategory::Setting; std::string cvarName; @@ -337,6 +339,7 @@ protected: bool disabled = false; UIWidgets::CheckboxGraphics disabledGraphic = UIWidgets::CheckboxGraphics::Cross; std::string disabledText; + std::unordered_map optionsTextToVar = {}; }; class TrickOption : public Option { @@ -348,12 +351,11 @@ public: * @param quest_ MQ, Vanilla, or Both. * @param area_ The area the trick is relevant for. * @param tags_ The set of RandomizerTrickTags for this trick. - * @param glitch_ Whether or not this trick is a glitch. * @param name_ The name of the trick. Appears in the spoiler/patch file. * @param description_ A brief description of the trick. * @return Option */ - static TrickOption LogicTrick(RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, bool glitch_, const std::string& name_, std::string description_); + static TrickOption LogicTrick(RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, const std::string& name_, std::string description_); /** * @brief Retrieve the quest type this trick is relevant for. @@ -369,13 +371,6 @@ public: */ RandomizerArea GetArea() const; - /** - * @brief Get whether or not this Trick is considered a glitch. - * - * @return true or false - */ - bool IsGlitch() const; - /** * @brief Check if this Trick has the given tag * @@ -387,11 +382,10 @@ public: const std::set& GetTags() const; private: - TrickOption(RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, bool glitch_, const std::string& name_, std::string description_); + TrickOption(RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, const std::string& name_, std::string description_); RandomizerCheckQuest mQuest; RandomizerArea mArea; std::set mTags; - bool mGlitch; }; enum class OptionGroupType { @@ -418,13 +412,11 @@ class OptionGroup { * @param options A vector of Option pointers * @param groupType `DEFAULT` if this group is not contained within any other groups, `SUBGROUP` if it is a * subgroup of another group. - * @param printInSpoiler Whether or not to print the contents of this group to the spoiler/patch file. * @param containerType Specifies the type of container this widget should render as in ImGui. * @param description A description that can appear in a tooltip in ImGui. */ OptionGroup(std::string name, std::vector options, OptionGroupType groupType = OptionGroupType::DEFAULT, - bool printInSpoiler = true, WidgetContainerType containerType = WidgetContainerType::BASIC, - std::string description = ""); + WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** * @brief Construct a new Option Group containing a list of `OptionGroup` pointers. @@ -433,13 +425,11 @@ class OptionGroup { * @param subGroups A vector of OptionGroup pointers that will be subgroups of this group. * @param groupType `DEFAULT` if this group is not contained within any other groups, `SUBGROUP` if it is a * subgroup of another group. - * @param printInSpoiler Whether or not to print the contents of this group to spoiler/patch file. * @param containerType Specifies the type of container this widget should render as in ImGui. * @param description A description that can appear in a tooltip in ImGui. */ OptionGroup(std::string name, std::vector subGroups, OptionGroupType groupType = OptionGroupType::DEFAULT, - bool printInSpoiler = true, WidgetContainerType containerType = WidgetContainerType::BASIC, - std::string description = ""); + WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** * @brief Convenience function for constructing an OptionGroup of groupType `SUBGROUP` with @@ -447,13 +437,11 @@ class OptionGroup { * * @param name The name of this option group. Appears in the spoiler/patch file. * @param options A vector of Option pointers. - * @param printInSpoiler Whether or not to print the options of this group to the spoiler/patch file. * @param containerType Specifies the type of container this widget should render as in ImGui. * @param description A description that can appear in a tooltip in ImGui. * @return OptionGroup */ - static OptionGroup SubGroup(std::string name, std::vector options, bool printInSpoiler = true, - WidgetContainerType containerType = WidgetContainerType::BASIC, + static OptionGroup SubGroup(std::string name, std::vector options, WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** @@ -462,13 +450,11 @@ class OptionGroup { * * @param name The name of this option group. Appears in the spoiler/patch file. * @param subGroups A vector of OptionGroup pointers. - * @param printInSpoiler Whether or not to print the options of this group to the spoiler/patch file. * @param containerType Specifies the type of container this widget should render as in ImGui. * @param description A description that can appear in a tooltip in ImGui. * @return OptionGroup */ - static OptionGroup SubGroup(std::string name, std::vector subGroups, bool printInSpoiler = true, - WidgetContainerType containerType = WidgetContainerType::BASIC, + static OptionGroup SubGroup(std::string name, std::vector subGroups, WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** @@ -492,15 +478,6 @@ class OptionGroup { */ const std::vector& GetSubGroups() const; - /** - * @brief Returns whether or not this `OptionGroup`'s contents should be printed to the - * spoiler/patch file. - * - * @return true - * @return false - */ - bool PrintInSpoiler() const; - /** * @brief Get the Group Type of this `OptionGroup`. `DEFAULT` means this group is not contained * within any other groups, while `SUBGROUP` means that it is contained within at least one other. @@ -534,7 +511,6 @@ class OptionGroup { std::vector mOptions; std::vector mSubGroups; OptionGroupType mGroupType = OptionGroupType::DEFAULT; - bool mPrintInSpoiler = true; OptionGroupType mContainsType = OptionGroupType::DEFAULT; WidgetContainerType mContainerType = WidgetContainerType::BASIC; std::string mDescription; diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 7de98b3d0..f95f817e7 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -2,30 +2,32 @@ namespace Rando { void Settings::CreateOptionDescriptions() { - mOptionDescriptions[RSK_FOREST] = "Closed - Kokiri sword & shield are required to access " - "the Deku Tree, and completing the Deku Tree is required to " - "access the Hyrule Field exit.\n" + mOptionDescriptions[RSK_FOREST] = "Determines if Kokiri forest can be left for the Lost Woods bridge or the Deku Tree.\n" "\n" - "Closed Deku - Kokiri boy no longer blocks the path to Hyrule " - "Field but Mido still requires the Kokiri sword and Deku shield " + "On - Kokiri Sword & Deku Shield are required to access " + "the Deku Tree, and completing the Deku Tree is required to " + "access the Lost Woods Bridge Exit.\n" + "\n" + "Deku Only - Kokiri boy no longer blocks the path to the Bridge " + "but Mido still requires the Kokiri Sword and Deku Shield " "to access the tree.\n" "\n" - "Open - Mido no longer blocks the path to the Deku Tree. Kokiri " + "Off - Mido no longer blocks the path to the Deku Tree. Kokiri " "boy no longer blocks the path out of the forest."; - mOptionDescriptions[RSK_KAK_GATE] = "Closed - The gate will remain closed until Zelda's letter " + mOptionDescriptions[RSK_KAK_GATE] = "Closed - The gate will remain closed until Zelda's Letter " "is shown to the guard.\n" "\n" - "Open - The gate is always open. The happy mask shop " - "will open immediately after obtaining Zelda's letter."; + "Open - The gate is always open. The Happy Mask Shop " + "will open immediately after obtaining Zelda's Letter."; mOptionDescriptions[RSK_DOOR_OF_TIME] = "Closed - The Ocarina of Time, the Song of Time and all " - "three spiritual stones are required to open the Door of Time.\n" + "three Spiritual Stones are required to open the Door of Time.\n" "\n" "Song only - Play the Song of Time in front of the Door of " "Time to open it.\n" "\n" "Open - The Door of Time is permanently open with no requirements."; mOptionDescriptions[RSK_ZORAS_FOUNTAIN] = "Closed - King Zora obstructs the way to Zora's Fountain. " - "Ruto's letter must be shown as child Link in order to move " + "Ruto's Letter must be shown as child Link in order to move " "him in both time periods.\n" "\n" "Closed as child - Ruto's Letter is only required to move King Zora " @@ -33,18 +35,25 @@ void Settings::CreateOptionDescriptions() { "\n" "Open - King Zora has already mweeped out of the way in both " "time periods. Ruto's Letter is removed from the item pool."; + mOptionDescriptions[RSK_SLEEPING_WATERFALL] = "Closed - Sleeping Waterfall obstructs the entrance to Zora's " + "Domain. Zelda's Lullaby must be played in order to open it " + "(but only once; then it stays open in both time periods).\n" + "\n" + "Open - Sleeping Waterfall is always open. " + "Link may always enter Zora's Domain."; mOptionDescriptions[RSK_STARTING_AGE] = "Choose which age Link will start as.\n\n" "Starting as adult means you start with the Master Sword in your inventory.\n" "The child option is forcefully set if it would conflict with other options."; - mOptionDescriptions[RSK_GERUDO_FORTRESS] = "Sets the amount of carpenters required to repair the bridge " - "in Gerudo Valley.\n" + mOptionDescriptions[RSK_GERUDO_FORTRESS] = "Sets the state of the carpenters captured by Gerudo " + "in Gerudo Fortress, and with it the number of guards that spawn.\n" "\n" "Normal - All 4 carpenters are required to be saved.\n" "\n" "Fast - Only the bottom left carpenter requires rescuing.\n" "\n" - "Open - The bridge is repaired from the start.\n" + "Free - The bridge is repaired from the start, and Nabooru cannot spawn.\n" + "If the Gerudo Membership Card isn't shuffled, you start with it.\n" "\n" "Only \"Normal\" is compatible with Gerudo Fortress Key Rings."; mOptionDescriptions[RSK_RAINBOW_BRIDGE] = @@ -54,12 +63,12 @@ void Settings::CreateOptionDescriptions() { "\n" "Always open - No requirements.\n" "\n" - "Stones - Obtain the specified amount of spiritual stones.\n" + "Stones - Obtain the specified amount of Spiritual Stones.\n" "\n" "Medallions - Obtain the specified amount of medallions.\n" "\n" - "Dungeon rewards - Obtain the specified total sum of spiritual " - "stones or medallions.\n" + "Dungeon rewards - Obtain the specified total sum of Spiritual " + "Stones or medallions.\n" "\n" "Dungeons - Complete the specified amount of dungeons. Dungeons " "are considered complete after stepping in to the blue warp after " @@ -83,10 +92,10 @@ void Settings::CreateOptionDescriptions() { "\n" "Skip - No Trials are required and the barrier is already dispelled.\n" "\n" - "Set Number - Select a number of trials that will be required from the" + "Set Number - Select a number of trials that will be required from the " "slider below. Which specific trials you need to complete will be random.\n" "\n" - "Random Number - A Random number and set of trials will be required."; + "Random Number - A random number and set of trials will be required."; mOptionDescriptions[RSK_TRIAL_COUNT] = "Set the number of trials required to enter Ganon's Tower."; mOptionDescriptions[RSK_MQ_DUNGEON_RANDOM] = "Sets the number of Master Quest Dungeons that are shuffled into the pool.\n" @@ -96,7 +105,7 @@ void Settings::CreateOptionDescriptions() { "Set Number - Select a number of dungeons that will be their Master Quest versions " "using the slider below. Which dungeons are set to be the Master Quest variety will be random.\n" "\n" - "Random Number - A Random number and set of dungeons will be their Master Quest varieties.\n" + "Random Number - A random number and set of dungeons will be their Master Quest varieties.\n" "\n" "Selection Only - Specify which dungeons are Vanilla, Master Quest or a 50/50 between the two.\n" "Differs from Random Number in that they are rolled individually, making the exact total a bell curve."; @@ -118,14 +127,14 @@ void Settings::CreateOptionDescriptions() { "Keep in mind seed generation can fail if more pieces are placed than there are junk items in the item pool."; mOptionDescriptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED] = "The amount of Triforce pieces required to win the game."; mOptionDescriptions[RSK_SHUFFLE_DUNGEON_ENTRANCES] = - "Shuffle the pool of dungeon entrances, including Bottom of the Well, Ice Cavern and Gerudo Training Grounds.\n" + "Shuffle the pool of dungeon entrances, including Bottom of the Well, Ice Cavern and Gerudo Training Ground.\n" "\n" "Shuffling Ganon's Castle can be enabled separately.\n" "\n" "Additionally, the entrances of Deku Tree, Fire Temple, Bottom of the Well and Gerudo Training Ground are " "opened for both child and adult.\n" "\n" - "- Deku Tree will be open for adult after Mido has seen child Link with a sword and shield.\n" + "- Deku Tree will be open for adult after Mido has seen child Link with a sword and a shield.\n" "- Bottom of the Well will be open for adult after playing Song of Storms to the Windmill guy as child.\n" "- Gerudo Training Ground will be open for child after adult has paid to open the gate once."; mOptionDescriptions[RSK_SHUFFLE_BOSS_ENTRANCES] = @@ -171,23 +180,23 @@ void Settings::CreateOptionDescriptions() { "This also adds the one-way entrance from Gerudo Valley to Lake Hylia in the pool of " "overworld entrances when they are shuffled."; mOptionDescriptions[RSK_MIXED_ENTRANCE_POOLS] = - "Shuffle entrances into a mixed pool instead of separate ones. Has no affect on pools whose " + "Shuffle entrances into a mixed pool instead of separate ones. Has no effect on pools whose " "entrances aren't shuffled, and \"Shuffle Boss Entrances\" must be set to \"Full\" to include them.\n" "\n" "For example, enabling the settings to shuffle grotto, dungeon, and overworld entrances and " "selecting grotto and dungeon entrances here will allow a dungeon to be inside a grotto or " "vice versa, while overworld entrances are shuffled in their own separate pool and indoors stay vanilla."; - mOptionDescriptions[RSK_MIX_DUNGEON_ENTRANCES] = "Dungeon entrances will be part of the mixed pool"; - mOptionDescriptions[RSK_MIX_BOSS_ENTRANCES] = "Boss entrances will be part of the mixed pool"; - mOptionDescriptions[RSK_MIX_OVERWORLD_ENTRANCES] = "Overworld entrances will be part of the mixed pool"; - mOptionDescriptions[RSK_MIX_INTERIOR_ENTRANCES] = "Interior entrances will be part of the mixed pool"; - mOptionDescriptions[RSK_MIX_GROTTO_ENTRANCES] = "Grotto entrances will be part of the mixed pool"; + mOptionDescriptions[RSK_MIX_DUNGEON_ENTRANCES] = "Dungeon entrances will be part of the mixed pool."; + mOptionDescriptions[RSK_MIX_BOSS_ENTRANCES] = "Boss entrances will be part of the mixed pool."; + mOptionDescriptions[RSK_MIX_OVERWORLD_ENTRANCES] = "Overworld entrances will be part of the mixed pool."; + mOptionDescriptions[RSK_MIX_INTERIOR_ENTRANCES] = "Interior entrances will be part of the mixed pool."; + mOptionDescriptions[RSK_MIX_GROTTO_ENTRANCES] = "Grotto entrances will be part of the mixed pool."; mOptionDescriptions[RSK_SHUFFLE_SONGS] = "Song locations - Songs will only appear at locations that normally teach songs.\n" "\n" "Dungeon rewards - Songs appear after beating a major dungeon boss.\n" "The 4 remaining songs are located at:\n" - " - Zelda's lullaby location\n" + " - Zelda's Lullaby location\n" " - Ice Cavern's Serenade of Water location\n" " - Bottom of the Well Lens of Truth location\n" " - Gerudo Training Ground's Ice Arrows location\n" @@ -240,33 +249,45 @@ void Settings::CreateOptionDescriptions() { "\n" "The Weird Egg is required to unlock several events:\n" " - Zelda's Lullaby from Impa\n" - " - Saria's song in Sacred Forest Meadow\n" - " - Epona's song and chicken minigame at Lon Lon Ranch\n" - " - Zelda's letter for Kakariko gate (if set to closed)\n" + " - Saria's Song in Sacred Forest Meadow\n" + " - Epona's Song and chicken minigame at Lon Lon Ranch\n" + " - Zelda's Letter for Kakariko gate (if set to closed)\n" " - Happy Mask Shop sidequest\n"; mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD] = "Shuffles the Gerudo Membership Card into the item pool.\n" "\n" - "The Gerudo Card is required to enter the Gerudo Training Grounds, opening " + "The Gerudo Card is required to enter the Gerudo Training Ground, opening " "the gate to Haunted Wasteland and the Horseback Archery minigame."; + mOptionDescriptions[RSK_SHUFFLE_POTS] = "Pots will drop a randomized item the first time they're broken and collected. This does not include the flying pots." + " Pots will have a different appearance when they hold a randomized item.\n" + "With this option enabled, Ganon's boss key door is moved further up the stairs to\n" + "allow access to the pots before obtaining Ganon's Boss Key.\n" + "\n" + "Off - Pots will not be shuffled.\n" + "\n" + "Dungeons - Only shuffle pots that are within dungeons.\n" + "\n" + "Overworld - Only shuffle pots that are outside of dungeons.\n" + "\n" + "All pots - Shuffle all pots."; mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n" "\n" "The fishing pole is required to play the fishing pond minigame."; - mOptionDescriptions[RSK_INFINITE_UPGRADES] = "Adds upgrades that hold infinite quanities of items (bombs, arrows, etc.)\n" + mOptionDescriptions[RSK_INFINITE_UPGRADES] = "Adds upgrades that hold infinite quantities of items (bombs, arrows, etc.).\n" "\n" - "Progressive - The infinite upgrades are obtained after getting the last normal capacity upgrade\n" + "Progressive - The infinite upgrades are obtained after getting the last normal capacity upgrade.\n" "\n" - "Condensed Progressive - The infinite upgrades are obtained as the first capacity upgrade (doesn't apply to the infinite wallet or to infinite magic)"; - mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG] = "Shuffles the deku stick bag into the item pool.\n" + "Condensed Progressive - The infinite upgrades are obtained as the first capacity upgrade (doesn't apply to the infinite wallet or to infinite magic)."; + mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG] = "Shuffles the Deku Stick bag into the item pool.\n" "\n" - "The deku stick bag is required to hold deku sticks."; - mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG] = "Shuffles the deku nut bag into the item pool.\n" + "The Deku Stick bag is required to hold Deku Sticks."; + mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG] = "Shuffles the Deku Nut bag into the item pool.\n" "\n" - "The deku nut bag is required to hold deku nuts."; + "The Deku Nut bag is required to hold Deku Nuts."; mOptionDescriptions[RSK_SHOPSANITY] = "Off - All shop items will be the same as vanilla.\n" "\n" - "Specifc Count - Vanilla shop items will be shuffled among different shops, and " - "each shop will contain a specifc number (0-7) of non-vanilla shop items.\n" + "Specific Count - Vanilla shop items will be shuffled among different shops, and " + "each shop will contain a specific number (0-7) of non-vanilla shop items.\n" "\n" "Random - Vanilla shop items will be shuffled among different shops, and " "each shop will contain a random number (1-7) of non-vanilla shop items."; @@ -279,12 +300,12 @@ void Settings::CreateOptionDescriptions() { "8 Items - All shops will contain 8 non-vanilla shop items.\n" */; mOptionDescriptions[RSK_SHOPSANITY_PRICES] = - "Vanilla - The same price as the item it replaced\n" - "Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers\n" - "Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers\n" - "Fixed - A fixed number\n" - "Range - A random point between specific ranges\n" - "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen"; + "Vanilla - The same price as the item it replaced.\n" + "Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers.\n" + "Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers.\n" + "Fixed - A fixed number.\n" + "Range - A random point between specific ranges.\n" + "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen."; mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE] = "The price for Shopsanity checks."; mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_1] = @@ -300,13 +321,13 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT] = "The chance for Shopsanity checks to be purchasable with Giant's Wallet (201-500)."; mOptionDescriptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT] = - "The chance for Shopsanity checks to be purchasable with Tycoon Wallet. (500+)"; + "The chance for Shopsanity checks to be purchasable with Tycoon Wallet (500+)."; mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE] = "After choosing a price, set it to the affordable amount based on the wallet required.\n\n" "Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n" "Use this to enable wallet tier locking, but make shop items not as expensive as they could be."; mOptionDescriptions[RSK_FISHSANITY] = "Off - Fish will not be shuffled. No changes will be made to fishing behavior.\n\n" - "Shuffle only Hyrule Loach - Allows you to earn an item by catching the hyrule loach at the fishing pond and giving it to the owner.\n\n" + "Shuffle only Hyrule Loach - Allows you to earn an item by catching the Hyrule Loach at the fishing pond and giving it to the owner.\n\n" "Shuffle Fishing Pond - The fishing pond's fish will be shuffled. Catching a fish in the fishing pond will grant a reward.\n\n" "Shuffle Overworld Fish - Fish in generic grottos and Zora's Domain will be shuffled. Catching a fish in a bottle will give a reward.\n\n" "Shuffle Both - Both overworld fish and fish in the fishing pond will be shuffled."; @@ -326,12 +347,12 @@ void Settings::CreateOptionDescriptions() { "\n" "All - All Scrubs are shuffled."; mOptionDescriptions[RSK_SCRUBS_PRICES] = - "Vanilla - The same price as the item it replaced\n" - "Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers\n" - "Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers\n" - "Fixed - A fixed number\n" - "Range - A random point between specific ranges\n" - "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen"; + "Vanilla - The same price as the item it replaced.\n" + "Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers.\n" + "Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers.\n" + "Fixed - A fixed number.\n" + "Range - A random point between specific ranges.\n" + "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen."; mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE] = "The price for Scrub checks."; mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_1] = @@ -347,7 +368,7 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT] = "The chance for Scrub checks to be purchasable with Giant's Wallet (201-500)."; mOptionDescriptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT] = - "The chance for Scrub checks to be purchasable with Tycoon Wallet. (500+)"; + "The chance for Scrub checks to be purchasable with Tycoon Wallet (500+)."; mOptionDescriptions[RSK_SCRUBS_PRICES_AFFORDABLE] = "After choosing a price, set it to the affordable amount based on the wallet required.\n\n" "Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n" @@ -360,7 +381,7 @@ void Settings::CreateOptionDescriptions() { "This setting governs if the Bean Salesman, Medigoron, Granny and the Carpet Salesman " "sell a random item.\n" "Beans Only - Only the Bean Salesman will have a check, and a pack of Magic Beans will be added " - " to the item pool." + "to the item pool.\n" "All But Beans - Medigoron, Granny and the Carpet Salesman will have checks, " "A Giant's Knife and a pack of Bombchus will be added to the item pool, and " "one of the bottles will contain a Blue Potion.\n\n" @@ -370,12 +391,12 @@ void Settings::CreateOptionDescriptions() { "Otherwise when off, you will need to have found the Claim Check to buy her item (simulating the trade quest " "is complete)."; mOptionDescriptions[RSK_MERCHANT_PRICES] = - "Vanilla - The same price as the Check in vanilla, 60 for the Bean Salesman\n" - "Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers\n" - "Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers\n" - "Fixed - A fixed number\n" - "Range - A random point between specific ranges\n" - "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen"; + "Vanilla - The same price as the Check in vanilla, 60 for the Bean Salesman.\n" + "Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers.\n" + "Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers.\n" + "Fixed - A fixed number.\n" + "Range - A random point between specific ranges.\n" + "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen."; mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE] = "The price for Merchant checks."; mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_1] = @@ -391,7 +412,7 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT] = "The chance for Merchant checks to be purchasable with Giant's Wallet (201-500)."; mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT] = - "The chance for Merchant checks to be purchasable with Tycoon Wallet. (500+)"; + "The chance for Merchant checks to be purchasable with Tycoon Wallet (500+)."; mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE] = "After choosing a price, set it to the affordable amount based on the wallet required.\n\n" "Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n" @@ -415,17 +436,29 @@ void Settings::CreateOptionDescriptions() { "have collected all 100 Gold Skulltula Tokens.\n" "\n" "You can still talk to him multiple times to get Huge Rupees."; + mOptionDescriptions[RSK_SHUFFLE_FREESTANDING] = "Freestanding rupees & hearts are shuffles to random items. " + "Freestanding heart pieces and small keys are already shuffled by default.\n" + "\n" + "Off - freestanding rupees & hearts will not be shuffled.\n" + "\n" + "Dungeons - Only freestanding rupees & hearts that are within dungeons.\n" + "\n" + "Overworld - Only freestanding rupees & hearts that are outside of dungeons.\n" + "\n" + "All Items - Shuffle all freestanding rupees & hearts."; + mOptionDescriptions[RSK_SHUFFLE_FAIRIES] = + "Shuffle fairy locations."; mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS] = - "Shuffles the location of spiritual stones and medallions.\n" + "Shuffles the location of Spiritual Stones and medallions.\n" "\n" - "End of dungeons - Spiritual stones and medallions will be given as rewards " + "End of dungeons - Spiritual Stones and medallions will be given as rewards " "for beating major dungeons. Link will always start with one stone or medallion.\n" "\n" - "Any dungeon - Spiritual stones and medallions can be found inside any dungeon.\n" + "Any dungeon - Spiritual Stones and medallions can be found inside any dungeon.\n" "\n" - "Overworld - Spiritual stones and medallions can only be found outside of dungeons.\n" + "Overworld - Spiritual Stones and medallions can only be found outside of dungeons.\n" "\n" - "Anywhere - Spiritual stones and medallions can appear anywhere."; + "Anywhere - Spiritual Stones and medallions can appear anywhere."; mOptionDescriptions[RSK_SHUFFLE_MAPANDCOMPASS] = "Start with - You will start with Maps & Compasses from all dungeons.\n" "\n" @@ -433,7 +466,7 @@ void Settings::CreateOptionDescriptions() { "\n" "Own dungeon - Maps & Compasses can only appear in their respective dungeon.\n" "\n" - "Any dungeon - Maps & Compasses can only appear inside of any dungon.\n" + "Any dungeon - Maps & Compasses can only appear inside of any dungeon.\n" "\n" "Overworld - Maps & Compasses can only appear outside of dungeons.\n" "\n" @@ -447,18 +480,18 @@ void Settings::CreateOptionDescriptions() { "Own dungeon - Small Keys can only appear in their respective dungeon. " "If Fire Temple is not a Master Quest dungeon, the door to the Boss Key chest will be unlocked.\n" "\n" - "Any dungeon - Small Keys can only appear inside of any dungon.\n" + "Any dungeon - Small Keys can only appear inside of any dungeon.\n" "\n" "Overworld - Small Keys can only appear outside of dungeons.\n" "\n" "Anywhere - Small Keys can appear anywhere in the world."; mOptionDescriptions[RSK_KEYRINGS] = "Keyrings will replace all small keys from a particular dungeon with a single keyring that awards all keys for " - "it's associated dungeon\n" + "its associated dungeon.\n" "\n" "Off - No dungeons will have their keys replaced with keyrings.\n" "\n" - "Random - A random amount of dungeons(0-8 or 9) will have their keys replaced with keyrings.\n" + "Random - A random amount of dungeons (0-8 or 9) will have their keys replaced with keyrings.\n" "\n" "Count - A specified amount of randomly selected dungeons will have their keys replaced with keyrings.\n" "\n" @@ -470,20 +503,20 @@ void Settings::CreateOptionDescriptions() { "If Gerudo Fortress Carpenters is set to Normal, and Gerudo Fortress Keys is set to anything " "other than Vanilla, then the maximum amount of Key Rings that can be selected by Random or " "Count will be 9. Otherwise, the maximum amount of Key Rings will be 8."; - mOptionDescriptions[RSK_GERUDO_KEYS] = "Vanilla - Thieve's Hideout Keys will appear in their vanilla locations.\n" + mOptionDescriptions[RSK_GERUDO_KEYS] = "Vanilla - Thieves' Hideout Keys will appear in their vanilla locations.\n" "\n" - "Any dungeon - Thieve's Hideout Keys can only appear inside of any dungon.\n" + "Any dungeon - Thieves' Hideout Keys can only appear inside of any dungon.\n" "\n" - "Overworld - Thieve's Hideout Keys can only appear outside of dungeons.\n" + "Overworld - Thieves' Hideout Keys can only appear outside of dungeons.\n" "\n" - "Anywhere - Thieve's Hideout Keys can appear anywhere in the world."; + "Anywhere - Thieves' Hideout Keys can appear anywhere in the world."; mOptionDescriptions[RSK_BOSS_KEYSANITY] = "Start with - You will start with Boss keys from all dungeons.\n" "\n" "Vanilla - Boss Keys will appear in their vanilla locations.\n" "\n" "Own dungeon - Boss Keys can only appear in their respective dungeon.\n" "\n" - "Any dungeon - Boss Keys can only appear inside of any dungon.\n" + "Any dungeon - Boss Keys can only appear inside of any dungeon.\n" "\n" "Overworld - Boss Keys can only appear outside of dungeons.\n" "\n" @@ -495,7 +528,7 @@ void Settings::CreateOptionDescriptions() { "\n" "Start with - Places Ganon's Boss Key in your starting inventory." "\n" - "Any dungeon - Ganon's Boss Key Key can only appear inside of any dungon.\n" + "Any dungeon - Ganon's Boss Key Key can only appear inside of any dungeon.\n" "\n" "Overworld - Ganon's Boss Key Key can only appear outside of dungeons.\n" "\n" @@ -504,9 +537,9 @@ void Settings::CreateOptionDescriptions() { "LACS - These settings put the boss key on the Light Arrow Cutscene location, from Zelda in Temple of Time as " "adult, with differing requirements:\n" "- Vanilla: Obtain the Shadow Medallion and Spirit Medallion\n" - "- Stones: Obtain the specified amount of spiritual stones.\n" + "- Stones: Obtain the specified amount of Spiritual Stones.\n" "- Medallions: Obtain the specified amount of medallions.\n" - "- Dungeon rewards: Obtain the specified total sum of spiritual stones or medallions.\n" + "- Dungeon rewards: Obtain the specified total sum of Spiritual Stones or medallions.\n" "- Dungeons: Complete the specified amount of dungeons. Dungeons are considered complete after stepping in to " "the blue warp after the boss.\n" "- Tokens: Obtain the specified amount of Skulltula tokens.\n" @@ -523,7 +556,7 @@ void Settings::CreateOptionDescriptions() { "\n" "Greg as Wildcard - Greg does not change logic, Greg helps obtain GBK, max number of " "rewards on slider does not change."; - mOptionDescriptions[RSK_CUCCO_COUNT] = "The amount of cuccos needed to claim the reward from Anju the cucco lady"; + mOptionDescriptions[RSK_CUCCO_COUNT] = "The amount of cuccos needed to claim the reward from Anju the Cucco Lady."; mOptionDescriptions[RSK_BIG_POE_COUNT] = "The Poe collector will give a reward for turning in this many Big Poes."; mOptionDescriptions[RSK_SKIP_CHILD_STEALTH] = "The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards."; @@ -532,11 +565,11 @@ void Settings::CreateOptionDescriptions() { "until after meeting Zelda. Disables the ability to shuffle Weird Egg."; mOptionDescriptions[RSK_SKIP_EPONA_RACE] = "Epona can be summoned with Epona's Song without needing to race Ingo."; mOptionDescriptions[RSK_COMPLETE_MASK_QUEST] = - "Once the happy mask shop is opened, all masks will be available to be borrowed."; + "Once the Happy Mask Shop is opened, all masks will be available to be borrowed."; mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG] = - "Start with the ability to summon Pierre the scarecrow. Pulling out an ocarina in the usual locations will " + "Start with the ability to summon Pierre the Scarecrow. Pulling out an Ocarina in the usual locations will " "automatically summon him.\n" - "With \"Shuffle Ocarina Buttons\" enabled, you'll need at least two ocarina buttons to summon him."; + "With \"Shuffle Ocarina Buttons\" enabled, you'll need at least two Ocarina buttons to summon him."; mOptionDescriptions[RSK_ITEM_POOL] = "Sets how many major items appear in the item pool.\n" "\n" "Plentiful - Extra major items are added to the pool.\n" @@ -592,12 +625,12 @@ void Settings::CreateOptionDescriptions() { "Very Strong - Many powerful hints."; mOptionDescriptions[RSK_TOT_ALTAR_HINT] = "Reading the Temple of Time altar as child will tell you the locations of the Spiritual Stones.\n" - "Reading the Temple of Time altar as adult will tell you the locations of the Medallions, as well as the " + "Reading the Temple of Time altar as adult will tell you the locations of the medallions, as well as the " "conditions for building the Rainbow Bridge and getting the Boss Key for Ganon's Castle."; mOptionDescriptions[RSK_GANONDORF_HINT] = "Talking to Ganondorf in his boss room will tell you the location of the Light Arrows and Master Sword." "If this option is enabled and Ganondorf is reachable without these items, Gossip Stones will never hint the " - "appropriote items.";//RANDOTODO make this hint text about no dupe hints a global hint for static hints. Add to navi? + "appropriate items.";//RANDOTODO make this hint text about no dupe hints a global hint for static hints. Add to navi? mOptionDescriptions[RSK_SHEIK_LA_HINT] = "Talking to Sheik inside Ganon's Castle will tell you the location of the Light Arrows." "If this option is enabled and Sheik is reachable without Light Arrows, Gossip Stones will never hint the " @@ -613,37 +646,37 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_FISHING_POLE_HINT] = "Talking to the fishing pond owner without the fishing pole will tell you its location."; mOptionDescriptions[RSK_OOT_HINT] = "Sheik in the Temple of Time will tell you the item and song on the Ocarina of Time."; mOptionDescriptions[RSK_FROGS_HINT] = "Standing near the pedestal for the frogs in Zora's River will tell you the " - "reward for the frogs' ocarina game."; + "reward for the frogs' Ocarina game."; mOptionDescriptions[RSK_BIGGORON_HINT] = "Talking to Biggoron will tell you the item he will give you in exchange for the Claim Check."; mOptionDescriptions[RSK_BIG_POES_HINT] = "Talking to the Poe Collector in the Market Guardhouse while adult will tell you what you receive for handing in Big Poes."; - mOptionDescriptions[RSK_CHICKENS_HINT] = "Talking to Anju as a child will tell you the item she will give you for delivering her Cuccos to the pen"; - mOptionDescriptions[RSK_MALON_HINT] = "Talking to Malon as adult will tell you the item on \"Link's cow\", the cow you win from beating her time on the Lon Lon Obsticle Course."; + mOptionDescriptions[RSK_CHICKENS_HINT] = "Talking to Anju as a child will tell you the item she will give you for delivering her cuccos to the pen."; + mOptionDescriptions[RSK_MALON_HINT] = "Talking to Malon as adult will tell you the item on \"Link's cow\", the cow you win from beating her time on the Lon Lon Obstacle Course."; mOptionDescriptions[RSK_HBA_HINT] = "Talking to the Horseback Archery gerudo in Gerudo Fortress, or the nearby sign, will tell you what you win for scoring 1000 and 1500 points on Horseback Archery."; mOptionDescriptions[RSK_WARP_SONG_HINTS] = "Playing a warp song will tell you where it leads. (If warp song destinations are vanilla, this is always enabled.)"; mOptionDescriptions[RSK_SCRUB_TEXT_HINT] = "Business scrubs will reveal the identity of what they're selling."; mOptionDescriptions[RSK_MERCHANT_TEXT_HINT] = "Merchants will reveal the identity of what they're selling (Shops are not affected by this setting)."; - mOptionDescriptions[RSK_KAK_10_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 10 tokens will tell you the reward"; - mOptionDescriptions[RSK_KAK_20_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 20 tokens will tell you the reward"; - mOptionDescriptions[RSK_KAK_30_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 30 tokens will tell you the reward"; - mOptionDescriptions[RSK_KAK_40_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 40 tokens will tell you the reward"; - mOptionDescriptions[RSK_KAK_50_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 50 tokens will tell you the reward"; - mOptionDescriptions[RSK_KAK_100_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 100 tokens will tell you the reward"; + mOptionDescriptions[RSK_KAK_10_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 10 tokens will tell you the reward."; + mOptionDescriptions[RSK_KAK_20_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 20 tokens will tell you the reward."; + mOptionDescriptions[RSK_KAK_30_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 30 tokens will tell you the reward."; + mOptionDescriptions[RSK_KAK_40_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 40 tokens will tell you the reward."; + mOptionDescriptions[RSK_KAK_50_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 50 tokens will tell you the reward."; + mOptionDescriptions[RSK_KAK_100_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 100 tokens will tell you the reward."; mOptionDescriptions[RSK_MASK_SHOP_HINT] = "Reading the mask shop sign will tell you rewards from showing masks at the Deku Theatre."; mOptionDescriptions[RSK_FULL_WALLETS] = "Start with a full wallet. All wallet upgrades come filled with rupees."; mOptionDescriptions[RSK_BOMBCHUS_IN_LOGIC] = - "Bombchus are properly considered in logic. Without this setting, any Bombchu requirement" - " is filled by Bomb Bag + a renewable source of Bombchus\n" + "Bombchus are properly considered in logic. Without this setting, any Bombchu requirement " + "is filled by Bomb Bag + a renewable source of Bombchus.\n" "\n" "The first Bombchu pack will always be 20, and subsequent packs will be " "5 or 10 based on how many you have.\n" "Once found, they can be replenished at the Bombchu shop.\n" "\n" "Bombchu Bowling is opened by obtaining Bombchus."; - mOptionDescriptions[RSK_ENABLE_BOMBCHU_DROPS] = "Once you obtain bombchus for the first time, refills can be found " + mOptionDescriptions[RSK_ENABLE_BOMBCHU_DROPS] = "Once you obtain Bombchus for the first time, refills can be found " "in bushes and other places where bomb drops can normally spawn." "\n" - "If you have Bombchus in Logic disabled, you will also need a" - "Bomb bag for bombchus to drop"; + "If you have Bombchus in Logic disabled, you will also need a " + "Bomb Bag for Bombchus to drop."; mOptionDescriptions[RSK_BLUE_FIRE_ARROWS] = "Ice Arrows act like Blue Fire, making them able to melt red ice. " "Item placement logic will respect this option, so it might be required to use this to progress."; @@ -671,4 +704,4 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS] = "Shuffles 8 boss souls (one for each blue warp dungeon). A boss will not appear until you collect its respective soul." "\n\"On + Ganon\" will also hide Ganon and Ganondorf behind a boss soul."; } -} // namespace Rando \ No newline at end of file +} // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/rando_hash.h b/soh/soh/Enhancements/randomizer/rando_hash.h index 76c3ce0a3..3fdcd205e 100644 --- a/soh/soh/Enhancements/randomizer/rando_hash.h +++ b/soh/soh/Enhancements/randomizer/rando_hash.h @@ -10,7 +10,7 @@ #include #include -std::array gSeedTextures = { { +inline std::array gSeedTextures = { { { dgItemIconDekuNutTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 0 }, { dgItemIconDekuStickTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 1 }, { dgItemIconBombTex, 32, 32, G_IM_FMT_RGBA, G_IM_SIZ_32b, 2 }, diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index c99a43dfb..0acb8542d 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -10,7 +10,9 @@ #include #include "3drando/rando_main.hpp" #include "3drando/random.hpp" -#include "3drando/custom_messages.hpp" +#include "soh/ResourceManagerHelpers.h" +#include "soh/UIWidgets.hpp" +#include "3drando/custom_messages.hpp" #include "../../UIWidgets.hpp" #ifndef IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS @@ -41,9 +43,6 @@ #include "fishsanity.h" #include "randomizerTypes.h" -extern "C" uint32_t ResourceMgr_IsGameMasterQuest(); -extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum); - extern std::map rcAreaNames; using json = nlohmann::json; @@ -165,7 +164,7 @@ std::unordered_map spoilerFileDungeonToScene = { { "Shadow Temple", SCENE_SHADOW_TEMPLE }, { "Bottom of the Well", SCENE_BOTTOM_OF_THE_WELL }, { "Ice Cavern", SCENE_ICE_CAVERN }, - { "Gerudo Training Grounds", SCENE_GERUDO_TRAINING_GROUND }, + { "Gerudo Training Ground", SCENE_GERUDO_TRAINING_GROUND }, { "Ganon's Castle", SCENE_INSIDE_GANONS_CASTLE } }; @@ -479,7 +478,8 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe (CUR_UPG_VALUE(UPG_STICKS) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); case RG_DEKU_STICK_1: case RG_BUY_DEKU_STICK_1: - return CUR_UPG_VALUE(UPG_STICKS) ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; + return CUR_UPG_VALUE(UPG_STICKS) || !OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).GetContextOptionIndex() + ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; case RG_PROGRESSIVE_NUT_UPGRADE: return infiniteUpgrades != RO_INF_UPGRADES_OFF ? (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN) : @@ -488,7 +488,8 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_DEKU_NUTS_10: case RG_BUY_DEKU_NUTS_5: case RG_BUY_DEKU_NUTS_10: - return CUR_UPG_VALUE(UPG_NUTS) ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; + return CUR_UPG_VALUE(UPG_NUTS) || !OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).GetContextOptionIndex() + ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; case RG_PROGRESSIVE_BOMB_BAG: return infiniteUpgrades != RO_INF_UPGRADES_OFF ? (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMB_BAG) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN) : @@ -732,8 +733,8 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe return gSaveContext.inventory.dungeonKeys[SCENE_SHADOW_TEMPLE] < SHADOW_TEMPLE_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: return gSaveContext.inventory.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] < BOTTOM_OF_THE_WELL_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; - case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] < GERUDO_TRAINING_GROUNDS_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + case RG_GERUDO_TRAINING_GROUND_SMALL_KEY: + return gSaveContext.inventory.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] < GERUDO_TRAINING_GROUND_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_GERUDO_FORTRESS_SMALL_KEY: return gSaveContext.inventory.dungeonKeys[SCENE_THIEVES_HIDEOUT] < GERUDO_FORTRESS_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_GANONS_CASTLE_SMALL_KEY: @@ -1008,6 +1009,548 @@ std::map rcToRandomizerInf = { { RC_ZD_FISH_3, RAND_INF_ZD_FISH_3 }, { RC_ZD_FISH_4, RAND_INF_ZD_FISH_4 }, { RC_ZD_FISH_5, RAND_INF_ZD_FISH_5 }, + + { RC_KF_LINKS_HOUSE_POT, RAND_INF_KF_LINKS_HOUSE_POT }, + { RC_KF_TWINS_HOUSE_POT_1, RAND_INF_KF_TWINS_HOUSE_POT_1 }, + { RC_KF_TWINS_HOUSE_POT_2, RAND_INF_KF_TWINS_HOUSE_POT_2 }, + { RC_KF_BROTHERS_HOUSE_POT_1, RAND_INF_KF_BROTHERS_HOUSE_POT_1 }, + { RC_KF_BROTHERS_HOUSE_POT_2, RAND_INF_KF_BROTHERS_HOUSE_POT_2 }, + { RC_GF_BREAK_ROOM_POT_1, RAND_INF_GF_BREAK_ROOM_POT_1 }, + { RC_GF_BREAK_ROOM_POT_2, RAND_INF_GF_BREAK_ROOM_POT_2 }, + { RC_GF_KITCHEN_POT_1, RAND_INF_GF_KITCHEN_POT_1 }, + { RC_GF_KITCHEN_POT_2, RAND_INF_GF_KITCHEN_POT_2 }, + { RC_GF_NORTH_F1_CARPENTER_POT_1, RAND_INF_GF_NORTH_F1_CARPENTER_POT_1 }, + { RC_GF_NORTH_F1_CARPENTER_POT_2, RAND_INF_GF_NORTH_F1_CARPENTER_POT_2 }, + { RC_GF_NORTH_F1_CARPENTER_POT_3, RAND_INF_GF_NORTH_F1_CARPENTER_POT_3 }, + { RC_GF_NORTH_F2_CARPENTER_POT_1, RAND_INF_GF_NORTH_F2_CARPENTER_POT_1 }, + { RC_GF_NORTH_F2_CARPENTER_POT_2, RAND_INF_GF_NORTH_F2_CARPENTER_POT_2 }, + { RC_GF_SOUTH_F1_CARPENTER_POT_1, RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1 }, + { RC_GF_SOUTH_F1_CARPENTER_POT_2, RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2 }, + { RC_GF_SOUTH_F1_CARPENTER_POT_3, RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3 }, + { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_1, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1 }, + { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2 }, + { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3 }, + { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_4, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4 }, + { RC_WASTELAND_NEAR_GS_POT_1, RAND_INF_WASTELAND_NEAR_GS_POT_1 }, + { RC_WASTELAND_NEAR_GS_POT_2, RAND_INF_WASTELAND_NEAR_GS_POT_2 }, + { RC_WASTELAND_NEAR_GS_POT_3, RAND_INF_WASTELAND_NEAR_GS_POT_3 }, + { RC_WASTELAND_NEAR_GS_POT_4, RAND_INF_WASTELAND_NEAR_GS_POT_4 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_1, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_2, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_3, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_4, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_5, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_6, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_7, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_8, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_9, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_10, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_11, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_12, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_13, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_14, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_15, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_16, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_17, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_18, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_19, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_20, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_21, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_22, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_23, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_24, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_25, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_26, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_27, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_28, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_29, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_30, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_31, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_32, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_33, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_34, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_35, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_36, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_37, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_38, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_39, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_40, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_41, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_42, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_43, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_44, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_1, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_2, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_3, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_4, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_5, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_6, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_7, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_8, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_9, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_10, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_11, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11 }, + { RC_MK_BACK_ALLEY_HOUSE_POT_1, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1 }, + { RC_MK_BACK_ALLEY_HOUSE_POT_2, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2 }, + { RC_MK_BACK_ALLEY_HOUSE_POT_3, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3 }, + { RC_KAK_NEAR_POTION_SHOP_POT_1, RAND_INF_KAK_NEAR_POTION_SHOP_POT_1 }, + { RC_KAK_NEAR_POTION_SHOP_POT_2, RAND_INF_KAK_NEAR_POTION_SHOP_POT_2 }, + { RC_KAK_NEAR_POTION_SHOP_POT_3, RAND_INF_KAK_NEAR_POTION_SHOP_POT_3 }, + { RC_KAK_NEAR_IMPAS_HOUSE_POT_1, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1 }, + { RC_KAK_NEAR_IMPAS_HOUSE_POT_2, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2 }, + { RC_KAK_NEAR_IMPAS_HOUSE_POT_3, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3 }, + { RC_KAK_NEAR_GUARDS_HOUSE_POT_1, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1 }, + { RC_KAK_NEAR_GUARDS_HOUSE_POT_2, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2 }, + { RC_KAK_NEAR_GUARDS_HOUSE_POT_3, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3 }, + { RC_KAK_NEAR_MEDICINE_SHOP_POT_1, RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1 }, + { RC_KAK_NEAR_MEDICINE_SHOP_POT_2, RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2 }, + { RC_GY_DAMPES_GRAVE_POT_1, RAND_INF_GY_DAMPES_GRAVE_POT_1 }, + { RC_GY_DAMPES_GRAVE_POT_2, RAND_INF_GY_DAMPES_GRAVE_POT_2 }, + { RC_GY_DAMPES_GRAVE_POT_3, RAND_INF_GY_DAMPES_GRAVE_POT_3 }, + { RC_GY_DAMPES_GRAVE_POT_4, RAND_INF_GY_DAMPES_GRAVE_POT_4 }, + { RC_GY_DAMPES_GRAVE_POT_5, RAND_INF_GY_DAMPES_GRAVE_POT_5 }, + { RC_GY_DAMPES_GRAVE_POT_6, RAND_INF_GY_DAMPES_GRAVE_POT_6 }, + { RC_GC_LOWER_STAIRCASE_POT_1, RAND_INF_GC_LOWER_STAIRCASE_POT_1 }, + { RC_GC_LOWER_STAIRCASE_POT_2, RAND_INF_GC_LOWER_STAIRCASE_POT_2 }, + { RC_GC_UPPER_STAIRCASE_POT_1, RAND_INF_GC_UPPER_STAIRCASE_POT_1 }, + { RC_GC_UPPER_STAIRCASE_POT_2, RAND_INF_GC_UPPER_STAIRCASE_POT_2 }, + { RC_GC_UPPER_STAIRCASE_POT_3, RAND_INF_GC_UPPER_STAIRCASE_POT_3 }, + { RC_GC_MEDIGORON_POT_1, RAND_INF_GC_MEDIGORON_POT_1 }, + { RC_GC_DARUNIA_POT_1, RAND_INF_GC_DARUNIA_POT_1 }, + { RC_GC_DARUNIA_POT_2, RAND_INF_GC_DARUNIA_POT_2 }, + { RC_GC_DARUNIA_POT_3, RAND_INF_GC_DARUNIA_POT_3 }, + { RC_DMC_NEAR_GC_POT_1, RAND_INF_DMC_NEAR_GC_POT_1 }, + { RC_DMC_NEAR_GC_POT_2, RAND_INF_DMC_NEAR_GC_POT_2 }, + { RC_DMC_NEAR_GC_POT_3, RAND_INF_DMC_NEAR_GC_POT_3 }, + { RC_DMC_NEAR_GC_POT_4, RAND_INF_DMC_NEAR_GC_POT_4 }, + { RC_ZD_NEAR_SHOP_POT_1, RAND_INF_ZD_NEAR_SHOP_POT_1 }, + { RC_ZD_NEAR_SHOP_POT_2, RAND_INF_ZD_NEAR_SHOP_POT_2 }, + { RC_ZD_NEAR_SHOP_POT_3, RAND_INF_ZD_NEAR_SHOP_POT_3 }, + { RC_ZD_NEAR_SHOP_POT_4, RAND_INF_ZD_NEAR_SHOP_POT_4 }, + { RC_ZD_NEAR_SHOP_POT_5, RAND_INF_ZD_NEAR_SHOP_POT_5 }, + { RC_ZF_HIDDEN_CAVE_POT_1, RAND_INF_ZF_HIDDEN_CAVE_POT_1 }, + { RC_ZF_HIDDEN_CAVE_POT_2, RAND_INF_ZF_HIDDEN_CAVE_POT_2 }, + { RC_ZF_HIDDEN_CAVE_POT_3, RAND_INF_ZF_HIDDEN_CAVE_POT_3 }, + { RC_ZF_NEAR_JABU_POT_1, RAND_INF_ZF_NEAR_JABU_POT_1 }, + { RC_ZF_NEAR_JABU_POT_2, RAND_INF_ZF_NEAR_JABU_POT_2 }, + { RC_ZF_NEAR_JABU_POT_3, RAND_INF_ZF_NEAR_JABU_POT_3 }, + { RC_ZF_NEAR_JABU_POT_4, RAND_INF_ZF_NEAR_JABU_POT_4 }, + { RC_LLR_FRONT_POT_1, RAND_INF_LLR_FRONT_POT_1 }, + { RC_LLR_FRONT_POT_2, RAND_INF_LLR_FRONT_POT_2 }, + { RC_LLR_FRONT_POT_3, RAND_INF_LLR_FRONT_POT_3 }, + { RC_LLR_FRONT_POT_4, RAND_INF_LLR_FRONT_POT_4 }, + { RC_LLR_RAIN_SHED_POT_1, RAND_INF_LLR_RAIN_SHED_POT_1 }, + { RC_LLR_RAIN_SHED_POT_2, RAND_INF_LLR_RAIN_SHED_POT_2 }, + { RC_LLR_RAIN_SHED_POT_3, RAND_INF_LLR_RAIN_SHED_POT_3 }, + { RC_LLR_TALONS_HOUSE_POT_1, RAND_INF_LLR_TALONS_HOUSE_POT_1 }, + { RC_LLR_TALONS_HOUSE_POT_2, RAND_INF_LLR_TALONS_HOUSE_POT_2 }, + { RC_LLR_TALONS_HOUSE_POT_3, RAND_INF_LLR_TALONS_HOUSE_POT_3 }, + { RC_HF_COW_GROTTO_POT_1, RAND_INF_HF_COW_GROTTO_POT_1 }, + { RC_HF_COW_GROTTO_POT_2, RAND_INF_HF_COW_GROTTO_POT_2 }, + { RC_HC_STORMS_GROTTO_POT_1, RAND_INF_HC_STORMS_GROTTO_POT_1 }, + { RC_HC_STORMS_GROTTO_POT_2, RAND_INF_HC_STORMS_GROTTO_POT_2 }, + { RC_HC_STORMS_GROTTO_POT_3, RAND_INF_HC_STORMS_GROTTO_POT_3 }, + { RC_HC_STORMS_GROTTO_POT_4, RAND_INF_HC_STORMS_GROTTO_POT_4 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_1, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_2, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_3, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_4, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_5, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_6, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_1, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_2, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_3, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_4, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4 }, + { RC_DODONGOS_CAVERN_SINGLE_EYE_POT_1, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1 }, + { RC_DODONGOS_CAVERN_SINGLE_EYE_POT_2, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2 }, + { RC_DODONGOS_CAVERN_BLADE_POT_1, RAND_INF_DODONGOS_CAVERN_BLADE_POT_1 }, + { RC_DODONGOS_CAVERN_BLADE_POT_2, RAND_INF_DODONGOS_CAVERN_BLADE_POT_2 }, + { RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1 }, + { RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4 }, + { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1 }, + { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2 }, + { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_1, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_2, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_3, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_4, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_5, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_6, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6 }, + { RC_JABU_JABUS_BELLY_BASEMENT_POT_1, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1 }, + { RC_JABU_JABUS_BELLY_BASEMENT_POT_2, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2 }, + { RC_JABU_JABUS_BELLY_BASEMENT_POT_3, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5 }, + { RC_FOREST_TEMPLE_LOBBY_POT_1, RAND_INF_FOREST_TEMPLE_LOBBY_POT_1 }, + { RC_FOREST_TEMPLE_LOBBY_POT_2, RAND_INF_FOREST_TEMPLE_LOBBY_POT_2 }, + { RC_FOREST_TEMPLE_LOBBY_POT_3, RAND_INF_FOREST_TEMPLE_LOBBY_POT_3 }, + { RC_FOREST_TEMPLE_LOBBY_POT_4, RAND_INF_FOREST_TEMPLE_LOBBY_POT_4 }, + { RC_FOREST_TEMPLE_LOBBY_POT_5, RAND_INF_FOREST_TEMPLE_LOBBY_POT_5 }, + { RC_FOREST_TEMPLE_LOBBY_POT_6, RAND_INF_FOREST_TEMPLE_LOBBY_POT_6 }, + { RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_GREEN_POE_POT_1, RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1 }, + { RC_FOREST_TEMPLE_GREEN_POE_POT_2, RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_4, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4 }, + { RC_FOREST_TEMPLE_BLUE_POE_POT_1, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1 }, + { RC_FOREST_TEMPLE_BLUE_POE_POT_2, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2 }, + { RC_FOREST_TEMPLE_BLUE_POE_POT_3, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3 }, + { RC_FOREST_TEMPLE_FROZEN_EYE_POT_1, RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1 }, + { RC_FOREST_TEMPLE_FROZEN_EYE_POT_2, RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4 }, + { RC_FIRE_TEMPLE_BIG_LAVA_POT_1, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1 }, + { RC_FIRE_TEMPLE_BIG_LAVA_POT_2, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2 }, + { RC_FIRE_TEMPLE_BIG_LAVA_POT_3, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2 }, + { RC_WATER_TEMPLE_TORCH_POT_1, RAND_INF_WATER_TEMPLE_TORCH_POT_1 }, + { RC_WATER_TEMPLE_TORCH_POT_2, RAND_INF_WATER_TEMPLE_TORCH_POT_2 }, + { RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1 }, + { RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2 }, + { RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3 }, + { RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1 }, + { RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_1, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_2, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_3, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_4, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4 }, + { RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1 }, + { RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2 }, + { RC_WATER_TEMPLE_RIVER_POT_1, RAND_INF_WATER_TEMPLE_RIVER_POT_1 }, + { RC_WATER_TEMPLE_RIVER_POT_2, RAND_INF_WATER_TEMPLE_RIVER_POT_2 }, + { RC_WATER_TEMPLE_LIKE_LIKE_POT_1, RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1 }, + { RC_WATER_TEMPLE_LIKE_LIKE_POT_2, RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2 }, + { RC_WATER_TEMPLE_BOSS_KEY_POT_1, RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1 }, + { RC_WATER_TEMPLE_BOSS_KEY_POT_2, RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2 }, + { RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5 }, + { RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1 }, + { RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4 }, + { RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1 }, + { RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2 }, + { RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1 }, + { RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1 }, + { RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4 }, + { RC_SPIRIT_TEMPLE_LOBBY_POT_1, RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1 }, + { RC_SPIRIT_TEMPLE_LOBBY_POT_2, RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_1, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_2, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_3, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_4, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4 }, + { RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1 }, + { RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1 }, + { RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6 }, + { RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1 }, + { RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_WATER_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_WATER_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_WATER_TRIAL_POT_3, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4 }, + { RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1 }, + { RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_1, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_2, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_3, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_4, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_5, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_6, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_7, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_8, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_9, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_10, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_11, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_12, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_13, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_14, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_15, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_16, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_17, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_18, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12 }, + { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3 }, + { RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT }, + { RC_ICE_CAVERN_HALL_POT_1, RAND_INF_ICE_CAVERN_HALL_POT_1 }, + { RC_ICE_CAVERN_HALL_POT_2, RAND_INF_ICE_CAVERN_HALL_POT_2 }, + { RC_ICE_CAVERN_SPINNING_BLADE_POT_1, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1 }, + { RC_ICE_CAVERN_SPINNING_BLADE_POT_2, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2 }, + { RC_ICE_CAVERN_SPINNING_BLADE_POT_3, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3 }, + { RC_ICE_CAVERN_NEAR_END_POT_1, RAND_INF_ICE_CAVERN_NEAR_END_POT_1 }, + { RC_ICE_CAVERN_NEAR_END_POT_2, RAND_INF_ICE_CAVERN_NEAR_END_POT_2 }, + { RC_ICE_CAVERN_FROZEN_POT_1, RAND_INF_ICE_CAVERN_FROZEN_POT_1 }, + + { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_1, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_2, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_3, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_4, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_5, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_6, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6 }, + { RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4 }, + { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1 }, + { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2 }, + { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3 }, + { RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1 }, + { RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_1, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_2, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_3, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_4, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT, RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SW_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT, RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT, RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2 }, + { RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3 }, + { RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3 }, + { RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4 }, + { RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT }, + { RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3 }, + { RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT }, + { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3 }, + { RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1 }, + { RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2 }, + { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1 }, + { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2 }, + { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1 }, + { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2 }, + { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3 }, + { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1 }, + { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2 }, + { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1 }, + { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2 }, + { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3 }, + { RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1 }, + { RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2 }, + { RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1 }, + { RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2 }, + { RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3 }, + { RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4 }, + { RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5 }, + { RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8 }, + { RC_ICE_CAVERN_MQ_ENTRANCE_POT, RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT }, + { RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1 }, + { RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4 }, + { RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1 }, + { RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2 }, + { RC_ICE_CAVERN_MQ_COMPASS_POT_1, RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1 }, + { RC_ICE_CAVERN_MQ_COMPASS_POT_2, RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5 }, + { RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_WEST_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SE_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_NORTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3 }, + { RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1 }, + { RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2 }, + { RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3 }, + { RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4 }, + { RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5 }, + { RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1 }, + { RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2 }, + { RC_WATER_TEMPLE_MQ_RIVER_POT_1, RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1 }, + { RC_WATER_TEMPLE_MQ_RIVER_POT_2, RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2 }, + { RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1 }, + { RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2 }, + { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1 }, + { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2 }, + { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3 }, + { RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1 }, + { RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4 }, + { RC_WATER_TEMPLE_MQ_BOSS_KEY_POT, RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1 }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2 }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1 }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2 }, }; BeehiveIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { @@ -1184,7 +1727,7 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa scrubIdentity.isShuffled = GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_ALL; if (location->GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO || location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE) { - scrubIdentity.isShuffled = GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF;; + scrubIdentity.isShuffled = GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF; } scrubIdentity.itemPrice = OTRGlobals::Instance->gRandoContext->GetItemLocation(scrubIdentity.randomizerCheck)->GetPrice(); @@ -1249,6 +1792,32 @@ CowIdentity Randomizer::IdentifyCow(s32 sceneNum, s32 posX, s32 posZ) { return cowIdentity; } +PotIdentity Randomizer::IdentifyPot(s32 sceneNum, s32 posX, s32 posZ) { + struct PotIdentity potIdentity; + uint32_t potSceneNum = sceneNum; + + if (sceneNum == SCENE_GANONDORF_BOSS) { + potSceneNum = SCENE_GANONS_TOWER; + } + + potIdentity.randomizerInf = RAND_INF_MAX; + potIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + s32 actorParams = TWO_ACTOR_PARAMS(posX, posZ); + + Rando::Location* location = GetCheckObjectFromActor(ACTOR_OBJ_TSUBO, potSceneNum, actorParams); + + if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { + LUSLOG_WARN("IdentifyPot did not receive a valid RC value (%d).", location->GetRandomizerCheck()); + assert(false); + } else { + potIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + potIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return potIdentity; +} + FishIdentity Randomizer::IdentifyFish(s32 sceneNum, s32 actorParams) { struct FishIdentity fishIdentity; @@ -1271,7 +1840,7 @@ FishIdentity Randomizer::IdentifyFish(s32 sceneNum, s32 actorParams) { } u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { - return Rando::Context::GetInstance()->GetOption(randoSettingKey).GetSelectedOptionIndex(); + return Rando::Context::GetInstance()->GetOption(randoSettingKey).GetContextOptionIndex(); } GetItemEntry Randomizer::GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability) { @@ -1304,10 +1873,9 @@ void GenerateRandomizerImgui(std::string seed = "") { CVarSetInteger(CVAR_GENERAL("RandoGenerating"), 1); CVarSave(); auto ctx = Rando::Context::GetInstance(); - if (!ctx->IsSpoilerLoaded()) { - // We use the settings from the spoiler rather than CVars. - ctx->GetSettings()->SetAllFromCVar(); - } + //RANDOTODO proper UI for selecting if a spoiler loaded should be used for settings + ctx->GetSettings()->SetAllFromCVar(); + // todo: this efficently when we build out cvar array support std::set excludedLocations; std::stringstream excludedLocationStringStream(CVarGetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), "")); @@ -1340,7 +1908,7 @@ void GenerateRandomizerImgui(std::string seed = "") { RandoMain::GenerateRando(excludedLocations, enabledTricks, seed); CVarSetInteger(CVAR_GENERAL("RandoGenerating"), 0); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); generated = 1; } @@ -1393,12 +1961,12 @@ void RandomizerSettingsWindow::DrawElement() { } UIWidgets::Spacer(0); - ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0) && gSaveContext.gameMode != GAMEMODE_FILE_SELECT); + ImGui::BeginDisabled((CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0) && gSaveContext.gameMode != GAMEMODE_FILE_SELECT) || + GameInteractor::IsSaveLoaded()); if (ImGui::Button("Generate Randomizer")) { ctx->SetSpoilerLoaded(false); GenerateRandomizer(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0) ? seedString : ""); } - UIWidgets::Tooltip("You can also press L on the Quest Select screen to generate a new seed"); ImGui::EndDisabled(); UIWidgets::Spacer(0); @@ -1511,7 +2079,7 @@ void RandomizerSettingsWindow::DrawElement() { excludedLocationString += ","; } CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), excludedLocationString.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); ImGui::Text("%s", Rando::StaticData::GetLocation(location)->GetShortName().c_str()); @@ -1556,7 +2124,7 @@ void RandomizerSettingsWindow::DrawElement() { } else { CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), excludedLocationString.c_str()); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); ImGui::Text("%s", Rando::StaticData::GetLocation(location)->GetShortName().c_str()); @@ -1596,7 +2164,7 @@ void RandomizerSettingsWindow::DrawElement() { enabledGlitches.insert((RandomizerTrick)std::stoi(enabledGlitchString)); } } - + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); if (ImGui::BeginTable("tableRandoLogic", 1, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 200.0f); @@ -1703,11 +2271,13 @@ void RandomizerSettingsWindow::DrawElement() { }; static std::map showTag { - {Rando::Tricks::Tag::NOVICE,true}, - {Rando::Tricks::Tag::INTERMEDIATE,true}, - {Rando::Tricks::Tag::ADVANCED,true}, - {Rando::Tricks::Tag::EXPERT,true}, - {Rando::Tricks::Tag::EXTREME,true} + { Rando::Tricks::Tag::NOVICE, true }, + { Rando::Tricks::Tag::INTERMEDIATE, true }, + { Rando::Tricks::Tag::ADVANCED, true }, + { Rando::Tricks::Tag::EXPERT, true }, + { Rando::Tricks::Tag::EXTREME, true }, + { Rando::Tricks::Tag::EXPERIMENTAL, true }, + //{ Rando::Tricks::Tag::GLITCH, false }, }; static ImGuiTextFilter trickSearch; trickSearch.Draw("Filter (inc,-exc)", 490.0f); @@ -1716,7 +2286,7 @@ void RandomizerSettingsWindow::DrawElement() { if (ImGui::Button("Disable All")) { for (int i = 0; i < RT_MAX; i++) { auto etfound = enabledTricks.find(static_cast(i)); - if (!ctx->GetTrickOption(static_cast(i)).IsGlitch() && etfound != enabledTricks.end()) { + if (etfound != enabledTricks.end()) { enabledTricks.erase(etfound); } } @@ -1726,12 +2296,12 @@ void RandomizerSettingsWindow::DrawElement() { enabledTrickString += ","; } CVarClear(CVAR_RANDOMIZER_SETTING("EnabledTricks")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); if (ImGui::Button("Enable All")) { for (int i = 0; i < RT_MAX; i++) { - if (!ctx->GetTrickOption(static_cast(i)).IsGlitch() && !enabledTricks.count(static_cast(i))) { + if (!enabledTricks.count(static_cast(i))) { enabledTricks.insert(static_cast(i)); } } @@ -1741,15 +2311,20 @@ void RandomizerSettingsWindow::DrawElement() { enabledTrickString += ","; } CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } if (ImGui::BeginTable("trickTags", showTag.size(), ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) { for (auto [rtTag, isShown] : showTag) { ImGui::TableNextColumn(); - ImGui::PushStyleColor(ImGuiCol_Header, Rando::Tricks::GetRTTagColor(rtTag)); - ImGui::Selectable(Rando::Tricks::GetRTTagName(rtTag).c_str(), &showTag[rtTag]); - ImGui::PopStyleColor(1); + if (isShown) { + ImGui::PushStyleColor(ImGuiCol_Text, Rando::Tricks::GetTextColor(rtTag)); + } else { + ImGui::PushStyleColor(ImGuiCol_Text, { 1.0f, 1.0f, 1.0f, 1.0f }); + } + ImGui::PushStyleColor(ImGuiCol_Header, Rando::Tricks::GetTagColor(rtTag)); + ImGui::Selectable(Rando::Tricks::GetTagName(rtTag).c_str(), &showTag[rtTag]); + ImGui::PopStyleColor(2); } ImGui::EndTable(); } @@ -1761,13 +2336,12 @@ void RandomizerSettingsWindow::DrawElement() { ImGui::TableHeadersRow(); ImGui::PopItemFlag(); ImGui::TableNextRow(); - - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC) { + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC) { // COLUMN 1 - DISABLED TRICKS ImGui::TableNextColumn(); window->DC.CurrLineTextBaseOffset = 0.0f; - + if (ImGui::Button("Collapse All##disabled")) { for (int i = 0; i < RA_MAX; i++) { areaTreeDisabled[static_cast(i)] = false; @@ -1783,10 +2357,10 @@ void RandomizerSettingsWindow::DrawElement() { if (ImGui::Button("Enable Visible")) { for (int i = 0; i < RT_MAX; i++) { auto option = mSettings->GetTrickOption(static_cast(i)); - if (!option.IsGlitch() && !enabledTricks.count(static_cast(i)) && + if (!enabledTricks.count(static_cast(i)) && trickSearch.PassFilter(option.GetName().c_str()) && areaTreeDisabled[option.GetArea()] && - Rando::Tricks::CheckRTTags(showTag, option.GetTags())) { + Rando::Tricks::CheckTags(showTag, option.GetTags())) { enabledTricks.insert(static_cast(i)); } } @@ -1796,9 +2370,9 @@ void RandomizerSettingsWindow::DrawElement() { enabledTrickString += ","; } CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } - + ImGui::BeginChild("ChildTricksDisabled", ImVec2(0, -8), false, ImGuiWindowFlags_HorizontalScrollbar); for (auto [area, trickIds] : mSettings->mTricksByArea) { @@ -1806,22 +2380,20 @@ void RandomizerSettingsWindow::DrawElement() { for (auto rt : trickIds) { auto option = mSettings->GetTrickOption(rt); if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) && - !enabledTricks.count(rt) && Rando::Tricks::CheckRTTags(showTag, option.GetTags()) && - !option.IsGlitch()) { + !enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) { hasTricks = true; break; } } if (hasTricks) { - ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetRTAreaName(area) + "##disabled").c_str()), areaTreeDisabled[area]); + ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetAreaName(area) + "##disabled").c_str()), areaTreeDisabled[area]); ImGui::SetNextItemOpen(true, ImGuiCond_Once); - if (ImGui::TreeNode((Rando::Tricks::GetRTAreaName(area) + "##disabled").c_str())) { + if (ImGui::TreeNode((Rando::Tricks::GetAreaName(area) + "##disabled").c_str())) { for (auto rt : trickIds) { auto option = mSettings->GetTrickOption(rt); if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) && - !enabledTricks.count(rt) && Rando::Tricks::CheckRTTags(showTag, option.GetTags()) && - !option.IsGlitch()) { - ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetRTAreaName(option.GetArea()) + "##disabled").c_str()), areaTreeDisabled[option.GetArea()]); + !enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) { + ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetAreaName(option.GetArea()) + "##disabled").c_str()), areaTreeDisabled[option.GetArea()]); ImGui::SetNextItemOpen(true, ImGuiCond_Once); if (ImGui::ArrowButton(std::to_string(rt).c_str(), ImGuiDir_Right)) { enabledTricks.insert(rt); @@ -1831,7 +2403,7 @@ void RandomizerSettingsWindow::DrawElement() { enabledTrickString += ","; } CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } Rando::Tricks::DrawTagChips(option.GetTags()); ImGui::SameLine(); @@ -1848,13 +2420,10 @@ void RandomizerSettingsWindow::DrawElement() { } ImGui::EndChild(); - - // COLUMN 2 - ENABLED TRICKS ImGui::TableNextColumn(); window->DC.CurrLineTextBaseOffset = 0.0f; - if (ImGui::Button("Collapse All##enabled")) { for (int i = 0; i < RA_MAX; i++) { areaTreeEnabled[static_cast(i)] = false; @@ -1870,10 +2439,10 @@ void RandomizerSettingsWindow::DrawElement() { if (ImGui::Button("Disable Visible")) { for (int i = 0; i < RT_MAX; i++) { auto option = mSettings->GetTrickOption(static_cast(i)); - if (!option.IsGlitch() && enabledTricks.count(static_cast(i)) && + if (enabledTricks.count(static_cast(i)) && trickSearch.PassFilter(option.GetName().c_str()) && areaTreeEnabled[option.GetArea()] && - Rando::Tricks::CheckRTTags(showTag, option.GetTags())) { + Rando::Tricks::CheckTags(showTag, option.GetTags())) { enabledTricks.erase(static_cast(i)); } } @@ -1887,9 +2456,9 @@ void RandomizerSettingsWindow::DrawElement() { } else { CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str()); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } - + ImGui::BeginChild("ChildTricksEnabled", ImVec2(0, -8), false, ImGuiWindowFlags_HorizontalScrollbar); for (auto [area, trickIds] : mSettings->mTricksByArea) { @@ -1897,22 +2466,20 @@ void RandomizerSettingsWindow::DrawElement() { for (auto rt : trickIds) { auto option = mSettings->GetTrickOption(rt); if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) && - enabledTricks.count(rt) && Rando::Tricks::CheckRTTags(showTag, option.GetTags()) && - !option.IsGlitch()) { + enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) { hasTricks = true; break; } } if (hasTricks) { - ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetRTAreaName(area) + "##enabled").c_str()), areaTreeEnabled[area]); + ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetAreaName(area) + "##enabled").c_str()), areaTreeEnabled[area]); ImGui::SetNextItemOpen(true, ImGuiCond_Once); - if (ImGui::TreeNode((Rando::Tricks::GetRTAreaName(area) + "##enabled").c_str())) { + if (ImGui::TreeNode((Rando::Tricks::GetAreaName(area) + "##enabled").c_str())) { for (auto rt : trickIds) { auto option = mSettings->GetTrickOption(rt); if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) && - enabledTricks.count(rt) && Rando::Tricks::CheckRTTags(showTag, option.GetTags()) && - !option.IsGlitch()) { - ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetRTAreaName(option.GetArea()) + "##enabled").c_str()), areaTreeEnabled[option.GetArea()]); + enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) { + ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetAreaName(option.GetArea()) + "##enabled").c_str()), areaTreeEnabled[option.GetArea()]); ImGui::SetNextItemOpen(true, ImGuiCond_Once); if (ImGui::ArrowButton(std::to_string(rt).c_str(), ImGuiDir_Left)) { enabledTricks.erase(rt); @@ -1926,7 +2493,7 @@ void RandomizerSettingsWindow::DrawElement() { } else { CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str()); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } Rando::Tricks::DrawTagChips(option.GetTags()); ImGui::SameLine(); @@ -1944,10 +2511,6 @@ void RandomizerSettingsWindow::DrawElement() { ImGui::EndChild(); } else { - ImGui::TableNextColumn(); - ImGui::BeginChild("ChildTrickAreas", ImVec2(0, -8)); - ImGui::Text("Requires Logic Turned On."); - ImGui::EndChild(); ImGui::TableNextColumn(); ImGui::BeginChild("ChildTricksDisabled", ImVec2(0, -8)); ImGui::Text("Requires Logic Turned On."); @@ -2790,7 +3353,7 @@ void Randomizer::CreateCustomMessages() { "You found a %pBottom of the &Well %wSmall Key!", "Du erhältst einen %rKleinen&Schlüssel%w für den %pGrund des Brunnens%w!", "Vous obtenez une %rPetite Clé %w&du %pPuits%w!"), - GIMESSAGE(RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, ITEM_KEY_SMALL, + GIMESSAGE(RG_GERUDO_TRAINING_GROUND_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yGerudo Training &Grounds %wSmall Key!", "Du erhältst einen %rKleinen&Schlüssel%w für die %yGerudo-Trainingsarena%w!", "Vous obtenez une %rPetite Clé %w&du %yGymnase Gerudo%w!"), @@ -2827,7 +3390,7 @@ void Randomizer::CreateCustomMessages() { "You found a %pBottom of the &Well %wKeyring!", "Du erhältst ein %rSchlüsselbund%w&für den %pGrund des Brunnens%w!", "Vous obtenez un trousseau de&clés du %pPuits%w!"), - GIMESSAGE(RG_GERUDO_TRAINING_GROUNDS_KEY_RING, ITEM_KEY_SMALL, + GIMESSAGE(RG_GERUDO_TRAINING_GROUND_KEY_RING, ITEM_KEY_SMALL, "You found a %yGerudo Training &Grounds %wKeyring!", "Du erhältst ein %rSchlüsselbund%w&für die %yGerudo-Trainingsarena%w!", "Vous obtenez un trousseau de&clés du %yGymnase Gerudo%w!"), @@ -3025,3 +3588,352 @@ void RandomizerSettingsWindow::InitElement() { seedString = (char*)calloc(MAX_SEED_STRING_SIZE, sizeof(char)); Rando::Context::GetInstance()->GetSettings()->UpdateOptionProperties(); } + +// Gameplay stat tracking: Update time the item was acquired +// (special cases for rando items) +void Randomizer_GameplayStats_SetTimestamp(uint16_t item) { + + u32 time = GAMEPLAYSTAT_TOTAL_TIME; + + // Have items in Link's pocket shown as being obtained at 0.1 seconds + if (time == 0) { + time = 1; + } + + // Use ITEM_KEY_BOSS to timestamp Ganon's boss key + if (item == RG_GANONS_CASTLE_BOSS_KEY) { + gSaveContext.sohStats.itemTimestamp[ITEM_KEY_BOSS] = time; + } + + // Count any bottled item as a bottle + if (item >= RG_EMPTY_BOTTLE && item <= RG_BOTTLE_WITH_BIG_POE) { + if (gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] == 0) { + gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] = time; + } + return; + } + // Count any bombchu pack as bombchus + if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS) { + if (gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = 0) { + gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = time; + } + return; + } + if (item == RG_MAGIC_SINGLE) { + gSaveContext.sohStats.itemTimestamp[ITEM_SINGLE_MAGIC] = time; + } + if (item == RG_DOUBLE_DEFENSE) { + gSaveContext.sohStats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time; + } +} + +extern "C" u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem); + +// used for items that only set a rand inf when obtained +std::map randomizerGetToRandInf = { + { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, + { RG_BRONZE_SCALE, RAND_INF_CAN_SWIM }, + { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, + { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, + { RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG }, + { RG_STICK_UPGRADE_INF, RAND_INF_HAS_INFINITE_STICK_UPGRADE }, + { RG_NUT_UPGRADE_INF, RAND_INF_HAS_INFINITE_NUT_UPGRADE }, + { RG_MAGIC_INF, RAND_INF_HAS_INFINITE_MAGIC_METER }, + { RG_BOMBCHU_INF, RAND_INF_HAS_INFINITE_BOMBCHUS }, + { RG_WALLET_INF, RAND_INF_HAS_INFINITE_MONEY }, + { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, + { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, + { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, + { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, + { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, + { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, + { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, + { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, + { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, + { RG_PHANTOM_GANON_SOUL, RAND_INF_PHANTOM_GANON_SOUL }, + { RG_VOLVAGIA_SOUL, RAND_INF_VOLVAGIA_SOUL }, + { RG_MORPHA_SOUL, RAND_INF_MORPHA_SOUL }, + { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, + { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, + { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, +}; + +extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { + if (giEntry.modIndex != MOD_RANDOMIZER) { + LUSLOG_WARN("Randomizer_Item_Give was called with a GetItemEntry with a mod index different from MOD_RANDOMIZER (%d)", giEntry.modIndex); + assert(false); + return -1; + } + + RandomizerGet item = (RandomizerGet)giEntry.getItemId; + + // Gameplay stats: Update the time the item was obtained + Randomizer_GameplayStats_SetTimestamp(item); + + //if it's an item that just sets a randomizerInf, set it + if (randomizerGetToRandInf.find(item) != randomizerGetToRandInf.end()) { + Flags_SetRandomizerInf(randomizerGetToRandInf.find(item)->second); + return Return_Item_Entry(giEntry, RG_NONE); + } + + //bottle items + if (item >= RG_BOTTLE_WITH_RED_POTION && item <= RG_BOTTLE_WITH_BIG_POE) { + for (u16 i = 0; i < 4; i++) { + if (gSaveContext.inventory.items[SLOT_BOTTLE_1 + i] == ITEM_NONE) { + ItemID bottleItem = ITEM_NONE; + switch (item) { + case RG_BOTTLE_WITH_RED_POTION: + bottleItem = ITEM_POTION_RED; + break; + case RG_BOTTLE_WITH_GREEN_POTION: + bottleItem = ITEM_POTION_GREEN; + break; + case RG_BOTTLE_WITH_BLUE_POTION: + bottleItem = ITEM_POTION_BLUE; + break; + case RG_BOTTLE_WITH_FAIRY: + bottleItem = ITEM_FAIRY; + break; + case RG_BOTTLE_WITH_FISH: + bottleItem = ITEM_FISH; + break; + case RG_BOTTLE_WITH_BLUE_FIRE: + bottleItem = ITEM_BLUE_FIRE; + break; + case RG_BOTTLE_WITH_BUGS: + bottleItem = ITEM_BUG; + break; + case RG_BOTTLE_WITH_POE: + bottleItem = ITEM_POE; + break; + case RG_BOTTLE_WITH_BIG_POE: + bottleItem = ITEM_BIG_POE; + break; + default: + break; + } + + gSaveContext.inventory.items[SLOT_BOTTLE_1 + i] = bottleItem; + return Return_Item_Entry(giEntry, RG_NONE); + } + } + } + + //dungeon items + if ( + (item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_GANONS_CASTLE_SMALL_KEY) || + (item >= RG_FOREST_TEMPLE_KEY_RING && item <= RG_GANONS_CASTLE_KEY_RING) || + (item >= RG_FOREST_TEMPLE_BOSS_KEY && item <= RG_GANONS_CASTLE_BOSS_KEY) || + (item >= RG_DEKU_TREE_MAP && item <= RG_ICE_CAVERN_MAP) || + (item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS) + ) { + u16 mapIndex = gSaveContext.mapIndex; + u8 numOfKeysOnKeyring = 0; + switch (item) { + case RG_DEKU_TREE_MAP: + case RG_DEKU_TREE_COMPASS: + mapIndex = SCENE_DEKU_TREE; + break; + case RG_DODONGOS_CAVERN_MAP: + case RG_DODONGOS_CAVERN_COMPASS: + mapIndex = SCENE_DODONGOS_CAVERN; + break; + case RG_JABU_JABUS_BELLY_MAP: + case RG_JABU_JABUS_BELLY_COMPASS: + mapIndex = SCENE_JABU_JABU; + break; + case RG_FOREST_TEMPLE_MAP: + case RG_FOREST_TEMPLE_COMPASS: + case RG_FOREST_TEMPLE_SMALL_KEY: + case RG_FOREST_TEMPLE_KEY_RING: + case RG_FOREST_TEMPLE_BOSS_KEY: + mapIndex = SCENE_FOREST_TEMPLE; + numOfKeysOnKeyring = FOREST_TEMPLE_SMALL_KEY_MAX; + break; + case RG_FIRE_TEMPLE_MAP: + case RG_FIRE_TEMPLE_COMPASS: + case RG_FIRE_TEMPLE_SMALL_KEY: + case RG_FIRE_TEMPLE_KEY_RING: + case RG_FIRE_TEMPLE_BOSS_KEY: + mapIndex = SCENE_FIRE_TEMPLE; + numOfKeysOnKeyring = FIRE_TEMPLE_SMALL_KEY_MAX; + break; + case RG_WATER_TEMPLE_MAP: + case RG_WATER_TEMPLE_COMPASS: + case RG_WATER_TEMPLE_SMALL_KEY: + case RG_WATER_TEMPLE_KEY_RING: + case RG_WATER_TEMPLE_BOSS_KEY: + mapIndex = SCENE_WATER_TEMPLE; + numOfKeysOnKeyring = WATER_TEMPLE_SMALL_KEY_MAX; + break; + case RG_SPIRIT_TEMPLE_MAP: + case RG_SPIRIT_TEMPLE_COMPASS: + case RG_SPIRIT_TEMPLE_SMALL_KEY: + case RG_SPIRIT_TEMPLE_KEY_RING: + case RG_SPIRIT_TEMPLE_BOSS_KEY: + mapIndex = SCENE_SPIRIT_TEMPLE; + numOfKeysOnKeyring = SPIRIT_TEMPLE_SMALL_KEY_MAX; + break; + case RG_SHADOW_TEMPLE_MAP: + case RG_SHADOW_TEMPLE_COMPASS: + case RG_SHADOW_TEMPLE_SMALL_KEY: + case RG_SHADOW_TEMPLE_KEY_RING: + case RG_SHADOW_TEMPLE_BOSS_KEY: + mapIndex = SCENE_SHADOW_TEMPLE; + numOfKeysOnKeyring = SHADOW_TEMPLE_SMALL_KEY_MAX; + break; + case RG_BOTTOM_OF_THE_WELL_MAP: + case RG_BOTTOM_OF_THE_WELL_COMPASS: + case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: + case RG_BOTTOM_OF_THE_WELL_KEY_RING: + mapIndex = SCENE_BOTTOM_OF_THE_WELL; + numOfKeysOnKeyring = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; + break; + case RG_ICE_CAVERN_MAP: + case RG_ICE_CAVERN_COMPASS: + mapIndex = SCENE_ICE_CAVERN; + break; + case RG_GANONS_CASTLE_BOSS_KEY: + mapIndex = SCENE_GANONS_TOWER; + break; + case RG_GERUDO_TRAINING_GROUND_SMALL_KEY: + case RG_GERUDO_TRAINING_GROUND_KEY_RING: + mapIndex = SCENE_GERUDO_TRAINING_GROUND; + numOfKeysOnKeyring = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; + break; + case RG_GERUDO_FORTRESS_SMALL_KEY: + case RG_GERUDO_FORTRESS_KEY_RING: + mapIndex = SCENE_THIEVES_HIDEOUT; + numOfKeysOnKeyring = GERUDO_FORTRESS_SMALL_KEY_MAX; + break; + case RG_GANONS_CASTLE_SMALL_KEY: + case RG_GANONS_CASTLE_KEY_RING: + mapIndex = SCENE_INSIDE_GANONS_CASTLE; + numOfKeysOnKeyring = GANONS_CASTLE_SMALL_KEY_MAX; + break; + default: + break; + } + + if ((item >= RG_FOREST_TEMPLE_SMALL_KEY) && (item <= RG_GANONS_CASTLE_SMALL_KEY)) { + gSaveContext.sohStats.dungeonKeys[mapIndex]++; + if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { + gSaveContext.inventory.dungeonKeys[mapIndex] = 1; + } else { + gSaveContext.inventory.dungeonKeys[mapIndex]++; + } + return Return_Item_Entry(giEntry, RG_NONE); + } + + if ((item >= RG_FOREST_TEMPLE_KEY_RING) && (item <= RG_GANONS_CASTLE_KEY_RING)) { + gSaveContext.sohStats.dungeonKeys[mapIndex] = numOfKeysOnKeyring; + gSaveContext.inventory.dungeonKeys[mapIndex] = numOfKeysOnKeyring; + return Return_Item_Entry(giEntry, RG_NONE); + } + + u32 bitmask; + if ((item >= RG_DEKU_TREE_MAP) && (item <= RG_ICE_CAVERN_MAP)) { + bitmask = gBitFlags[2]; + } else if ((item >= RG_DEKU_TREE_COMPASS) && (item <= RG_ICE_CAVERN_COMPASS)) { + bitmask = gBitFlags[1]; + } else { + bitmask = gBitFlags[0]; + } + + gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; + return Return_Item_Entry(giEntry, RG_NONE); + } + + switch (item) { + case RG_MAGIC_SINGLE: + gSaveContext.isMagicAcquired = true; + gSaveContext.magicFillTarget = MAGIC_NORMAL_METER; + Magic_Fill(play); + break; + case RG_MAGIC_DOUBLE: + if (!gSaveContext.isMagicAcquired) { + gSaveContext.isMagicAcquired = true; + } + gSaveContext.isDoubleMagicAcquired = true; + gSaveContext.magicFillTarget = MAGIC_DOUBLE_METER; + gSaveContext.magicLevel = 0; + Magic_Fill(play); + break; + case RG_MAGIC_BEAN_PACK: + if (INV_CONTENT(ITEM_BEAN) == ITEM_NONE) { + INV_CONTENT(ITEM_BEAN) = ITEM_BEAN; + AMMO(ITEM_BEAN) = 10; + } + break; + case RG_DOUBLE_DEFENSE: + gSaveContext.isDoubleDefenseAcquired = true; + gSaveContext.inventory.defenseHearts = 20; + gSaveContext.healthAccumulator = 0x140; + break; + case RG_TYCOON_WALLET: + Inventory_ChangeUpgrade(UPG_WALLET, 3); + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FULL_WALLETS)) { + Rupees_ChangeBy(999); + } + break; + case RG_CHILD_WALLET: + Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FULL_WALLETS)) { + Rupees_ChangeBy(99); + } + break; + case RG_GREG_RUPEE: + Rupees_ChangeBy(1); + Flags_SetRandomizerInf(RAND_INF_GREG_FOUND); + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_FOUND_GREG] = GAMEPLAYSTAT_TOTAL_TIME; + break; + case RG_TRIFORCE_PIECE: + gSaveContext.triforcePiecesCollected++; + GameInteractor_SetTriforceHuntPieceGiven(true); + + // Teleport to credits when goal is reached. + if (gSaveContext.triforcePiecesCollected == (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1)) { + gSaveContext.sohStats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = GAMEPLAYSTAT_TOTAL_TIME; + gSaveContext.sohStats.gameComplete = 1; + Flags_SetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY); + Play_PerformSave(play); + GameInteractor_SetTriforceHuntCreditsWarpActive(true); + } + + break; + case RG_PROGRESSIVE_BOMBCHUS: + if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE) { + INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU; + AMMO(ITEM_BOMBCHU) = 20; + } else if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INFINITE_UPGRADES)) { + Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS); + } else { + AMMO(ITEM_BOMBCHU) += AMMO(ITEM_BOMBCHU) < 5 ? 10 : 5; + if (AMMO(ITEM_BOMBCHU) > 50) { + AMMO(ITEM_BOMBCHU) = 50; + } + } + break; + case RG_MASTER_SWORD: + if (!CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { + gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_TYPE_SWORD]; + } + break; + case RG_DEKU_STICK_BAG: + Inventory_ChangeUpgrade(UPG_STICKS, 1); + INV_CONTENT(ITEM_STICK) = ITEM_STICK; + AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS); + break; + case RG_DEKU_NUT_BAG: + Inventory_ChangeUpgrade(UPG_NUTS, 1); + INV_CONTENT(ITEM_NUT) = ITEM_NUT; + AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS); + break; + default: + LUSLOG_WARN("Randomizer_Item_Give didn't have behaviour specified for getItemId=%d", item); + assert(false); + return -1; + } + + return Return_Item_Entry(giEntry, RG_NONE); +} diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 4a84d6302..76bde6a4f 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -52,6 +52,7 @@ class Randomizer { BeehiveIdentity IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData); ShopItemIdentity IdentifyShopItem(s32 sceneNum, u8 slotIndex); CowIdentity IdentifyCow(s32 sceneNum, s32 posX, s32 posZ); + PotIdentity IdentifyPot(s32 sceneNum, s32 posX, s32 posZ); FishIdentity IdentifyFish(s32 sceneNum, s32 actorParams); GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability = true); GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, bool checkObtainability = true); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index f6f3b5bab..3f1adcbe1 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -6,6 +6,8 @@ #define MAX_TRICK_NAME_SIZE 50 +#define TWO_ACTOR_PARAMS(a, b) ((((a)&0xFFFF) << 16) | ((b)&0xFFFF)) + // This should probably go in a less rando-specific location // but the best location will probably be in the modding engine // which doesn't exist yet. @@ -141,7 +143,7 @@ typedef enum { LOGIC_SPIRIT_TEMPLE_KEYS, LOGIC_SHADOW_TEMPLE_KEYS, LOGIC_BOTTOM_OF_THE_WELL_KEYS, - LOGIC_GERUDO_TRAINING_GROUNDS_KEYS, + LOGIC_GERUDO_TRAINING_GROUND_KEYS, LOGIC_GERUDO_FORTRESS_KEYS, LOGIC_GANONS_CASTLE_KEYS, LOGIC_TREASURE_GAME_KEYS, @@ -261,10 +263,13 @@ typedef enum { RCTYPE_STATIC_HINT, // RANDOTODO make these into event access RCTYPE_SONG_LOCATION, // Song locations RCTYPE_BOSS_HEART_OR_OTHER_REWARD, // Boss heart container or lesser dungeon rewards (lens, ice arrow) + RCTYPE_POT, // Pots RCTYPE_DUNGEON_REWARD, // Dungeon rewards (blue warps) RCTYPE_OCARINA, // Ocarina locations RCTYPE_BEEHIVE, // Beehives RCTYPE_FISH, // Fishes + RCTYPE_FREESTANDING, // Freestanding rupees and hearts + RCTYPE_FAIRY, // Fairies } RandomizerCheckType; typedef enum { RCQUEST_VANILLA, RCQUEST_MQ, RCQUEST_BOTH } RandomizerCheckQuest; @@ -355,6 +360,7 @@ typedef enum { RR_HF_OPEN_GROTTO, RR_HF_INSIDE_FENCE_GROTTO, RR_HF_COW_GROTTO, + RR_HF_COW_GROTTO_BEHIND_WEBS, RR_HF_NEAR_MARKET_GROTTO, RR_HF_FAIRY_GROTTO, RR_HF_NEAR_KAK_GROTTO, @@ -363,7 +369,7 @@ typedef enum { RR_LH_FISHING_ISLAND, RR_LH_OWL_FLIGHT, RR_LH_LAB, - RR_LH_FISHING_HOLE, + RR_LH_FISHING_POND, RR_LH_GROTTO, RR_GERUDO_VALLEY, RR_GV_UPPER_STREAM, @@ -381,7 +387,8 @@ typedef enum { RR_HAUNTED_WASTELAND, RR_WASTELAND_NEAR_COLOSSUS, RR_DESERT_COLOSSUS, - RR_DESERT_COLOSSUS_FROM_SPIRIT_ENTRYWAY, + RR_DESERT_COLOSSUS_OASIS, + RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, RR_COLOSSUS_GROTTO, RR_MARKET_ENTRANCE, @@ -406,6 +413,7 @@ typedef enum { RR_HC_GARDEN, RR_HC_GREAT_FAIRY_FOUNTAIN, RR_HC_STORMS_GROTTO, + RR_HC_STORMS_GROTTO_BEHIND_WALLS, RR_GANONS_CASTLE_GROUNDS, RR_OGC_GREAT_FAIRY_FOUNTAIN, RR_GANONS_CASTLE_LEDGE, @@ -420,10 +428,12 @@ typedef enum { RR_KAK_SHOOTING_GALLERY, RR_KAK_POTION_SHOP_FRONT, RR_KAK_POTION_SHOP_BACK, + RR_KAK_WATCHTOWER, RR_KAK_ROOFTOP, RR_KAK_IMPAS_ROOFTOP, RR_KAK_BEHIND_GATE, RR_KAK_BACKYARD, + RR_KAK_WELL, RR_KAK_ODD_POTION_BUILDING, RR_KAK_REDEAD_GROTTO, RR_KAK_OPEN_GROTTO, @@ -431,6 +441,7 @@ typedef enum { RR_GRAVEYARD_DAMPES_GRAVE, RR_GRAVEYARD_DAMPES_HOUSE, RR_GRAVEYARD_SHIELD_GRAVE, + RR_GRAVEYARD_SHIELD_GRAVE_BACK, RR_GRAVEYARD_COMPOSERS_GRAVE, RR_GRAVEYARD_HEART_PIECE_GRAVE, RR_GRAVEYARD_WARP_PAD_REGION, @@ -441,6 +452,7 @@ typedef enum { RR_DMT_COW_GROTTO, RR_DMT_STORMS_GROTTO, RR_GORON_CITY, + RR_GC_MEDIGORON, RR_GC_WOODS_WARP, RR_GC_DARUNIAS_CHAMBER, RR_GC_GROTTO_PLATFORM, @@ -456,6 +468,7 @@ typedef enum { RR_DMC_UPPER_GROTTO, RR_DMC_HAMMER_GROTTO, RR_DMC_GREAT_FAIRY_FOUNTAIN, + RR_DMC_DISTANT_PLATFORM, RR_ZR_FRONT, RR_ZORAS_RIVER, RR_ZR_BEHIND_WATERFALL, @@ -463,6 +476,7 @@ typedef enum { RR_ZR_FAIRY_GROTTO, RR_ZR_STORMS_GROTTO, RR_ZORAS_DOMAIN, + RR_ZORAS_DOMAIN_ISLAND, RR_ZD_BEHIND_KING_ZORA, RR_ZD_SHOP, RR_ZD_STORMS_GROTTO, @@ -484,7 +498,7 @@ typedef enum { RR_SHADOW_TEMPLE_ENTRYWAY, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, RR_ICE_CAVERN_ENTRYWAY, - RR_GERUDO_TRAINING_GROUNDS_ENTRYWAY, + RR_GERUDO_TRAINING_GROUND_ENTRYWAY, RR_GANONS_CASTLE_ENTRYWAY, RR_DEKU_TREE_LOBBY, @@ -545,6 +559,7 @@ typedef enum { RR_DODONGOS_CAVERN_MQ_BEGINNING, RR_DODONGOS_CAVERN_MQ_LOBBY, + RR_DODONGOS_CAVERN_MQ_GOSSIP_STONE, RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL, RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, @@ -568,27 +583,29 @@ typedef enum { RR_DODONGOS_CAVERN_BOSS_ROOM, RR_JABU_JABUS_BELLY_BEGINNING, - RR_JABU_JABUS_BELLY_LIFT_MIDDLE, - RR_JABU_JABUS_BELLY_MAIN_UPPER, - RR_JABU_JABUS_BELLY_MAIN_LOWER, - RR_JABU_JABUS_BELLY_SHABOMB_CORRIDOR, - RR_JABU_JABUS_BELLY_LOWER_SIDE_ROOM, - RR_JABU_JABUS_BELLY_LIFT_LOWER, - RR_JABU_JABUS_BELLY_FORKED_CORRIDOR, - RR_JABU_JABUS_BELLY_BOOMERANG_ROOM, - RR_JABU_JABUS_BELLY_MAP_ROOM, + RR_JABU_JABUS_BELLY_MAIN, + RR_JABU_JABUS_BELLY_B1_NORTH, + RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_SOUTH, + RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, RR_JABU_JABUS_BELLY_COMPASS_ROOM, RR_JABU_JABUS_BELLY_BLUE_TENTACLE, RR_JABU_JABUS_BELLY_GREEN_TENTACLE, - RR_JABU_JABUS_BELLY_BIGOCTO_ROOM, + RR_JABU_JABUS_BELLY_BIGOCTO_LEDGE, RR_JABU_JABUS_BELLY_ABOVE_BIGOCTO, RR_JABU_JABUS_BELLY_LIFT_UPPER, RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, RR_JABU_JABUS_BELLY_MQ_BEGINNING, - RR_JABU_JABUS_BELLY_MQ_MAIN, - RR_JABU_JABUS_BELLY_MQ_DEPTHS, - RR_JABU_JABUS_BELLY_MQ_BOSS_AREA, + RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM, + RR_JABU_JABUS_BELLY_MQ_LIFT_ROOM_EAST_LEDGE, + RR_JABU_JABUS_BELLY_MQ_UNDERWATER_ALCOVE, + RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, + RR_JABU_JABUS_BELLY_MQ_WATER_SWITCH_ROOM, + RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, + RR_JABU_JABUS_BELLY_MQ_WEST_FORKED_ROOMS, + RR_JABU_JABUS_BELLY_MQ_INVISIBLE_KEESE_ROOM, + RR_JABU_JABUS_BELLY_MQ_PAST_OCTO, + RR_JABU_JABUS_BELLY_MQ_EAST_ROOM, RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, RR_JABU_JABUS_BELLY_BOSS_ROOM, @@ -641,6 +658,7 @@ typedef enum { RR_FOREST_TEMPLE_MQ_FALLING_ROOM, RR_FOREST_TEMPLE_MQ_AMY_ROOM, RR_FOREST_TEMPLE_MQ_BASEMENT, + RR_FOREST_TEMPLE_MQ_BASEMENT_POT_ROOM, RR_FOREST_TEMPLE_MQ_BOSS_REGION, RR_FOREST_TEMPLE_BOSS_ENTRYWAY, @@ -648,6 +666,7 @@ typedef enum { RR_FIRE_TEMPLE_FIRST_ROOM, RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, + RR_FIRE_TEMPLE_NEAR_BOSS_ROOM_NORTH, RR_FIRE_TEMPLE_LOOP_ENEMIES, RR_FIRE_TEMPLE_LOOP_TILES, RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, @@ -706,8 +725,8 @@ typedef enum { RR_FIRE_TEMPLE_MQ_HIGH_TORCH_ROOM, RR_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE, RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PLATFORMS, - RR_FIRE_TEMPLE_MQ_FIRE_MAZE_SIDE_ROOM, RR_FIRE_TEMPLE_MQ_NORTH_FIRE_MAZE, + RR_FIRE_TEMPLE_MQ_WEST_FIRE_MAZE, RR_FIRE_TEMPLE_MQ_FIRE_MAZE_PAST_WALL, RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER, RR_FIRE_TEMPLE_MQ_SCARECROW_ROOM, @@ -744,11 +763,48 @@ typedef enum { RR_WATER_TEMPLE_RIVER, RR_WATER_TEMPLE_PRE_BOSS_ROOM, - RR_WATER_TEMPLE_MQ_LOBBY, - RR_WATER_TEMPLE_MQ_DIVE, - RR_WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS, - RR_WATER_TEMPLE_MQ_DARK_LINK_REGION, - RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS, + RR_WATER_TEMPLE_MQ_3F_SOUTH_LEDGE, + RR_WATER_TEMPLE_MQ_MAIN, + RR_WATER_TEMPLE_MQ_3F_CENTRAL, + RR_WATER_TEMPLE_MQ_2F_CENTRAL, + RR_WATER_TEMPLE_MQ_2F_CENTRAL_HIGH, + RR_WATER_TEMPLE_MQ_HIGH_EMBLEM, + RR_WATER_TEMPLE_MQ_3F_NORTH_LEDGE, + RR_WATER_TEMPLE_MQ_BOSS_DOOR, + RR_WATER_TEMPLE_MQ_EAST_TOWER, + RR_WATER_TEMPLE_MQ_EAST_TOWER_1F_ROOM, + RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_1F, + RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_2F, + RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, + RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, + RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1_FINAL, + RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_2F, + RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_3F, + RR_WATER_TEMPLE_MQ_STORAGE_ROOM, + RR_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY, + RR_WATER_TEMPLE_MQ_LIZALFOS_CAGE, + RR_WATER_TEMPLE_MQ_3F_EAST_LEDGE, + RR_WATER_TEMPLE_MQ_WATERFALL, + RR_WATER_TEMPLE_MQ_STALFOS_PIT, + RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, + RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, + RR_WATER_TEMPLE_MQ_AFTER_DARK_LINK, + RR_WATER_TEMPLE_MQ_RIVER_SKULL, + RR_WATER_TEMPLE_MQ_RIVER_POTS, + RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, + RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL, + RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE, + RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, + RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT, + RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, + RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH, + RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM, + RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE, + RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, + RR_WATER_TEMPLE_MQ_SINGLE_STALFOS_ROOM, + RR_WATER_TEMPLE_MQ_4_TORCH_ROOM, + RR_WATER_TEMPLE_MQ_DODONGO_ROOM, + RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_CAGE, RR_WATER_TEMPLE_BOSS_ENTRYWAY, RR_WATER_TEMPLE_BOSS_ROOM, @@ -764,13 +820,39 @@ typedef enum { RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, RR_SPIRIT_TEMPLE_MQ_LOBBY, - RR_SPIRIT_TEMPLE_MQ_CHILD, - RR_SPIRIT_TEMPLE_MQ_ADULT, - RR_SPIRIT_TEMPLE_MQ_SHARED, - RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT, - RR_SPIRIT_TEMPLE_MQ_BOSS_AREA, - RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, + RR_SPIRIT_TEMPLE_MQ_1F_WEST, + RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH, + RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH, + RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, + RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH, + RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, + RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, + RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, + RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, + RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, + RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, + RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, + RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH, + RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, + RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, + RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, + RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, + RR_SPIRIT_TEMPLE_MQ_1F_EAST, + RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM, + RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, + RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM, + RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, + RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, + RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, + RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, + RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, + RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM, + RR_SPIRIT_TEMPLE_MQ_BIG_WALL, + RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, + RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM, + RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, + RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, @@ -784,13 +866,28 @@ typedef enum { RR_SHADOW_TEMPLE_MQ_ENTRYWAY, RR_SHADOW_TEMPLE_MQ_BEGINNING, + RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, + RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, + RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, + RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR, RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, + RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, + RR_SHADOW_TEMPLE_MQ_STONE_UMBRELLA_ROOM, + RR_SHADOW_TEMPLE_MQ_UPPER_STONE_UMBRELLA, + RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, + RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, + RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, + RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, + RR_SHADOW_TEMPLE_MQ_DOCK, RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, + RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, + RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, + RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, RR_SHADOW_TEMPLE_BOSS_ROOM, @@ -820,27 +917,43 @@ typedef enum { RR_ICE_CAVERN_MAIN, RR_ICE_CAVERN_MQ_BEGINNING, + RR_ICE_CAVERN_MQ_HUB, RR_ICE_CAVERN_MQ_MAP_ROOM, - RR_ICE_CAVERN_MQ_IRON_BOOTS_REGION, + RR_ICE_CAVERN_MQ_SCARECROW_ROOM, + RR_ICE_CAVERN_MQ_STALFOS_ROOM, + RR_ICE_CAVERN_MQ_WEST_CORRIDOR, RR_ICE_CAVERN_MQ_COMPASS_ROOM, - RR_GERUDO_TRAINING_GROUNDS_LOBBY, - RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE, - RR_GERUDO_TRAINING_GROUNDS_CENTRAL_MAZE_RIGHT, - RR_GERUDO_TRAINING_GROUNDS_LAVA_ROOM, - RR_GERUDO_TRAINING_GROUNDS_HAMMER_ROOM, - RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_LOWER, - RR_GERUDO_TRAINING_GROUNDS_EYE_STATUE_UPPER, - RR_GERUDO_TRAINING_GROUNDS_HEAVY_BLOCK_ROOM, - RR_GERUDO_TRAINING_GROUNDS_LIKE_LIKE_ROOM, + RR_GERUDO_TRAINING_GROUND_LOBBY, + RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE, + RR_GERUDO_TRAINING_GROUND_CENTRAL_MAZE_RIGHT, + RR_GERUDO_TRAINING_GROUND_LAVA_ROOM, + RR_GERUDO_TRAINING_GROUND_HAMMER_ROOM, + RR_GERUDO_TRAINING_GROUND_EYE_STATUE_LOWER, + RR_GERUDO_TRAINING_GROUND_EYE_STATUE_UPPER, + RR_GERUDO_TRAINING_GROUND_HEAVY_BLOCK_ROOM, + RR_GERUDO_TRAINING_GROUND_LIKE_LIKE_ROOM, - RR_GERUDO_TRAINING_GROUNDS_MQ_LOBBY, - RR_GERUDO_TRAINING_GROUNDS_MQ_RIGHT_SIDE, - RR_GERUDO_TRAINING_GROUNDS_MQ_UNDERWATER, - RR_GERUDO_TRAINING_GROUNDS_MQ_LEFT_SIDE, - RR_GERUDO_TRAINING_GROUNDS_MQ_STALFOS_ROOM, - RR_GERUDO_TRAINING_GROUNDS_MQ_BACK_AREAS, - RR_GERUDO_TRAINING_GROUNDS_MQ_CENTRAL_MAZE_RIGHT, + RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, + RR_GERUDO_TRAINING_GROUND_MQ_MAZE_HIDDEN_ROOM, + RR_GERUDO_TRAINING_GROUND_MQ_MAZE_FIRST_LOCK, + RR_GERUDO_TRAINING_GROUND_MQ_MAZE_CENTER, + RR_GERUDO_TRAINING_GROUND_MQ_SAND_ROOM, + RR_GERUDO_TRAINING_GROUND_MQ_LEFT_SIDE, + RR_GERUDO_TRAINING_GROUND_MQ_STALFOS_ROOM, + RR_GERUDO_TRAINING_GROUND_MQ_BEHIND_BLOCK, + RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM_LEDGE, + RR_GERUDO_TRAINING_GROUND_MQ_MAGENTA_FIRE_ROOM, + RR_GERUDO_TRAINING_GROUND_MQ_STATUE_ROOM, + RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SLUG_ROOM, + RR_GERUDO_TRAINING_GROUND_MQ_SWITCH_LEDGE, + RR_GERUDO_TRAINING_GROUND_MQ_LEDGE_SIDE_PLATFORMS, + RR_GERUDO_TRAINING_GROUND_MQ_FURTHEST_PLATFORM, + RR_GERUDO_TRAINING_GROUND_MQ_TORCH_SIDE_PLATFORMS, + RR_GERUDO_TRAINING_GROUND_MQ_PLATFORMS_UNLIT_TORCH, + RR_GERUDO_TRAINING_GROUND_MQ_DINOLFOS_ROOM, + RR_GERUDO_TRAINING_GROUND_MQ_UNDERWATER, + RR_GERUDO_TRAINING_GROUND_MQ_MAZE_RIGHT, RR_GANONS_CASTLE_LOBBY, RR_GANONS_CASTLE_MAIN, @@ -880,6 +993,14 @@ typedef enum { RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_BACK, RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM, + RR_GANONS_TOWER_FLOOR_1, + RR_GANONS_TOWER_FLOOR_2, + RR_GANONS_TOWER_FLOOR_3, + RR_GANONS_TOWER_BEFORE_GANONDORF_LAIR, + RR_GANONS_TOWER_GANONDORF_LAIR, + RR_GANONS_CASTLE_ESCAPE, + RR_GANONS_CASTLE_GANON_ARENA, + RR_MARKER_AREAS_END, // Used for area key count // DUNGEONS @@ -893,7 +1014,7 @@ typedef enum { RR_SHADOW_TEMPLE, RR_BOTTOM_OF_THE_WELL, RR_ICE_CAVERN, - RR_GERUDO_TRAINING_GROUNDS, + RR_GERUDO_TRAINING_GROUND, RR_GANONS_CASTLE, RR_MAX, } RandomizerRegion; @@ -910,7 +1031,7 @@ typedef enum { RC_BONGO_BONGO, RC_TWINROVA, RC_GANON, - RC_GIFT_FROM_SAGES, + RC_GIFT_FROM_RAURU, RC_SONG_FROM_IMPA, RC_SONG_FROM_MALON, RC_SONG_FROM_SARIA, @@ -1155,7 +1276,7 @@ typedef enum { RC_ZD_SHOP_ITEM_7, RC_ZD_SHOP_ITEM_8, RC_ZF_GREAT_FAIRY_REWARD, - RC_ZF_ICEBERC_FREESTANDING_POH, + RC_ZF_ICEBERG_FREESTANDING_POH, RC_ZF_BOTTOM_FREESTANDING_POH, RC_ZF_GS_ABOVE_THE_LOG, RC_ZF_GS_TREE, @@ -1640,6 +1761,554 @@ typedef enum { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RC_GANONS_TOWER_BOSS_KEY_CHEST, + + // Overworld Pots + RC_KF_LINKS_HOUSE_POT, + RC_KF_TWINS_HOUSE_POT_1, + RC_KF_TWINS_HOUSE_POT_2, + RC_KF_BROTHERS_HOUSE_POT_1, + RC_KF_BROTHERS_HOUSE_POT_2, + RC_GF_BREAK_ROOM_POT_1, + RC_GF_BREAK_ROOM_POT_2, + RC_GF_KITCHEN_POT_1, + RC_GF_KITCHEN_POT_2, + RC_GF_NORTH_F1_CARPENTER_POT_1, + RC_GF_NORTH_F1_CARPENTER_POT_2, + RC_GF_NORTH_F1_CARPENTER_POT_3, + RC_GF_NORTH_F2_CARPENTER_POT_1, + RC_GF_NORTH_F2_CARPENTER_POT_2, + RC_GF_SOUTH_F1_CARPENTER_POT_1, + RC_GF_SOUTH_F1_CARPENTER_POT_2, + RC_GF_SOUTH_F1_CARPENTER_POT_3, + RC_GF_SOUTH_F1_CARPENTER_CELL_POT_1, + RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2, + RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3, + RC_GF_SOUTH_F1_CARPENTER_CELL_POT_4, + RC_WASTELAND_NEAR_GS_POT_1, + RC_WASTELAND_NEAR_GS_POT_2, + RC_WASTELAND_NEAR_GS_POT_3, + RC_WASTELAND_NEAR_GS_POT_4, + RC_HF_COW_GROTTO_POT_1, + RC_HF_COW_GROTTO_POT_2, + RC_MK_GUARD_HOUSE_CHILD_POT_1, + RC_MK_GUARD_HOUSE_CHILD_POT_2, + RC_MK_GUARD_HOUSE_CHILD_POT_3, + RC_MK_GUARD_HOUSE_CHILD_POT_4, + RC_MK_GUARD_HOUSE_CHILD_POT_5, + RC_MK_GUARD_HOUSE_CHILD_POT_6, + RC_MK_GUARD_HOUSE_CHILD_POT_7, + RC_MK_GUARD_HOUSE_CHILD_POT_8, + RC_MK_GUARD_HOUSE_CHILD_POT_9, + RC_MK_GUARD_HOUSE_CHILD_POT_10, + RC_MK_GUARD_HOUSE_CHILD_POT_11, + RC_MK_GUARD_HOUSE_CHILD_POT_12, + RC_MK_GUARD_HOUSE_CHILD_POT_13, + RC_MK_GUARD_HOUSE_CHILD_POT_14, + RC_MK_GUARD_HOUSE_CHILD_POT_15, + RC_MK_GUARD_HOUSE_CHILD_POT_16, + RC_MK_GUARD_HOUSE_CHILD_POT_17, + RC_MK_GUARD_HOUSE_CHILD_POT_18, + RC_MK_GUARD_HOUSE_CHILD_POT_19, + RC_MK_GUARD_HOUSE_CHILD_POT_20, + RC_MK_GUARD_HOUSE_CHILD_POT_21, + RC_MK_GUARD_HOUSE_CHILD_POT_22, + RC_MK_GUARD_HOUSE_CHILD_POT_23, + RC_MK_GUARD_HOUSE_CHILD_POT_24, + RC_MK_GUARD_HOUSE_CHILD_POT_25, + RC_MK_GUARD_HOUSE_CHILD_POT_26, + RC_MK_GUARD_HOUSE_CHILD_POT_27, + RC_MK_GUARD_HOUSE_CHILD_POT_28, + RC_MK_GUARD_HOUSE_CHILD_POT_29, + RC_MK_GUARD_HOUSE_CHILD_POT_30, + RC_MK_GUARD_HOUSE_CHILD_POT_31, + RC_MK_GUARD_HOUSE_CHILD_POT_32, + RC_MK_GUARD_HOUSE_CHILD_POT_33, + RC_MK_GUARD_HOUSE_CHILD_POT_34, + RC_MK_GUARD_HOUSE_CHILD_POT_35, + RC_MK_GUARD_HOUSE_CHILD_POT_36, + RC_MK_GUARD_HOUSE_CHILD_POT_37, + RC_MK_GUARD_HOUSE_CHILD_POT_38, + RC_MK_GUARD_HOUSE_CHILD_POT_39, + RC_MK_GUARD_HOUSE_CHILD_POT_40, + RC_MK_GUARD_HOUSE_CHILD_POT_41, + RC_MK_GUARD_HOUSE_CHILD_POT_42, + RC_MK_GUARD_HOUSE_CHILD_POT_43, + RC_MK_GUARD_HOUSE_CHILD_POT_44, + RC_MK_GUARD_HOUSE_ADULT_POT_1, + RC_MK_GUARD_HOUSE_ADULT_POT_2, + RC_MK_GUARD_HOUSE_ADULT_POT_3, + RC_MK_GUARD_HOUSE_ADULT_POT_4, + RC_MK_GUARD_HOUSE_ADULT_POT_5, + RC_MK_GUARD_HOUSE_ADULT_POT_6, + RC_MK_GUARD_HOUSE_ADULT_POT_7, + RC_MK_GUARD_HOUSE_ADULT_POT_8, + RC_MK_GUARD_HOUSE_ADULT_POT_9, + RC_MK_GUARD_HOUSE_ADULT_POT_10, + RC_MK_GUARD_HOUSE_ADULT_POT_11, + RC_MK_BACK_ALLEY_HOUSE_POT_1, + RC_MK_BACK_ALLEY_HOUSE_POT_2, + RC_MK_BACK_ALLEY_HOUSE_POT_3, + RC_HC_STORMS_GROTTO_POT_1, + RC_HC_STORMS_GROTTO_POT_2, + RC_HC_STORMS_GROTTO_POT_3, + RC_HC_STORMS_GROTTO_POT_4, + RC_LLR_FRONT_POT_1, + RC_LLR_FRONT_POT_2, + RC_LLR_FRONT_POT_3, + RC_LLR_FRONT_POT_4, + RC_LLR_RAIN_SHED_POT_1, + RC_LLR_RAIN_SHED_POT_2, + RC_LLR_RAIN_SHED_POT_3, + RC_LLR_TALONS_HOUSE_POT_1, + RC_LLR_TALONS_HOUSE_POT_2, + RC_LLR_TALONS_HOUSE_POT_3, + RC_KAK_NEAR_POTION_SHOP_POT_1, + RC_KAK_NEAR_POTION_SHOP_POT_2, + RC_KAK_NEAR_POTION_SHOP_POT_3, + RC_KAK_NEAR_IMPAS_HOUSE_POT_1, + RC_KAK_NEAR_IMPAS_HOUSE_POT_2, + RC_KAK_NEAR_IMPAS_HOUSE_POT_3, + RC_KAK_NEAR_GUARDS_HOUSE_POT_1, + RC_KAK_NEAR_GUARDS_HOUSE_POT_2, + RC_KAK_NEAR_GUARDS_HOUSE_POT_3, + RC_KAK_NEAR_MEDICINE_SHOP_POT_1, + RC_KAK_NEAR_MEDICINE_SHOP_POT_2, + RC_GY_DAMPES_GRAVE_POT_1, + RC_GY_DAMPES_GRAVE_POT_2, + RC_GY_DAMPES_GRAVE_POT_3, + RC_GY_DAMPES_GRAVE_POT_4, + RC_GY_DAMPES_GRAVE_POT_5, + RC_GY_DAMPES_GRAVE_POT_6, + RC_GC_LOWER_STAIRCASE_POT_1, + RC_GC_LOWER_STAIRCASE_POT_2, + RC_GC_UPPER_STAIRCASE_POT_1, + RC_GC_UPPER_STAIRCASE_POT_2, + RC_GC_UPPER_STAIRCASE_POT_3, + RC_GC_MEDIGORON_POT_1, + RC_GC_DARUNIA_POT_1, + RC_GC_DARUNIA_POT_2, + RC_GC_DARUNIA_POT_3, + RC_DMC_NEAR_GC_POT_1, + RC_DMC_NEAR_GC_POT_2, + RC_DMC_NEAR_GC_POT_3, + RC_DMC_NEAR_GC_POT_4, + RC_ZD_NEAR_SHOP_POT_1, + RC_ZD_NEAR_SHOP_POT_2, + RC_ZD_NEAR_SHOP_POT_3, + RC_ZD_NEAR_SHOP_POT_4, + RC_ZD_NEAR_SHOP_POT_5, + RC_ZF_HIDDEN_CAVE_POT_1, + RC_ZF_HIDDEN_CAVE_POT_2, + RC_ZF_HIDDEN_CAVE_POT_3, + RC_ZF_NEAR_JABU_POT_1, + RC_ZF_NEAR_JABU_POT_2, + RC_ZF_NEAR_JABU_POT_3, + RC_ZF_NEAR_JABU_POT_4, + + // Dungeon Pots + RC_DODONGOS_CAVERN_LIZALFOS_POT_1, + RC_DODONGOS_CAVERN_LIZALFOS_POT_2, + RC_DODONGOS_CAVERN_LIZALFOS_POT_3, + RC_DODONGOS_CAVERN_LIZALFOS_POT_4, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_4, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_5, + RC_DODONGOS_CAVERN_SIDE_ROOM_POT_6, + RC_DODONGOS_CAVERN_TORCH_ROOM_POT_1, + RC_DODONGOS_CAVERN_TORCH_ROOM_POT_2, + RC_DODONGOS_CAVERN_TORCH_ROOM_POT_3, + RC_DODONGOS_CAVERN_TORCH_ROOM_POT_4, + RC_DODONGOS_CAVERN_STAIRCASE_POT_1, + RC_DODONGOS_CAVERN_STAIRCASE_POT_2, + RC_DODONGOS_CAVERN_STAIRCASE_POT_3, + RC_DODONGOS_CAVERN_STAIRCASE_POT_4, + RC_DODONGOS_CAVERN_SINGLE_EYE_POT_1, + RC_DODONGOS_CAVERN_SINGLE_EYE_POT_2, + RC_DODONGOS_CAVERN_BLADE_POT_1, + RC_DODONGOS_CAVERN_BLADE_POT_2, + RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, + RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, + RC_DODONGOS_CAVERN_BACK_ROOM_POT_1, + RC_DODONGOS_CAVERN_BACK_ROOM_POT_2, + RC_DODONGOS_CAVERN_BACK_ROOM_POT_3, + RC_DODONGOS_CAVERN_BACK_ROOM_POT_4, + RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, + RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, + RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, + RC_JABU_JABUS_BELLY_BARINADE_POT_1, + RC_JABU_JABUS_BELLY_BARINADE_POT_2, + RC_JABU_JABUS_BELLY_BARINADE_POT_3, + RC_JABU_JABUS_BELLY_BARINADE_POT_4, + RC_JABU_JABUS_BELLY_BARINADE_POT_5, + RC_JABU_JABUS_BELLY_BARINADE_POT_6, + RC_JABU_JABUS_BELLY_BASEMENT_POT_1, + RC_JABU_JABUS_BELLY_BASEMENT_POT_2, + RC_JABU_JABUS_BELLY_BASEMENT_POT_3, + RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, + RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, + RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, + RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, + RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, + RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, + RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, + RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, + RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, + RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, + RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, + RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, + RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, + RC_FOREST_TEMPLE_LOBBY_POT_1, + RC_FOREST_TEMPLE_LOBBY_POT_2, + RC_FOREST_TEMPLE_LOBBY_POT_3, + RC_FOREST_TEMPLE_LOBBY_POT_4, + RC_FOREST_TEMPLE_LOBBY_POT_5, + RC_FOREST_TEMPLE_LOBBY_POT_6, + RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, + RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, + RC_FOREST_TEMPLE_GREEN_POE_POT_1, + RC_FOREST_TEMPLE_GREEN_POE_POT_2, + RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, + RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, + RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, + RC_FOREST_TEMPLE_UPPER_STALFOS_POT_4, + RC_FOREST_TEMPLE_BLUE_POE_POT_1, + RC_FOREST_TEMPLE_BLUE_POE_POT_2, + RC_FOREST_TEMPLE_BLUE_POE_POT_3, + RC_FOREST_TEMPLE_FROZEN_EYE_POT_1, + RC_FOREST_TEMPLE_FROZEN_EYE_POT_2, + RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, + RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, + RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, + RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, + RC_FIRE_TEMPLE_BIG_LAVA_POT_1, + RC_FIRE_TEMPLE_BIG_LAVA_POT_2, + RC_FIRE_TEMPLE_BIG_LAVA_POT_3, + RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, + RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, + RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, + RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, + RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, + RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, + RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, + RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, + RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, + RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, + RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, + RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, + RC_WATER_TEMPLE_TORCH_POT_1, + RC_WATER_TEMPLE_TORCH_POT_2, + RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, + RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, + RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, + RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, + RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, + RC_WATER_TEMPLE_BEHIND_GATE_POT_1, + RC_WATER_TEMPLE_BEHIND_GATE_POT_2, + RC_WATER_TEMPLE_BEHIND_GATE_POT_3, + RC_WATER_TEMPLE_BEHIND_GATE_POT_4, + RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, + RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, + RC_WATER_TEMPLE_RIVER_POT_1, + RC_WATER_TEMPLE_RIVER_POT_2, + RC_WATER_TEMPLE_LIKE_LIKE_POT_1, + RC_WATER_TEMPLE_LIKE_LIKE_POT_2, + RC_WATER_TEMPLE_BOSS_KEY_POT_1, + RC_WATER_TEMPLE_BOSS_KEY_POT_2, + RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, + RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, + RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, + RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, + RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, + RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, + RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, + RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, + RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, + RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, + RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, + RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, + RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, + RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, + RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, + RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, + RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, + RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, + RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, + RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, + RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, + RC_SPIRIT_TEMPLE_LOBBY_POT_1, + RC_SPIRIT_TEMPLE_LOBBY_POT_2, + RC_SPIRIT_TEMPLE_ANUBIS_POT_1, + RC_SPIRIT_TEMPLE_ANUBIS_POT_2, + RC_SPIRIT_TEMPLE_ANUBIS_POT_3, + RC_SPIRIT_TEMPLE_ANUBIS_POT_4, + RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, + RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, + RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, + RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, + RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, + RC_ICE_CAVERN_HALL_POT_1, + RC_ICE_CAVERN_HALL_POT_2, + RC_ICE_CAVERN_SPINNING_BLADE_POT_1, + RC_ICE_CAVERN_SPINNING_BLADE_POT_2, + RC_ICE_CAVERN_SPINNING_BLADE_POT_3, + RC_ICE_CAVERN_NEAR_END_POT_1, + RC_ICE_CAVERN_NEAR_END_POT_2, + RC_ICE_CAVERN_FROZEN_POT_1, + RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, + RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, + RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, + RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, + RC_GANONS_CASTLE_WATER_TRIAL_POT_1, + RC_GANONS_CASTLE_WATER_TRIAL_POT_2, + RC_GANONS_CASTLE_WATER_TRIAL_POT_3, + RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, + RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, + RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, + RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, + RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, + RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, + RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, + RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, + RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, + RC_GANONS_CASTLE_GANONS_TOWER_POT_1, + RC_GANONS_CASTLE_GANONS_TOWER_POT_2, + RC_GANONS_CASTLE_GANONS_TOWER_POT_3, + RC_GANONS_CASTLE_GANONS_TOWER_POT_4, + RC_GANONS_CASTLE_GANONS_TOWER_POT_5, + RC_GANONS_CASTLE_GANONS_TOWER_POT_6, + RC_GANONS_CASTLE_GANONS_TOWER_POT_7, + RC_GANONS_CASTLE_GANONS_TOWER_POT_8, + RC_GANONS_CASTLE_GANONS_TOWER_POT_9, + RC_GANONS_CASTLE_GANONS_TOWER_POT_10, + RC_GANONS_CASTLE_GANONS_TOWER_POT_11, + RC_GANONS_CASTLE_GANONS_TOWER_POT_12, + RC_GANONS_CASTLE_GANONS_TOWER_POT_13, + RC_GANONS_CASTLE_GANONS_TOWER_POT_14, + RC_GANONS_CASTLE_GANONS_TOWER_POT_15, + RC_GANONS_CASTLE_GANONS_TOWER_POT_16, + RC_GANONS_CASTLE_GANONS_TOWER_POT_17, + RC_GANONS_CASTLE_GANONS_TOWER_POT_18, + + // MQ Dungeon Pots + RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, + RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, + RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, + RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, + RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, + RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1, + RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2, + RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, + RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, + RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, + RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, + RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, + RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, + RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, + RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, + RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, + RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, + RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, + RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT, + RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT, + RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT, + RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SW_POT, + RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, + RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, + RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT, + RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT, + RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, + RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, + RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, + RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, + RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, + RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, + RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, + RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, + RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, + RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, + RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, + RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, + RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, + RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, + RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2, + RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_1, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_2, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_3, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_4, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_5, + RC_FOREST_TEMPLE_MQ_LOBBY_POT_6, + RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, + RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, + RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, + RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, + RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, + RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, + RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, + RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, + RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, + RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, + RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, + RC_FOREST_TEMPLE_MQ_BASEMENT_POT_1, + RC_FOREST_TEMPLE_MQ_BASEMENT_POT_2, + RC_FOREST_TEMPLE_MQ_BASEMENT_POT_3, + RC_FOREST_TEMPLE_MQ_BASEMENT_POT_4, + RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, + RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, + RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, + RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, + RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, + RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, + RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, + RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, + RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, + RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, + RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, + RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, + RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, + RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, + RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, + RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT, + RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT, + RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, + RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_WEST_POT, + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SOUTH_POT, + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SE_POT, + RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_SOUTH_POT, + RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_NORTH_POT, + RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, + RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, + RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, + RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, + RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, + RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, + RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, + RC_WATER_TEMPLE_MQ_RIVER_POT_1, + RC_WATER_TEMPLE_MQ_RIVER_POT_2, + RC_WATER_TEMPLE_MQ_BOSS_KEY_POT, + RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, + RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, + RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, + RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, + RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, + RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, + RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, + RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, + RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, + RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, + RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, + RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, + RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, + RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, + RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, + RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, + RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, + RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, + RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, + RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, + RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, + RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, + RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, + RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, + RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, + RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, + RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, + RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, + RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, + RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, + RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, + RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, + RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, + RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, + RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, + RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, + RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, + RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, + RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, + RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, + RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, + RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, + RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, + RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, + RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, + RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, + RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, + RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, + RC_ICE_CAVERN_MQ_ENTRANCE_POT, + RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, + RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, + RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, + RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, + RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, + RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, + RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, + RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, + RC_ICE_CAVERN_MQ_COMPASS_POT_1, + RC_ICE_CAVERN_MQ_COMPASS_POT_2, + RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, + RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, + RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, + RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, + RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, + RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, + // End Pots + RC_PIERRE, RC_DELIVER_RUTOS_LETTER, RC_MASTER_SWORD_PEDESTAL, @@ -1741,6 +2410,417 @@ typedef enum { RC_ZD_FISH_3, RC_ZD_FISH_4, RC_ZD_FISH_5, + RC_KF_BOULDER_RUPEE_1, + RC_KF_BOULDER_RUPEE_2, + RC_KF_BRIDGE_RUPEE, + RC_KF_BEHIND_MIDOS_RUPEE, + RC_KF_SARIAS_ROOF_WEST_HEART, + RC_KF_SARIAS_ROOF_EAST_HEART, + RC_KF_SARIAS_ROOF_NORTH_HEART, + RC_KF_SOUTH_GRASS_WEST_RUPEE, + RC_KF_NORTH_GRASS_WEST_RUPEE, + RC_KF_NORTH_GRASS_EAST_RUPEE, + RC_KF_SOUTH_GRASS_EAST_RUPEE, + RC_KF_SARIAS_TOP_LEFT_HEART, + RC_KF_SARIAS_TOP_RIGHT_HEART, + RC_KF_SARIAS_BOTTOM_LEFT_HEART, + RC_KF_SARIAS_BOTTOM_RIGHT_HEART, + RC_KF_BEAN_RUPEE_1, + RC_KF_BEAN_RUPEE_2, + RC_KF_BEAN_RUPEE_3, + RC_KF_BEAN_RUPEE_4, + RC_KF_BEAN_RUPEE_5, + RC_KF_BEAN_RUPEE_6, + RC_KF_BEAN_RED_RUPEE, + RC_LW_BOULDER_RUPEE, + RC_LW_SHORTCUT_RUPEE_1, + RC_LW_SHORTCUT_RUPEE_2, + RC_LW_SHORTCUT_RUPEE_3, + RC_LW_SHORTCUT_RUPEE_4, + RC_LW_SHORTCUT_RUPEE_5, + RC_LW_SHORTCUT_RUPEE_6, + RC_LW_SHORTCUT_RUPEE_7, + RC_LW_SHORTCUT_RUPEE_8, + RC_LH_FRONT_RUPEE, + RC_LH_MIDDLE_RUPEE, + RC_LH_BACK_RUPEE, + RC_LH_LAB_FRONT_RUPEE, + RC_LH_LAB_LEFT_RUPEE, + RC_LH_LAB_RIGHT_RUPEE, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_1, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_2, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_3, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_4, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_5, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_6, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_7, + RC_GRAVEYARD_DAMPE_RACE_RUPEE_8, + RC_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, + RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, + RC_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, + RC_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, + RC_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, + RC_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, + RC_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, + RC_GV_OCTOROK_GROTTO_RED_RUPEE, + RC_DMT_BLUE_RUPEE, + RC_DMT_RED_RUPEE, + RC_DMT_COW_GROTTO_LEFT_HEART, + RC_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, + RC_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, + RC_DMT_COW_GROTTO_RIGHT_HEART, + RC_DMT_COW_GROTTO_RUPEE_1, + RC_DMT_COW_GROTTO_RUPEE_2, + RC_DMT_COW_GROTTO_RUPEE_3, + RC_DMT_COW_GROTTO_RUPEE_4, + RC_DMT_COW_GROTTO_RUPEE_5, + RC_DMT_COW_GROTTO_RUPEE_6, + RC_DMT_COW_GROTTO_RED_RUPEE, + RC_DMC_NEAR_PLATFORM_RED_RUPEE, + RC_DMC_MIDDLE_PLATFORM_RED_RUPEE, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, + RC_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, + RC_DMC_DISTANT_PLATFORM_RED_RUPEE, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_1, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_2, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_3, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_4, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_5, + RC_DMC_DISTANT_PLATFORM_GREEN_RUPEE_6, + RC_ZR_BENEATH_WATERFALL_LEFT_RUPEE, + RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, + RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, + RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, + RC_ZF_BOTTOM_NORTH_INNER_RUPEE, + RC_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, + RC_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, + RC_ZF_BOTTOM_SOUTH_INNER_RUPEE, + RC_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, + RC_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, + RC_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, + RC_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, + RC_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, + RC_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, + RC_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, + RC_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, + RC_ZF_BOTTOM_NORTH_OUTER_RUPEE, + RC_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, + RC_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, + RC_ZF_BOTTOM_SOUTH_OUTER_RUPEE, + RC_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, + RC_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, + RC_DEKU_TREE_LOBBY_LOWER_HEART, + RC_DEKU_TREE_LOBBY_UPPER_HEART, + RC_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, + RC_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, + RC_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, + RC_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, + RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, + RC_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, + RC_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, + RC_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, + RC_FOREST_TEMPLE_COURTYARD_LEFT_HEART, + RC_FOREST_TEMPLE_WELL_WEST_HEART, + RC_FOREST_TEMPLE_WELL_EAST_HEART, + RC_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, + RC_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, + RC_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, + RC_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, + RC_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, + RC_WATER_TEMPLE_RIVER_HEART_1, + RC_WATER_TEMPLE_RIVER_HEART_2, + RC_WATER_TEMPLE_RIVER_HEART_3, + RC_WATER_TEMPLE_RIVER_HEART_4, + RC_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, + RC_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, + RC_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, + RC_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, + RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, + RC_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, + RC_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, + RC_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, + RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, + RC_ICE_CAVERN_LOBBY_RUPEE, + RC_ICE_CAVERN_MAP_ROOM_LEFT_HEART, + RC_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, + RC_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, + RC_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, + RC_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, + RC_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, + RC_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, + RC_GANONS_CASTLE_FIRE_TRIAL_HEART, + RC_GANONS_CASTLE_SPIRIT_TRIAL_HEART, + RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, + RC_DEKU_TREE_MQ_DEKU_BABA_HEART, + RC_DEKU_TREE_MQ_LOBBY_HEART, + RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, + RC_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, + RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, + RC_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, + RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, + RC_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, + RC_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, + RC_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, + RC_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, + RC_FOREST_TEMPLE_MQ_WELL_WEST_HEART, + RC_FOREST_TEMPLE_MQ_WELL_MIDDLE_HEART, + RC_FOREST_TEMPLE_MQ_WELL_EAST_HEART, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, + RC_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, + RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, + RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, + RC_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, + RC_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, + RC_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, + RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, + RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, + RC_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, + RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, + RC_SFM_FAIRY_GROTTO_FAIRY_1, + RC_SFM_FAIRY_GROTTO_FAIRY_2, + RC_SFM_FAIRY_GROTTO_FAIRY_3, + RC_SFM_FAIRY_GROTTO_FAIRY_4, + RC_SFM_FAIRY_GROTTO_FAIRY_5, + RC_SFM_FAIRY_GROTTO_FAIRY_6, + RC_SFM_FAIRY_GROTTO_FAIRY_7, + RC_SFM_FAIRY_GROTTO_FAIRY_8, + RC_ZR_FAIRY_GROTTO_FAIRY_1, + RC_ZR_FAIRY_GROTTO_FAIRY_2, + RC_ZR_FAIRY_GROTTO_FAIRY_3, + RC_ZR_FAIRY_GROTTO_FAIRY_4, + RC_ZR_FAIRY_GROTTO_FAIRY_5, + RC_ZR_FAIRY_GROTTO_FAIRY_6, + RC_ZR_FAIRY_GROTTO_FAIRY_7, + RC_ZR_FAIRY_GROTTO_FAIRY_8, + RC_HF_FAIRY_GROTTO_FAIRY_1, + RC_HF_FAIRY_GROTTO_FAIRY_2, + RC_HF_FAIRY_GROTTO_FAIRY_3, + RC_HF_FAIRY_GROTTO_FAIRY_4, + RC_HF_FAIRY_GROTTO_FAIRY_5, + RC_HF_FAIRY_GROTTO_FAIRY_6, + RC_HF_FAIRY_GROTTO_FAIRY_7, + RC_HF_FAIRY_GROTTO_FAIRY_8, + RC_ZD_FAIRY_GROTTO_FAIRY_1, + RC_ZD_FAIRY_GROTTO_FAIRY_2, + RC_ZD_FAIRY_GROTTO_FAIRY_3, + RC_ZD_FAIRY_GROTTO_FAIRY_4, + RC_ZD_FAIRY_GROTTO_FAIRY_5, + RC_ZD_FAIRY_GROTTO_FAIRY_6, + RC_ZD_FAIRY_GROTTO_FAIRY_7, + RC_ZD_FAIRY_GROTTO_FAIRY_8, + RC_GF_FAIRY_GROTTO_FAIRY_1, + RC_GF_FAIRY_GROTTO_FAIRY_2, + RC_GF_FAIRY_GROTTO_FAIRY_3, + RC_GF_FAIRY_GROTTO_FAIRY_4, + RC_GF_FAIRY_GROTTO_FAIRY_5, + RC_GF_FAIRY_GROTTO_FAIRY_6, + RC_GF_FAIRY_GROTTO_FAIRY_7, + RC_GF_FAIRY_GROTTO_FAIRY_8, + RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, + RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, + RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, + RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, + RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, + RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, + RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, + RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, + RC_GANONS_CASTLE_SCRUBS_FAIRY_1, + RC_GANONS_CASTLE_SCRUBS_FAIRY_2, + RC_GANONS_CASTLE_SCRUBS_FAIRY_3, + RC_GANONS_CASTLE_SCRUBS_FAIRY_4, + RC_GANONS_CASTLE_SCRUBS_FAIRY_5, + RC_GANONS_CASTLE_SCRUBS_FAIRY_6, + RC_GANONS_CASTLE_SCRUBS_FAIRY_7, + RC_GANONS_CASTLE_SCRUBS_FAIRY_8, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, + RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, + RC_COLOSSUS_OASIS_FAIRY_1, + RC_COLOSSUS_OASIS_FAIRY_2, + RC_COLOSSUS_OASIS_FAIRY_3, + RC_COLOSSUS_OASIS_FAIRY_4, + RC_COLOSSUS_OASIS_FAIRY_5, + RC_COLOSSUS_OASIS_FAIRY_6, + RC_COLOSSUS_OASIS_FAIRY_7, + RC_COLOSSUS_OASIS_FAIRY_8, + RC_ZR_BEAN_SPROUT_FAIRY_1, + RC_ZR_BEAN_SPROUT_FAIRY_2, + RC_ZR_BEAN_SPROUT_FAIRY_3, + RC_KF_BEAN_SPROUT_FAIRY_1, + RC_KF_BEAN_SPROUT_FAIRY_2, + RC_KF_BEAN_SPROUT_FAIRY_3, + RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, + RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, + RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, + RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, + RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, + RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, + RC_LH_BEAN_SPROUT_FAIRY_1, + RC_LH_BEAN_SPROUT_FAIRY_2, + RC_LH_BEAN_SPROUT_FAIRY_3, + RC_GV_BEAN_SPROUT_FAIRY_1, + RC_GV_BEAN_SPROUT_FAIRY_2, + RC_GV_BEAN_SPROUT_FAIRY_3, + RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, + RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, + RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, + RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, + RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, + RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, + RC_DMC_BEAN_SPROUT_FAIRY_1, + RC_DMC_BEAN_SPROUT_FAIRY_2, + RC_DMC_BEAN_SPROUT_FAIRY_3, + RC_DMT_BEAN_SPROUT_FAIRY_1, + RC_DMT_BEAN_SPROUT_FAIRY_2, + RC_DMT_BEAN_SPROUT_FAIRY_3, + RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, + RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, + RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, + RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, + RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, + RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, + RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, + RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, + RC_DMC_GOSSIP_STONE_FAIRY, + RC_DMC_GOSSIP_STONE_FAIRY_BIG, + RC_DMT_GOSSIP_STONE_FAIRY, + RC_DMT_GOSSIP_STONE_FAIRY_BIG, + RC_COLOSSUS_GOSSIP_STONE_FAIRY, + RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, + RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, + RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, + RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, + RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, + RC_GV_GOSSIP_STONE_FAIRY, + RC_GV_GOSSIP_STONE_FAIRY_BIG, + RC_GC_MAZE_GOSSIP_STONE_FAIRY, + RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, + RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY, + RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, + RC_GRAVEYARD_GOSSIP_STONE_FAIRY, + RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, + RC_HC_MALON_GOSSIP_STONE_FAIRY, + RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, + RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, + RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, + RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, + RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, + RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, + RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, + RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, + RC_KF_GOSSIP_STONE_FAIRY, + RC_KF_GOSSIP_STONE_FAIRY_BIG, + RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, + RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_LH_LAB_GOSSIP_STONE_FAIRY, + RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG, + RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, + RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, + RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, + RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, + RC_LW_GOSSIP_STONE_FAIRY, + RC_LW_GOSSIP_STONE_FAIRY_BIG, + RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, + RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, + RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, + RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, + RC_SFM_SARIA_GOSSIP_STONE_FAIRY, + RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, + RC_ZD_GOSSIP_STONE_FAIRY, + RC_ZD_GOSSIP_STONE_FAIRY_BIG, + RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, + RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, + RC_ZF_JABU_GOSSIP_STONE_FAIRY, + RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, + RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, + RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, + RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, + RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, + RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, + RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, + RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, + RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, + RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, + RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, + RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, + RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, + RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, + RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RC_LH_ISLAND_SUN_FAIRY, + RC_HF_POND_STORMS_FAIRY, + RC_HF_FENCE_GROTTO_STORMS_FAIRY, + RC_DMT_FLAG_SUN_FAIRY, + RC_LW_SHORTCUT_STORMS_FAIRY, + RC_GF_KITCHEN_SUN_FAIRY, + RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, + RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, + RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, + RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, + RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, + RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, + RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, + RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, + RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, + RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, + RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, + RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, + RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, + RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, + RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, + RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, + RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, + RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, + RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, + RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, RC_MAX } RandomizerCheck; @@ -1796,12 +2876,14 @@ typedef enum { RT_ZR_CUCCO, RT_ZD_KING_ZORA_SKIP, RT_ZD_GS, + RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES, RT_LH_LAB_WALL_GS, RT_LH_LAB_DIVING, RT_LH_WATER_HOOKSHOT, RT_GV_CRATE_HOVERS, RT_GF_KITCHEN, RT_GF_JUMP, + RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON, RT_HW_BUNNY_CROSSING, RT_HW_CROSSING, RT_LENS_HW, @@ -1841,6 +2923,7 @@ typedef enum { RT_FOREST_OUTDOORS_LEDGE, RT_FOREST_DOORFRAME, RT_FOREST_OUTSIDE_BACKDOOR, + RT_FOREST_OUTDOORS_HEARTS_BOOMERANG, RT_FOREST_MQ_WELL_SWIM, RT_FOREST_MQ_BLOCK_PUZZLE, RT_FOREST_MQ_JS_HALLWAY_SWITCH, @@ -2116,7 +3199,7 @@ typedef enum { RG_SPIRIT_TEMPLE_SMALL_KEY, RG_SHADOW_TEMPLE_SMALL_KEY, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, - RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY, + RG_GERUDO_TRAINING_GROUND_SMALL_KEY, RG_GERUDO_FORTRESS_SMALL_KEY, RG_GANONS_CASTLE_SMALL_KEY, RG_TREASURE_GAME_SMALL_KEY, @@ -2126,7 +3209,7 @@ typedef enum { RG_SPIRIT_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_KEY_RING, RG_BOTTOM_OF_THE_WELL_KEY_RING, - RG_GERUDO_TRAINING_GROUNDS_KEY_RING, + RG_GERUDO_TRAINING_GROUND_KEY_RING, RG_GERUDO_FORTRESS_KEY_RING, RG_GANONS_CASTLE_KEY_RING, RG_KOKIRI_EMERALD, @@ -2521,6 +3604,35 @@ typedef enum { RHT_JUNK_SG_6, RHT_JUNK_SG_7, RHT_JUNK_SG_8, + RHT_JUNK_CREW_1, + RHT_JUNK_CREW_2, + RHT_JUNK_CREW_3, + RHT_JUNK_CREW_4, + RHT_JUNK_CREW_5, + RHT_JUNK_CREW_6, + RHT_JUNK_CREW_7, + RHT_JUNK_CREW_8, + RHT_JUNK_CREW_9, + RHT_JUNK_CREW_10, + RHT_JUNK_CREW_11, + RHT_JUNK_CREW_12, + RHT_JUNK_CREW_13, + RHT_JUNK_CREW_14, + RHT_JUNK_CREW_15, + RHT_JUNK_CREW_16, + RHT_JUNK_CREW_17, + RHT_JUNK_CREW_18, + RHT_JUNK_CREW_19, + RHT_JUNK_CREW_20, + RHT_JUNK_CREW_21, + RHT_JUNK_CREW_22, + RHT_JUNK_CREW_23, + RHT_JUNK_CREW_24, + RHT_JUNK_CREW_25, + RHT_JUNK_CREW_26, + RHT_JUNK_CREW_27, + RHT_JUNK_CREW_28, + RHT_JUNK_CREW_29, // Locations RHT_LINKS_POCKET, RHT_QUEEN_GOHMA, @@ -2531,6 +3643,7 @@ typedef enum { RHT_MORPHA, RHT_BONGO_BONGO, RHT_TWINROVA, + RHT_GIFT_FROM_RAURU, RHT_SONG_FROM_IMPA, RHT_SONG_FROM_MALON, RHT_SONG_FROM_SARIA, @@ -3360,7 +4473,7 @@ typedef enum { RHT_SPIRIT_TEMPLE_SMALL_KEY, RHT_SHADOW_TEMPLE_SMALL_KEY, RHT_BOTTOM_OF_THE_WELL_SMALL_KEY, - RHT_GERUDO_TRAINING_GROUNDS_SMALL_KEY, + RHT_GERUDO_TRAINING_GROUND_SMALL_KEY, RHT_GERUDO_FORTRESS_SMALL_KEY, RHT_GANONS_CASTLE_SMALL_KEY, RHT_TREASURE_GAME_SMALL_KEY, @@ -3370,7 +4483,7 @@ typedef enum { RHT_SPIRIT_TEMPLE_KEY_RING, RHT_SHADOW_TEMPLE_KEY_RING, RHT_BOTTOM_OF_THE_WELL_KEY_RING, - RHT_GERUDO_TRAINING_GROUNDS_KEY_RING, + RHT_GERUDO_TRAINING_GROUND_KEY_RING, RHT_GERUDO_FORTRESS_KEY_RING, RHT_GANONS_CASTLE_KEY_RING, RHT_KOKIRI_EMERALD, @@ -3513,7 +4626,7 @@ typedef enum { RHT_GV_FORTRESS_SIDE_TO_GV_CARPENTER_TENT, RHT_GRAVEYARD_WARP_PAD_REGION_TO_SHADOW_TEMPLE_ENTRYWAY, RHT_LAKE_HYLIA_TO_WATER_TEMPLE_LOBBY, - RHT_GERUDO_FORTRESS_TO_GERUDO_TRAINING_GROUNDS_LOBBY, + RHT_GERUDO_FORTRESS_TO_GERUDO_TRAINING_GROUND_LOBBY, RHT_ZORAS_FOUNTAIN_TO_JABU_JABUS_BELLY_BEGINNING, RHT_KAKARIKO_VILLAGE_TO_BOTTOM_OF_THE_WELL, // Exits @@ -3548,7 +4661,7 @@ typedef enum { RHT_KF_KNOW_IT_ALL_HOUSE, RHT_KF_KOKIRI_SHOP, RHT_LH_LAB, - RHT_LH_FISHING_HOLE, + RHT_LH_FISHING_POND, RHT_GV_CARPENTER_TENT, RHT_MARKET_GUARD_HOUSE, RHT_MARKET_MASK_SHOP, @@ -3704,6 +4817,31 @@ typedef enum { RHT_OOT_HINT, RHT_SKULLS_HINT, RHT_MASK_SHOP_HINT, + // Shuffle Pots + RHT_POT_KOKIRI_FOREST, + RHT_POT_GERUDO_FORTRESS, + RHT_POT_WASTELAND, + RHT_POT_MARKET, + RHT_POT_KAKARIKO, + RHT_POT_GRAVEYARD, + RHT_POT_GORON_CITY, + RHT_POT_DEATH_MOUNTAIN_CRATER, + RHT_POT_ZORAS_DOMAIN, + RHT_POT_ZORAS_FOUNTAIN, + RHT_POT_LON_LON_RANCH, + RHT_POT_HYRULE_FIELD, + RHT_POT_HYRULE_CASTLE, + RHT_POT_DODONGOS_CAVERN, + RHT_POT_JABU_JABUS_BELLY, + RHT_POT_FOREST_TEMPLE, + RHT_POT_FIRE_TEMPLE, + RHT_POT_WATER_TEMPLE, + RHT_POT_GERUDO_TRAINING_GROUND, + RHT_POT_SHADOW_TEMPLE, + RHT_POT_SPIRIT_TEMPLE, + RHT_POT_GANONS_CASTLE, + RHT_POT_BOTTOM_OF_THE_WELL, + RHT_POT_ICE_CAVERN, // Ganon Line RHT_GANON_JOKE01, RHT_GANON_JOKE02, @@ -3721,6 +4859,151 @@ typedef enum { RHT_ISOLATED_PLACE, RHT_DUNGEON_ORDINARY, RHT_DUNGEON_MASTERFUL, + // Shuffle Rupees & Hearts + RHT_KOKIRI_FOREST_RUPEE, + RHT_KOKIRI_FOREST_HEART, + RHT_SARIAS_HOUSE_HEART, + RHT_LOST_WOODS_RUPEE, + RHT_LOST_WOODS_SHORTCUT_RUPEE, + RHT_LAKE_HYLIA_RUPEE, + RHT_LABORATORY_RUPEE, + RHT_DAMPES_GRAVE_RUPEE, + RHT_GERUDO_VALLEY_GROTTO_RUPEE, + RHT_DEATH_MOUNTAIN_TRAIL_RUPEE, + RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_HEART, + RHT_DEATH_MOUNTAIN_TRAIL_GROTTO_RUPEE, + RHT_DEATH_MOUNTAIN_CRATER_RUPEE, + RHT_ZORAS_RIVER_WATERFALL_RUPEE, + RHT_ZORAS_FOUNTAIN_RUPEE, + RHT_DEKU_TREE_HEART, + RHT_DODONGOS_CAVERN_HEART, + RHT_JABU_JABU_RUPEE, + RHT_JABU_JABU_HEART, + RHT_FOREST_TEMPLE_HEART, + RHT_FIRE_TEMPLE_HEART, + RHT_WATER_TEMPLE_HEART, + RHT_SHADOW_TEMPLE_HEART, + RHT_SPIRIT_TEMPLE_HEART, + RHT_SPIRIT_TEMPLE_MQ_HEART, + RHT_BOTTOM_OF_THE_WELL_HEART, + RHT_BOTTOM_OF_THE_WELL_RUPEE, + RHT_ICE_CAVERN_HEART, + RHT_ICE_CAVERN_RUPEE, + RHT_GERUDO_TRAINING_GROUNDS_HEART, + RHT_GANONS_CASTLE_HEART, + // Fairy Shuffle + RHT_SFM_FAIRY_GROTTO_FAIRY, + RHT_ZR_FAIRY_GROTTO_FAIRY, + RHT_HF_FAIRY_GROTTO_FAIRY, + RHT_ZD_FAIRY_GROTTO_FAIRY, + RHT_GF_FAIRY_GROTTO_FAIRY, + RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, + RHT_GANONS_CASTLE_SCRUBS_FAIRY, + RHT_COLOSSUS_OASIS_FAIRY, + RHT_ZR_BEAN_SPROUT_FAIRY, + RHT_KF_BEAN_SPROUT_FAIRY, + RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, + RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, + RHT_LH_BEAN_SPROUT_FAIRY, + RHT_GV_BEAN_SPROUT_FAIRY, + RHT_COLOSSUS_BEAN_SPROUT_FAIRY, + RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, + RHT_DMC_BEAN_SPROUT_FAIRY, + RHT_DMT_BEAN_SPROUT_FAIRY, + RHT_TOT_GOSSIP_STONE_FAIRY, + RHT_TOT_GOSSIP_STONE_FAIRY_BIG, + RHT_DMC_GOSSIP_STONE_FAIRY, + RHT_DMC_GOSSIP_STONE_FAIRY_BIG, + RHT_DMT_GOSSIP_STONE_FAIRY, + RHT_DMT_GOSSIP_STONE_FAIRY_BIG, + RHT_COLOSSUS_GOSSIP_STONE_FAIRY, + RHT_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, + RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, + RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, + RHT_GV_GOSSIP_STONE_FAIRY, + RHT_GV_GOSSIP_STONE_FAIRY_BIG, + RHT_GC_MAZE_GOSSIP_STONE_FAIRY, + RHT_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, + RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY, + RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, + RHT_GRAVEYARD_GOSSIP_STONE_FAIRY, + RHT_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, + RHT_HC_MALON_GOSSIP_STONE_FAIRY, + RHT_HC_MALON_GOSSIP_STONE_FAIRY_BIG, + RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, + RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, + RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, + RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, + RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, + RHT_KF_GOSSIP_STONE_FAIRY, + RHT_KF_GOSSIP_STONE_FAIRY_BIG, + RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, + RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_LH_LAB_GOSSIP_STONE_FAIRY, + RHT_LH_LAB_GOSSIP_STONE_FAIRY_BIG, + RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, + RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, + RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, + RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, + RHT_LW_GOSSIP_STONE_FAIRY, + RHT_LW_GOSSIP_STONE_FAIRY_BIG, + RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, + RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, + RHT_SFM_SARIA_GOSSIP_STONE_FAIRY, + RHT_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, + RHT_ZD_GOSSIP_STONE_FAIRY, + RHT_ZD_GOSSIP_STONE_FAIRY_BIG, + RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY, + RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, + RHT_ZF_JABU_GOSSIP_STONE_FAIRY, + RHT_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, + RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, + RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, + RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, + RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, + RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, + RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, + RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, + RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, + RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, + RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, + RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, + RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, + RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, + RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RHT_LH_ISLAND_SUN_FAIRY, + RHT_HF_POND_STORMS_FAIRY, + RHT_HF_FENCE_GROTTO_STORMS_FAIRY, + RHT_DMT_FLAG_SUN_FAIRY, + RHT_LW_SHORTCUT_STORMS_FAIRY, + RHT_GF_KITCHEN_SUN_FAIRY, + RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, + RHT_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, + RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, + RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, + RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, + RHT_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, + RHT_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, + RHT_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, + RHT_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, + RHT_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, + RHT_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, + RHT_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, + RHT_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, + RHT_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, + RHT_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, + RHT_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, + RHT_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, + // MAX RHT_MAX } RandomizerHintTextKey; @@ -3761,7 +5044,7 @@ typedef enum { RSG_EXCLUDES_GERUDO_FORTRESS, RSG_EXCLUDES_HAUNTED_WASTELAND, RSG_EXCLUDES_DESERT_COLOSSUS, - RSG_EXCLUDES_GERUDO_TRAINING_GROUNDS, + RSG_EXCLUDES_GERUDO_TRAINING_GROUND, RSG_EXCLUDES_SPIRIT_TEMPLE, RSG_EXCLUDES_HYRULE_CASTLE, RSG_EXCLUDES_MARKET, @@ -3812,6 +5095,7 @@ typedef enum { RSK_KAK_GATE, RSK_DOOR_OF_TIME, RSK_ZORAS_FOUNTAIN, + RSK_SLEEPING_WATERFALL, RSK_STARTING_AGE, RSK_GERUDO_FORTRESS, RSK_RAINBOW_BRIDGE, @@ -3876,6 +5160,7 @@ typedef enum { RSK_SHUFFLE_COWS, RSK_SHUFFLE_WEIRD_EGG, RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, + RSK_SHUFFLE_POTS, RSK_SHUFFLE_FROG_SONG_RUPEES, RSK_ITEM_POOL, RSK_ICE_TRAPS, @@ -3914,7 +5199,8 @@ typedef enum { RSK_GANONS_BOSS_KEY, RSK_SKIP_CHILD_STEALTH, RSK_SKIP_CHILD_ZELDA, - RSK_STARTING_CONSUMABLES, + RSK_STARTING_STICKS, + RSK_STARTING_NUTS, RSK_FULL_WALLETS, RSK_SHUFFLE_CHEST_MINIGAME, RSK_CUCCO_COUNT, @@ -4006,6 +5292,8 @@ typedef enum { RSK_SKELETON_KEY, RSK_SHUFFLE_DEKU_STICK_BAG, RSK_SHUFFLE_DEKU_NUT_BAG, + RSK_SHUFFLE_FREESTANDING, + RSK_SHUFFLE_FAIRIES, RSK_MAX } RandomizerSettingKey; @@ -4028,11 +5316,11 @@ typedef enum { RO_GENERIC_SKIP, } RandoOptionGenericSkip; -//Forest settings (closed, closed deku, open) +//Closed Forest settings (On, Deku Only, Off) typedef enum { - RO_FOREST_CLOSED, - RO_FOREST_CLOSED_DEKU, - RO_FOREST_OPEN, + RO_CLOSED_FOREST_ON, + RO_CLOSED_FOREST_DEKU_ONLY, + RO_CLOSED_FOREST_OFF, } RandoOptionForest; //Door of Time settings (closed, song only, open) @@ -4049,6 +5337,12 @@ typedef enum { RO_ZF_OPEN, } RandoOptionZorasFountain; +//Sleeping Waterfall settings (closed, open) +typedef enum { + RO_WATERFALL_CLOSED, + RO_WATERFALL_OPEN, +} RandoOptionSleepingWaterfall; + //Starting Age settings (child, adult, random) typedef enum { RO_AGE_CHILD, @@ -4056,11 +5350,11 @@ typedef enum { RO_AGE_RANDOM, } RandoOptionStartingAge; -//Gerudo Fortress settings (normal, fast, open) +//Fortress Carpenters settings (normal, fast, free) typedef enum { - RO_GF_NORMAL, - RO_GF_FAST, - RO_GF_OPEN, + RO_GF_CARPENTERS_NORMAL, + RO_GF_CARPENTERS_FAST, + RO_GF_CARPENTERS_FREE, } RandoOptionGerudoFortress; //Kakariko Gate settings (closed/open) @@ -4330,6 +5624,22 @@ typedef enum { RO_TOKENSANITY_ALL, } RandoOptionTokensanity; +//Freestanding Hearts/Rupees settings (off, dungeons, overworld, all) +typedef enum { + RO_SHUFFLE_FREESTANDING_OFF, + RO_SHUFFLE_FREESTANDING_DUNGEONS, + RO_SHUFFLE_FREESTANDING_OVERWORLD, + RO_SHUFFLE_FREESTANDING_ALL, +} RandoOptionFreestanding; + +// Shuffle Pots settings (off, dungeons, overworld, all) +typedef enum { + RO_SHUFFLE_POTS_OFF, + RO_SHUFFLE_POTS_DUNGEONS, + RO_SHUFFLE_POTS_OVERWORLD, + RO_SHUFFLE_POTS_ALL, +} RandoOptionShufflePots; + //Link's Pocket Settings (dungeon reward, advancement, anything, nothing) typedef enum { RO_LINKS_POCKET_DUNGEON_REWARD, @@ -4416,6 +5726,11 @@ typedef struct CowIdentity { RandomizerCheck randomizerCheck; } CowIdentity; +typedef struct PotIdentity { + RandomizerInf randomizerInf; + RandomizerCheck randomizerCheck; +} PotIdentity; + typedef struct FishIdentity { RandomizerInf randomizerInf; RandomizerCheck randomizerCheck; @@ -4482,13 +5797,88 @@ typedef enum { RE_GREEN_BUBBLE, RE_DINOLFOS, RE_TORCH_SLUG, + RE_FREEZARD, + RE_SPIKE, + RE_WHITE_WOLFOS, + RE_STINGER, + RE_BIG_OCTO, + RE_GERUDO_WARRIOR, + RE_GIBDO, + RE_GANONDORF, + RE_GANON, + RE_DARK_LINK, + RE_ANUBIS, + RE_BEAMOS, + RE_WALLMASTER, + RE_PURPLE_LEEVER, + RE_TENTACLE, + RE_BARI, + RE_SHABOM, + RE_OCTOROK, } RandomizerEnemy; +//RANDOTODO compare child long jumpslash range with adult short typedef enum { ED_CLOSE, - ED_HAMMER_JUMPSLASH, + //hammer or kokiri sword + ED_SHORT_JUMPSLASH, ED_MASTER_SWORD_JUMPSLASH, - ED_RANG_OR_HOOKSHOT, + //sticks or BGS + ED_LONG_JUMPSLASH, + ED_BOMB_THROW, + ED_BOOMERANG, + ED_HOOKSHOT, ED_LONGSHOT, ED_FAR, } EnemyDistance; + +typedef enum { + WL_LOW, + WL_MID, + WL_HIGH, + WL_LOW_OR_MID, + WL_HIGH_OR_MID +} RandoWaterLevel; + +#define ENTRANCE_GROTTO_LOAD_START 0x0700 +#define ENTRANCE_GROTTO_EXIT_START 0x0800 + +#define ENTRANCE_GROTTO_LOAD(index) ENTRANCE_GROTTO_LOAD_START + index +#define ENTRANCE_GROTTO_EXIT(index) ENTRANCE_GROTTO_EXIT_START + index + +typedef enum { + /* 0x00 */ GROTTO_COLOSSUS_OFFSET, + /* 0x01 */ GROTTO_LH_OFFSET, + /* 0x02 */ GROTTO_ZR_STORMS_OFFSET, + /* 0x03 */ GROTTO_ZR_FAIRY_OFFSET, + /* 0x04 */ GROTTO_ZR_OPEN_OFFSET, + /* 0x05 */ GROTTO_DMC_HAMMER_OFFSET, + /* 0x06 */ GROTTO_DMC_UPPER_OFFSET, + /* 0x07 */ GROTTO_GORON_CITY_OFFSET, + /* 0x08 */ GROTTO_DMT_STORMS_OFFSET, + /* 0x09 */ GROTTO_DMT_COW_OFFSET, + /* 0x0A */ GROTTO_KAK_OPEN_OFFSET, + /* 0x0B */ GROTTO_KAK_REDEAD_OFFSET, + /* 0x0C */ GROTTO_HC_STORMS_OFFSET, + /* 0x0D */ GROTTO_HF_TEKTITE_OFFSET, + /* 0x0E */ GROTTO_HF_NEAR_KAK_OFFSET, + /* 0x0F */ GROTTO_HF_FAIRY_OFFSET, + /* 0x10 */ GROTTO_HF_NEAR_MARKET_OFFSET, + /* 0x11 */ GROTTO_HF_COW_OFFSET, + /* 0x12 */ GROTTO_HF_INSIDE_FENCE_OFFSET, + /* 0x13 */ GROTTO_HF_OPEN_OFFSET, + /* 0x14 */ GROTTO_HF_SOUTHEAST_OFFSET, + /* 0x15 */ GROTTO_LLR_OFFSET, + /* 0x16 */ GROTTO_SFM_WOLFOS_OFFSET, + /* 0x17 */ GROTTO_SFM_STORMS_OFFSET, + /* 0x18 */ GROTTO_SFM_FAIRY_OFFSET, + /* 0x19 */ GROTTO_LW_SCRUBS_OFFSET, + /* 0x1A */ GROTTO_LW_NEAR_SHORTCUTS_OFFSET, + /* 0x1B */ GROTTO_KF_STORMS_OFFSET, + /* 0x1C */ GROTTO_ZD_STORMS_OFFSET, + /* 0x1D */ GROTTO_GF_STORMS_OFFSET, + /* 0x1E */ GROTTO_GV_STORMS_OFFSET, + /* 0x1F */ GROTTO_GV_OCTOROK_OFFSET, + /* 0x20 */ GROTTO_LW_DEKU_THEATRE_OFFSET, + /* 0x21 */ GROTTO_OFFSET_MAX, +} GrottoEntranceOffsets; diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 4e50edddd..b8d435fd8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -6,6 +6,7 @@ #include #include "z64.h" #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" #include "fishsanity.h" std::map rcAreaNames = { @@ -39,7 +40,7 @@ std::map rcAreaNames = { { RCAREA_SHADOW_TEMPLE, "Shadow Temple" }, { RCAREA_BOTTOM_OF_THE_WELL, "Bottom of the Well" }, { RCAREA_ICE_CAVERN, "Ice Cavern" }, - { RCAREA_GERUDO_TRAINING_GROUND, "Gerudo Training Grounds" }, + { RCAREA_GERUDO_TRAINING_GROUND, "Gerudo Training Ground" }, { RCAREA_GANONS_CASTLE, "Ganon's Castle" }, { RCAREA_INVALID, "Invalid" }, }; @@ -110,7 +111,7 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { auto itemLoc = ctx->GetItemLocation(location.GetRandomizerCheck()); itemLoc->SetVisible( (location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) && - (!RandomizerCheckObjects::AreaIsDungeon(location.GetArea()) || location.GetQuest() == RCQUEST_BOTH || + (location.GetQuest() == RCQUEST_BOTH || location.GetQuest() == RCQUEST_MQ && ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) == RO_MQ_DUNGEONS_SET_NUMBER && (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeonCount"), 12) > 0) || // at least one MQ dungeon @@ -162,8 +163,15 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { RandomizerCheckObjects::AreaIsOverworld(location.GetArea())) || ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF) == RO_TOKENSANITY_DUNGEONS) && RandomizerCheckObjects::AreaIsDungeon(location.GetArea()))) && + (location.GetRCType() != RCTYPE_FREESTANDING || + (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == RO_SHUFFLE_FREESTANDING_ALL) || + ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == RO_SHUFFLE_FREESTANDING_OVERWORLD) && + RandomizerCheckObjects::AreaIsOverworld(location.GetArea())) || + ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == RO_SHUFFLE_FREESTANDING_DUNGEONS) && + RandomizerCheckObjects::AreaIsDungeon(location.GetArea()))) && (location.GetRCType() != RCTYPE_BEEHIVE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_COW || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCows"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_POT || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShufflePots"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_FISH || ctx->GetFishsanity()->GetFishLocationIncluded(&location, FSO_SOURCE_CVARS)) && (location.GetRCType() != RCTYPE_ADULT_TRADE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), RO_GENERIC_NO)) && @@ -177,6 +185,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), RO_GENERIC_NO)) && (location.GetRCType() != RCTYPE_FROG_SONG || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_FAIRY || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFairies"), RO_GENERIC_NO)) && ((location.GetRCType() != RCTYPE_MAP && location.GetRCType() != RCTYPE_COMPASS) || CVarGetInteger(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) != RO_DUNGEON_ITEM_LOC_VANILLA) && @@ -205,14 +215,14 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) != RO_GANON_BOSS_KEY_KAK_TOKENS) && // 100 skull reward ganon boss key (location.GetRCType() != RCTYPE_GF_KEY && location.GetRandomizerCheck() != RC_GF_GERUDO_MEMBERSHIP_CARD || - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) == RO_GF_OPEN && + (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == RO_GF_CARPENTERS_FREE && location.GetRCType() != RCTYPE_GF_KEY && location.GetRandomizerCheck() != RC_GF_GERUDO_MEMBERSHIP_CARD) || - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) == RO_GF_FAST && + (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == RO_GF_CARPENTERS_FAST && ((location.GetRandomizerCheck() == RC_GF_GERUDO_MEMBERSHIP_CARD && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), RO_GENERIC_NO) == RO_GENERIC_YES) || (location.GetRandomizerCheck() == RC_GF_NORTH_F1_CARPENTER && CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) != RO_GERUDO_KEYS_VANILLA))) || - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) == RO_GF_NORMAL && + (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == RO_GF_CARPENTERS_NORMAL && ((location.GetRandomizerCheck() == RC_GF_GERUDO_MEMBERSHIP_CARD && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), RO_GENERIC_NO) == RO_GENERIC_YES) || (location.GetRCType() == RCTYPE_GF_KEY && diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.h b/soh/soh/Enhancements/randomizer/randomizer_check_objects.h index bf9cc98f7..6ab5b8314 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.h @@ -6,10 +6,6 @@ #include #include -// ABS macro to use since `std::abs` is not constexpr yet -#define ABS(x) ((x) < 0 ? -(x) : (x)) -#define TWO_ACTOR_PARAMS(a, b) (ABS(a) << 16) | ABS(b) - namespace RandomizerCheckObjects { bool AreaIsDungeon(RandomizerCheckArea area); bool AreaIsOverworld(RandomizerCheckArea area); diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index f57aefc32..c78ff62ce 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -2,9 +2,12 @@ #include "randomizer_entrance_tracker.h" #include "randomizer_item_tracker.h" #include "randomizerTypes.h" +#include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" +#include "soh/SaveManager.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/UIWidgets.hpp" #include "dungeon.h" -#include "../../OTRGlobals.h" -#include "../../UIWidgets.hpp" #include "3drando/location_access.hpp" #include @@ -24,7 +27,6 @@ extern "C" { #include "macros.h" extern PlayState* gPlayState; } -extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum); extern "C" GetItemEntry ItemTable_RetrieveEntry(s16 modIndex, s16 getItemID); extern std::vector dungeonRewardStones; @@ -32,8 +34,6 @@ extern std::vector dungeonRewardMedallions; extern std::vector songItems; extern std::vector equipmentItems; -#define RCO_RAORU { RC_GIFT_FROM_SAGES, RCVORMQ_BOTH, RCTYPE_DUNGEON_REWARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, GI_NONE, false, "Gift from Raoru", "Gift from Raoru", true }; - using json = nlohmann::json; namespace CheckTracker { @@ -48,13 +48,18 @@ bool showMajorScrubs; bool showMerchants; bool showBeehives; bool showCows; +bool showOverworldFreestanding; +bool showDungeonFreestanding; bool showAdultTrade; bool showKokiriSword; bool showMasterSword; bool showHyruleLoach; bool showWeirdEgg; bool showGerudoCard; +bool showOverworldPots; +bool showDungeonPots; bool showFrogSongRupees; +bool showFairies; bool showStartingMapsCompasses; bool showKeysanity; bool showGerudoFortressKeys; @@ -103,19 +108,19 @@ std::map DungeonRCAreasBySceneID = { // Dungeon entrances with obvious visual differences between MQ and vanilla qualifying as spoiling on sight std::vector spoilingEntrances = { - 0x0000, // ENTR_DEKU_TREE_0 - 0x0467, // ENTR_DODONGOS_CAVERN_1 - 0x0028, // ENTR_JABU_JABU_0 - 0x0407, // ENTR_JABU_JABU_1 - 0x0169, // ENTR_FOREST_TEMPLE_0 - 0x0165, // ENTR_FIRE_TEMPLE_0 - 0x0175, // ENTR_FIRE_TEMPLE_1 - 0x0423, // ENTR_WATER_TEMPLE_1 - 0x0082, // ENTR_SPIRIT_TEMPLE_0 - 0x02B2, // ENTR_SHADOW_TEMPLE_1 - 0x0088, // ENTR_ICE_CAVERN_0 - 0x0008, // ENTR_GERUDO_TRAINING_GROUNDS_0 - 0x0467 // ENTR_INSIDE_GANONS_CASTLE_0 + ENTR_DEKU_TREE_ENTRANCE, + ENTR_DODONGOS_CAVERN_BOSS_DOOR, + ENTR_JABU_JABU_ENTRANCE, + ENTR_JABU_JABU_BOSS_DOOR, + ENTR_FOREST_TEMPLE_ENTRANCE, + ENTR_FIRE_TEMPLE_ENTRANCE, + ENTR_FIRE_TEMPLE_BOSS_DOOR, + ENTR_WATER_TEMPLE_BOSS_DOOR, + ENTR_SPIRIT_TEMPLE_ENTRANCE, + ENTR_SHADOW_TEMPLE_BOSS_DOOR, + ENTR_ICE_CAVERN_ENTRANCE, + ENTR_GERUDO_TRAINING_GROUND_ENTRANCE, + ENTR_INSIDE_GANONS_CASTLE_ENTRANCE }; std::map> checksByArea; @@ -216,34 +221,6 @@ static ImGuiTextFilter checkSearch; std::array filterAreasHidden = { 0 }; std::array filterChecksHidden = { 0 }; -void SongFromImpa() { - if (IS_RANDO) { - if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_CHILD_ZELDA) == RO_GENERIC_ON && IS_RANDO) { - //if (gSaveContext.checkTrackerData[RC_SONG_FROM_IMPA].status != RCSHOW_SAVED) { - // gSaveContext.checkTrackerData[RC_SONG_FROM_IMPA].status = RCSHOW_SAVED; - //} - } - } -} - -void GiftFromSages() { - if (!IS_RANDO) { - //DefaultCheckData(RC_GIFT_FROM_SAGES); - } -} - -std::vector checks; -// Function for adding Link's Pocket check -void LinksPocket() { - /*if (IS_RANDO) { - if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING || - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_DUNGEON_REWARDS) == RO_DUNGEON_REWARDS_END_OF_DUNGEON) { - DefaultCheckData(RC_LINKS_POCKET); - gSaveContext.checkTrackerData[RC_LINKS_POCKET].status = RCSHOW_SAVED; - } - }*/ -} - void TrySetAreas() { if (checksByArea.empty()) { for (int i = RCAREA_KOKIRI_FOREST; i < RCAREA_INVALID; i++) { @@ -285,6 +262,33 @@ void RecalculateAreaTotals(RandomizerCheckArea rcArea) { CalculateTotals(); } +std::map MapRGtoRandomizerCheckArea = { + { RG_DEKU_TREE_MAP, RCAREA_DEKU_TREE}, + { RG_DODONGOS_CAVERN_MAP, RCAREA_DODONGOS_CAVERN }, + { RG_JABU_JABUS_BELLY_MAP, RCAREA_JABU_JABUS_BELLY }, + { RG_FOREST_TEMPLE_MAP, RCAREA_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_MAP, RCAREA_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_MAP, RCAREA_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_MAP, RCAREA_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_MAP, RCAREA_SHADOW_TEMPLE }, + { RG_BOTTOM_OF_THE_WELL_MAP, RCAREA_BOTTOM_OF_THE_WELL }, + { RG_ICE_CAVERN_MAP, RCAREA_ICE_CAVERN } +}; + +void SpoilAreaFromCheck(RandomizerCheck rc) { + Rando::Location* loc = Rando::StaticData::GetLocation(rc); + Rando::ItemLocation* itemLoc = Rando::Context::GetInstance()->GetItemLocation(rc); + if (itemLoc->GetPlacedItem().GetItemType() == ItemType::ITEMTYPE_MAP) { + RandomizerCheckArea area = MapRGtoRandomizerCheckArea[itemLoc->GetPlacedRandomizerGet()]; + if (!IsAreaSpoiled(area)) { + SetAreaSpoiled(area); + } + } + if (!IsAreaSpoiled(loc->GetArea())) { + SetAreaSpoiled(loc->GetArea()); + } +} + void RecalculateAllAreaTotals() { for (auto& [rcArea, checks] : checksByArea) { if (rcArea == RCAREA_INVALID) { @@ -385,7 +389,7 @@ RandomizerCheckArea AreaFromEntranceGroup[] = { RandomizerCheckArea GetCheckArea() { auto scene = static_cast(gPlayState->sceneNum); bool grottoScene = (scene == SCENE_GROTTOS || scene == SCENE_FAIRYS_FOUNTAIN); - const EntranceData* ent = GetEntranceData(grottoScene ? ENTRANCE_RANDO_GROTTO_EXIT_START + GetCurrentGrottoId() : gSaveContext.entranceIndex); + const EntranceData* ent = GetEntranceData(grottoScene ? ENTRANCE_GROTTO_EXIT_START + GetCurrentGrottoId() : gSaveContext.entranceIndex); RandomizerCheckArea area = RCAREA_INVALID; if (ent != nullptr && !IsAreaScene(scene) && ent->type != ENTRANCE_TYPE_DUNGEON) { if (ent->source == "Desert Colossus" || ent->destination == "Desert Colossus") { @@ -463,7 +467,8 @@ void CheckTrackerLoadGame(int32_t fileNum) { } } - if (areaChecksGotten[entry2->GetArea()] != 0 || RandomizerCheckObjects::AreaIsOverworld(entry2->GetArea())) { + if (areaChecksGotten[entry2->GetArea()] != 0 || RandomizerCheckObjects::AreaIsOverworld(entry2->GetArea()) || + loc->GetCheckStatus() == RCSHOW_SCUMMED) { areasSpoiled |= (1 << entry2->GetArea()); } @@ -507,9 +512,6 @@ void CheckTrackerLoadGame(int32_t fileNum) { showVOrMQ = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_RANDOM_NUMBER || (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SET_NUMBER && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) < 12)); - LinksPocket(); - SongFromImpa(); - GiftFromSages(); initialized = true; UpdateAllOrdering(); UpdateInventoryChecks(); @@ -590,7 +592,7 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) { SetCheckCollected(RC_TWINROVA); return; } else if (giEntry.itemId == ITEM_MEDALLION_LIGHT) { - SetCheckCollected(RC_GIFT_FROM_SAGES); + SetCheckCollected(RC_GIFT_FROM_RAURU); return; } else if (giEntry.itemId == ITEM_SONG_EPONA) { SetCheckCollected(RC_SONG_FROM_MALON); @@ -851,7 +853,7 @@ void CheckTrackerWindow::DrawElement() { if (CVarGetInteger(CVAR_TRACKER_CHECK("DisplayType"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_COMBO_BUTTON) { int comboButton1Mask = buttons[CVarGetInteger(CVAR_TRACKER_CHECK("ComboButton1"), TRACKER_COMBO_BUTTON_L)]; int comboButton2Mask = buttons[CVarGetInteger(CVAR_TRACKER_CHECK("ComboButton2"), TRACKER_COMBO_BUTTON_R)]; - OSContPad* trackerButtonsPressed = Ship::Context::GetInstance()->GetControlDeck()->GetPads(); + OSContPad* trackerButtonsPressed = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); bool comboButtonsHeld = trackerButtonsPressed != nullptr && trackerButtonsPressed[0].button & comboButton1Mask && trackerButtonsPressed[0].button & comboButton2Mask; @@ -908,6 +910,7 @@ void CheckTrackerWindow::DrawElement() { ImGui::SameLine(); if (ImGui::Button("Clear")) { checkSearch.Clear(); + UpdateFilters(); doAreaScroll = true; } UIWidgets::Tooltip("Clear the search field"); @@ -1064,12 +1067,22 @@ bool UpdateFilters() { } bool ShouldShowCheck(RandomizerCheck check) { + auto itemLoc = Rando::Context::GetInstance()->GetItemLocation(check); + std::string search = (Rando::StaticData::GetLocation(check)->GetShortName() + " " + + Rando::StaticData::GetLocation(check)->GetName() + " " + + RandomizerCheckObjects::GetRCAreaName(Rando::StaticData::GetLocation(check)->GetArea())); + if (itemLoc->HasObtained() || itemLoc->GetCheckStatus() == RCSHOW_SCUMMED || + (!mystery && (itemLoc->GetCheckStatus() == RCSHOW_IDENTIFIED || itemLoc->GetCheckStatus() == RCSHOW_SEEN) && itemLoc->GetPlacedRandomizerGet() != RG_ICE_TRAP)) { + search += " " + itemLoc->GetPlacedItemName().GetForLanguage(gSaveContext.language); + } else if (itemLoc->GetCheckStatus() == RCSHOW_IDENTIFIED && !mystery) { + search += OTRGlobals::Instance->gRandoContext->overrides[check].GetTrickName().GetForLanguage(gSaveContext.language); + } else if (itemLoc->GetCheckStatus() == RCSHOW_SEEN && !mystery) { + search += Rando::StaticData::RetrieveItem(OTRGlobals::Instance->gRandoContext->overrides[check].LooksLike()).GetName().GetForLanguage(gSaveContext.language); + } return ( - IsVisibleInCheckTracker(check) && + IsVisibleInCheckTracker(check) && (checkSearch.Filters.Size == 0 || - checkSearch.PassFilter((Rando::StaticData::GetLocation(check)->GetShortName() + " " + - Rando::StaticData::GetLocation(check)->GetName() + " " + - RandomizerCheckObjects::GetRCAreaName(Rando::StaticData::GetLocation(check)->GetArea())).c_str())) + checkSearch.PassFilter(search.c_str())) ); } @@ -1152,6 +1165,9 @@ void LoadSettings() { showFrogSongRupees = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FROG_SONG_RUPEES) == RO_GENERIC_YES : false; + showFairies = IS_RANDO ? + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FAIRIES) == RO_GENERIC_YES + : false; showStartingMapsCompasses = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MAPANDCOMPASS) != RO_DUNGEON_ITEM_LOC_VANILLA : false; @@ -1198,22 +1214,43 @@ void LoadSettings() { showDungeonTokens = false; break; } + + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_POTS)) { + case RO_SHUFFLE_POTS_ALL: + showOverworldPots = true; + showDungeonPots = true; + break; + case RO_SHUFFLE_POTS_OVERWORLD: + showOverworldPots = true; + showDungeonPots = false; + break; + case RO_SHUFFLE_POTS_DUNGEONS: + showOverworldPots = false; + showDungeonPots = true; + break; + default: + showOverworldPots = false; + showDungeonPots = false; + break; + } } else { // Vanilla showOverworldTokens = true; showDungeonTokens = true; + showOverworldPots = false; + showDungeonPots = false; } fortressFast = false; fortressNormal = false; switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_FORTRESS)) { - case RO_GF_OPEN: + case RO_GF_CARPENTERS_FREE: showGerudoFortressKeys = false; showGerudoCard = false; break; - case RO_GF_FAST: + case RO_GF_CARPENTERS_FAST: fortressFast = true; break; - case RO_GF_NORMAL: + case RO_GF_CARPENTERS_NORMAL: fortressNormal = true; break; } @@ -1221,6 +1258,30 @@ void LoadSettings() { fishsanityMode = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY); fishsanityPondCount = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_POND_COUNT); fishsanityAgeSplit = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_AGE_SPLIT); + + if (IS_RANDO) { + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FREESTANDING)) { + case RO_SHUFFLE_FREESTANDING_ALL: + showOverworldFreestanding = true; + showDungeonFreestanding = true; + break; + case RO_SHUFFLE_FREESTANDING_OVERWORLD: + showOverworldFreestanding = true; + showDungeonFreestanding = false; + break; + case RO_SHUFFLE_FREESTANDING_DUNGEONS: + showOverworldFreestanding = false; + showDungeonFreestanding = true; + break; + default: + showOverworldFreestanding = false; + showDungeonFreestanding = false; + break; + } + } else { // Vanilla + showOverworldFreestanding = false; + showDungeonFreestanding = true; + } } bool IsCheckShuffled(RandomizerCheck rc) { @@ -1236,15 +1297,10 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we support shuffling them (rc != RC_HC_ZELDAS_LETTER) && // don't show zeldas letter until we support shuffling it (rc != RC_LINKS_POCKET || showLinksPocket) && - (!RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()) || - loc->GetQuest() == RCQUEST_BOTH || - loc->GetQuest() == RCQUEST_MQ && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsMQ() || - loc->GetQuest() == RCQUEST_VANILLA && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsVanilla() - ) && + OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && (loc->GetRCType() != RCTYPE_SHOP || (showShops && OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1).enGirlAShopItem == 50)) && (rc != RC_TRIFORCE_COMPLETED || !hideTriforceCompleted) && - (rc != RC_GIFT_FROM_SAGES || !IS_RANDO) && (loc->GetRCType() != RCTYPE_SCRUB || showScrubs || (showMajorScrubs && (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized @@ -1258,8 +1314,15 @@ bool IsCheckShuffled(RandomizerCheck rc) { (showOverworldTokens && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonTokens && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea())) ) && + (loc->GetRCType() != RCTYPE_POT || + (showOverworldPots && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonPots && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && + (loc->GetRCType() != RCTYPE_FREESTANDING || + (showOverworldFreestanding && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonFreestanding && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea())) + ) && (loc->GetRCType() != RCTYPE_ADULT_TRADE || showAdultTrade || rc == RC_KAK_ANJU_AS_ADULT || // adult trade checks that are always shuffled @@ -1272,6 +1335,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { (rc != RC_HC_MALON_EGG || showWeirdEgg) && (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && ((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || showStartingMapsCompasses) && + (loc->GetRCType() != RCTYPE_FAIRY || showFairies) && (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && @@ -1283,10 +1347,7 @@ bool IsCheckShuffled(RandomizerCheck rc) { ); } else if (loc->IsVanillaCompletion()) { - return (loc->GetQuest() == RCQUEST_BOTH || - (loc->GetQuest() == RCQUEST_MQ && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsMQ()) || - (loc->GetQuest() == RCQUEST_VANILLA && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsVanilla()) || - rc == RC_GIFT_FROM_SAGES) && rc != RC_LINKS_POCKET; + return (OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) || rc == RC_GIFT_FROM_RAURU) && rc != RC_LINKS_POCKET; } return false; } @@ -1294,8 +1355,10 @@ bool IsCheckShuffled(RandomizerCheck rc) { bool IsVisibleInCheckTracker(RandomizerCheck rc) { auto loc = Rando::StaticData::GetLocation(rc); if (IS_RANDO) { - return IsCheckShuffled(rc) || (loc->GetRCType() == RCTYPE_SKULL_TOKEN && alwaysShowGS) || - (loc->GetRCType() == RCTYPE_SHOP && (showShops && (!hideShopUnshuffledChecks))); + return IsCheckShuffled(rc) || (alwaysShowGS && + loc->GetRCType() == RCTYPE_SKULL_TOKEN && + OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) + ) || (loc->GetRCType() == RCTYPE_SHOP && showShops && !hideShopUnshuffledChecks); } else { return loc->IsVanillaCompletion() && (!loc->IsDungeon() || (loc->IsDungeon() && loc->GetQuest() == gSaveContext.questId)); } @@ -1525,7 +1588,10 @@ void DrawLocation(RandomizerCheck rc) { txt = itemLoc->GetPlacedItem().GetName().GetForLanguage(gSaveContext.language); } if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery && !itemLoc->IsAddedToPool()) { - txt += fmt::format(" - {}", OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetPrice()); + auto price = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetPrice(); + if (price) { + txt += fmt::format(" - {}", price); + } } } else { if (IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID())) { @@ -1640,7 +1706,7 @@ void ImGuiDrawTwoColorPickerSection(const char* text, const char* cvarMainName, ImGui::EndTable(); } } - if (tooltip != "") { + if (tooltip != NULL && strlen(tooltip) != 0) { ImGui::SameLine(); ImGui::Text(" ?"); UIWidgets::Tooltip(tooltip); diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index 96aee4dde..851910489 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -59,4 +59,5 @@ void UpdateAreas(RandomizerCheckArea area); void UpdateAllOrdering(); void UpdateAllAreas(); void RecalculateAllAreaTotals(); +void SpoilAreaFromCheck(RandomizerCheck rc); } // namespace CheckTracker diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.c b/soh/soh/Enhancements/randomizer/randomizer_entrance.c index d52b09836..7a492fe9c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance.c +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.c @@ -9,6 +9,8 @@ #include "randomizer_entrance.h" #include "randomizer_grotto.h" +#include "soh/OTRGlobals.h" +#include "soh/SaveManager.h" #include #include "global.h" @@ -19,23 +21,23 @@ extern PlayState* gPlayState; //Overwrite the dynamic exit for the OGC Fairy Fountain to be 0x3E8 instead //of 0x340 (0x340 will stay as the exit for the HC Fairy Fountain -> Castle Grounds) s16 dynamicExitList[] = { - ENTR_DEATH_MOUNTAIN_TRAIL_4, - ENTR_DEATH_MOUNTAIN_CRATER_3, + ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT, + ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT, ENTR_POTION_SHOP_KAKARIKO_1, // OGC Fairy -- ENTR_POTION_SHOP_KAKARIKO_1 unused - ENTR_KAKARIKO_VILLAGE_9, - ENTR_MARKET_DAY_5, - ENTR_KAKARIKO_VILLAGE_3, - ENTR_MARKET_DAY_6, - ENTR_KAKARIKO_VILLAGE_11, - ENTR_BACK_ALLEY_DAY_2, - ENTR_KAKARIKO_VILLAGE_10, - ENTR_MARKET_DAY_8, - ENTR_ZORAS_FOUNTAIN_5, - ENTR_HYRULE_CASTLE_2, // HC Fairy - ENTR_DESERT_COLOSSUS_7 + ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_FRONT, + ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP, + ENTR_KAKARIKO_VILLAGE_OUTSIDE_BAZAAR, + ENTR_MARKET_DAY_OUTSIDE_BAZAAR, + ENTR_KAKARIKO_VILLAGE_OUTSIDE_SKULKLTULA_HOUSE, + ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP, + ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY, + ENTR_MARKET_DAY_OUTSIDE_SHOOTING_GALLERY, + ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY, + ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, // HC Fairy + ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT }; -// Warp Song indices array : 0x53C33C = { ENTR_SACRED_FOREST_MEADOW_2, ENTR_DEATH_MOUNTAIN_CRATER_4, ENTR_LAKE_HYLIA_8, ENTR_DESERT_COLOSSUS_5, ENTR_GRAVEYARD_7, ENTR_TEMPLE_OF_TIME_7 } +// Warp Song indices array : 0x53C33C = { ENTR_SACRED_FOREST_MEADOW_WARP_PAD, ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, ENTR_LAKE_HYLIA_WARP_PAD, ENTR_DESERT_COLOSSUS_WARP_PAD, ENTR_GRAVEYARD_WARP_PAD, ENTR_TEMPLE_OF_TIME_WARP_PAD } // Owl Flights : 0x492064 and 0x492080 @@ -57,15 +59,15 @@ typedef struct { } DungeonEntranceInfo; static DungeonEntranceInfo dungeons[] = { - //entryway exit, boss, reverse, bluewarp, dungeon scene, boss scene - { ENTR_DEKU_TREE_0, ENTR_KOKIRI_FOREST_1, ENTR_DEKU_TREE_BOSS_0, ENTR_DEKU_TREE_1, ENTR_KOKIRI_FOREST_11, SCENE_DEKU_TREE, SCENE_DEKU_TREE_BOSS }, - { ENTR_DODONGOS_CAVERN_0, ENTR_DEATH_MOUNTAIN_TRAIL_3, ENTR_DODONGOS_CAVERN_BOSS_0, ENTR_DODONGOS_CAVERN_1, ENTR_DEATH_MOUNTAIN_TRAIL_5, SCENE_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN_BOSS }, - { ENTR_JABU_JABU_0, ENTR_ZORAS_FOUNTAIN_1, ENTR_JABU_JABU_BOSS_0, ENTR_JABU_JABU_1, ENTR_ZORAS_FOUNTAIN_0, SCENE_JABU_JABU, SCENE_JABU_JABU_BOSS }, - { ENTR_FOREST_TEMPLE_0, ENTR_SACRED_FOREST_MEADOW_1, ENTR_FOREST_TEMPLE_BOSS_0, ENTR_FOREST_TEMPLE_1, ENTR_SACRED_FOREST_MEADOW_3, SCENE_FOREST_TEMPLE, SCENE_FOREST_TEMPLE_BOSS }, - { ENTR_FIRE_TEMPLE_0, ENTR_DEATH_MOUNTAIN_CRATER_2, ENTR_FIRE_TEMPLE_BOSS_0, ENTR_FIRE_TEMPLE_1, ENTR_DEATH_MOUNTAIN_CRATER_5, SCENE_FIRE_TEMPLE, SCENE_FIRE_TEMPLE_BOSS }, - { ENTR_WATER_TEMPLE_0, ENTR_LAKE_HYLIA_2, ENTR_WATER_TEMPLE_BOSS_0, ENTR_WATER_TEMPLE_1, ENTR_LAKE_HYLIA_9, SCENE_WATER_TEMPLE, SCENE_WATER_TEMPLE_BOSS }, - { ENTR_SPIRIT_TEMPLE_0, ENTR_DESERT_COLOSSUS_1, ENTR_SPIRIT_TEMPLE_BOSS_0, ENTR_SPIRIT_TEMPLE_1, ENTR_DESERT_COLOSSUS_8, SCENE_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE_BOSS }, - { ENTR_SHADOW_TEMPLE_0, ENTR_GRAVEYARD_1, ENTR_SHADOW_TEMPLE_BOSS_0, ENTR_SHADOW_TEMPLE_1, ENTR_GRAVEYARD_8, SCENE_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE_BOSS }, + //entryway exit, boss, reverse, bluewarp, dungeon scene, boss scene + { ENTR_DEKU_TREE_ENTRANCE, ENTR_KOKIRI_FOREST_OUTSIDE_DEKU_TREE, ENTR_DEKU_TREE_BOSS_ENTRANCE, ENTR_DEKU_TREE_BOSS_DOOR, ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP, SCENE_DEKU_TREE, SCENE_DEKU_TREE_BOSS }, + { ENTR_DODONGOS_CAVERN_ENTRANCE, ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN, ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE, ENTR_DODONGOS_CAVERN_BOSS_DOOR, ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP, SCENE_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN_BOSS }, + { ENTR_JABU_JABU_ENTRANCE, ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU, ENTR_JABU_JABU_BOSS_ENTRANCE, ENTR_JABU_JABU_BOSS_DOOR, ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP, SCENE_JABU_JABU, SCENE_JABU_JABU_BOSS }, + { ENTR_FOREST_TEMPLE_ENTRANCE, ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE, ENTR_FOREST_TEMPLE_BOSS_ENTRANCE, ENTR_FOREST_TEMPLE_BOSS_DOOR, ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP, SCENE_FOREST_TEMPLE, SCENE_FOREST_TEMPLE_BOSS }, + { ENTR_FIRE_TEMPLE_ENTRANCE, ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE, ENTR_FIRE_TEMPLE_BOSS_ENTRANCE, ENTR_FIRE_TEMPLE_BOSS_DOOR, ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP, SCENE_FIRE_TEMPLE, SCENE_FIRE_TEMPLE_BOSS }, + { ENTR_WATER_TEMPLE_ENTRANCE, ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE, ENTR_WATER_TEMPLE_BOSS_ENTRANCE, ENTR_WATER_TEMPLE_BOSS_DOOR, ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP, SCENE_WATER_TEMPLE, SCENE_WATER_TEMPLE_BOSS }, + { ENTR_SPIRIT_TEMPLE_ENTRANCE, ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE, ENTR_SPIRIT_TEMPLE_BOSS_DOOR, ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP, SCENE_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE_BOSS }, + { ENTR_SHADOW_TEMPLE_ENTRANCE, ENTR_GRAVEYARD_OUTSIDE_TEMPLE, ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE, ENTR_SHADOW_TEMPLE_BOSS_DOOR, ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP, SCENE_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE_BOSS }, }; static s8 hasCopiedEntranceTable = 0; @@ -79,18 +81,18 @@ u8 Entrance_EntranceIsNull(EntranceOverride* entranceOverride) { } static void Entrance_SeparateOGCFairyFountainExit(void) { - //Overwrite unused entrance 0x03E8 (ENTR_POTION_SHOP_KAKARIKO_1) with values from 0x0340 (ENTR_HYRULE_CASTLE_2) to use it as the + //Overwrite unused entrance 0x03E8 (ENTR_POTION_SHOP_KAKARIKO_1) with values from 0x0340 (ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT) to use it as the //exit from OGC Great Fairy Fountain -> Castle Grounds for (size_t i = 0; i < 4; ++i) { - gEntranceTable[ENTR_POTION_SHOP_KAKARIKO_1 + i] = gEntranceTable[ENTR_HYRULE_CASTLE_2 + i]; + gEntranceTable[ENTR_POTION_SHOP_KAKARIKO_1 + i] = gEntranceTable[ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT + i]; } } static void Entrance_SeparateAdultSpawnAndPrelude() { - // Overwrite unused entrance 0x0282 (ENTR_HYRULE_FIELD_10) with values from 0x05F4 (ENTR_TEMPLE_OF_TIME_7) to use it as the + // Overwrite unused entrance 0x0282 (ENTR_HYRULE_FIELD_10) with values from 0x05F4 (ENTR_TEMPLE_OF_TIME_WARP_PAD) to use it as the // Adult Spawn index and separate it from Prelude of Light for (size_t i = 0; i < 4; ++i) { - gEntranceTable[ENTR_HYRULE_FIELD_10 + i] = gEntranceTable[ENTR_TEMPLE_OF_TIME_7 + i]; + gEntranceTable[ENTR_HYRULE_FIELD_10 + i] = gEntranceTable[ENTR_TEMPLE_OF_TIME_WARP_PAD + i]; } } @@ -99,19 +101,19 @@ static void Entrance_ReplaceChildTempleWarps() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) { // Forest Temple - gEntranceTable[ENTR_SACRED_FOREST_MEADOW_3] = gEntranceTable[ENTR_SACRED_FOREST_MEADOW_2]; + gEntranceTable[ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_SACRED_FOREST_MEADOW_WARP_PAD]; gEntranceTable[ENTR_SACRED_FOREST_MEADOW_3_1] = gEntranceTable[ENTR_SACRED_FOREST_MEADOW_2_1]; // Fire Temple - gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_5] = gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_4]; + gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD]; gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_5_1] = gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_4_1]; // Water Temple - gEntranceTable[ENTR_LAKE_HYLIA_9] = gEntranceTable[ENTR_LAKE_HYLIA_8]; + gEntranceTable[ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_LAKE_HYLIA_WARP_PAD]; gEntranceTable[ENTR_LAKE_HYLIA_9_1] = gEntranceTable[ENTR_LAKE_HYLIA_8_1]; // Shadow Temple - gEntranceTable[ENTR_GRAVEYARD_8] = gEntranceTable[ENTR_GRAVEYARD_7]; + gEntranceTable[ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_GRAVEYARD_WARP_PAD]; gEntranceTable[ENTR_GRAVEYARD_8_1] = gEntranceTable[ENTR_GRAVEYARD_7_1]; // Spirit Temple - gEntranceTable[ENTR_DESERT_COLOSSUS_8] = gEntranceTable[ENTR_DESERT_COLOSSUS_5]; + gEntranceTable[ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_DESERT_COLOSSUS_WARP_PAD]; gEntranceTable[ENTR_DESERT_COLOSSUS_8_1] = gEntranceTable[ENTR_DESERT_COLOSSUS_5_1]; } } @@ -159,7 +161,7 @@ void Entrance_Init(void) { } // Initialize all boss room save/death warps with their vanilla dungeon entryway - for (s16 i = 1; i < SHUFFLEABLE_BOSS_COUNT; i++) { + for (s16 i = 0; i < SHUFFLEABLE_BOSS_COUNT; i++) { bossSceneSaveDeathWarps[i] = dungeons[i].entryway; } @@ -183,7 +185,7 @@ void Entrance_Init(void) { // Search for boss room overrides and look for the matching save/death warp value to use // If the boss room is in a dungeon, use the dungeons entryway as the save warp // Otherwise use the "exit" value for the entrance that lead to the boss room - for (int j = 0; j <= SHUFFLEABLE_BOSS_COUNT; j++) { + for (int j = 0; j < SHUFFLEABLE_BOSS_COUNT; j++) { if (overrideIndex == dungeons[j].bossDoor) { bossScene = dungeons[j].bossScene; } @@ -198,13 +200,13 @@ void Entrance_Init(void) { bossSceneSaveDeathWarps[bossScene - SCENE_DEKU_TREE_BOSS] = saveWarpEntrance; } - //Overwrite grotto related indices - if (originalIndex >= ENTRANCE_RANDO_GROTTO_EXIT_START) { + // Overwrite grotto related indices + if (originalIndex >= ENTRANCE_GROTTO_EXIT_START) { Grotto_SetExitOverride(originalIndex, overrideIndex); continue; } - if (originalIndex >= ENTRANCE_RANDO_GROTTO_LOAD_START && originalIndex < ENTRANCE_RANDO_GROTTO_EXIT_START) { + if (originalIndex >= ENTRANCE_GROTTO_LOAD_START && originalIndex < ENTRANCE_GROTTO_EXIT_START) { Grotto_SetLoadOverride(originalIndex, overrideIndex); continue; } @@ -213,9 +215,9 @@ void Entrance_Init(void) { entranceOverrideTable[originalIndex] = overrideIndex; //Override both land and water entrances for Hyrule Field -> ZR Front and vice versa - if (originalIndex == ENTR_ZORAS_RIVER_0) { //Hyrule Field -> ZR Front land entrance + if (originalIndex == ENTR_ZORAS_RIVER_WEST_EXIT) { //Hyrule Field -> ZR Front land entrance entranceOverrideTable[ENTR_ZORAS_RIVER_3] = overrideIndex; - } else if (originalIndex == ENTR_HYRULE_FIELD_2) { //ZR Front -> Hyrule Field land entrance + } else if (originalIndex == ENTR_HYRULE_FIELD_RIVER_EXIT) { //ZR Front -> Hyrule Field land entrance entranceOverrideTable[ENTR_HYRULE_FIELD_14] = overrideIndex; } } @@ -226,12 +228,12 @@ void Entrance_Init(void) { s16 indicesToSilenceBackgroundMusic[2] = { // The lost woods music playing near the GC Woods Warp keeps playing - // in the next area if the bvackground music is allowed to keep playing - entranceOverrideTable[ENTR_LOST_WOODS_6], // Goron City -> Lost Woods override + // in the next area if the background music is allowed to keep playing + entranceOverrideTable[ENTR_LOST_WOODS_TUNNEL_SHORTCUT], // Goron City -> Lost Woods override // If Malon is singing at night, then her singing will be transferred // to the next area if it allows the background music to keep playing - entranceOverrideTable[ENTR_MARKET_DAY_1], // Castle Grounds -> Market override + entranceOverrideTable[ENTR_MARKET_DAY_CASTLE_EXIT], // Castle Grounds -> Market override }; for (size_t j = 0; j < sizeof(indicesToSilenceBackgroundMusic) / sizeof(s16); j++) { @@ -265,17 +267,10 @@ s16 Entrance_PeekNextIndexOverride(int16_t nextEntranceIndex) { } s16 Entrance_OverrideNextIndex(s16 nextEntranceIndex) { - // When entering Spirit Temple, clear temp flags so they don't carry over to the randomized dungeon - if (nextEntranceIndex == ENTR_SPIRIT_TEMPLE_0 && Entrance_GetOverride(nextEntranceIndex) != nextEntranceIndex && - gPlayState != NULL) { - gPlayState->actorCtx.flags.tempSwch = 0; - gPlayState->actorCtx.flags.tempCollect = 0; - } - // Exiting through the crawl space from Hyrule Castle courtyard is the same exit as leaving Ganon's castle // Don't override the entrance if we came from the Castle courtyard (day and night scenes) if (gPlayState != NULL && (gPlayState->sceneNum == SCENE_CASTLE_COURTYARD_GUARDS_DAY || gPlayState->sceneNum == SCENE_CASTLE_COURTYARD_GUARDS_NIGHT) && - nextEntranceIndex == ENTR_HYRULE_CASTLE_1) { + nextEntranceIndex == ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT) { return nextEntranceIndex; } @@ -327,29 +322,29 @@ void Entrance_SetGameOverEntrance(void) { //Set the current entrance depending on which entrance the player last came through switch (gSaveContext.entranceIndex) { - case ENTR_DEKU_TREE_BOSS_0 : //Deku Tree Boss Room - gSaveContext.entranceIndex = ENTR_DEKU_TREE_0; + case ENTR_DEKU_TREE_BOSS_ENTRANCE : //Deku Tree Boss Room + gSaveContext.entranceIndex = ENTR_DEKU_TREE_ENTRANCE; return; - case ENTR_DODONGOS_CAVERN_BOSS_0 : //Dodongos Cavern Boss Room - gSaveContext.entranceIndex = ENTR_DODONGOS_CAVERN_0; + case ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE : //Dodongos Cavern Boss Room + gSaveContext.entranceIndex = ENTR_DODONGOS_CAVERN_ENTRANCE; return; - case ENTR_JABU_JABU_BOSS_0 : //Jabu Jabus Belly Boss Room - gSaveContext.entranceIndex = ENTR_JABU_JABU_0; + case ENTR_JABU_JABU_BOSS_ENTRANCE : //Jabu Jabus Belly Boss Room + gSaveContext.entranceIndex = ENTR_JABU_JABU_ENTRANCE; return; - case ENTR_FOREST_TEMPLE_BOSS_0 : //Forest Temple Boss Room - gSaveContext.entranceIndex = ENTR_FOREST_TEMPLE_0; + case ENTR_FOREST_TEMPLE_BOSS_ENTRANCE : //Forest Temple Boss Room + gSaveContext.entranceIndex = ENTR_FOREST_TEMPLE_ENTRANCE; return; - case ENTR_FIRE_TEMPLE_BOSS_0 : //Fire Temple Boss Room - gSaveContext.entranceIndex = ENTR_FIRE_TEMPLE_0; + case ENTR_FIRE_TEMPLE_BOSS_ENTRANCE : //Fire Temple Boss Room + gSaveContext.entranceIndex = ENTR_FIRE_TEMPLE_ENTRANCE; return; - case ENTR_WATER_TEMPLE_BOSS_0 : //Water Temple Boss Room - gSaveContext.entranceIndex = ENTR_WATER_TEMPLE_0; + case ENTR_WATER_TEMPLE_BOSS_ENTRANCE : //Water Temple Boss Room + gSaveContext.entranceIndex = ENTR_WATER_TEMPLE_ENTRANCE; return; - case ENTR_SPIRIT_TEMPLE_BOSS_0 : //Spirit Temple Boss Room - gSaveContext.entranceIndex = ENTR_SPIRIT_TEMPLE_0; + case ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE : //Spirit Temple Boss Room + gSaveContext.entranceIndex = ENTR_SPIRIT_TEMPLE_ENTRANCE; return; - case ENTR_SHADOW_TEMPLE_BOSS_0 : //Shadow Temple Boss Room - gSaveContext.entranceIndex = ENTR_SHADOW_TEMPLE_0; + case ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE : //Shadow Temple Boss Room + gSaveContext.entranceIndex = ENTR_SHADOW_TEMPLE_ENTRANCE; return; case ENTR_GANONDORF_BOSS_0 : //Ganondorf Boss Room gSaveContext.entranceIndex = ENTR_GANONS_TOWER_0; // Inside Ganon's Castle -> Ganon's Tower Climb @@ -371,44 +366,44 @@ void Entrance_SetSavewarpEntrance(void) { } if (scene == SCENE_DEKU_TREE || scene == SCENE_DEKU_TREE_BOSS) { - gSaveContext.entranceIndex = ENTR_DEKU_TREE_0; + gSaveContext.entranceIndex = ENTR_DEKU_TREE_ENTRANCE; } else if (scene == SCENE_DODONGOS_CAVERN || scene == SCENE_DODONGOS_CAVERN_BOSS) { - gSaveContext.entranceIndex = ENTR_DODONGOS_CAVERN_0; + gSaveContext.entranceIndex = ENTR_DODONGOS_CAVERN_ENTRANCE; } else if (scene == SCENE_JABU_JABU || scene == SCENE_JABU_JABU_BOSS) { - gSaveContext.entranceIndex = ENTR_JABU_JABU_0; + gSaveContext.entranceIndex = ENTR_JABU_JABU_ENTRANCE; } else if (scene == SCENE_FOREST_TEMPLE || scene == SCENE_FOREST_TEMPLE_BOSS) { //Forest Temple Boss Room - gSaveContext.entranceIndex = ENTR_FOREST_TEMPLE_0; + gSaveContext.entranceIndex = ENTR_FOREST_TEMPLE_ENTRANCE; } else if (scene == SCENE_FIRE_TEMPLE || scene == SCENE_FIRE_TEMPLE_BOSS) { //Fire Temple Boss Room - gSaveContext.entranceIndex = ENTR_FIRE_TEMPLE_0; + gSaveContext.entranceIndex = ENTR_FIRE_TEMPLE_ENTRANCE; } else if (scene == SCENE_WATER_TEMPLE || scene == SCENE_WATER_TEMPLE_BOSS) { //Water Temple Boss Room - gSaveContext.entranceIndex = ENTR_WATER_TEMPLE_0; + gSaveContext.entranceIndex = ENTR_WATER_TEMPLE_ENTRANCE; } else if (scene == SCENE_SPIRIT_TEMPLE || scene == SCENE_SPIRIT_TEMPLE_BOSS) { //Spirit Temple Boss Room - gSaveContext.entranceIndex = ENTR_SPIRIT_TEMPLE_0; + gSaveContext.entranceIndex = ENTR_SPIRIT_TEMPLE_ENTRANCE; } else if (scene == SCENE_SHADOW_TEMPLE || scene == SCENE_SHADOW_TEMPLE_BOSS) { //Shadow Temple Boss Room - gSaveContext.entranceIndex = ENTR_SHADOW_TEMPLE_0; + gSaveContext.entranceIndex = ENTR_SHADOW_TEMPLE_ENTRANCE; } else if (scene == SCENE_BOTTOM_OF_THE_WELL) { // BOTW - gSaveContext.entranceIndex = ENTR_BOTTOM_OF_THE_WELL_0; + gSaveContext.entranceIndex = ENTR_BOTTOM_OF_THE_WELL_ENTRANCE; } else if (scene == SCENE_GERUDO_TRAINING_GROUND) { // GTG - gSaveContext.entranceIndex = ENTR_GERUDO_TRAINING_GROUND_0; + gSaveContext.entranceIndex = ENTR_GERUDO_TRAINING_GROUND_ENTRANCE; } else if (scene == SCENE_ICE_CAVERN) { // Ice cavern - gSaveContext.entranceIndex = ENTR_ICE_CAVERN_0; + gSaveContext.entranceIndex = ENTR_ICE_CAVERN_ENTRANCE; } else if (scene == SCENE_INSIDE_GANONS_CASTLE) { - gSaveContext.entranceIndex = ENTR_INSIDE_GANONS_CASTLE_0; + gSaveContext.entranceIndex = ENTR_INSIDE_GANONS_CASTLE_ENTRANCE; } else if (scene == SCENE_GANONS_TOWER || scene == SCENE_INSIDE_GANONS_CASTLE_COLLAPSE || scene == SCENE_GANONS_TOWER_COLLAPSE_INTERIOR || scene == SCENE_GANON_BOSS || scene == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) { gSaveContext.entranceIndex = ENTR_GANONS_TOWER_0; // Inside Ganon's Castle -> Ganon's Tower Climb } else if (scene == SCENE_THIEVES_HIDEOUT) { // Theives hideout gSaveContext.entranceIndex = ENTR_THIEVES_HIDEOUT_0; // Gerudo Fortress -> Thieve's Hideout spawn 0 } else if (scene == SCENE_LINKS_HOUSE) { - gSaveContext.entranceIndex = Entrance_OverrideNextIndex(ENTR_LINKS_HOUSE_0); + gSaveContext.entranceIndex = Entrance_OverrideNextIndex(ENTR_LINKS_HOUSE_CHILD_SPAWN); } else if (CVarGetInteger(CVAR_ENHANCEMENT("RememberSaveLocation"), 0) && scene != SCENE_FAIRYS_FOUNTAIN && scene != SCENE_GROTTOS && gSaveContext.entranceIndex != ENTR_LOAD_OPENING) { // Use the saved entrance value with remember save location, except when in grottos/fairy fountains or if // the entrance index is -1 (new save) return; } else if (LINK_IS_CHILD) { - gSaveContext.entranceIndex = Entrance_OverrideNextIndex(ENTR_LINKS_HOUSE_0); // Child Overworld Spawn + gSaveContext.entranceIndex = Entrance_OverrideNextIndex(ENTR_LINKS_HOUSE_CHILD_SPAWN); // Child Overworld Spawn } else { - gSaveContext.entranceIndex = Entrance_OverrideNextIndex(ENTR_HYRULE_FIELD_10); // Adult Overworld Spawn (Normally 0x5F4 (ENTR_TEMPLE_OF_TIME_7), but 0x282 (ENTR_HYRULE_FIELD_10) has been repurposed to differentiate from Prelude which also uses 0x5F4) + gSaveContext.entranceIndex = Entrance_OverrideNextIndex(ENTR_HYRULE_FIELD_10); // Adult Overworld Spawn (Normally 0x5F4 (ENTR_TEMPLE_OF_TIME_WARP_PAD), but 0x282 (ENTR_HYRULE_FIELD_10) has been repurposed to differentiate from Prelude which also uses 0x5F4) } } @@ -417,22 +412,22 @@ void Entrance_SetWarpSongEntrance(void) { gPlayState->transitionType = TRANS_TYPE_FADE_WHITE_FAST; switch (gPlayState->msgCtx.lastPlayedSong) { case OCARINA_SONG_MINUET: - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_SACRED_FOREST_MEADOW_2); // Minuet + gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_SACRED_FOREST_MEADOW_WARP_PAD); // Minuet break; case OCARINA_SONG_BOLERO: - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_DEATH_MOUNTAIN_CRATER_4); // Bolero + gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD); // Bolero break; case OCARINA_SONG_SERENADE: - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_8); // Serenade + gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_WARP_PAD); // Serenade break; case OCARINA_SONG_REQUIEM: - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_DESERT_COLOSSUS_5); // Requiem + gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_DESERT_COLOSSUS_WARP_PAD); // Requiem break; case OCARINA_SONG_NOCTURNE: - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_GRAVEYARD_7); // Nocturne + gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_GRAVEYARD_WARP_PAD); // Nocturne break; case OCARINA_SONG_PRELUDE: - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_TEMPLE_OF_TIME_7); // Prelude + gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_TEMPLE_OF_TIME_WARP_PAD); // Prelude break; default: gPlayState->transitionTrigger = TRANS_TRIGGER_OFF; // if something goes wrong, the animation plays normally @@ -452,45 +447,31 @@ void Entrance_SetWarpSongEntrance(void) { } void Entrance_OverrideBlueWarp(void) { - // Handles first time entering bluewarp (with item give) + // Remap child 2nd visits in adult dungeons for warp pad -> bluewarp + if (gSaveContext.entranceIndex == ENTR_SACRED_FOREST_MEADOW_WARP_PAD) { + gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP; + } else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD) { + gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP; + } else if (gSaveContext.entranceIndex == ENTR_LAKE_HYLIA_WARP_PAD) { + gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP; + } else if (gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_WARP_PAD) { + gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP; + } else if (gSaveContext.entranceIndex == ENTR_GRAVEYARD_WARP_PAD) { + gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP; + } + switch (gSaveContext.entranceIndex) { - case ENTR_KOKIRI_FOREST_11: // Gohma blue warp - case ENTR_DEATH_MOUNTAIN_TRAIL_5: // KD blue warp - case ENTR_ZORAS_FOUNTAIN_0: // Barinade blue warp - case ENTR_SACRED_FOREST_MEADOW_3: // Phantom Ganon blue warp - case ENTR_DEATH_MOUNTAIN_CRATER_5: // Volvagia blue warp - case ENTR_LAKE_HYLIA_9: // Morpha blue warp - case ENTR_DESERT_COLOSSUS_8: // Bongo-Bongo blue warp - case ENTR_GRAVEYARD_8: // Twinrova blue warp + case ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP: // Gohma blue warp + case ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP: // KD blue warp + case ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP: // Barinade blue warp + case ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP: // Phantom Ganon blue warp + case ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP: // Volvagia blue warp + case ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP: // Morpha blue warp + case ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP: // Bongo-Bongo blue warp + case ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP: // Twinrova blue warp gSaveContext.entranceIndex = Entrance_OverrideNextIndex(gSaveContext.entranceIndex); return; } - - // Handles second+ times entering bluewarp - switch (gPlayState->nextEntranceIndex) { - case ENTR_KOKIRI_FOREST_11: // Gohma blue warp - case ENTR_DEATH_MOUNTAIN_TRAIL_5: // KD blue warp - case ENTR_ZORAS_FOUNTAIN_0: // Barinade blue warp - case ENTR_SACRED_FOREST_MEADOW_3: // Phantom Ganon blue warp - case ENTR_DEATH_MOUNTAIN_CRATER_5: // Volvagia blue warp - case ENTR_LAKE_HYLIA_9: // Morpha blue warp - case ENTR_DESERT_COLOSSUS_8: // Bongo-Bongo blue warp - case ENTR_GRAVEYARD_8: // Twinrova blue warp - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(gPlayState->nextEntranceIndex); - return; - } -} - -void Entrance_OverrideCutsceneEntrance(u16 cutsceneCmd) { - switch (cutsceneCmd) { - case 24: // Dropping a fish for Jabu Jabu - gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_JABU_JABU_0); - gPlayState->transitionTrigger = TRANS_TRIGGER_START; - gPlayState->transitionType = TRANS_TYPE_FADE_BLACK; - // In case Jabu's mouth leads to a grotto return - Grotto_ForceGrottoReturnOnSpecialEntrance(); - break; - } } void Entrance_EnableFW(void) { @@ -530,23 +511,23 @@ void Entrance_HandleEponaState(void) { } static const s16 validEponaEntrances[] = { - ENTR_LAKE_HYLIA_0, // Hyrule Field -> Lake Hylia - ENTR_HYRULE_FIELD_4, // Lake Hylia -> Hyrule Field - ENTR_LAKE_HYLIA_6, // LH Fishing Hole -> LH Fishing Island - ENTR_LAKE_HYLIA_4, // LH Lab -> Lake Hylia - ENTR_GERUDO_VALLEY_0, // Hyrule Field -> Gerudo Valley - ENTR_HYRULE_FIELD_5, // Gerudo Valley -> Hyrule Field - ENTR_LON_LON_RANCH_0, // Hyrule Field -> Lon Lon Ranch - ENTR_HYRULE_FIELD_6, // Lon Lon Ranch -> Hyrule Field - ENTR_HYRULE_FIELD_7, // Market Entrance -> Hyrule Field - ENTR_HYRULE_FIELD_2, // ZR Front -> Hyrule Field - ENTR_HYRULE_FIELD_3, // LW Bridge -> Hyrule Field - ENTR_GERUDOS_FORTRESS_0, // GV Fortress Side -> Gerudo Fortress - ENTR_GERUDO_VALLEY_3, // Gerudo Fortress -> GV Fortress Side - ENTR_GERUDO_VALLEY_4, // GV Carpenter Tent -> GV Fortress Side - ENTR_LON_LON_RANCH_5, // LLR Stables -> Lon Lon Ranch - ENTR_LON_LON_RANCH_10, // LLR Tower -> Lon Lon Ranch - ENTR_LON_LON_RANCH_4, // LLR Talons House -> Lon Lon Ranch + ENTR_LAKE_HYLIA_NORTH_EXIT, // Hyrule Field -> Lake Hylia + ENTR_HYRULE_FIELD_FENCE_EXIT, // Lake Hylia -> Hyrule Field + ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND, // LH Fishing Hole -> LH Fishing Island + ENTR_LAKE_HYLIA_OUTSIDE_LAB, // LH Lab -> Lake Hylia + ENTR_GERUDO_VALLEY_EAST_EXIT, // Hyrule Field -> Gerudo Valley + ENTR_HYRULE_FIELD_ROCKY_PATH, // Gerudo Valley -> Hyrule Field + ENTR_LON_LON_RANCH_ENTRANCE, // Hyrule Field -> Lon Lon Ranch + ENTR_HYRULE_FIELD_CENTER_EXIT, // Lon Lon Ranch -> Hyrule Field + ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN, // Market Entrance -> Hyrule Field + ENTR_HYRULE_FIELD_RIVER_EXIT, // ZR Front -> Hyrule Field + ENTR_HYRULE_FIELD_WOODED_EXIT, // LW Bridge -> Hyrule Field + ENTR_GERUDOS_FORTRESS_EAST_EXIT, // GV Fortress Side -> Gerudo Fortress + ENTR_GERUDO_VALLEY_WEST_EXIT, // Gerudo Fortress -> GV Fortress Side + ENTR_GERUDO_VALLEY_OUTSIDE_TENT, // GV Carpenter Tent -> GV Fortress Side + ENTR_LON_LON_RANCH_OUTSIDE_STABLES, // LLR Stables -> Lon Lon Ranch + ENTR_LON_LON_RANCH_OUTSIDE_TOWER, // LLR Tower -> Lon Lon Ranch + ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE, // LLR Talons House -> Lon Lon Ranch ENTR_HYRULE_FIELD_11, // LLR Southern Fence Jump ENTR_HYRULE_FIELD_12, // LLR Western Fence Jump ENTR_HYRULE_FIELD_13, // LLR Eastern Fence Jump @@ -588,15 +569,15 @@ void Entrance_OverrideWeatherState() { } // Hyrule Market - if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_7) { // Hyrule Field by Market Entrance + if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN) { // Hyrule Field by Market Entrance gWeatherMode = 1; return; } // Lon Lon Ranch (No Epona) if (!Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED)){ // if you don't have Epona switch (gSaveContext.entranceIndex) { - case ENTR_LON_LON_RANCH_0: // Lon Lon Ranch from HF - case ENTR_HYRULE_FIELD_6: // Hyrule Field from LLR + case ENTR_LON_LON_RANCH_ENTRANCE: // Lon Lon Ranch from HF + case ENTR_HYRULE_FIELD_CENTER_EXIT: // Hyrule Field from LLR gWeatherMode = 2; return; } @@ -604,9 +585,9 @@ void Entrance_OverrideWeatherState() { // Water Temple if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { // have not beaten Water Temple switch (gSaveContext.entranceIndex) { - case ENTR_ZORAS_RIVER_2: // Zora River from behind waterfall - case ENTR_ZORAS_RIVER_4: // Zora River from LW water shortcut - case ENTR_LOST_WOODS_7: // Lost Woods water shortcut from ZR + case ENTR_ZORAS_RIVER_WATERFALL_EXIT: // Zora River from behind waterfall + case ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT: // Zora River from LW water shortcut + case ENTR_LOST_WOODS_UNDERWATER_SHORTCUT: // Lost Woods water shortcut from ZR gWeatherMode = 3; return; } @@ -625,9 +606,9 @@ void Entrance_OverrideWeatherState() { case SCENE_GRAVEYARD: // Graveyard gPlayState->envCtx.gloomySkyMode = 2; switch (gSaveContext.entranceIndex) { - case ENTR_KAKARIKO_VILLAGE_0: // Kakariko from HF - case ENTR_KAKARIKO_VILLAGE_1: // Kakariko from Death Mountain Trail - case ENTR_GRAVEYARD_1: // Graveyard from Shadow Temple + case ENTR_KAKARIKO_VILLAGE_FRONT_GATE: // Kakariko from HF + case ENTR_KAKARIKO_VILLAGE_GUARD_GATE: // Kakariko from Death Mountain Trail + case ENTR_GRAVEYARD_OUTSIDE_TEMPLE: // Graveyard from Shadow Temple break; default: gWeatherMode = 5; @@ -637,7 +618,7 @@ void Entrance_OverrideWeatherState() { } // Death Mountain Cloudy if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { // have not beaten Fire Temple - if (gPlayState->nextEntranceIndex == ENTR_LOST_WOODS_6) { // Lost Woods Goron City Shortcut + if (gPlayState->nextEntranceIndex == ENTR_LOST_WOODS_TUNNEL_SHORTCUT) { // Lost Woods Goron City Shortcut gWeatherMode = 2; return; } @@ -650,8 +631,8 @@ void Entrance_OverrideWeatherState() { gPlayState->envCtx.gloomySkyMode = 1; } switch (gSaveContext.entranceIndex) { - case ENTR_KAKARIKO_VILLAGE_0: // Kakariko from HF - case ENTR_KAKARIKO_VILLAGE_2: // Kakariko from Graveyard + case ENTR_KAKARIKO_VILLAGE_FRONT_GATE: // Kakariko from HF + case ENTR_KAKARIKO_VILLAGE_SOUTHEAST_EXIT: // Kakariko from Graveyard break; default: gWeatherMode = 2; @@ -672,7 +653,7 @@ void Entrance_OverrideGeurdoGuardCapture(void) { if ((LINK_IS_CHILD || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) && gPlayState->nextEntranceIndex == ENTR_GERUDO_VALLEY_1) { // Geurdo Valley thrown out if (gPlayState->sceneNum != SCENE_GERUDO_VALLEY) { // Geurdo Valley - gPlayState->nextEntranceIndex = ENTR_GERUDOS_FORTRESS_0; // Gerudo Fortress + gPlayState->nextEntranceIndex = ENTR_GERUDOS_FORTRESS_EAST_EXIT; // Gerudo Fortress } } } diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.h b/soh/soh/Enhancements/randomizer/randomizer_entrance.h index cc22b31f3..d2c8c79cb 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance.h +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.h @@ -8,50 +8,7 @@ #define ENTRANCE_TABLE_SIZE ENTR_MAX -#define ENTRANCE_RANDO_GROTTO_LOAD_START 0x0700 -#define ENTRANCE_RANDO_GROTTO_EXIT_START 0x0800 #define MAX_ENTRANCE_RANDO_USED_INDEX 0x0820 - -typedef enum { - /* 0x00 */ GROTTO_COLOSSUS_OFFSET, - /* 0x01 */ GROTTO_LH_OFFSET, - /* 0x02 */ GROTTO_ZR_STORMS_OFFSET, - /* 0x03 */ GROTTO_ZR_FAIRY_OFFSET, - /* 0x04 */ GROTTO_ZR_OPEN_OFFSET, - /* 0x05 */ GROTTO_DMC_HAMMER_OFFSET, - /* 0x06 */ GROTTO_DMC_UPPER_OFFSET, - /* 0x07 */ GROTTO_GORON_CITY_OFFSET, - /* 0x08 */ GROTTO_DMT_STORMS_OFFSET, - /* 0x09 */ GROTTO_DMT_COW_OFFSET, - /* 0x0A */ GROTTO_KAK_OPEN_OFFSET, - /* 0x0B */ GROTTO_KAK_REDEAD_OFFSET, - /* 0x0C */ GROTTO_HC_STORMS_OFFSET, - /* 0x0D */ GROTTO_HF_TEKTITE_OFFSET, - /* 0x0E */ GROTTO_HF_NEAR_KAK_OFFSET, - /* 0x0F */ GROTTO_HF_FAIRY_OFFSET, - /* 0x10 */ GROTTO_HF_NEAR_MARKET_OFFSET, - /* 0x11 */ GROTTO_HF_COW_OFFSET, - /* 0x12 */ GROTTO_HF_INSIDE_FENCE_OFFSET, - /* 0x13 */ GROTTO_HF_OPEN_OFFSET, - /* 0x14 */ GROTTO_HF_SOUTHEAST_OFFSET, - /* 0x15 */ GROTTO_LLR_OFFSET, - /* 0x16 */ GROTTO_SFM_WOLFOS_OFFSET, - /* 0x17 */ GROTTO_SFM_STORMS_OFFSET, - /* 0x18 */ GROTTO_SFM_FAIRY_OFFSET, - /* 0x19 */ GROTTO_LW_SCRUBS_OFFSET, - /* 0x1A */ GROTTO_LW_NEAR_SHORTCUTS_OFFSET, - /* 0x1B */ GROTTO_KF_STORMS_OFFSET, - /* 0x1C */ GROTTO_ZD_STORMS_OFFSET, - /* 0x1D */ GROTTO_GF_STORMS_OFFSET, - /* 0x1E */ GROTTO_GV_STORMS_OFFSET, - /* 0x1F */ GROTTO_GV_OCTOROK_OFFSET, - /* 0x20 */ GROTTO_LW_DEKU_THEATRE_OFFSET, - /* 0x21 */ GROTTO_OFFSET_MAX, -} GrottoEntranceOffsets; - -#define ENTRANCE_RANDO_GROTTO_LOAD(index) ENTRANCE_RANDO_GROTTO_LOAD_START + index -#define ENTRANCE_RANDO_GROTTO_EXIT(index) ENTRANCE_RANDO_GROTTO_EXIT_START + index - #define ENTRANCE_OVERRIDES_MAX_COUNT 267 // 19 one-way entrances + 124 two-way entrances (x2) #define SHUFFLEABLE_BOSS_COUNT 8 @@ -88,7 +45,6 @@ void Entrance_SetGameOverEntrance(void); void Entrance_SetSavewarpEntrance(void); void Entrance_SetWarpSongEntrance(void); void Entrance_OverrideBlueWarp(void); -void Entrance_OverrideCutsceneEntrance(uint16_t cutsceneCmd); void Entrance_HandleEponaState(void); void Entrance_OverrideWeatherState(void); void Entrance_OverrideGeurdoGuardCapture(void); diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 4cf9d623a..8d951dfdc 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -1,5 +1,6 @@ #include "randomizer_entrance_tracker.h" #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" #include "soh/UIWidgets.hpp" #include @@ -16,6 +17,7 @@ extern PlayState* gPlayState; #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/randomizer/randomizer_grotto.h" +#include "soh/Enhancements/randomizer/randomizerTypes.h" } #include "soh/Enhancements/game-interactor/GameInteractor.h" @@ -71,311 +73,311 @@ static std::string groupTypeNames[] = { // ENTR_HYRULE_FIELD_10 and ENTR_POTION_SHOP_KAKARIKO_1 have been repurposed for entrance randomizer const EntranceData entranceData[] = { //index, reverse, scenes (and spawns), source name, destination name, source group, destination group, type, metaTag, oneExit - { ENTR_LINKS_HOUSE_0, -1, SINGLE_SCENE_INFO(SCENE_LINKS_HOUSE), "Child Spawn", "Link's House", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, + { ENTR_LINKS_HOUSE_CHILD_SPAWN, -1, SINGLE_SCENE_INFO(SCENE_LINKS_HOUSE), "Child Spawn", "Link's House", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, { ENTR_HYRULE_FIELD_10, -1, SINGLE_SCENE_INFO(SCENE_TEMPLE_OF_TIME), "Adult Spawn", "Temple of Time", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, - { ENTR_SACRED_FOREST_MEADOW_2, -1, {{ -1 }}, "Minuet of Forest", "SFM Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, - { ENTR_DEATH_MOUNTAIN_CRATER_4, -1, {{ -1 }}, "Bolero of Fire", "DMC Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, - { ENTR_LAKE_HYLIA_8, -1, {{ -1 }}, "Serenade of Water", "Lake Hylia Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, - { ENTR_DESERT_COLOSSUS_5, -1, {{ -1 }}, "Requiem of Spirit", "Desert Colossus Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, - { ENTR_GRAVEYARD_7, -1, {{ -1 }}, "Nocturne of Shadow", "Graveyard Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, - { ENTR_TEMPLE_OF_TIME_7, -1, {{ -1 }}, "Prelude of Light", "Temple of Time Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, + { ENTR_SACRED_FOREST_MEADOW_WARP_PAD, -1, {{ -1 }}, "Minuet of Forest", "SFM Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, + { ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, -1, {{ -1 }}, "Bolero of Fire", "DMC Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, + { ENTR_LAKE_HYLIA_WARP_PAD, -1, {{ -1 }}, "Serenade of Water", "Lake Hylia Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, + { ENTR_DESERT_COLOSSUS_WARP_PAD, -1, {{ -1 }}, "Requiem of Spirit", "Desert Colossus Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, + { ENTR_GRAVEYARD_WARP_PAD, -1, {{ -1 }}, "Nocturne of Shadow", "Graveyard Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, + { ENTR_TEMPLE_OF_TIME_WARP_PAD, -1, {{ -1 }}, "Prelude of Light", "Temple of Time Warp Pad", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, - { ENTR_KAKARIKO_VILLAGE_14, -1, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT Owl Flight", "Kakariko Village Owl Drop", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, - { ENTR_HYRULE_FIELD_9, -1, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "LH Owl Flight", "Hyrule Field Owl Drop", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, + { ENTR_KAKARIKO_VILLAGE_OWL_DROP, -1, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT Owl Flight", "Kakariko Village Owl Drop", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, + { ENTR_HYRULE_FIELD_OWL_DROP, -1, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "LH Owl Flight", "Hyrule Field Owl Drop", ENTRANCE_GROUP_ONE_WAY, ENTRANCE_GROUP_ONE_WAY, ENTRANCE_TYPE_ONE_WAY}, // Kokiri Forest - { ENTR_LOST_WOODS_9, ENTR_KOKIRI_FOREST_2, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF", "Lost Woods Bridge", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"}, - { ENTR_LOST_WOODS_0, ENTR_KOKIRI_FOREST_6, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF", "Lost Woods", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"}, - { ENTR_LINKS_HOUSE_1, ENTR_KOKIRI_FOREST_3, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF", "Link's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_MIDOS_HOUSE_0, ENTR_KOKIRI_FOREST_9, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF", "Mido's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_SARIAS_HOUSE_0, ENTR_KOKIRI_FOREST_10, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF", "Saria's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_TWINS_HOUSE_0, ENTR_KOKIRI_FOREST_8, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF", "House of Twins", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_KNOW_IT_ALL_BROS_HOUSE_0, ENTR_KOKIRI_FOREST_5, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF", "Know-It-All House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_KOKIRI_SHOP_0, ENTR_KOKIRI_FOREST_4, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF", "KF Shop", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF", "KF Storms Grotto", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTR_DEKU_TREE_0, ENTR_KOKIRI_FOREST_1, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF", "Deku Tree", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_KOKIRI_FOREST_3, ENTR_LINKS_HOUSE_1, SINGLE_SCENE_INFO(SCENE_LINKS_HOUSE), "Link's House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, - { ENTR_KOKIRI_FOREST_9, ENTR_MIDOS_HOUSE_0, SINGLE_SCENE_INFO(SCENE_MIDOS_HOUSE), "Mido's House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, - { ENTR_KOKIRI_FOREST_10, ENTR_SARIAS_HOUSE_0, SINGLE_SCENE_INFO(SCENE_SARIAS_HOUSE), "Saria's House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, - { ENTR_KOKIRI_FOREST_8, ENTR_TWINS_HOUSE_0, SINGLE_SCENE_INFO(SCENE_TWINS_HOUSE), "House of Twins", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, - { ENTR_KOKIRI_FOREST_5, ENTR_KNOW_IT_ALL_BROS_HOUSE_0, SINGLE_SCENE_INFO(SCENE_KNOW_IT_ALL_BROS_HOUSE), "Know-It-All House", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, - { ENTR_KOKIRI_FOREST_4, ENTR_KOKIRI_SHOP_0, SINGLE_SCENE_INFO(SCENE_KOKIRI_SHOP), "KF Shop", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "KF Storms Grotto", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_GROTTO, "chest"}, - { ENTR_KOKIRI_FOREST_1, ENTR_DEKU_TREE_0, SINGLE_SCENE_INFO(SCENE_DEKU_TREE), "Deku Tree", "KF", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, ""}, - { ENTR_DEKU_TREE_BOSS_0, ENTR_DEKU_TREE_1, SINGLE_SCENE_INFO(SCENE_DEKU_TREE), "Deku Tree Boss Door", "Gohma", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_DEKU_TREE_1, ENTR_DEKU_TREE_BOSS_0, SINGLE_SCENE_INFO(SCENE_DEKU_TREE_BOSS), "Gohma", "Deku Tree Boss Door", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_KOKIRI_FOREST_11, -1, SINGLE_SCENE_INFO(SCENE_DEKU_TREE_BOSS), "Gohma", "Deku Tree Blue Warp", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, + { ENTR_LOST_WOODS_BRIDGE_EAST_EXIT, ENTR_KOKIRI_FOREST_LOWER_EXIT, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "Kokiri Forest Lower Exit", "Lost Woods Bridge East Exit", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"}, + { ENTR_LOST_WOODS_SOUTH_EXIT, ENTR_KOKIRI_FOREST_UPPER_EXIT, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "Kokiri Forest Upper Exit", "Lost Woods Sout Exit", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"}, + { ENTR_LINKS_HOUSE_1, ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF Outside Link's House", "Link's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_MIDOS_HOUSE_0, ENTR_KOKIRI_FOREST_OUTSIDE_MIDOS_HOUSE, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF Outside Mido's House", "Mido's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_SARIAS_HOUSE_0, ENTR_KOKIRI_FOREST_OUTSIDE_SARIAS_HOUSE, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF Outside Saria's House", "Saria's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_TWINS_HOUSE_0, ENTR_KOKIRI_FOREST_OUTSIDE_TWINS_HOUSE, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF Outside House of Twins", "House of Twins", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_KNOW_IT_ALL_BROS_HOUSE_0, ENTR_KOKIRI_FOREST_OUTSIDE_KNOW_IT_ALL_HOUSE, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF Outside Know-It-All House", "Know-It-All House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_KOKIRI_SHOP_0, ENTR_KOKIRI_FOREST_OUTSIDE_SHOP, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF Oustide Shop", "KF Shop", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF Storms Grotto Exit", "KF Storms Grotto", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_GROTTO, "chest", 1}, + { ENTR_DEKU_TREE_ENTRANCE, ENTR_KOKIRI_FOREST_OUTSIDE_DEKU_TREE, SINGLE_SCENE_INFO(SCENE_KOKIRI_FOREST), "KF Oustide Deku Tree", "Deku Tree Entrance", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE, ENTR_LINKS_HOUSE_1, SINGLE_SCENE_INFO(SCENE_LINKS_HOUSE), "Link's House", "KF Outside Link's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, + { ENTR_KOKIRI_FOREST_OUTSIDE_MIDOS_HOUSE, ENTR_MIDOS_HOUSE_0, SINGLE_SCENE_INFO(SCENE_MIDOS_HOUSE), "Mido's House", "KF Outside Mido's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, + { ENTR_KOKIRI_FOREST_OUTSIDE_SARIAS_HOUSE, ENTR_SARIAS_HOUSE_0, SINGLE_SCENE_INFO(SCENE_SARIAS_HOUSE), "Saria's House", "KF Outside Saria's House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, + { ENTR_KOKIRI_FOREST_OUTSIDE_TWINS_HOUSE, ENTR_TWINS_HOUSE_0, SINGLE_SCENE_INFO(SCENE_TWINS_HOUSE), "House of Twins", "KF Outside House of Twins", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, + { ENTR_KOKIRI_FOREST_OUTSIDE_KNOW_IT_ALL_HOUSE, ENTR_KNOW_IT_ALL_BROS_HOUSE_0, SINGLE_SCENE_INFO(SCENE_KNOW_IT_ALL_BROS_HOUSE), "Know-It-All House", "KF Outside Know-It-All House", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, + { ENTR_KOKIRI_FOREST_OUTSIDE_SHOP, ENTR_KOKIRI_SHOP_0, SINGLE_SCENE_INFO(SCENE_KOKIRI_SHOP), "KF Shop", "KF Oustide Shop", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_INTERIOR, ""}, + { ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "KF Storms Grotto", "KF Storms Grotto Exit", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_GROTTO, "chest"}, + { ENTR_KOKIRI_FOREST_OUTSIDE_DEKU_TREE, ENTR_DEKU_TREE_ENTRANCE, SINGLE_SCENE_INFO(SCENE_DEKU_TREE), "Deku Tree Entrance", "KF Oustide Deku Tree", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, ""}, + { ENTR_DEKU_TREE_BOSS_ENTRANCE, ENTR_DEKU_TREE_BOSS_DOOR, SINGLE_SCENE_INFO(SCENE_DEKU_TREE), "Deku Tree Boss Door", "Gohma", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_DEKU_TREE_BOSS_DOOR, ENTR_DEKU_TREE_BOSS_ENTRANCE, SINGLE_SCENE_INFO(SCENE_DEKU_TREE_BOSS), "Gohma", "Deku Tree Boss Door", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP, -1, SINGLE_SCENE_INFO(SCENE_DEKU_TREE_BOSS), "Gohma", "Deku Tree Blue Warp", ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, // Lost Woods - { ENTR_KOKIRI_FOREST_2, ENTR_LOST_WOODS_9, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods Bridge", "KF", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_OVERWORLD, "lw"}, - { ENTR_HYRULE_FIELD_3, ENTR_LOST_WOODS_8, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods Bridge", "Hyrule Field", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "lw,hf"}, - { ENTR_KOKIRI_FOREST_6, ENTR_LOST_WOODS_0, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods", "KF", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_OVERWORLD, "lw"}, - { ENTR_GORON_CITY_3, ENTR_LOST_WOODS_6, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods", "Goron City", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_OVERWORLD, "lw,gc"}, - { ENTR_ZORAS_RIVER_4, ENTR_LOST_WOODS_7, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods", "ZR", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_OVERWORLD, "lw"}, - { ENTR_SACRED_FOREST_MEADOW_0, ENTR_LOST_WOODS_1, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods", "SFM", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_OVERWORLD, "lw"}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods", "LW Near Shortcuts Grotto", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,chest", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET), SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods", "LW Scrubs Grotto", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_LW_DEKU_THEATRE_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_LW_DEKU_THEATRE_OFFSET), SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods", "Deku Theater", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,mask,stage", 1}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "LW Near Shortcuts Grotto", "Lost Woods", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,chest"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET), {{ SCENE_GROTTOS, 0x07 }}, "LW Scrubs Grotto", "Lost Woods", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_LW_DEKU_THEATRE_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_LW_DEKU_THEATRE_OFFSET), {{ SCENE_GROTTOS, 0x0C }}, "Deku Theater", "Lost Woods", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,mask,stage"}, + { ENTR_KOKIRI_FOREST_LOWER_EXIT, ENTR_LOST_WOODS_BRIDGE_EAST_EXIT, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods Bridge East Exit", "Kokiri Forest Lower Exit", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_OVERWORLD, "lw"}, + { ENTR_HYRULE_FIELD_WOODED_EXIT, ENTR_LOST_WOODS_BRIDGE_WEST_EXIT, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "Lost Woods Bridge West Exit", "Hyrule Field Wooded Path", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "lw,hf"}, + { ENTR_KOKIRI_FOREST_UPPER_EXIT, ENTR_LOST_WOODS_SOUTH_EXIT, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW South Exit", "KF Upper Exit", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_KOKIRI_FOREST, ENTRANCE_TYPE_OVERWORLD, "lw"}, + { ENTR_GORON_CITY_TUNNEL_SHORTCUT, ENTR_LOST_WOODS_TUNNEL_SHORTCUT, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW Tunnel Shortcut", "GC Tunnel Shortcut", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_OVERWORLD, "lw,gc"}, + { ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT, ENTR_LOST_WOODS_UNDERWATER_SHORTCUT, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW Underwater Shortcut", "ZR Underwater Shortcut", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_OVERWORLD, "lw"}, + { ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT, ENTR_LOST_WOODS_NORTH_EXIT, SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW North Exit", "SFM South Exit", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_OVERWORLD, "lw"}, + { ENTRANCE_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW Tunnel Grotto", "LW Near Shortcuts Grotto", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,chest", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET), SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW North Exit Grotto", "LW Scrubs Grotto", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_LW_DEKU_THEATRE_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_LW_DEKU_THEATRE_OFFSET), SINGLE_SCENE_INFO(SCENE_LOST_WOODS), "LW Meadow Grotto", "Deku Theater", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,mask,stage", 1}, + { ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "LW Near Shortcuts Grotto", "LW Tunnel Grotto Exit", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,chest"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET), {{ SCENE_GROTTOS, 0x07 }}, "LW Scrubs Grotto", "LW North Grotto Exit", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_LW_DEKU_THEATRE_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_LW_DEKU_THEATRE_OFFSET), {{ SCENE_GROTTOS, 0x0C }}, "Deku Theater", "LW Meadow Grotto", ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_GROTTO, "lw,mask,stage"}, // Sacred Forest Meadow - { ENTR_LOST_WOODS_1, ENTR_SACRED_FOREST_MEADOW_0, SINGLE_SCENE_INFO(SCENE_SACRED_FOREST_MEADOW), "SFM", "Lost Woods", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_SFM_WOLFOS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_SFM_WOLFOS_OFFSET), SINGLE_SCENE_INFO(SCENE_SACRED_FOREST_MEADOW), "SFM", "SFM Wolfos Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET), SINGLE_SCENE_INFO(SCENE_SACRED_FOREST_MEADOW), "SFM", "SFM Fairy Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_SFM_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_SFM_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_SACRED_FOREST_MEADOW), "SFM", "SFM Storms Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, - { ENTR_FOREST_TEMPLE_0, ENTR_SACRED_FOREST_MEADOW_1, SINGLE_SCENE_INFO(SCENE_SACRED_FOREST_MEADOW), "SFM", "Forest Temple", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_SFM_WOLFOS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_SFM_WOLFOS_OFFSET), {{ SCENE_GROTTOS, 0x08 }}, "SFM Wolfos Grotto", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "SFM Fairy Grotto", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_SFM_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_SFM_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x0A }}, "SFM Storms Grotto", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "scrubs"}, - { ENTR_SACRED_FOREST_MEADOW_1, ENTR_FOREST_TEMPLE_0, SINGLE_SCENE_INFO(SCENE_FOREST_TEMPLE), "Forest Temple", "SFM", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON}, - { ENTR_FOREST_TEMPLE_BOSS_0, ENTR_FOREST_TEMPLE_1, SINGLE_SCENE_INFO(SCENE_FOREST_TEMPLE), "Forest Temple Boss Door", "Phantom Ganon", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_FOREST_TEMPLE_1, ENTR_FOREST_TEMPLE_BOSS_0, SINGLE_SCENE_INFO(SCENE_FOREST_TEMPLE_BOSS), "Phantom Ganon", "Forest Temple Boss Door", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_SACRED_FOREST_MEADOW_3, -1, SINGLE_SCENE_INFO(SCENE_FOREST_TEMPLE_BOSS), "Phantom Ganon", "Forest Temple Blue Warp", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, + { ENTR_LOST_WOODS_NORTH_EXIT, ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT, SINGLE_SCENE_INFO(SCENE_SACRED_FOREST_MEADOW), "SFM South Exit", "LW North Exit", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"}, + { ENTRANCE_GROTTO_LOAD(GROTTO_SFM_WOLFOS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_SFM_WOLFOS_OFFSET), SINGLE_SCENE_INFO(SCENE_SACRED_FOREST_MEADOW), "SFM Outside Wolfos Grotto", "SFM Wolfos Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "chest", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET), SINGLE_SCENE_INFO(SCENE_SACRED_FOREST_MEADOW), "SFM Outside Fairy Grotto", "SFM Fairy Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_SFM_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_SFM_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_SACRED_FOREST_MEADOW), "SFM Outside Storms Grotto", "SFM Storms Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, + { ENTR_FOREST_TEMPLE_ENTRANCE, ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE, SINGLE_SCENE_INFO(SCENE_SACRED_FOREST_MEADOW), "SFM Outside Forest Temple", "Forest Temple Entrance", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTRANCE_GROTTO_EXIT(GROTTO_SFM_WOLFOS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_SFM_WOLFOS_OFFSET), {{ SCENE_GROTTOS, 0x08 }}, "SFM Wolfos Grotto", "SFM Outside Wolfos Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO}, + { ENTRANCE_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "SFM Fairy Grotto", "SFM Outside Fairy Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO}, + { ENTRANCE_GROTTO_EXIT(GROTTO_SFM_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_SFM_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x0A }}, "SFM Storms Grotto", "SFM Outside Storms Grotto", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_GROTTO, "scrubs"}, + { ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE, ENTR_FOREST_TEMPLE_ENTRANCE, SINGLE_SCENE_INFO(SCENE_FOREST_TEMPLE), "Forest Temple Entrance", "SFM Outside Forest Temple", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON}, + { ENTR_FOREST_TEMPLE_BOSS_ENTRANCE, ENTR_FOREST_TEMPLE_BOSS_DOOR, SINGLE_SCENE_INFO(SCENE_FOREST_TEMPLE), "Forest Temple Boss Door", "Phantom Ganon", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_FOREST_TEMPLE_BOSS_DOOR, ENTR_FOREST_TEMPLE_BOSS_ENTRANCE, SINGLE_SCENE_INFO(SCENE_FOREST_TEMPLE_BOSS), "Phantom Ganon", "Forest Temple Boss Door", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP, -1, SINGLE_SCENE_INFO(SCENE_FOREST_TEMPLE_BOSS), "Phantom Ganon", "Forest Temple Blue Warp", ENTRANCE_GROUP_SFM, ENTRANCE_GROUP_SFM, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, // Kakariko Village - { ENTR_HYRULE_FIELD_1, ENTR_KAKARIKO_VILLAGE_0, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Hyrule Field", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, - { ENTR_GRAVEYARD_0, ENTR_KAKARIKO_VILLAGE_2, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Graveyard", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_DEATH_MOUNTAIN_TRAIL_0, ENTR_KAKARIKO_VILLAGE_1, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "DMT", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0, ENTR_KAKARIKO_VILLAGE_6, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Carpenter Boss House", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_HOUSE_OF_SKULLTULA_0, ENTR_KAKARIKO_VILLAGE_11, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "House of Skulltula", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_IMPAS_HOUSE_0, ENTR_KAKARIKO_VILLAGE_5, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Impa's House Front", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_IMPAS_HOUSE_1, ENTR_KAKARIKO_VILLAGE_15, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Impa's House Back", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "cow", 1}, - { ENTR_WINDMILL_AND_DAMPES_GRAVE_1, ENTR_KAKARIKO_VILLAGE_8, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Windmill", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_SHOOTING_GALLERY_0, ENTR_KAKARIKO_VILLAGE_10, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Kak Shooting Gallery", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "adult", 1}, - { ENTR_POTION_SHOP_GRANNY_0, ENTR_KAKARIKO_VILLAGE_7, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Granny's Potion Shop", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_BAZAAR_0, ENTR_KAKARIKO_VILLAGE_3, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Kak Bazaar", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "shop", 1}, - { ENTR_POTION_SHOP_KAKARIKO_0, ENTR_KAKARIKO_VILLAGE_9, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Kak Potion Shop Front", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_POTION_SHOP_KAKARIKO_2, ENTR_KAKARIKO_VILLAGE_12, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Kak Potion Shop Back", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_KAK_OPEN_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_KAK_OPEN_OFFSET), SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Kak Open Grotto", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_KAK_REDEAD_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_KAK_REDEAD_OFFSET), SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Kak Redead Grotto", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTR_BOTTOM_OF_THE_WELL_0, ENTR_KAKARIKO_VILLAGE_4, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko", "Bottom of the Well", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_DUNGEON, "botw", 1}, - { ENTR_KAKARIKO_VILLAGE_6, ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0, SINGLE_SCENE_INFO(SCENE_KAKARIKO_CENTER_GUEST_HOUSE), "Carpenter Boss House", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, - { ENTR_KAKARIKO_VILLAGE_11, ENTR_HOUSE_OF_SKULLTULA_0, SINGLE_SCENE_INFO(SCENE_HOUSE_OF_SKULLTULA), "House of Skulltula", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, - { ENTR_KAKARIKO_VILLAGE_5, ENTR_IMPAS_HOUSE_0, SINGLE_SCENE_INFO(SCENE_IMPAS_HOUSE), "Impa's House Front", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, - { ENTR_KAKARIKO_VILLAGE_15, ENTR_IMPAS_HOUSE_1, SINGLE_SCENE_INFO(SCENE_IMPAS_HOUSE), "Impa's House Back", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "cow"}, - { ENTR_KAKARIKO_VILLAGE_8, ENTR_WINDMILL_AND_DAMPES_GRAVE_1, SINGLE_SCENE_INFO(SCENE_WINDMILL_AND_DAMPES_GRAVE), "Windmill", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, - { ENTR_KAKARIKO_VILLAGE_10, ENTR_SHOOTING_GALLERY_0, {{ SCENE_SHOOTING_GALLERY, 0x00 }}, "Kak Shooting Gallery", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, - { ENTR_KAKARIKO_VILLAGE_7, ENTR_POTION_SHOP_GRANNY_0, SINGLE_SCENE_INFO(SCENE_POTION_SHOP_GRANNY), "Granny's Potion Shop", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, - { ENTR_KAKARIKO_VILLAGE_3, ENTR_BAZAAR_0, {{ SCENE_BAZAAR, 0x00 }}, "Kak Bazaar", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "shop"}, - { ENTR_KAKARIKO_VILLAGE_9, ENTR_POTION_SHOP_KAKARIKO_0, SINGLE_SCENE_INFO(SCENE_POTION_SHOP_KAKARIKO), "Kak Potion Shop Front", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, - { ENTR_KAKARIKO_VILLAGE_12, ENTR_POTION_SHOP_KAKARIKO_2, SINGLE_SCENE_INFO(SCENE_POTION_SHOP_KAKARIKO), "Kak Potion Shop Back", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_KAK_OPEN_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_KAK_OPEN_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "Kak Open Grotto", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_GROTTO, "chest"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_KAK_REDEAD_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_KAK_REDEAD_OFFSET), {{ SCENE_GROTTOS, 0x03 }}, "Kak Redead Grotto", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_GROTTO, "chest"}, - { ENTR_KAKARIKO_VILLAGE_4, ENTR_BOTTOM_OF_THE_WELL_0, SINGLE_SCENE_INFO(SCENE_BOTTOM_OF_THE_WELL), "Bottom of the Well", "Kakariko", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_DUNGEON, "botw"}, + { ENTR_HYRULE_FIELD_STAIRS_EXIT, ENTR_KAKARIKO_VILLAGE_FRONT_GATE, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko Front Gate", "Hyrule Field Stairs Exit", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, + { ENTR_GRAVEYARD_ENTRANCE, ENTR_KAKARIKO_VILLAGE_SOUTHEAST_EXIT, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko Southeast Exit", "Graveyard Entrance", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT, ENTR_KAKARIKO_VILLAGE_GUARD_GATE, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kakariko Guard Gate Exit", "Death Mountain Trail Bottom Exit", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0, ENTR_KAKARIKO_VILLAGE_OUTSIDE_CENTER_GUEST_HOUSE, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside Boss House", "Carpenter Boss House", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_HOUSE_OF_SKULLTULA_0, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SKULKLTULA_HOUSE, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside Skulltula House", "House of Skulltula", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_IMPAS_HOUSE_FRONT, ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_FRONT, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside Impa's House Front", "Impa's House Front", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_IMPAS_HOUSE_BACK, ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_BACK, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside Impa's House Back", "Impa's House Back", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "cow", 1}, + { ENTR_WINDMILL_AND_DAMPES_GRAVE_WINDMILL, ENTR_KAKARIKO_VILLAGE_OUTSIDE_WINDMILL, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside Windmill", "Windmill", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_SHOOTING_GALLERY_0, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside Shooting Gallery", "Kak Shooting Gallery", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "adult", 1}, + { ENTR_POTION_SHOP_GRANNY_0, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOP_GRANNY, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside Granny's Potion Shop", "Granny's Potion Shop", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_BAZAAR_0, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BAZAAR, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside Bazaar", "Kak Bazaar", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "shop", 1}, + { ENTR_POTION_SHOP_KAKARIKO_FRONT, ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_FRONT, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside Potion Shop Front", "Kak Potion Shop Front", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_POTION_SHOP_KAKARIKO_BACK, ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_BACK, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside Potion Shop Back", "Kak Potion Shop Back", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_KAK_OPEN_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_KAK_OPEN_OFFSET), SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Open Grotto Exit", "Kak Open Grotto", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_GROTTO, "chest", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_KAK_REDEAD_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_KAK_REDEAD_OFFSET), SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Redead Grotto Exit", "Kak Redead Grotto", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_GROTTO, "chest", 1}, + { ENTR_BOTTOM_OF_THE_WELL_ENTRANCE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL, SINGLE_SCENE_INFO(SCENE_KAKARIKO_VILLAGE), "Kak Outside BotW", "Bottom of the Well Entrance", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_DUNGEON, "botw", 1}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_CENTER_GUEST_HOUSE, ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0, SINGLE_SCENE_INFO(SCENE_KAKARIKO_CENTER_GUEST_HOUSE), "Carpenter Boss House", "Kak Outside Boss House", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_SKULKLTULA_HOUSE, ENTR_HOUSE_OF_SKULLTULA_0, SINGLE_SCENE_INFO(SCENE_HOUSE_OF_SKULLTULA), "House of Skulltula", "Kak Outside Skulltula House", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_FRONT, ENTR_IMPAS_HOUSE_FRONT, SINGLE_SCENE_INFO(SCENE_IMPAS_HOUSE), "Impa's House Front", "Kak Outside Impa's House Front", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_BACK, ENTR_IMPAS_HOUSE_BACK, SINGLE_SCENE_INFO(SCENE_IMPAS_HOUSE), "Impa's House Back", "Kak Outside Impa's House Back", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "cow"}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_WINDMILL, ENTR_WINDMILL_AND_DAMPES_GRAVE_WINDMILL, SINGLE_SCENE_INFO(SCENE_WINDMILL_AND_DAMPES_GRAVE), "Windmill", "Kak Outside Windmill", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY, ENTR_SHOOTING_GALLERY_0, {{ SCENE_SHOOTING_GALLERY, 0x00 }}, "Kak Shooting Gallery", "Kak Outside Shooting Gallery", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOP_GRANNY, ENTR_POTION_SHOP_GRANNY_0, SINGLE_SCENE_INFO(SCENE_POTION_SHOP_GRANNY), "Granny's Potion Shop", "Kak Outside Granny's Potion Shop", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_BAZAAR, ENTR_BAZAAR_0, {{ SCENE_BAZAAR, 0x00 }}, "Kak Bazaar", "Kak Outside Bazaar", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR, "shop"}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_FRONT, ENTR_POTION_SHOP_KAKARIKO_FRONT, SINGLE_SCENE_INFO(SCENE_POTION_SHOP_KAKARIKO), "Kak Potion Shop Front", "Kak Outside Potion Shop Front", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_BACK, ENTR_POTION_SHOP_KAKARIKO_BACK, SINGLE_SCENE_INFO(SCENE_POTION_SHOP_KAKARIKO), "Kak Potion Shop Back", "Kak Outside Potion Shop Back", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_INTERIOR}, + { ENTRANCE_GROTTO_EXIT(GROTTO_KAK_OPEN_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_KAK_OPEN_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "Kak Open Grotto", "Kak Open Grotto Exit", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_GROTTO, "chest"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_KAK_REDEAD_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_KAK_REDEAD_OFFSET), {{ SCENE_GROTTOS, 0x03 }}, "Kak Redead Grotto", "Kak Redead Grotto Exit", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_GROTTO, "chest"}, + { ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL, ENTR_BOTTOM_OF_THE_WELL_ENTRANCE, SINGLE_SCENE_INFO(SCENE_BOTTOM_OF_THE_WELL), "Bottom of the Well Entrance", "Kak Outside BotW", ENTRANCE_GROUP_KAKARIKO, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_DUNGEON, "botw"}, // The Graveyard - { ENTR_KAKARIKO_VILLAGE_2, ENTR_GRAVEYARD_0, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "Graveyard", "Kakariko", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_GRAVEKEEPERS_HUT_0, ENTR_GRAVEYARD_2, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "Graveyard", "Dampe's Shack", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0, ENTR_GRAVEYARD_4, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "Graveyard", "Shield Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1}, - { ENTR_REDEAD_GRAVE_0, ENTR_GRAVEYARD_5, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "Graveyard", "Heart Piece Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1}, - { ENTR_ROYAL_FAMILYS_TOMB_0, ENTR_GRAVEYARD_6, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "Graveyard", "Composer's Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1}, - { ENTR_WINDMILL_AND_DAMPES_GRAVE_0, ENTR_GRAVEYARD_3, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "Graveyard", "Dampe's Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "race", 1}, - { ENTR_SHADOW_TEMPLE_0, ENTR_GRAVEYARD_1, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "Graveyard", "Shadow Temple", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_GRAVEYARD_2, ENTR_GRAVEKEEPERS_HUT_0, SINGLE_SCENE_INFO(SCENE_GRAVEKEEPERS_HUT), "Dampe's Shack", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_INTERIOR}, - { ENTR_GRAVEYARD_4, ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0, SINGLE_SCENE_INFO(SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN), "Shield Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO}, - { ENTR_GRAVEYARD_5, ENTR_REDEAD_GRAVE_0, SINGLE_SCENE_INFO(SCENE_REDEAD_GRAVE), "Heart Piece Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO}, - { ENTR_GRAVEYARD_6, ENTR_ROYAL_FAMILYS_TOMB_0, SINGLE_SCENE_INFO(SCENE_ROYAL_FAMILYS_TOMB), "Composer's Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO}, - { ENTR_GRAVEYARD_3, ENTR_WINDMILL_AND_DAMPES_GRAVE_0, SINGLE_SCENE_INFO(SCENE_WINDMILL_AND_DAMPES_GRAVE), "Dampe's Grave", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "race"}, - { ENTR_GRAVEYARD_1, ENTR_SHADOW_TEMPLE_0, SINGLE_SCENE_INFO(SCENE_SHADOW_TEMPLE), "Shadow Temple", "Graveyard", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON}, - { ENTR_SHADOW_TEMPLE_BOSS_0, ENTR_SHADOW_TEMPLE_1, SINGLE_SCENE_INFO(SCENE_SHADOW_TEMPLE), "Shadow Temple Boss Door", "Bongo-Bongo", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_SHADOW_TEMPLE_1, ENTR_SHADOW_TEMPLE_BOSS_0, SINGLE_SCENE_INFO(SCENE_SHADOW_TEMPLE_BOSS), "Bongo-Bongo", "Shadow Temple Boss Door", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_GRAVEYARD_8, -1, SINGLE_SCENE_INFO(SCENE_SHADOW_TEMPLE_BOSS), "Bongo-Bongo", "Shadow Temple Blue Warp", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, + { ENTR_KAKARIKO_VILLAGE_SOUTHEAST_EXIT, ENTR_GRAVEYARD_ENTRANCE, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "Graveyard Entrance", "Kakariko Southeast Exit", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_GRAVEKEEPERS_HUT_0, ENTR_GRAVEYARD_OUTSIDE_DAMPES_HUT, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "GY Outside Dampe's Hut", "Dampe's Hut", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0, ENTR_GRAVEYARD_SHIELD_GRAVE_EXIT, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "GY Near-Hut Grave Exit", "Shield Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1}, + { ENTR_REDEAD_GRAVE_0, ENTR_GRAVEYARD_HEART_PIECE_GRAVE_EXIT, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "GY Near-Tomb Grave Exit", "Heart Piece Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1}, + { ENTR_ROYAL_FAMILYS_TOMB_0, ENTR_GRAVEYARD_ROYAL_TOMB_EXIT, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "GY Royal Family's Tomb Exit", "Royal Family's Tomb", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "", 1}, + { ENTR_WINDMILL_AND_DAMPES_GRAVE_GRAVE, ENTR_GRAVEYARD_DAMPES_GRAVE_EXIT, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "GY Near-Ledge Grave Exit", "Dampe's Grave", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "race", 1}, + { ENTR_SHADOW_TEMPLE_ENTRANCE, ENTR_GRAVEYARD_OUTSIDE_TEMPLE, SINGLE_SCENE_INFO(SCENE_GRAVEYARD), "Graveyard Outside Temple", "Shadow Temple Entrance", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_GRAVEYARD_OUTSIDE_DAMPES_HUT, ENTR_GRAVEKEEPERS_HUT_0, SINGLE_SCENE_INFO(SCENE_GRAVEKEEPERS_HUT), "Dampe's Hut", "GY Outside Dampe's Hut", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_INTERIOR}, + { ENTR_GRAVEYARD_SHIELD_GRAVE_EXIT, ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0, SINGLE_SCENE_INFO(SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN), "Shield Grave", "GY Near-Hut Grave Exit", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO}, + { ENTR_GRAVEYARD_HEART_PIECE_GRAVE_EXIT, ENTR_REDEAD_GRAVE_0, SINGLE_SCENE_INFO(SCENE_REDEAD_GRAVE), "Heart Piece Grave", "GY Near-Tomb Grave Exit", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO}, + { ENTR_GRAVEYARD_ROYAL_TOMB_EXIT, ENTR_ROYAL_FAMILYS_TOMB_0, SINGLE_SCENE_INFO(SCENE_ROYAL_FAMILYS_TOMB), "Royal Family's Tomb", "GY Royal Family's Tomb Exit", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO}, + { ENTR_GRAVEYARD_DAMPES_GRAVE_EXIT, ENTR_WINDMILL_AND_DAMPES_GRAVE_GRAVE, SINGLE_SCENE_INFO(SCENE_WINDMILL_AND_DAMPES_GRAVE), "Dampe's Grave", "GY Near-Ledge Grave Exit", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_GROTTO, "race"}, + { ENTR_GRAVEYARD_OUTSIDE_TEMPLE, ENTR_SHADOW_TEMPLE_ENTRANCE, SINGLE_SCENE_INFO(SCENE_SHADOW_TEMPLE), "Shadow Temple Entrance", "Graveyard Outside Temple", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON}, + { ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE, ENTR_SHADOW_TEMPLE_BOSS_DOOR, SINGLE_SCENE_INFO(SCENE_SHADOW_TEMPLE), "Shadow Temple Boss Door", "Bongo-Bongo", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_SHADOW_TEMPLE_BOSS_DOOR, ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE, SINGLE_SCENE_INFO(SCENE_SHADOW_TEMPLE_BOSS), "Bongo-Bongo", "Shadow Temple Boss Door", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP, -1, SINGLE_SCENE_INFO(SCENE_SHADOW_TEMPLE_BOSS), "Bongo-Bongo", "Shadow Temple Blue Warp", ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_GROUP_GRAVEYARD, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, // Death Mountain Trail - { ENTR_GORON_CITY_0, ENTR_DEATH_MOUNTAIN_TRAIL_1, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT", "Goron City", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_OVERWORLD, "gc"}, - { ENTR_KAKARIKO_VILLAGE_1, ENTR_DEATH_MOUNTAIN_TRAIL_0, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT", "Kakariko", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_DEATH_MOUNTAIN_CRATER_0, ENTR_DEATH_MOUNTAIN_TRAIL_2, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT", "DMC", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0, ENTR_DEATH_MOUNTAIN_TRAIL_4, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT", "DMT Great Fairy Fountain", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_DMT_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_DMT_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT", "DMT Storms Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT", "DMT Cow Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "", 1}, - { ENTR_DODONGOS_CAVERN_0, ENTR_DEATH_MOUNTAIN_TRAIL_3, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT", "Dodongo's Cavern", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc", 1}, - { ENTR_DEATH_MOUNTAIN_TRAIL_4, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0x00 }}, "DMT Great Fairy Fountain", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_INTERIOR}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_DMT_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_DMT_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "DMT Storms Grotto", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "chest"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET), {{ SCENE_GROTTOS, 0x0D }}, "DMT Cow Grotto", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO}, - { ENTR_DEATH_MOUNTAIN_TRAIL_3, ENTR_DODONGOS_CAVERN_0, SINGLE_SCENE_INFO(SCENE_DODONGOS_CAVERN), "Dodongo's Cavern", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc"}, - { ENTR_DODONGOS_CAVERN_BOSS_0, ENTR_DODONGOS_CAVERN_1, SINGLE_SCENE_INFO(SCENE_DODONGOS_CAVERN), "Dodongo's Cavern Boss Door", "King Dodongo", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc", 1}, - { ENTR_DODONGOS_CAVERN_1, ENTR_DODONGOS_CAVERN_BOSS_0, SINGLE_SCENE_INFO(SCENE_DODONGOS_CAVERN_BOSS), "King Dodongo", "Dodongo's Cavern Boss Door", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc", 1}, - { ENTR_DEATH_MOUNTAIN_TRAIL_5, -1, SINGLE_SCENE_INFO(SCENE_DODONGOS_CAVERN_BOSS), "King Dodongo", "Dodongo's Cavern Blue Warp", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_ONE_WAY, "dc,bw", 1}, + { ENTR_GORON_CITY_UPPER_EXIT, ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "Death Mountain Trail Middle Exit", "Goron City Upper Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_OVERWORLD, "gc"}, + { ENTR_KAKARIKO_VILLAGE_GUARD_GATE, ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "Death Mountain Trail Bottom Exit", "Kakariko Guard Gate Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT, ENTR_DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "Death Mountain Trail Top Exit", "Death Mountain Crater Upper Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT, ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT Great Fairy Exit", "DMT Great Fairy Fountain", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_DMT_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_DMT_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT Rock Circle Grotto Exit", "DMT Storms Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "chest", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT Boulder Grotto Exit", "DMT Cow Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "", 1}, + { ENTR_DODONGOS_CAVERN_ENTRANCE, ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_TRAIL), "DMT Outside Dodongo's Cavern", "Dodongo's Cavern Entrance", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc", 1}, + { ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0x00 }}, "DMT Great Fairy Fountain", "DMT Great Fairy Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_INTERIOR}, + { ENTRANCE_GROTTO_EXIT(GROTTO_DMT_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_DMT_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "DMT Storms Grotto", "DMT Rock Circle Grotto Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO, "chest"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET), {{ SCENE_GROTTOS, 0x0D }}, "DMT Cow Grotto", "DMT Boulder Grotto Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_GROTTO}, + { ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN, ENTR_DODONGOS_CAVERN_ENTRANCE, SINGLE_SCENE_INFO(SCENE_DODONGOS_CAVERN), "Dodongo's Cavern Entrance", "DMT Outside Dodongo's Cavern", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc"}, + { ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE, ENTR_DODONGOS_CAVERN_BOSS_DOOR, SINGLE_SCENE_INFO(SCENE_DODONGOS_CAVERN), "Dodongo's Cavern Boss Door", "King Dodongo", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc", 1}, + { ENTR_DODONGOS_CAVERN_BOSS_DOOR, ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE, SINGLE_SCENE_INFO(SCENE_DODONGOS_CAVERN_BOSS), "King Dodongo", "Dodongo's Cavern Boss Door", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_DUNGEON, "dc", 1}, + { ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP, -1, SINGLE_SCENE_INFO(SCENE_DODONGOS_CAVERN_BOSS), "King Dodongo", "Dodongo's Cavern Blue Warp", ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_ONE_WAY, "dc,bw", 1}, // Death Mountain Crater - { ENTR_GORON_CITY_1, ENTR_DEATH_MOUNTAIN_CRATER_1, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC", "Goron City", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_OVERWORLD, "gc"}, - { ENTR_DEATH_MOUNTAIN_TRAIL_2, ENTR_DEATH_MOUNTAIN_CRATER_0, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC", "DMT", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1, ENTR_DEATH_MOUNTAIN_CRATER_3, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC", "DMC Great Fairy Fountain", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_DMC_UPPER_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_DMC_UPPER_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC", "DMC Upper Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC", "DMC Hammer Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, - { ENTR_FIRE_TEMPLE_0, ENTR_DEATH_MOUNTAIN_CRATER_2, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC", "Fire Temple", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_DEATH_MOUNTAIN_CRATER_3, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0x01 }}, "DMC Great Fairy Fountain", "DMC", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_INTERIOR}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_DMC_UPPER_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_DMC_UPPER_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "DMC Upper Grotto", "DMC", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "chest"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "DMC Hammer Grotto", "DMC", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "scrubs"}, - { ENTR_DEATH_MOUNTAIN_CRATER_2, ENTR_FIRE_TEMPLE_0, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE), "Fire Temple", "DMC", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON}, - { ENTR_FIRE_TEMPLE_BOSS_0, ENTR_FIRE_TEMPLE_1, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE), "Fire Temple Boss Door", "Volvagia", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_FIRE_TEMPLE_1, ENTR_FIRE_TEMPLE_BOSS_0, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE_BOSS), "Volvagia", "Fire Temple Boss Door", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_DEATH_MOUNTAIN_CRATER_5, -1, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE_BOSS), "Volvagia", "Fire Temple Blue Warp", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, + { ENTR_GORON_CITY_DARUNIA_ROOM_EXIT, ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "Death Mountain Crater Bridge Exit", "Goron City Darunia's Room Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_OVERWORLD, "gc"}, + { ENTR_DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT, ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "Death Mountain Crater Upper Exit", "Death Mountain Trail Top Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC, ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC Great Fairy Exit", "DMC Great Fairy Fountain", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_DMC_UPPER_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_DMC_UPPER_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC Upper Grotto Exit", "DMC Upper Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "chest", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET), SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "DMC Hammer Grotto Exit", "DMC Hammer Scrubs Grotto", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, + { ENTR_FIRE_TEMPLE_ENTRANCE, ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE, SINGLE_SCENE_INFO(SCENE_DEATH_MOUNTAIN_CRATER), "Death Mountain Crater Outside Temple", "Fire Temple Entrance", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0x01 }}, "DMC Great Fairy Fountain", "DMC Great Fairy Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_INTERIOR}, + { ENTRANCE_GROTTO_EXIT(GROTTO_DMC_UPPER_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_DMC_UPPER_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "DMC Upper Grotto", "DMC Upper Grotto Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "chest"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "DMC Hammer Grotto", "DMC Hammer Grotto Exit", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_GROTTO, "scrubs"}, + { ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE, ENTR_FIRE_TEMPLE_ENTRANCE, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE), "Fire Temple Entrance", "Death Mountain Crater Outside Temple", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON}, + { ENTR_FIRE_TEMPLE_BOSS_ENTRANCE, ENTR_FIRE_TEMPLE_BOSS_DOOR, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE), "Fire Temple Boss Door", "Volvagia", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_FIRE_TEMPLE_BOSS_DOOR, ENTR_FIRE_TEMPLE_BOSS_ENTRANCE, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE_BOSS), "Volvagia", "Fire Temple Boss Door", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP, -1, SINGLE_SCENE_INFO(SCENE_FIRE_TEMPLE_BOSS), "Volvagia", "Fire Temple Blue Warp", ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, // Goron City - { ENTR_DEATH_MOUNTAIN_TRAIL_1, ENTR_GORON_CITY_0, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "Goron City", "DMT", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_OVERWORLD, "gc"}, - { ENTR_DEATH_MOUNTAIN_CRATER_1, ENTR_GORON_CITY_1, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "Goron City", "DMC", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_OVERWORLD, "gc"}, - { ENTR_LOST_WOODS_6, ENTR_GORON_CITY_3, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "Goron City", "Lost Woods", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "gc,lw"}, - { ENTR_GORON_SHOP_0, ENTR_GORON_CITY_2, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "Goron City", "Goron Shop", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_INTERIOR, "gc", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET), SINGLE_SCENE_INFO(SCENE_GORON_CITY), "Goron City", "Goron City Grotto", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_GROTTO, "gc,scrubs", 1}, - { ENTR_GORON_CITY_2, ENTR_GORON_SHOP_0, SINGLE_SCENE_INFO(SCENE_GORON_SHOP), "Goron Shop", "Goron City", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_INTERIOR, "gc"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "Goron City Grotto", "Goron City", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_GROTTO, "gc,scrubs"}, + { ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT, ENTR_GORON_CITY_UPPER_EXIT, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "Goron City Upper Exit", "Death Mountain Trail Middle Exit", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_DEATH_MOUNTAIN_TRAIL, ENTRANCE_TYPE_OVERWORLD, "gc"}, + { ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT, ENTR_GORON_CITY_DARUNIA_ROOM_EXIT, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "Goron City Darunia's Room Exit", "Death Mountain Crater Bridge Exit", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_DEATH_MOUNTAIN_CRATER, ENTRANCE_TYPE_OVERWORLD, "gc"}, + { ENTR_LOST_WOODS_TUNNEL_SHORTCUT, ENTR_GORON_CITY_TUNNEL_SHORTCUT, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "GC Tunnel Shortcut", "LW Tunnel Shortcut", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "gc,lw"}, + { ENTR_GORON_SHOP_0, ENTR_GORON_CITY_OUTSIDE_SHOP, SINGLE_SCENE_INFO(SCENE_GORON_CITY), "GC Outside Shop", "Goron Shop", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_INTERIOR, "gc", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET), SINGLE_SCENE_INFO(SCENE_GORON_CITY), "GC Lava Grotto Exit", "Goron City Grotto", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_GROTTO, "gc,scrubs", 1}, + { ENTR_GORON_CITY_OUTSIDE_SHOP, ENTR_GORON_SHOP_0, SINGLE_SCENE_INFO(SCENE_GORON_SHOP), "Goron Shop", "GC Outside Shop", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_INTERIOR, "gc"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "Goron City Grotto", "GC Lava Grotto Exit", ENTRANCE_GROUP_GORON_CITY, ENTRANCE_GROUP_GORON_CITY, ENTRANCE_TYPE_GROTTO, "gc,scrubs"}, // Zora's River - { ENTR_HYRULE_FIELD_2, ENTR_ZORAS_RIVER_0, SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR", "Hyrule Field", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, - { ENTR_LOST_WOODS_7, ENTR_ZORAS_RIVER_4, SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR", "Lost Woods", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"}, - { ENTR_ZORAS_DOMAIN_0, ENTR_ZORAS_RIVER_2, SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR", "Zora's Domain", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR", "ZR Storms Grotto", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_ZR_FAIRY_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_ZR_FAIRY_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR", "ZR Fairy Grotto", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_ZR_OPEN_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_ZR_OPEN_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR", "ZR Open Grotto", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x0A }}, "ZR Storms Grotto", "ZR", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "scrubs"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_ZR_FAIRY_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_ZR_FAIRY_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "ZR Fairy Grotto", "ZR", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_ZR_OPEN_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_ZR_OPEN_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "ZR Open Grotto", "ZR", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "chest"}, + { ENTR_HYRULE_FIELD_RIVER_EXIT, ENTR_ZORAS_RIVER_WEST_EXIT, SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "Zora's River West Exit", "Hyrule Field River Exit", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, + { ENTR_LOST_WOODS_UNDERWATER_SHORTCUT, ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT, SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR Underwater Shortcut", "LW Underwater Shortcut", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "lw"}, + { ENTR_ZORAS_DOMAIN_ENTRANCE, ENTR_ZORAS_RIVER_WATERFALL_EXIT, SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "Zora's River Waterfall Exit", "Zora's Domain Entrance", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD}, + { ENTRANCE_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR Rock Circle Grotto Exit", "ZR Storms Grotto", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_ZR_FAIRY_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_ZR_FAIRY_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR Raised Boulder Grotto Exit", "ZR Fairy Grotto", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_ZR_OPEN_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_ZR_OPEN_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_RIVER), "ZR Raised Open Grotto Exit", "ZR Open Grotto", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "chest", 1}, + { ENTRANCE_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x0A }}, "ZR Storms Grotto", "ZR Rock Circle Grotto Exit", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "scrubs"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_ZR_FAIRY_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_ZR_FAIRY_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "ZR Fairy Grotto", "ZR Raised Boulder Grotto Exit", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO}, + { ENTRANCE_GROTTO_EXIT(GROTTO_ZR_OPEN_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_ZR_OPEN_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "ZR Open Grotto", "ZR Raised Open Grotto Exit", ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_GROTTO, "chest"}, // Zora's Domain - { ENTR_ZORAS_RIVER_2, ENTR_ZORAS_DOMAIN_0, SINGLE_SCENE_INFO(SCENE_ZORAS_DOMAIN), "Zora's Domain", "ZR", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_LAKE_HYLIA_7, ENTR_ZORAS_DOMAIN_4, SINGLE_SCENE_INFO(SCENE_ZORAS_DOMAIN), "Zora's Domain", "Lake Hylia", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_OVERWORLD, "lh"}, - { ENTR_ZORAS_FOUNTAIN_2, ENTR_ZORAS_DOMAIN_1, SINGLE_SCENE_INFO(SCENE_ZORAS_DOMAIN), "Zora's Domain", "ZF", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_ZORA_SHOP_0, ENTR_ZORAS_DOMAIN_2, SINGLE_SCENE_INFO(SCENE_ZORAS_DOMAIN), "Zora's Domain", "Zora Shop", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_DOMAIN), "Zora's Domain", "ZD Storms Grotto", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_GROTTO, "fairy", 1}, - { ENTR_ZORAS_DOMAIN_2, ENTR_ZORA_SHOP_0, SINGLE_SCENE_INFO(SCENE_ZORA_SHOP), "Zora Shop", "Zora's Domain", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_INTERIOR}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "ZD Storms Grotto", "Zora's Domain", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_GROTTO, "fairy"}, + { ENTR_ZORAS_RIVER_WATERFALL_EXIT, ENTR_ZORAS_DOMAIN_ENTRANCE, SINGLE_SCENE_INFO(SCENE_ZORAS_DOMAIN), "Zora's Domain Entrance", "Zora's River Waterfall Exit", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT, ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT, SINGLE_SCENE_INFO(SCENE_ZORAS_DOMAIN), "ZD Underwater Shortcut", "LH Underwater Shortcut", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_OVERWORLD, "lh"}, + { ENTR_ZORAS_FOUNTAIN_TUNNEL_EXIT, ENTR_ZORAS_DOMAIN_KING_ZORA_EXIT, SINGLE_SCENE_INFO(SCENE_ZORAS_DOMAIN), "Zora's Domain King Zora Exit", "Zora's Fountain Tunnel Exit", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_ZORA_SHOP_0, ENTR_ZORAS_DOMAIN_OUTSIDE_SHOP, SINGLE_SCENE_INFO(SCENE_ZORAS_DOMAIN), "ZD Outside Shop", "Zora Shop", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_ZORAS_DOMAIN), "ZD Island Grotto Exit", "ZD Storms Grotto", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_GROTTO, "fairy", 1}, + { ENTR_ZORAS_DOMAIN_OUTSIDE_SHOP, ENTR_ZORA_SHOP_0, SINGLE_SCENE_INFO(SCENE_ZORA_SHOP), "Zora Shop", "ZD Outside Shop", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_INTERIOR}, + { ENTRANCE_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "ZD Storms Grotto", "ZD Island Grotto Exit", ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_GROTTO, "fairy"}, // Zora's Fountain - { ENTR_ZORAS_DOMAIN_1, ENTR_ZORAS_FOUNTAIN_2, SINGLE_SCENE_INFO(SCENE_ZORAS_FOUNTAIN), "ZF", "Zora's Domain", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0, ENTR_ZORAS_FOUNTAIN_5, SINGLE_SCENE_INFO(SCENE_ZORAS_FOUNTAIN), "ZF", "ZF Great Fairy Fountain", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_JABU_JABU_0, ENTR_ZORAS_FOUNTAIN_1, SINGLE_SCENE_INFO(SCENE_ZORAS_FOUNTAIN), "ZF", "Jabu Jabu's Belly", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_ICE_CAVERN_0, ENTR_ZORAS_FOUNTAIN_3, SINGLE_SCENE_INFO(SCENE_ZORAS_FOUNTAIN), "ZF", "Ice Cavern", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_ZORAS_FOUNTAIN_5, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0x00 }}, "ZF Great Fairy Fountain", "ZF", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_INTERIOR}, - { ENTR_ZORAS_FOUNTAIN_1, ENTR_JABU_JABU_0, SINGLE_SCENE_INFO(SCENE_JABU_JABU), "Jabu Jabu's Belly", "ZF", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON}, - { ENTR_JABU_JABU_BOSS_0, ENTR_JABU_JABU_1, SINGLE_SCENE_INFO(SCENE_JABU_JABU), "Jabu Jabu's Belly Boss Door", "Barinade", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_JABU_JABU_1, ENTR_JABU_JABU_BOSS_0, SINGLE_SCENE_INFO(SCENE_JABU_JABU_BOSS), "Barinade", "Jabu Jabu's Belly Boss Door", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_ZORAS_FOUNTAIN_0, -1, SINGLE_SCENE_INFO(SCENE_JABU_JABU_BOSS), "Barinade", "Jabu Jabu's Belly Blue Warp", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, - { ENTR_ZORAS_FOUNTAIN_3, ENTR_ICE_CAVERN_0, SINGLE_SCENE_INFO(SCENE_ICE_CAVERN), "Ice Cavern", "ZF", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON}, + { ENTR_ZORAS_DOMAIN_KING_ZORA_EXIT, ENTR_ZORAS_FOUNTAIN_TUNNEL_EXIT, SINGLE_SCENE_INFO(SCENE_ZORAS_FOUNTAIN), "Zora's Fountain Tunnel Exit", "Zora's Domain King Zora Exit", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF, ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY, SINGLE_SCENE_INFO(SCENE_ZORAS_FOUNTAIN), "ZF Outside Great Fairy", "ZF Great Fairy Fountain", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_JABU_JABU_ENTRANCE, ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU, SINGLE_SCENE_INFO(SCENE_ZORAS_FOUNTAIN), "ZF Outside Jabu Jabu", "Jabu Jabu's Belly Entrance", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_ICE_CAVERN_ENTRANCE, ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN, SINGLE_SCENE_INFO(SCENE_ZORAS_FOUNTAIN), "ZF Outside Ice Cavern", "Ice Cavern Entrance", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0x00 }}, "ZF Great Fairy Fountain", "ZF Outside Great Fairy", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_INTERIOR}, + { ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU, ENTR_JABU_JABU_ENTRANCE, SINGLE_SCENE_INFO(SCENE_JABU_JABU), "Jabu Jabu's Belly Entrance", "ZF Outside Jabu Jabu", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON}, + { ENTR_JABU_JABU_BOSS_ENTRANCE, ENTR_JABU_JABU_BOSS_DOOR, SINGLE_SCENE_INFO(SCENE_JABU_JABU), "Jabu Jabu's Belly Boss Door", "Barinade", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_JABU_JABU_BOSS_DOOR, ENTR_JABU_JABU_BOSS_ENTRANCE, SINGLE_SCENE_INFO(SCENE_JABU_JABU_BOSS), "Barinade", "Jabu Jabu's Belly Boss Door", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP, -1, SINGLE_SCENE_INFO(SCENE_JABU_JABU_BOSS), "Barinade", "Jabu Jabu's Belly Blue Warp", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, + { ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN, ENTR_ICE_CAVERN_ENTRANCE, SINGLE_SCENE_INFO(SCENE_ICE_CAVERN), "Ice Cavern Entrance", "ZF Outside Ice Cavern", ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_GROUP_ZORAS_FOUNTAIN, ENTRANCE_TYPE_DUNGEON}, // Hyrule Field - { ENTR_LOST_WOODS_8, ENTR_HYRULE_FIELD_3, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "Lost Woods Bridge", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "hf,lw"}, - { ENTR_MARKET_ENTRANCE_DAY_1, ENTR_HYRULE_FIELD_7, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "Market Entrance", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD, "hf"}, - { ENTR_LON_LON_RANCH_0, ENTR_HYRULE_FIELD_6, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "Lon Lon Ranch", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_OVERWORLD, "hf,llr"}, - { ENTR_KAKARIKO_VILLAGE_0, ENTR_HYRULE_FIELD_1, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "Kakariko", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_OVERWORLD, "hf"}, - { ENTR_ZORAS_RIVER_0, ENTR_HYRULE_FIELD_2, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "ZR", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_OVERWORLD, "hf"}, - { ENTR_LAKE_HYLIA_0, ENTR_HYRULE_FIELD_4, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "Lake Hylia", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_OVERWORLD, "hf,lh"}, - { ENTR_GERUDO_VALLEY_0, ENTR_HYRULE_FIELD_5, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "GV", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_OVERWORLD, "hf"}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_NEAR_MARKET_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_NEAR_MARKET_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "HF Near Market Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_NEAR_KAK_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_NEAR_KAK_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "HF Near Kak Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "spider", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_TEKTITE_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_TEKTITE_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "HF Tektite Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "water", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_FAIRY_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_FAIRY_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "HF Fairy Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_COW_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_COW_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "HF Cow Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "webbed", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_OPEN_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_OPEN_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "HF Open Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "HF Inside Fence Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_SOUTHEAST_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_SOUTHEAST_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field", "HF Southeast Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest", 1}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_NEAR_MARKET_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_NEAR_MARKET_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "HF Near Market Grotto", "Hyrule Field", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_NEAR_KAK_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_NEAR_KAK_OFFSET), {{ SCENE_GROTTOS, 0x01 }}, "HF Near Kak Grotto", "Hyrule Field", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "spider"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_TEKTITE_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_TEKTITE_OFFSET), {{ SCENE_GROTTOS, 0x0B }}, "HF Tektite Grotto", "Hyrule Field", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "water"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_FAIRY_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_FAIRY_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "HF Fairy Grotto", "Hyrule Field", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_COW_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_COW_OFFSET), {{ SCENE_GROTTOS, 0x05 }}, "HF Cow Grotto", "Hyrule Field", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "webbed"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_OPEN_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_OPEN_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "HF Open Grotto", "Hyrule Field", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET), {{ SCENE_GROTTOS, 0x02 }}, "HF Inside Fence Grotto", "Hyrule Field", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "srubs"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HF_SOUTHEAST_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HF_SOUTHEAST_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "HF Southeast Grotto", "Hyrule Field", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest"}, + { ENTR_LOST_WOODS_BRIDGE_WEST_EXIT, ENTR_HYRULE_FIELD_WOODED_EXIT, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field Wooded Exit", "Lost Woods Bridge West Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_LOST_WOODS, ENTRANCE_TYPE_OVERWORLD, "hf,lw"}, + { ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT, ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field Drawbridge Exit", "Market Entrance South Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD, "hf"}, + { ENTR_LON_LON_RANCH_ENTRANCE, ENTR_HYRULE_FIELD_CENTER_EXIT, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field Center Exit", "Lon Lon Ranch Entrance", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_OVERWORLD, "hf,llr"}, + { ENTR_KAKARIKO_VILLAGE_FRONT_GATE, ENTR_HYRULE_FIELD_STAIRS_EXIT, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field Stairs Exit", "Kakariko Front Gate", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_KAKARIKO, ENTRANCE_TYPE_OVERWORLD, "hf"}, + { ENTR_ZORAS_RIVER_WEST_EXIT, ENTR_HYRULE_FIELD_RIVER_EXIT, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field River Exit", "Zora's River West Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_ZORAS_RIVER, ENTRANCE_TYPE_OVERWORLD, "hf"}, + { ENTR_LAKE_HYLIA_NORTH_EXIT, ENTR_HYRULE_FIELD_FENCE_EXIT, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field Fence Exit", "Lake Hylia North Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_OVERWORLD, "hf,lh"}, + { ENTR_GERUDO_VALLEY_EAST_EXIT, ENTR_HYRULE_FIELD_ROCKY_PATH, SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "Hyrule Field Rocky Path", "Gerudo Valley East Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_OVERWORLD, "hf"}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_MARKET_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_MARKET_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF Near Market Boulder Grotto Exit", "HF Near Market Boulder Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_KAK_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_KAK_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF Near Stairs Tree Grotto Exit", "HF Near Stairs Tree Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "spider", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HF_TEKTITE_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_TEKTITE_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF Northwest Tree Grotto Exit", "HF Tektite Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "water", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HF_FAIRY_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_FAIRY_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF Northwest Boulder Grotto Exit", "HF Fairy Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HF_COW_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_COW_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF West Rock Circle Grotto Exit", "HF Cow Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "webbed", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HF_OPEN_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_OPEN_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF South Open Grotto Exit", "HF Open Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF Fenced Grotto Exit", "HF Fenced Scrub Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HF_SOUTHEAST_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HF_SOUTHEAST_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_FIELD), "HF Southeast Boulder Grotto Exit", "HF Southeast Grotto", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest", 1}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_MARKET_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_MARKET_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "HF Near Market Boulder Grotto", "HF Near Market Boulder Grotto Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_KAK_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_KAK_OFFSET), {{ SCENE_GROTTOS, 0x01 }}, "HF Near Kak Grotto", "Hyrule Field", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "spider"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HF_TEKTITE_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_TEKTITE_OFFSET), {{ SCENE_GROTTOS, 0x0B }}, "HF Tektite Grotto", "HF Northwest Tree Grotto Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "water"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HF_FAIRY_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_FAIRY_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "HF Fairy Grotto", "HF Northwest Boulder Grotto Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HF_COW_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_COW_OFFSET), {{ SCENE_GROTTOS, 0x05 }}, "HF Cow Grotto", "Hyrule Field", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "webbed"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HF_OPEN_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_OPEN_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "HF Open Grotto", "HF South Open Grotto Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET), {{ SCENE_GROTTOS, 0x02 }}, "HF Fenced Scrub Grotto", "HF Fenced Grotto Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "srubs"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HF_SOUTHEAST_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HF_SOUTHEAST_OFFSET), {{ SCENE_GROTTOS, 0x00 }}, "HF Southeast Grotto", "HF Southeast Boulder Grotto Exit", ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_GROTTO, "chest"}, // Lon Lon Ranch - { ENTR_HYRULE_FIELD_6, ENTR_LON_LON_RANCH_0, SINGLE_SCENE_INFO(SCENE_LON_LON_RANCH), "Lon Lon Ranch", "Hyrule Field", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, - { ENTR_LON_LON_BUILDINGS_0, ENTR_LON_LON_RANCH_4, SINGLE_SCENE_INFO(SCENE_LON_LON_RANCH), "Lon Lon Ranch", "Talon's House", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "llr", 1}, - { ENTR_STABLE_0, ENTR_LON_LON_RANCH_5, SINGLE_SCENE_INFO(SCENE_LON_LON_RANCH), "Lon Lon Ranch", "LLR Stables", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "cow", 1}, - { ENTR_LON_LON_BUILDINGS_1, ENTR_LON_LON_RANCH_10, SINGLE_SCENE_INFO(SCENE_LON_LON_RANCH), "Lon Lon Ranch", "LLR Tower", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "cow", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_LLR_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_LLR_OFFSET), SINGLE_SCENE_INFO(SCENE_LON_LON_RANCH), "Lon Lon Ranch", "LLR Grotto", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, - { ENTR_LON_LON_RANCH_4, ENTR_LON_LON_BUILDINGS_0, {{ SCENE_LON_LON_BUILDINGS, 0x00 }}, "Talon's House", "Lon Lon Ranch", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "llr"}, - { ENTR_LON_LON_RANCH_5, ENTR_STABLE_0, SINGLE_SCENE_INFO(SCENE_STABLE), "LLR Stables", "Lon Lon Ranch", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "cow"}, - { ENTR_LON_LON_RANCH_10, ENTR_LON_LON_BUILDINGS_1, {{ SCENE_LON_LON_BUILDINGS, 0x01 }}, "LLR Tower", "Lon Lon Ranch", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "cow"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_LLR_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_LLR_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "LLR Grotto", "Lon Lon Ranch", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_GROTTO, "scrubs"}, + { ENTR_HYRULE_FIELD_CENTER_EXIT, ENTR_LON_LON_RANCH_ENTRANCE, SINGLE_SCENE_INFO(SCENE_LON_LON_RANCH), "Lon Lon Ranch Entrance", "Hyrule Field Center Exit", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, + { ENTR_LON_LON_BUILDINGS_TALONS_HOUSE, ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE, SINGLE_SCENE_INFO(SCENE_LON_LON_RANCH), "LLR Outside Talon's House", "Talon's House", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "llr", 1}, + { ENTR_STABLE_0, ENTR_LON_LON_RANCH_OUTSIDE_STABLES, SINGLE_SCENE_INFO(SCENE_LON_LON_RANCH), "LLR Outside Stables", "LLR Stables", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "cow", 1}, + { ENTR_LON_LON_BUILDINGS_TOWER, ENTR_LON_LON_RANCH_OUTSIDE_TOWER, SINGLE_SCENE_INFO(SCENE_LON_LON_RANCH), "LLR Outside Tower", "LLR Tower", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "cow", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_LLR_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_LLR_OFFSET), SINGLE_SCENE_INFO(SCENE_LON_LON_RANCH), "LLR Grotto Exit", "LLR Scrubs Grotto", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, + { ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE, ENTR_LON_LON_BUILDINGS_TALONS_HOUSE, {{ SCENE_LON_LON_BUILDINGS, 0x00 }}, "Talon's House", "LLR Outside Talon's House", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "llr"}, + { ENTR_LON_LON_RANCH_OUTSIDE_STABLES, ENTR_STABLE_0, SINGLE_SCENE_INFO(SCENE_STABLE), "LLR Stables", "LLR Outside Stables", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "cow"}, + { ENTR_LON_LON_RANCH_OUTSIDE_TOWER, ENTR_LON_LON_BUILDINGS_TOWER, {{ SCENE_LON_LON_BUILDINGS, 0x01 }}, "LLR Tower", "Lon Lon Ranch", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_INTERIOR, "cow"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_LLR_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_LLR_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "LLR Scrubs Grotto", "LLR Grotto Exit", ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_GROUP_LON_LON_RANCH, ENTRANCE_TYPE_GROTTO, "scrubs"}, // Lake Hylia - { ENTR_HYRULE_FIELD_4, ENTR_LAKE_HYLIA_0, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "Lake Hylia", "Hyrule Field", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "lh"}, - { ENTR_ZORAS_DOMAIN_4, ENTR_LAKE_HYLIA_7, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "Lake Hylia", "Zora's Domain", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD, "lh"}, - { ENTR_LAKESIDE_LABORATORY_0, ENTR_LAKE_HYLIA_4, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "Lake Hylia", "LH Lab", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh", 1}, - { ENTR_FISHING_POND_0, ENTR_LAKE_HYLIA_6, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "Lake Hylia", "Fishing Hole", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_LH_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_LH_OFFSET), SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "Lake Hylia", "LH Grotto", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, - { ENTR_WATER_TEMPLE_0, ENTR_LAKE_HYLIA_2, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "Lake Hylia", "Water Temple", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh", 1}, - { ENTR_LAKE_HYLIA_4, ENTR_LAKESIDE_LABORATORY_0, SINGLE_SCENE_INFO(SCENE_LAKESIDE_LABORATORY), "LH Lab", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh"}, - { ENTR_LAKE_HYLIA_6, ENTR_FISHING_POND_0, SINGLE_SCENE_INFO(SCENE_FISHING_POND), "Fishing Hole", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_LH_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_LH_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "LH Grotto", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_GROTTO, "lh,scrubs"}, - { ENTR_LAKE_HYLIA_2, ENTR_WATER_TEMPLE_0, SINGLE_SCENE_INFO(SCENE_WATER_TEMPLE), "Water Temple", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh"}, - { ENTR_WATER_TEMPLE_BOSS_0, ENTR_WATER_TEMPLE_1, SINGLE_SCENE_INFO(SCENE_WATER_TEMPLE), "Water Temple Boss Door", "Morpha", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh", 1}, - { ENTR_WATER_TEMPLE_1, ENTR_WATER_TEMPLE_BOSS_0, SINGLE_SCENE_INFO(SCENE_WATER_TEMPLE_BOSS), "Morpha", "Water Temple Boss Door", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh", 1}, - { ENTR_LAKE_HYLIA_9, -1, SINGLE_SCENE_INFO(SCENE_WATER_TEMPLE_BOSS), "Morpha", "Water Temple Blue Warp", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_ONE_WAY, "lh,bw", 1}, + { ENTR_HYRULE_FIELD_FENCE_EXIT, ENTR_LAKE_HYLIA_NORTH_EXIT, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "Lake Hylia North Exit", "Hyrule Field Fenced Exit", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "lh"}, + { ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT, ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "LH Underwater Shortcut", "ZD Underwater Shortcut", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_ZORAS_DOMAIN, ENTRANCE_TYPE_OVERWORLD, "lh"}, + { ENTR_LAKESIDE_LABORATORY_0, ENTR_LAKE_HYLIA_OUTSIDE_LAB, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "LH Outside Lab", "LH Lab", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh", 1}, + { ENTR_FISHING_POND_0, ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "LH Outside Fishing Pond", "Fishing Pond", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_LH_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_LH_OFFSET), SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "LH Grave Grotto Exit", "LH Grotto", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, + { ENTR_WATER_TEMPLE_ENTRANCE, ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE, SINGLE_SCENE_INFO(SCENE_LAKE_HYLIA), "Lake Hylia Outside Temple", "Water Temple Entrance", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh", 1}, + { ENTR_LAKE_HYLIA_OUTSIDE_LAB, ENTR_LAKESIDE_LABORATORY_0, SINGLE_SCENE_INFO(SCENE_LAKESIDE_LABORATORY), "LH Lab", "LH Outside Lab", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh"}, + { ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND, ENTR_FISHING_POND_0, SINGLE_SCENE_INFO(SCENE_FISHING_POND), "Fishing Pond", "LH Outside Fishing Pond", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_INTERIOR, "lh"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_LH_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_LH_OFFSET), {{ SCENE_GROTTOS, 0x04 }}, "LH Grotto", "Lake Hylia", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_GROTTO, "lh,scrubs"}, + { ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE, ENTR_WATER_TEMPLE_ENTRANCE, SINGLE_SCENE_INFO(SCENE_WATER_TEMPLE), "Water Temple Entrance", "Lake Hylia Outside Temple", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh"}, + { ENTR_WATER_TEMPLE_BOSS_ENTRANCE, ENTR_WATER_TEMPLE_BOSS_DOOR, SINGLE_SCENE_INFO(SCENE_WATER_TEMPLE), "Water Temple Boss Door", "Morpha", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh", 1}, + { ENTR_WATER_TEMPLE_BOSS_DOOR, ENTR_WATER_TEMPLE_BOSS_ENTRANCE, SINGLE_SCENE_INFO(SCENE_WATER_TEMPLE_BOSS), "Morpha", "Water Temple Boss Door", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_DUNGEON, "lh", 1}, + { ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP, -1, SINGLE_SCENE_INFO(SCENE_WATER_TEMPLE_BOSS), "Morpha", "Water Temple Blue Warp", ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_ONE_WAY, "lh,bw", 1}, // Gerudo Area - { ENTR_HYRULE_FIELD_5, ENTR_GERUDO_VALLEY_0, SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "GV", "Hyrule Field", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, - { ENTR_GERUDOS_FORTRESS_0, ENTR_GERUDO_VALLEY_3, SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "GV", "GF", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_OVERWORLD, "gerudo fortress"}, - { ENTR_LAKE_HYLIA_1, -1, SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "GV", "Lake Hylia", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_OVERWORLD, "lh"}, - { ENTR_CARPENTERS_TENT_0, ENTR_GERUDO_VALLEY_4, SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "GV", "Carpenters' Tent", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_GV_OCTOROK_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_GV_OCTOROK_OFFSET), SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "GV", "GV Octorok Grotto", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_GV_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_GV_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "GV", "GV Storms Grotto", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, - { ENTR_GERUDO_VALLEY_3, ENTR_GERUDOS_FORTRESS_0, SINGLE_SCENE_INFO(SCENE_GERUDOS_FORTRESS), "GF", "GV", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_OVERWORLD, "gerudo fortress"}, - { ENTR_HAUNTED_WASTELAND_0, ENTR_GERUDOS_FORTRESS_15, SINGLE_SCENE_INFO(SCENE_GERUDOS_FORTRESS), "GF", "Haunted Wasteland", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_OVERWORLD, "gerudo fortress"}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_GF_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_GERUDOS_FORTRESS), "GF", "GF Storms Grotto", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO, "gerudo fortress", 1}, - { ENTR_GERUDO_TRAINING_GROUND_0, ENTR_GERUDOS_FORTRESS_14, SINGLE_SCENE_INFO(SCENE_GERUDOS_FORTRESS), "GF", "Gerudo Training Grounds", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_DUNGEON, "gerudo fortress,gtg", 1}, - { ENTR_GERUDO_VALLEY_4, ENTR_CARPENTERS_TENT_0, SINGLE_SCENE_INFO(SCENE_CARPENTERS_TENT), "Carpenters' Tent", "GV", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_INTERIOR}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_GV_OCTOROK_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_GV_OCTOROK_OFFSET), {{ SCENE_GROTTOS, 0x06 }}, "GV Octorok Grotto", "GV", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_GV_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_GV_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x0A }}, "GV Storms Grotto", "GV", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO, "scrubs"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_GF_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "GF Storms Grotto", "GF", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO, "gerudo fortress"}, - { ENTR_GERUDOS_FORTRESS_14, ENTR_GERUDO_TRAINING_GROUND_0, SINGLE_SCENE_INFO(SCENE_GERUDO_TRAINING_GROUND), "Gerudo Training Grounds", "GF", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_DUNGEON, "gerudo fortress,gtg"}, + { ENTR_HYRULE_FIELD_ROCKY_PATH, ENTR_GERUDO_VALLEY_EAST_EXIT, SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "Gerudo Valley East Exit", "Hyrule Field Rocky Path", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, + { ENTR_GERUDOS_FORTRESS_EAST_EXIT, ENTR_GERUDO_VALLEY_WEST_EXIT, SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "Gerudo Valley West Exit", "Gerudo Fortress East Exit", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_OVERWORLD, "gerudo fortress"}, + { ENTR_LAKE_HYLIA_RIVER_EXIT, -1, SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "Gerudo Valley River Exit", "Lake Hylia River Exit", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_LAKE_HYLIA, ENTRANCE_TYPE_OVERWORLD, "lh"}, + { ENTR_CARPENTERS_TENT_0, ENTR_GERUDO_VALLEY_OUTSIDE_TENT, SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "GV Outside Carpenters' Tent", "Carpenters' Tent", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_GV_OCTOROK_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_GV_OCTOROK_OFFSET), SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "GV Silver Rock Grotto Exit", "GV Octorok Grotto", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_GV_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_GV_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_GERUDO_VALLEY), "GV Behind Tent Grotto Exit", "GV Storms Grotto", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO, "scrubs", 1}, + { ENTR_GERUDO_VALLEY_WEST_EXIT, ENTR_GERUDOS_FORTRESS_EAST_EXIT, SINGLE_SCENE_INFO(SCENE_GERUDOS_FORTRESS), "Gerudo Fortress East Exit", "Gerudo Valley West Exit", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_OVERWORLD, "gerudo fortress"}, + { ENTR_HAUNTED_WASTELAND_EAST_EXIT, ENTR_GERUDOS_FORTRESS_GATE_EXIT, SINGLE_SCENE_INFO(SCENE_GERUDOS_FORTRESS), "Gerudo Fortress Gate Exit", "Haunted Wasteland", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_OVERWORLD, "gerudo fortress"}, + { ENTRANCE_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_GF_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_GERUDOS_FORTRESS), "GF Outside Storms Grotto", "GF Storms Grotto", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO, "gerudo fortress", 1}, + { ENTR_GERUDO_TRAINING_GROUND_ENTRANCE, ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND, SINGLE_SCENE_INFO(SCENE_GERUDOS_FORTRESS), "GF Outside Training Ground", "Gerudo Training Ground Entrance", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_DUNGEON, "gerudo fortress,gtg", 1}, + { ENTR_GERUDO_VALLEY_OUTSIDE_TENT, ENTR_CARPENTERS_TENT_0, SINGLE_SCENE_INFO(SCENE_CARPENTERS_TENT), "Carpenters' Tent", "GV Outside Carpenters' Tent", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_INTERIOR}, + { ENTRANCE_GROTTO_EXIT(GROTTO_GV_OCTOROK_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_GV_OCTOROK_OFFSET), {{ SCENE_GROTTOS, 0x06 }}, "GV Octorok Grotto", "GV Silver Rock Grotto Exit", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO}, + { ENTRANCE_GROTTO_EXIT(GROTTO_GV_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_GV_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x0A }}, "GV Storms Grotto", "GV Behind Tent Grotto Exit", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO, "scrubs"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_GF_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET), {{ SCENE_FAIRYS_FOUNTAIN, 0x00 }}, "GF Storms Grotto", "GF Storms Grotto Exit", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_GROTTO, "gerudo fortress"}, + { ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE, SINGLE_SCENE_INFO(SCENE_GERUDO_TRAINING_GROUND), "Gerudo Training Ground Entrance", "GF Outside Training Ground", ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_DUNGEON, "gerudo fortress,gtg"}, // The Wasteland - { ENTR_GERUDOS_FORTRESS_15, ENTR_HAUNTED_WASTELAND_0, SINGLE_SCENE_INFO(SCENE_HAUNTED_WASTELAND), "Haunted Wasteland", "GF", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_OVERWORLD, "hw,gerudo fortress"}, - { ENTR_DESERT_COLOSSUS_0, ENTR_HAUNTED_WASTELAND_1, SINGLE_SCENE_INFO(SCENE_HAUNTED_WASTELAND), "Haunted Wasteland", "Desert Colossus", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_OVERWORLD, "dc,hw"}, - { ENTR_HAUNTED_WASTELAND_1, ENTR_DESERT_COLOSSUS_0, SINGLE_SCENE_INFO(SCENE_DESERT_COLOSSUS), "Desert Colossus", "Haunted Wasteland", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_OVERWORLD, "dc,hw"}, - { ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2, ENTR_DESERT_COLOSSUS_7, SINGLE_SCENE_INFO(SCENE_DESERT_COLOSSUS), "Desert Colossus", "Colossus Great Fairy Fountain", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_INTERIOR, "dc", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_COLOSSUS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_COLOSSUS_OFFSET), SINGLE_SCENE_INFO(SCENE_DESERT_COLOSSUS), "Desert Colossus", "Colossus Grotto", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_GROTTO, "dc,scrubs", 1}, - { ENTR_SPIRIT_TEMPLE_0, ENTR_DESERT_COLOSSUS_1, SINGLE_SCENE_INFO(SCENE_DESERT_COLOSSUS), "Desert Colossus", "Spirit Temple", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "dc", 1}, - { ENTR_DESERT_COLOSSUS_7, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0x02 }}, "Colossus Great Fairy Fountain", "Colossus", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_INTERIOR, "dc"}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_COLOSSUS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_COLOSSUS_OFFSET), {{ SCENE_GROTTOS, 0x0A }}, "Colossus Grotto", "Desert Colossus", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_GROTTO, "dc,scrubs"}, - { ENTR_DESERT_COLOSSUS_1, ENTR_SPIRIT_TEMPLE_0, SINGLE_SCENE_INFO(SCENE_SPIRIT_TEMPLE), "Spirit Temple", "Desert Colossus", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "dc"}, - { ENTR_SPIRIT_TEMPLE_BOSS_0, ENTR_SPIRIT_TEMPLE_1, SINGLE_SCENE_INFO(SCENE_SPIRIT_TEMPLE), "Spirit Temple Boss Door", "Twinrova", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_SPIRIT_TEMPLE_1, ENTR_SPIRIT_TEMPLE_BOSS_0, SINGLE_SCENE_INFO(SCENE_SPIRIT_TEMPLE_BOSS), "Twinrova", "Spirit Temple Boss Door", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "", 1}, - { ENTR_DESERT_COLOSSUS_8, -1, SINGLE_SCENE_INFO(SCENE_SPIRIT_TEMPLE_BOSS), "Twinrova", "Spirit Temple Blue Warp", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, + { ENTR_GERUDOS_FORTRESS_GATE_EXIT, ENTR_HAUNTED_WASTELAND_EAST_EXIT, SINGLE_SCENE_INFO(SCENE_HAUNTED_WASTELAND), "Haunted Wasteland East Exit", "GF Gate Exit", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_GERUDO_VALLEY, ENTRANCE_TYPE_OVERWORLD, "hw,gerudo fortress"}, + { ENTR_DESERT_COLOSSUS_EAST_EXIT, ENTR_HAUNTED_WASTELAND_WEST_EXIT, SINGLE_SCENE_INFO(SCENE_HAUNTED_WASTELAND), "Haunted Wasteland West Exit", "Desert Colossus East Exit", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_OVERWORLD, "dc,hw"}, + { ENTR_HAUNTED_WASTELAND_WEST_EXIT, ENTR_DESERT_COLOSSUS_EAST_EXIT, SINGLE_SCENE_INFO(SCENE_DESERT_COLOSSUS), "Desert Colossus East Exit", "Haunted Wasteland West Exit", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_OVERWORLD, "dc,hw"}, + { ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_NAYRUS_COLOSSUS, ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT, SINGLE_SCENE_INFO(SCENE_DESERT_COLOSSUS), "Colossus Great Fairy Exit", "Colossus Great Fairy Fountain", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_INTERIOR, "dc", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_COLOSSUS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_COLOSSUS_OFFSET), SINGLE_SCENE_INFO(SCENE_DESERT_COLOSSUS), "Colossus Grotto Exit", "Colossus Grotto", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_GROTTO, "dc,scrubs", 1}, + { ENTR_SPIRIT_TEMPLE_ENTRANCE, ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, SINGLE_SCENE_INFO(SCENE_DESERT_COLOSSUS), "Colossus Outside Temple", "Spirit Temple Entrance", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "dc", 1}, + { ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_NAYRUS_COLOSSUS, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0x02 }}, "Colossus Great Fairy Fountain", "Colossus Great Fairy Exit", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_INTERIOR, "dc"}, + { ENTRANCE_GROTTO_EXIT(GROTTO_COLOSSUS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_COLOSSUS_OFFSET), {{ SCENE_GROTTOS, 0x0A }}, "Colossus Grotto", "Colossus Grotto Exit", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_GROTTO, "dc,scrubs"}, + { ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, ENTR_SPIRIT_TEMPLE_ENTRANCE, SINGLE_SCENE_INFO(SCENE_SPIRIT_TEMPLE), "Spirit Temple Entrance", "Colossus Outside Temple", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "dc"}, + { ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE, ENTR_SPIRIT_TEMPLE_BOSS_DOOR, SINGLE_SCENE_INFO(SCENE_SPIRIT_TEMPLE), "Spirit Temple Boss Door", "Twinrova", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_SPIRIT_TEMPLE_BOSS_DOOR, ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE, SINGLE_SCENE_INFO(SCENE_SPIRIT_TEMPLE_BOSS), "Twinrova", "Spirit Temple Boss Door", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_DUNGEON, "", 1}, + { ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP, -1, SINGLE_SCENE_INFO(SCENE_SPIRIT_TEMPLE_BOSS), "Twinrova", "Spirit Temple Blue Warp", ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_GROUP_HAUNTED_WASTELAND, ENTRANCE_TYPE_ONE_WAY, "bw", 1}, // Market - { ENTR_HYRULE_FIELD_7, ENTR_MARKET_ENTRANCE_DAY_1, {SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_DAY), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_RUINS)}, "Market Entrance", "Hyrule Field", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, - { ENTR_MARKET_DAY_0, ENTR_MARKET_ENTRANCE_DAY_0, {SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_DAY), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_RUINS)}, "Market Entrance", "Market", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_MARKET_GUARD_HOUSE_0, ENTR_MARKET_ENTRANCE_DAY_2, {SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_DAY), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_RUINS)}, "Market Entrance", "Guard House", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "pots,poe", 1}, - { ENTR_MARKET_ENTRANCE_DAY_0, ENTR_MARKET_DAY_0, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "Market Entrance", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_HYRULE_CASTLE_0, ENTR_MARKET_DAY_1, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "HC Grounds / OGC", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_OVERWORLD, "outside ganon's castle"}, - { ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_0, ENTR_MARKET_DAY_2, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "Outside Temple of Time", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD}, - { ENTR_SHOOTING_GALLERY_1, ENTR_MARKET_DAY_8, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "MK Shooting Gallery", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "child", 1}, - { ENTR_BOMBCHU_BOWLING_ALLEY_0, ENTR_MARKET_DAY_7, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "Bombchu Bowling", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_TREASURE_BOX_SHOP_0, ENTR_MARKET_DAY_10, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "Treasure Chest Game", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_BACK_ALLEY_HOUSE_0, ENTR_BACK_ALLEY_DAY_3, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "Man-in-Green's House", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_HAPPY_MASK_SHOP_0, ENTR_MARKET_DAY_9, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "Mask Shop", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_BAZAAR_1, ENTR_MARKET_DAY_6, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "MK Bazaar", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "shop", 1}, - { ENTR_POTION_SHOP_MARKET_0, ENTR_MARKET_DAY_5, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "MK Potion Shop", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_BOMBCHU_SHOP_1, ENTR_BACK_ALLEY_DAY_2, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market", "Bombchu Shop", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTR_MARKET_ENTRANCE_DAY_2, ENTR_MARKET_GUARD_HOUSE_0, {{ SCENE_MARKET_GUARD_HOUSE }}, "Guard House", "Market Entrance", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "pots,poe"}, - { ENTR_MARKET_DAY_8, ENTR_SHOOTING_GALLERY_1, {{ SCENE_SHOOTING_GALLERY, 0x01 }}, "MK Shooting Gallery", "Market", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, - { ENTR_MARKET_DAY_7, ENTR_BOMBCHU_BOWLING_ALLEY_0, SINGLE_SCENE_INFO(SCENE_BOMBCHU_BOWLING_ALLEY), "Bombchu Bowling", "Market", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, - { ENTR_MARKET_DAY_10, ENTR_TREASURE_BOX_SHOP_0, SINGLE_SCENE_INFO(SCENE_TREASURE_BOX_SHOP), "Treasure Chest Game", "Market", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, - { ENTR_BACK_ALLEY_DAY_3, ENTR_BACK_ALLEY_HOUSE_0, SINGLE_SCENE_INFO(SCENE_BACK_ALLEY_HOUSE), "Man-in-Green's House", "Market", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, - { ENTR_MARKET_DAY_9, ENTR_HAPPY_MASK_SHOP_0, SINGLE_SCENE_INFO(SCENE_HAPPY_MASK_SHOP), "Mask Shop", "Market", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, - { ENTR_MARKET_DAY_6, ENTR_BAZAAR_1, {{ SCENE_BAZAAR, 0x01 }}, "MK Bazaar", "Market", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "shop"}, - { ENTR_MARKET_DAY_5, ENTR_POTION_SHOP_MARKET_0, SINGLE_SCENE_INFO(SCENE_POTION_SHOP_MARKET), "MK Potion Shop", "Market", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, - { ENTR_BACK_ALLEY_DAY_2, ENTR_BOMBCHU_SHOP_1, SINGLE_SCENE_INFO(SCENE_BOMBCHU_SHOP), "Bombchu Shop", "Market", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, - { ENTR_MARKET_DAY_2, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_0, {SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY), SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT), SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS)}, "Outside Temple of Time", "Market", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD, "tot"}, - { ENTR_TEMPLE_OF_TIME_0, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_1, {SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY), SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT), SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS)}, "Outside Temple of Time", "Temple of Time", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "tot", 1}, - { ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_1, ENTR_TEMPLE_OF_TIME_0, SINGLE_SCENE_INFO(SCENE_TEMPLE_OF_TIME), "Temple of Time", "Outside Temple of Time", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "tot"}, + { ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN, ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT, {SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_DAY), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_RUINS)}, "Market Entrance South Exit", "Hyrule Field Drawbridge Exit", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_HYRULE_FIELD, ENTRANCE_TYPE_OVERWORLD, "hf"}, + { ENTR_MARKET_SOUTH_EXIT, ENTR_MARKET_ENTRANCE_NORTH_EXIT, {SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_DAY), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_RUINS)}, "Market Entrance North Exit", "Market South Exit", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_MARKET_GUARD_HOUSE_0, ENTR_MARKET_ENTRANCE_OUTSIDE_GUARD_HOUSE, {SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_DAY), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_ENTRANCE_RUINS)}, "Market Entrance Outside Guard House", "Guard House", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "pots,poe", 1}, + { ENTR_MARKET_ENTRANCE_NORTH_EXIT, ENTR_MARKET_SOUTH_EXIT, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market South Exit", "Market Entrance North Exit", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_CASTLE_GROUNDS_SOUTH_EXIT, ENTR_MARKET_DAY_CASTLE_EXIT, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market Castle Exit", "Castle Grounds South Exit", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_OVERWORLD, "outside ganon's castle"}, + { ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT, ENTR_MARKET_DAY_TEMPLE_EXIT, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "Market Temple Exit", "Outside Temple of Time", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD}, + { ENTR_SHOOTING_GALLERY_1, ENTR_MARKET_DAY_OUTSIDE_SHOOTING_GALLERY, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "MK Outside Shooting Gallery", "MK Shooting Gallery", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "child", 1}, + { ENTR_BOMBCHU_BOWLING_ALLEY_0, ENTR_MARKET_DAY_OUTSIDE_BOMBCHU_BOWLING, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "MK Outside Bombchu Bowling", "Bombchu Bowling", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_TREASURE_BOX_SHOP_0, ENTR_MARKET_DAY_OUTSIDE_TREASURE_BOX_SHOP, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "MK Outside Treasure Chest Game", "Treasure Chest Game", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_BACK_ALLEY_MAN_IN_GREEN_HOUSE, ENTR_BACK_ALLEY_DAY_OUTSIDE_MAN_IN_GREEN_HOUSE, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "MK Outside Main-in-Green House", "Man-in-Green's House", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_HAPPY_MASK_SHOP_0, ENTR_MARKET_DAY_OUTSIDE_HAPPY_MASK_SHOP, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "MK Outside Mask Shop", "Mask Shop", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_BAZAAR_1, ENTR_MARKET_DAY_OUTSIDE_BAZAAR, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "MK Outside Bazaar", "MK Bazaar", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "shop", 1}, + { ENTR_POTION_SHOP_MARKET_0, ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "MK Outside Potion Shop", "MK Potion Shop", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_BOMBCHU_SHOP_1, ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP, {SCENE_NO_SPAWN(SCENE_MARKET_DAY), SCENE_NO_SPAWN(SCENE_MARKET_NIGHT), SCENE_NO_SPAWN(SCENE_MARKET_RUINS), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_DAY), SCENE_NO_SPAWN(SCENE_BACK_ALLEY_NIGHT)}, "MK Outside Bombchu Shop", "Bombchu Shop", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTR_MARKET_ENTRANCE_OUTSIDE_GUARD_HOUSE, ENTR_MARKET_GUARD_HOUSE_0, {{ SCENE_MARKET_GUARD_HOUSE }}, "Guard House", "MK Entrance Outside Guard House", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "pots,poe"}, + { ENTR_MARKET_DAY_OUTSIDE_SHOOTING_GALLERY, ENTR_SHOOTING_GALLERY_1, {{ SCENE_SHOOTING_GALLERY, 0x01 }}, "MK Shooting Gallery", "MK Outside Shooting Gallery", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, + { ENTR_MARKET_DAY_OUTSIDE_BOMBCHU_BOWLING, ENTR_BOMBCHU_BOWLING_ALLEY_0, SINGLE_SCENE_INFO(SCENE_BOMBCHU_BOWLING_ALLEY), "Bombchu Bowling", "MK Outside Bombchu Bowling", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, + { ENTR_MARKET_DAY_OUTSIDE_TREASURE_BOX_SHOP, ENTR_TREASURE_BOX_SHOP_0, SINGLE_SCENE_INFO(SCENE_TREASURE_BOX_SHOP), "Treasure Chest Game", "MK Outside Treasure Chest Game", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, + { ENTR_BACK_ALLEY_DAY_OUTSIDE_MAN_IN_GREEN_HOUSE, ENTR_BACK_ALLEY_MAN_IN_GREEN_HOUSE, SINGLE_SCENE_INFO(SCENE_BACK_ALLEY_HOUSE), "Man-in-Green's House", "MK Outside Main-in-Green House", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, + { ENTR_MARKET_DAY_OUTSIDE_HAPPY_MASK_SHOP, ENTR_HAPPY_MASK_SHOP_0, SINGLE_SCENE_INFO(SCENE_HAPPY_MASK_SHOP), "Mask Shop", "MK Outside Mask Shop", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, + { ENTR_MARKET_DAY_OUTSIDE_BAZAAR, ENTR_BAZAAR_1, {{ SCENE_BAZAAR, 0x01 }}, "MK Bazaar", "MK Outside Bazaar", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "shop"}, + { ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP, ENTR_POTION_SHOP_MARKET_0, SINGLE_SCENE_INFO(SCENE_POTION_SHOP_MARKET), "MK Potion Shop", "MK Outside Potion Shop", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, + { ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP, ENTR_BOMBCHU_SHOP_1, SINGLE_SCENE_INFO(SCENE_BOMBCHU_SHOP), "Bombchu Shop", "MK Outside Bombchu Shop", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR}, + { ENTR_MARKET_DAY_TEMPLE_EXIT, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT, {SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY), SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT), SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS)}, "Outside Temple of Time", "MK Temple Exit", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD, "tot"}, + { ENTR_TEMPLE_OF_TIME_ENTRANCE, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE, {SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY), SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT), SCENE_NO_SPAWN(SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS)}, "Outside Temple of Time", "Temple of Time Entrance", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "tot", 1}, + { ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE, ENTR_TEMPLE_OF_TIME_ENTRANCE, SINGLE_SCENE_INFO(SCENE_TEMPLE_OF_TIME), "Temple of Time Entrance", "Outside Temple of Time", ENTRANCE_GROUP_MARKET, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_INTERIOR, "tot"}, // Hyrule Castle - { ENTR_MARKET_DAY_1, ENTR_HYRULE_CASTLE_0, {SCENE_NO_SPAWN(SCENE_HYRULE_CASTLE), SCENE_NO_SPAWN(SCENE_OUTSIDE_GANONS_CASTLE)}, "HC Grounds / OGC", "Market", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD, "outside ganon's castle"}, - { ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1, ENTR_HYRULE_CASTLE_2, SINGLE_SCENE_INFO(SCENE_HYRULE_CASTLE), "HC Grounds", "HC Great Fairy Fountain", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "", 1}, - { ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_CASTLE), "HC Grounds", "HC Storms Grotto", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_GROTTO, "bombable", 1}, - { ENTR_HYRULE_CASTLE_2, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0x01 }}, "HC Great Fairy Fountain", "HC Grounds", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR}, - { ENTRANCE_RANDO_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET), ENTRANCE_RANDO_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x09 }}, "HC Storms Grotto", "HC Grounds", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_GROTTO, "bombable"}, - { ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2, ENTR_POTION_SHOP_KAKARIKO_1, SINGLE_SCENE_INFO(SCENE_OUTSIDE_GANONS_CASTLE), "OGC", "OGC Great Fairy Fountain", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "outside ganon's castle", 1}, - { ENTR_INSIDE_GANONS_CASTLE_0, ENTR_HYRULE_CASTLE_1, SINGLE_SCENE_INFO(SCENE_OUTSIDE_GANONS_CASTLE), "OGC", "Ganon's Castle", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_DUNGEON, "outside ganon's castle,gc", 1}, - { ENTR_POTION_SHOP_KAKARIKO_1, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0x02 }}, "OGC Great Fairy Fountain", "OGC", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "outside ganon's castle"}, - { ENTR_HYRULE_CASTLE_1, ENTR_INSIDE_GANONS_CASTLE_0, SINGLE_SCENE_INFO(SCENE_INSIDE_GANONS_CASTLE), "Ganon's Castle", "OGC", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_DUNGEON, "outside ganon's castle,gc"} + { ENTR_MARKET_DAY_CASTLE_EXIT, ENTR_CASTLE_GROUNDS_SOUTH_EXIT, {SCENE_NO_SPAWN(SCENE_HYRULE_CASTLE), SCENE_NO_SPAWN(SCENE_OUTSIDE_GANONS_CASTLE)}, "Castle Grounds South Exit", "Market Castle Exit", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_MARKET, ENTRANCE_TYPE_OVERWORLD, "outside ganon's castle"}, + { ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC, ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, SINGLE_SCENE_INFO(SCENE_HYRULE_CASTLE), "HC Boulder Crawlspace", "HC Great Fairy Fountain", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "", 1}, + { ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET), ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET), SINGLE_SCENE_INFO(SCENE_HYRULE_CASTLE), "HC Storms Grotto Exit", "HC Storms Grotto", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_GROTTO, "bombable", 1}, + { ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS, 0x01 }}, "HC Great Fairy Fountain", "HC Boulder Crawlspace", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR}, + { ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET), ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET), {{ SCENE_GROTTOS, 0x09 }}, "HC Storms Grotto", "HC Storms Grotto Exit", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_GROTTO, "bombable"}, + { ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD, ENTR_POTION_SHOP_KAKARIKO_1, SINGLE_SCENE_INFO(SCENE_OUTSIDE_GANONS_CASTLE), "OGC Behind Pillar", "OGC Great Fairy Fountain", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "outside ganon's castle", 1}, + { ENTR_INSIDE_GANONS_CASTLE_ENTRANCE, ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT, SINGLE_SCENE_INFO(SCENE_OUTSIDE_GANONS_CASTLE), "OGC Rainbow Bridge Exit", "Ganon's Castle", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_DUNGEON, "outside ganon's castle,gc", 1}, + { ENTR_POTION_SHOP_KAKARIKO_1, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD, {{ SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC, 0x02 }}, "OGC Great Fairy Fountain", "OGC Behind Pillar", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_INTERIOR, "outside ganon's castle"}, + { ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT, ENTR_INSIDE_GANONS_CASTLE_ENTRANCE, SINGLE_SCENE_INFO(SCENE_INSIDE_GANONS_CASTLE), "Inside Ganon's Castle Entrance", "OGC Rainbow Bridge Exit", ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_GROUP_HYRULE_CASTLE, ENTRANCE_TYPE_DUNGEON, "outside ganon's castle,gc"} }; // Check if Link is in the area and return that scene/entrance for tracking @@ -389,7 +391,7 @@ s8 LinkIsInArea(const EntranceData* entrance) { // Handle detecting the current grotto if ((gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN || gPlayState->sceneNum == SCENE_GROTTOS) && entrance->type == ENTRANCE_TYPE_GROTTO) { - if (entrance->index == (ENTRANCE_RANDO_GROTTO_EXIT_START + currentGrottoId)) { + if (entrance->index == (ENTRANCE_GROTTO_EXIT_START + currentGrottoId)) { // Return the grotto entrance for tracking return entrance->index; } else { @@ -421,9 +423,9 @@ bool IsEntranceDiscovered(s16 index) { if (!isDiscovered) { // If the pair included one of the hyrule field <-> zora's river entrances, // the randomizer will have also overriden the water-based entrances, so check those too - if ((index == ENTR_ZORAS_RIVER_0 && Entrance_GetIsEntranceDiscovered(ENTR_ZORAS_RIVER_3)) || (index == ENTR_ZORAS_RIVER_3 && Entrance_GetIsEntranceDiscovered(ENTR_ZORAS_RIVER_0))) { + if ((index == ENTR_ZORAS_RIVER_WEST_EXIT && Entrance_GetIsEntranceDiscovered(ENTR_ZORAS_RIVER_3)) || (index == ENTR_ZORAS_RIVER_3 && Entrance_GetIsEntranceDiscovered(ENTR_ZORAS_RIVER_WEST_EXIT))) { isDiscovered = true; - } else if ((index == ENTR_HYRULE_FIELD_2 && Entrance_GetIsEntranceDiscovered(ENTR_HYRULE_FIELD_14)) || (index == ENTR_HYRULE_FIELD_14 && Entrance_GetIsEntranceDiscovered(ENTR_HYRULE_FIELD_2))) { + } else if ((index == ENTR_HYRULE_FIELD_RIVER_EXIT && Entrance_GetIsEntranceDiscovered(ENTR_HYRULE_FIELD_14)) || (index == ENTR_HYRULE_FIELD_14 && Entrance_GetIsEntranceDiscovered(ENTR_HYRULE_FIELD_RIVER_EXIT))) { isDiscovered = true; } } @@ -689,10 +691,10 @@ void EntranceTrackerSettingsWindow::DrawElement() { UIWidgets::Spacer(2.0f); ImGui::Text("Spoiler Reveal"); - UIWidgets::PaddedEnhancementCheckbox("Show \"To\"", CVAR_TRACKER_ENTRANCE("ShowTo"), true, false); - UIWidgets::Tooltip("Reveal the \"To\" entrance for undiscovered entrances"); - UIWidgets::PaddedEnhancementCheckbox("Show \"From\"", CVAR_TRACKER_ENTRANCE("ShowFrom"), true, false); - UIWidgets::Tooltip("Reveal the \"From\" entrance for undiscovered entrances"); + UIWidgets::PaddedEnhancementCheckbox("Show Source", CVAR_TRACKER_ENTRANCE("ShowFrom"), true, false); + UIWidgets::Tooltip("Reveal the sourcefor undiscovered entrances"); + UIWidgets::PaddedEnhancementCheckbox("Show Destination", CVAR_TRACKER_ENTRANCE("ShowTo"), true, false); + UIWidgets::Tooltip("Reveal the destination for undiscovered entrances"); ImGui::EndTable(); } @@ -779,6 +781,13 @@ void EntranceTrackerWindow::DrawElement() { // Begin tracker list ImGui::BeginChild("ChildEntranceTrackerLocations", ImVec2(0, -8)); + bool showTo = CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowTo"), 0); + bool showFrom = CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowFrom"), 0); + bool collapsUndiscovered = CVarGetInteger(CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), 0); + bool highlightPrevious = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightPrevious"), 0); + bool highlightAvailable = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightAvailable"), 0); + bool hideReverse = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HideReverseEntrances"), 1); + bool autoScrollArea = CVarGetInteger(CVAR_TRACKER_ENTRANCE("AutoScroll"), 0); for (size_t i = 0; i < groupCount; i++) { std::string groupName = groupNames[i]; @@ -804,7 +813,7 @@ void EntranceTrackerWindow::DrawElement() { // However, if entrances are decoupled, then all transitions need to be displayed, so we proceed with the filtering if ((original->type == ENTRANCE_TYPE_DUNGEON || original->type == ENTRANCE_TYPE_GROTTO || original->type == ENTRANCE_TYPE_INTERIOR) && (original->oneExit != 1 && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == RO_GENERIC_OFF) && - CVarGetInteger(CVAR_TRACKER_ENTRANCE("HideReverseEntrances"), 1) == 1) { + hideReverse == 1) { continue; } @@ -815,8 +824,8 @@ void EntranceTrackerWindow::DrawElement() { bool isDiscovered = IsEntranceDiscovered(entrance.index); - bool showOriginal = (!destToggle ? CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowTo"), 0) : CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowFrom"), 0)) || isDiscovered; - bool showOverride = (!destToggle ? CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowFrom"), 0) : CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowTo"), 0)) || isDiscovered; + bool showOverride = (!destToggle ? showTo : showFrom) || isDiscovered; + bool showOriginal = (!destToggle ? showFrom : showTo) || isDiscovered; const char* origSrcAreaName = spoilerEntranceGroupNames[original->srcGroup].c_str(); const char* origTypeName = groupTypeNames[original->type].c_str(); @@ -824,17 +833,13 @@ void EntranceTrackerWindow::DrawElement() { const char* rplcTypeName = groupTypeNames[override->type].c_str(); const char* origSrcName = showOriginal ? original->source.c_str() : ""; - const char* origDstName = showOriginal ? original->destination.c_str() : ""; - const char* rplcSrcName = showOverride ? override->source.c_str() : ""; const char* rplcDstName = showOverride ? override->destination.c_str() : ""; // Filter for entrances by group name, type, source/destination names, and meta tags - if ((!locationSearch.IsActive() && (showOriginal || showOverride || !CVarGetInteger(CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), 0))) || - ((showOriginal && (locationSearch.PassFilter(origSrcName) || - locationSearch.PassFilter(origDstName) || locationSearch.PassFilter(origSrcAreaName) || + if ((!locationSearch.IsActive() && (showOriginal || showOverride || !collapsUndiscovered)) || + ((showOriginal && (locationSearch.PassFilter(origSrcName) || locationSearch.PassFilter(origSrcAreaName) || locationSearch.PassFilter(origTypeName) || locationSearch.PassFilter(original->metaTag.c_str()))) || - (showOverride && (locationSearch.PassFilter(rplcSrcName) || - locationSearch.PassFilter(rplcDstName) || locationSearch.PassFilter(rplcSrcAreaName) || + (showOverride && (locationSearch.PassFilter(rplcDstName) || locationSearch.PassFilter(rplcSrcAreaName) || locationSearch.PassFilter(rplcTypeName) || locationSearch.PassFilter(override->metaTag.c_str()))))) { // Detect if a scroll should happen and remember the scene for that scroll @@ -867,14 +872,12 @@ void EntranceTrackerWindow::DrawElement() { bool isDiscovered = IsEntranceDiscovered(entrance.index); - bool showOriginal = (!destToggle ? CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowTo"), 0) : CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowFrom"), 0)) || isDiscovered; - bool showOverride = (!destToggle ? CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowFrom"), 0) : CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowTo"), 0)) || isDiscovered; + bool showOverride = (!destToggle ? showTo : showFrom) || isDiscovered; + bool showOriginal = (!destToggle ? showFrom : showTo) || isDiscovered; const char* unknown = "???"; const char* origSrcName = showOriginal ? original->source.c_str() : unknown; - const char* origDstName = showOriginal ? original->destination.c_str() : unknown; - const char* rplcSrcName = showOverride ? override->source.c_str() : unknown; const char* rplcDstName = showOverride ? override->destination.c_str() : unknown; uint32_t color = isDiscovered ? IM_COL32_WHITE : COLOR_GRAY; @@ -882,16 +885,16 @@ void EntranceTrackerWindow::DrawElement() { // Handle highlighting and auto scroll if ((original->index == lastEntranceIndex || (override->reverseIndex == lastEntranceIndex && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == RO_GENERIC_OFF)) && - CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightPrevious"), 0)) { + highlightPrevious) { color = COLOR_ORANGE; } else if (LinkIsInArea(original) != -1) { - if (CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightAvailable"), 0)) { + if (highlightAvailable) { color = COLOR_GREEN; } if (doAreaScroll) { doAreaScroll = false; - if (CVarGetInteger(CVAR_TRACKER_ENTRANCE("AutoScroll"), 0)) { + if (autoScrollArea) { ImGui::SetScrollHereY(0.0f); } } @@ -901,19 +904,7 @@ void EntranceTrackerWindow::DrawElement() { // Use a non-breaking space to keep the arrow from wrapping to a newline by itself auto nbsp = u8"\u00A0"; - if (original->srcGroup != ENTRANCE_GROUP_ONE_WAY) { - ImGui::TextWrapped("%s to %s%s->", origSrcName, origDstName, nbsp); - } else { - ImGui::TextWrapped("%s%s->", origSrcName, nbsp); - } - - // Indent the destination - ImGui::SetCursorPosX(ImGui::GetCursorPosX() * 2); - if (!showOverride || (showOverride && (!override->oneExit && override->srcGroup != ENTRANCE_GROUP_ONE_WAY))) { - ImGui::TextWrapped("%s from %s", rplcDstName, rplcSrcName); - } else { - ImGui::TextWrapped("%s", rplcDstName); - } + ImGui::TextWrapped("%s%s-> %s", origSrcName, nbsp, rplcDstName); ImGui::PopStyleColor(); } diff --git a/soh/soh/Enhancements/randomizer/randomizer_grotto.c b/soh/soh/Enhancements/randomizer/randomizer_grotto.c index ef532f670..50cb093c8 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_grotto.c +++ b/soh/soh/Enhancements/randomizer/randomizer_grotto.c @@ -4,6 +4,7 @@ */ #include "randomizer_grotto.h" +#include "soh/OTRGlobals.h" #include "global.h" @@ -48,39 +49,39 @@ static const GrottoLoadInfo grottoLoadTable[NUM_GROTTOS] = { // Information necessary for setting up returning from a grotto static const GrottoReturnInfo grottoReturnTable[NUM_GROTTOS] = { - {.entranceIndex = ENTR_DESERT_COLOSSUS_0, .room = 0x00, .angle = 0xA71C, .pos = {.x = 62.5078f, .y = -32.0f, .z = -1296.2f}}, // Colossus Grotto -> Desert Colossus - {.entranceIndex = ENTR_LAKE_HYLIA_0, .room = 0x00, .angle = 0x0000, .pos = {.x = -3039.34f, .y = -1033.0f, .z = 6080.74f}}, // LH Grotto -> Lake Hylia - {.entranceIndex = ENTR_ZORAS_RIVER_0, .room = 0x00, .angle = 0x0000, .pos = {.x = -1630.05f, .y = 100.0f, .z = -132.104f}}, // ZR Storms Grotto -> Zora River - {.entranceIndex = ENTR_ZORAS_RIVER_0, .room = 0x00, .angle = 0xE000, .pos = {.x = 649.507f, .y = 570.0f, .z = -346.853f}}, // ZR Fairy Grotto -> Zora River - {.entranceIndex = ENTR_ZORAS_RIVER_0, .room = 0x00, .angle = 0x8000, .pos = {.x = 362.29f, .y = 570.0f, .z = 111.48f}}, // ZR Open Grotto -> Zora River - {.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_1, .room = 0x01, .angle = 0x31C7, .pos = {.x = -1666.73f, .y = 721.0f, .z = -459.21f}}, // DMC Hammer Grotto -> DMC Lower Local - {.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_0, .room = 0x01, .angle = 0x238E, .pos = {.x = 63.723f, .y = 1265.0f, .z = 1791.39f}}, // DMC Upper Grotto -> DMC Upper Local - {.entranceIndex = ENTR_GORON_CITY_0, .room = 0x03, .angle = 0x0000, .pos = {.x = 1104.73f, .y = 580.0f, .z = -1159.95f}}, // GC Grotto -> GC Grotto Platform - {.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_1, .room = 0x00, .angle = 0x8000, .pos = {.x = -387.584f, .y = 1386.0f, .z = -1213.05f}}, // DMT Storms Grotto -> Death Mountain - {.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_1, .room = 0x00, .angle = 0x8000, .pos = {.x = -691.022f, .y = 1946.0f, .z = -312.969f}}, // DMT Cow Grotto -> Death Mountain Summit - {.entranceIndex = ENTR_KAKARIKO_VILLAGE_0, .room = 0x00, .angle = 0x0000, .pos = {.x = 855.238f, .y = 80.0f, .z = -234.095f}}, // Kak Open Grotto -> Kak Backyard - {.entranceIndex = ENTR_KAKARIKO_VILLAGE_0, .room = 0x00, .angle = 0x0000, .pos = {.x = -401.873f, .y = 0.0f, .z = 402.792f}}, // Kak Redead Grotto -> Kakariko Village - {.entranceIndex = ENTR_HYRULE_CASTLE_0, .room = 0x00, .angle = 0x9555, .pos = {.x = 1009.02f, .y = 1571.0f, .z = 855.532f}}, // HC Storms Grotto -> Castle Grounds - {.entranceIndex = ENTR_HYRULE_FIELD_6, .room = 0x00, .angle = 0x1555, .pos = {.x = -4949.58f, .y = -300.0f, .z = 2837.59f}}, // HF Tektite Grotto -> Hyrule Field - {.entranceIndex = ENTR_HYRULE_FIELD_6, .room = 0x00, .angle = 0xC000, .pos = {.x = 2050.6f, .y = 20.0f, .z = -160.397f}}, // HF Near Kak Grotto -> Hyrule Field - {.entranceIndex = ENTR_HYRULE_FIELD_6, .room = 0x00, .angle = 0x0000, .pos = {.x = -4447.66f, .y = -300.0f, .z = -393.191f}}, // HF Fairy Grotto -> Hyrule Field - {.entranceIndex = ENTR_HYRULE_FIELD_6, .room = 0x00, .angle = 0xE000, .pos = {.x = -1446.56f, .y = 0.0f, .z = 830.775f}}, // HF Near Market Grotto -> Hyrule Field - {.entranceIndex = ENTR_HYRULE_FIELD_6, .room = 0x00, .angle = 0x0000, .pos = {.x = -7874.07f, .y = -300.0f, .z = 6921.31f}}, // HF Cow Grotto -> Hyrule Field - {.entranceIndex = ENTR_HYRULE_FIELD_6, .room = 0x00, .angle = 0xEAAB, .pos = {.x = -4989.13f, .y = -700.0f, .z = 13821.1f}}, // HF Inside Fence Grotto -> Hyrule Field - {.entranceIndex = ENTR_HYRULE_FIELD_6, .room = 0x00, .angle = 0x8000, .pos = {.x = -4032.61f, .y = -700.0f, .z = 13831.5f}}, // HF Open Grotto -> Hyrule Field - {.entranceIndex = ENTR_HYRULE_FIELD_6, .room = 0x00, .angle = 0x9555, .pos = {.x = -288.313f, .y = -500.0f, .z = 12320.2f}}, // HF Southeast Grotto -> Hyrule Field - {.entranceIndex = ENTR_LON_LON_RANCH_0, .room = 0x00, .angle = 0xAAAB, .pos = {.x = 1775.92f, .y = 0.0f, .z = 1486.82f}}, // LLR Grotto -> Lon Lon Ranch - {.entranceIndex = ENTR_SACRED_FOREST_MEADOW_0, .room = 0x00, .angle = 0x8000, .pos = {.x = -189.861f, .y = 0.0f, .z = 1898.09f}}, // SFM Wolfos Grotto -> SFM Entryway - {.entranceIndex = ENTR_SACRED_FOREST_MEADOW_0, .room = 0x00, .angle = 0xAAAB, .pos = {.x = 314.853f, .y = 480.0f, .z = -2300.39f}}, // SFM Storms Grotto -> Sacred Forest Meadow - {.entranceIndex = ENTR_SACRED_FOREST_MEADOW_0, .room = 0x00, .angle = 0x0000, .pos = {.x = 55.034f, .y = 0.0f, .z = 250.595f}}, // SFM Fairy Grotto -> Sacred Forest Meadow - {.entranceIndex = ENTR_LOST_WOODS_1, .room = 0x08, .angle = 0x2000, .pos = {.x = 691.994f, .y = 0.0f, .z = -2502.2f}}, // LW Scrubs Grotto -> LW Beyond Mido - {.entranceIndex = ENTR_LOST_WOODS_0, .room = 0x02, .angle = 0xE000, .pos = {.x = 905.755f, .y = 0.0f, .z = -901.43f}}, // LW Near Shortcuts Grotto -> Lost Woods - {.entranceIndex = ENTR_KOKIRI_FOREST_6, .room = 0x00, .angle = 0x4000, .pos = {.x = -507.065f, .y = 380.0f, .z = -1220.43f}}, // KF Storms Grotto -> Kokiri Forest - {.entranceIndex = ENTR_ZORAS_DOMAIN_0, .room = 0x01, .angle = 0xD555, .pos = {.x = -855.68f, .y = 14.0f, .z = -474.422f}}, // ZD Storms Grotto -> Zoras Domain - {.entranceIndex = ENTR_GERUDOS_FORTRESS_0, .room = 0x00, .angle = 0x4000, .pos = {.x = 380.521f, .y = 333.0f, .z = -1560.74f}}, // GF Storms Grotto -> Gerudo Fortress - {.entranceIndex = ENTR_GERUDO_VALLEY_3, .room = 0x00, .angle = 0x9555, .pos = {.x = -1326.34f, .y = 15.0f, .z = -983.994f}}, // GV Storms Grotto -> GV Fortress Side - {.entranceIndex = ENTR_GERUDO_VALLEY_0, .room = 0x00, .angle = 0x8000, .pos = {.x = 291.513f, .y = -555.0f, .z = 1478.39f}}, // GV Octorok Grotto -> GV Grotto Ledge - {.entranceIndex = ENTR_LOST_WOODS_1, .room = 0x06, .angle = 0x4000, .pos = {.x = 109.281f, .y = -20.0f, .z = -1601.42f}}, // Deku Theater -> LW Beyond Mido + {.entranceIndex = ENTR_DESERT_COLOSSUS_EAST_EXIT, .room = 0x00, .angle = 0xA71C, .pos = {.x = 62.5078f, .y = -32.0f, .z = -1296.2f}}, // Colossus Grotto -> Desert Colossus + {.entranceIndex = ENTR_LAKE_HYLIA_NORTH_EXIT, .room = 0x00, .angle = 0x0000, .pos = {.x = -3039.34f, .y = -1033.0f, .z = 6080.74f}}, // LH Grotto -> Lake Hylia + {.entranceIndex = ENTR_ZORAS_RIVER_WEST_EXIT, .room = 0x00, .angle = 0x0000, .pos = {.x = -1630.05f, .y = 100.0f, .z = -132.104f}}, // ZR Storms Grotto -> Zora River + {.entranceIndex = ENTR_ZORAS_RIVER_WEST_EXIT, .room = 0x00, .angle = 0xE000, .pos = {.x = 649.507f, .y = 570.0f, .z = -346.853f}}, // ZR Fairy Grotto -> Zora River + {.entranceIndex = ENTR_ZORAS_RIVER_WEST_EXIT, .room = 0x00, .angle = 0x8000, .pos = {.x = 362.29f, .y = 570.0f, .z = 111.48f}}, // ZR Open Grotto -> Zora River + {.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT, .room = 0x01, .angle = 0x31C7, .pos = {.x = -1666.73f, .y = 721.0f, .z = -459.21f}}, // DMC Hammer Grotto -> DMC Lower Local + {.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT, .room = 0x01, .angle = 0x238E, .pos = {.x = 63.723f, .y = 1265.0f, .z = 1791.39f}}, // DMC Upper Grotto -> DMC Upper Local + {.entranceIndex = ENTR_GORON_CITY_UPPER_EXIT, .room = 0x03, .angle = 0x0000, .pos = {.x = 1104.73f, .y = 580.0f, .z = -1159.95f}}, // GC Grotto -> GC Grotto Platform + {.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT, .room = 0x00, .angle = 0x8000, .pos = {.x = -387.584f, .y = 1386.0f, .z = -1213.05f}}, // DMT Storms Grotto -> Death Mountain + {.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT, .room = 0x00, .angle = 0x8000, .pos = {.x = -691.022f, .y = 1946.0f, .z = -312.969f}}, // DMT Cow Grotto -> Death Mountain Summit + {.entranceIndex = ENTR_KAKARIKO_VILLAGE_FRONT_GATE, .room = 0x00, .angle = 0x0000, .pos = {.x = 855.238f, .y = 80.0f, .z = -234.095f}}, // Kak Open Grotto -> Kak Backyard + {.entranceIndex = ENTR_KAKARIKO_VILLAGE_FRONT_GATE, .room = 0x00, .angle = 0x0000, .pos = {.x = -401.873f, .y = 0.0f, .z = 402.792f}}, // Kak Redead Grotto -> Kakariko Village + {.entranceIndex = ENTR_CASTLE_GROUNDS_SOUTH_EXIT, .room = 0x00, .angle = 0x9555, .pos = {.x = 1009.02f, .y = 1571.0f, .z = 855.532f}}, // HC Storms Grotto -> Castle Grounds + {.entranceIndex = ENTR_HYRULE_FIELD_CENTER_EXIT, .room = 0x00, .angle = 0x1555, .pos = {.x = -4949.58f, .y = -300.0f, .z = 2837.59f}}, // HF Tektite Grotto -> Hyrule Field + {.entranceIndex = ENTR_HYRULE_FIELD_CENTER_EXIT, .room = 0x00, .angle = 0xC000, .pos = {.x = 2050.6f, .y = 20.0f, .z = -160.397f}}, // HF Near Kak Grotto -> Hyrule Field + {.entranceIndex = ENTR_HYRULE_FIELD_CENTER_EXIT, .room = 0x00, .angle = 0x0000, .pos = {.x = -4447.66f, .y = -300.0f, .z = -393.191f}}, // HF Fairy Grotto -> Hyrule Field + {.entranceIndex = ENTR_HYRULE_FIELD_CENTER_EXIT, .room = 0x00, .angle = 0xE000, .pos = {.x = -1446.56f, .y = 0.0f, .z = 830.775f}}, // HF Near Market Grotto -> Hyrule Field + {.entranceIndex = ENTR_HYRULE_FIELD_CENTER_EXIT, .room = 0x00, .angle = 0x0000, .pos = {.x = -7874.07f, .y = -300.0f, .z = 6921.31f}}, // HF Cow Grotto -> Hyrule Field + {.entranceIndex = ENTR_HYRULE_FIELD_CENTER_EXIT, .room = 0x00, .angle = 0xEAAB, .pos = {.x = -4989.13f, .y = -700.0f, .z = 13821.1f}}, // HF Inside Fence Grotto -> Hyrule Field + {.entranceIndex = ENTR_HYRULE_FIELD_CENTER_EXIT, .room = 0x00, .angle = 0x8000, .pos = {.x = -4032.61f, .y = -700.0f, .z = 13831.5f}}, // HF Open Grotto -> Hyrule Field + {.entranceIndex = ENTR_HYRULE_FIELD_CENTER_EXIT, .room = 0x00, .angle = 0x9555, .pos = {.x = -288.313f, .y = -500.0f, .z = 12320.2f}}, // HF Southeast Grotto -> Hyrule Field + {.entranceIndex = ENTR_LON_LON_RANCH_ENTRANCE, .room = 0x00, .angle = 0xAAAB, .pos = {.x = 1775.92f, .y = 0.0f, .z = 1486.82f}}, // LLR Grotto -> Lon Lon Ranch + {.entranceIndex = ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT, .room = 0x00, .angle = 0x8000, .pos = {.x = -189.861f, .y = 0.0f, .z = 1898.09f}}, // SFM Wolfos Grotto -> SFM Entryway + {.entranceIndex = ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT, .room = 0x00, .angle = 0xAAAB, .pos = {.x = 314.853f, .y = 480.0f, .z = -2300.39f}}, // SFM Storms Grotto -> Sacred Forest Meadow + {.entranceIndex = ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT, .room = 0x00, .angle = 0x0000, .pos = {.x = 55.034f, .y = 0.0f, .z = 250.595f}}, // SFM Fairy Grotto -> Sacred Forest Meadow + {.entranceIndex = ENTR_LOST_WOODS_NORTH_EXIT, .room = 0x08, .angle = 0x2000, .pos = {.x = 691.994f, .y = 0.0f, .z = -2502.2f}}, // LW Scrubs Grotto -> LW Beyond Mido + {.entranceIndex = ENTR_LOST_WOODS_SOUTH_EXIT, .room = 0x02, .angle = 0xE000, .pos = {.x = 905.755f, .y = 0.0f, .z = -901.43f}}, // LW Near Shortcuts Grotto -> Lost Woods + {.entranceIndex = ENTR_KOKIRI_FOREST_UPPER_EXIT, .room = 0x00, .angle = 0x4000, .pos = {.x = -507.065f, .y = 380.0f, .z = -1220.43f}}, // KF Storms Grotto -> Kokiri Forest + {.entranceIndex = ENTR_ZORAS_DOMAIN_ENTRANCE, .room = 0x01, .angle = 0xD555, .pos = {.x = -855.68f, .y = 14.0f, .z = -474.422f}}, // ZD Storms Grotto -> Zoras Domain + {.entranceIndex = ENTR_GERUDOS_FORTRESS_EAST_EXIT, .room = 0x00, .angle = 0x4000, .pos = {.x = 380.521f, .y = 333.0f, .z = -1560.74f}}, // GF Storms Grotto -> Gerudo Fortress + {.entranceIndex = ENTR_GERUDO_VALLEY_WEST_EXIT, .room = 0x00, .angle = 0x9555, .pos = {.x = -1326.34f, .y = 15.0f, .z = -983.994f}}, // GV Storms Grotto -> GV Fortress Side + {.entranceIndex = ENTR_GERUDO_VALLEY_EAST_EXIT, .room = 0x00, .angle = 0x8000, .pos = {.x = 291.513f, .y = -555.0f, .z = 1478.39f}}, // GV Octorok Grotto -> GV Grotto Ledge + {.entranceIndex = ENTR_LOST_WOODS_NORTH_EXIT, .room = 0x06, .angle = 0x4000, .pos = {.x = 109.281f, .y = -20.0f, .z = -1601.42f}}, // Deku Theater -> LW Beyond Mido }; static s16 grottoExitList[NUM_GROTTOS] = {0}; @@ -96,9 +97,13 @@ static u8 overridingNextEntrance = false; // For the grotto exit list, the entrance index is 0x0800 + the grotto id void Grotto_InitExitAndLoadLists(void) { for (u8 i = 0; i < NUM_GROTTOS; i++) { - grottoLoadList[i] = ENTRANCE_RANDO_GROTTO_LOAD_START + i; - grottoExitList[i] = ENTRANCE_RANDO_GROTTO_EXIT_START + i; + grottoLoadList[i] = ENTRANCE_GROTTO_LOAD_START + i; + grottoExitList[i] = ENTRANCE_GROTTO_EXIT_START + i; } + + grottoId = 0xFF; + lastEntranceType = NOT_GROTTO; + overridingNextEntrance = false; } void Grotto_SetExitOverride(s16 originalIndex, s16 overrideIndex) { @@ -146,7 +151,7 @@ s16 Grotto_GetEntranceValueHandlingGrottoRando(s16 nextEntranceIndex) { s8 tempGrottoId = nextEntranceIndex & 0x00FF; // Grotto Returns - if (nextEntranceIndex >= ENTRANCE_RANDO_GROTTO_EXIT_START && nextEntranceIndex < ENTRANCE_RANDO_GROTTO_EXIT_START + NUM_GROTTOS) { + if (nextEntranceIndex >= ENTRANCE_GROTTO_EXIT_START && nextEntranceIndex < ENTRANCE_GROTTO_EXIT_START + NUM_GROTTOS) { GrottoReturnInfo grotto = grottoReturnTable[tempGrottoId]; // When the nextEntranceIndex is determined by a dynamic exit, @@ -161,7 +166,7 @@ s16 Grotto_GetEntranceValueHandlingGrottoRando(s16 nextEntranceIndex) { nextEntranceIndex = ENTR_RETURN_GROTTO; } // Grotto Loads - } else if (nextEntranceIndex >= ENTRANCE_RANDO_GROTTO_LOAD_START && nextEntranceIndex < ENTRANCE_RANDO_GROTTO_EXIT_START) { + } else if (nextEntranceIndex >= ENTRANCE_GROTTO_LOAD_START && nextEntranceIndex < ENTRANCE_GROTTO_EXIT_START) { GrottoLoadInfo grotto = grottoLoadTable[tempGrottoId]; nextEntranceIndex = grotto.entranceIndex; } @@ -181,8 +186,8 @@ s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) { // If Link hits a grotto exit, load the entrance index from the grotto exit list // based on the current grotto ID if (nextEntranceIndex == ENTR_RETURN_GROTTO) { - Entrance_SetEntranceDiscovered(ENTRANCE_RANDO_GROTTO_EXIT_START + grottoId, false); - EntranceTracker_SetLastEntranceOverride(ENTRANCE_RANDO_GROTTO_EXIT_START + grottoId); + Entrance_SetEntranceDiscovered(ENTRANCE_GROTTO_EXIT_START + grottoId, false); + EntranceTracker_SetLastEntranceOverride(ENTRANCE_GROTTO_EXIT_START + grottoId); nextEntranceIndex = grottoExitList[grottoId]; } @@ -190,7 +195,7 @@ s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) { grottoId = nextEntranceIndex & 0x00FF; // Grotto Returns - if (nextEntranceIndex >= ENTRANCE_RANDO_GROTTO_EXIT_START && nextEntranceIndex < ENTRANCE_RANDO_GROTTO_EXIT_START + NUM_GROTTOS) { + if (nextEntranceIndex >= ENTRANCE_GROTTO_EXIT_START && nextEntranceIndex < ENTRANCE_GROTTO_EXIT_START + NUM_GROTTOS) { GrottoReturnInfo grotto = grottoReturnTable[grottoId]; Grotto_SetupReturnInfo(grotto, RESPAWN_MODE_RETURN); @@ -215,7 +220,7 @@ s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) { lastEntranceType = GROTTO_RETURN; // Grotto Loads - } else if (nextEntranceIndex >= ENTRANCE_RANDO_GROTTO_LOAD_START && nextEntranceIndex < ENTRANCE_RANDO_GROTTO_EXIT_START) { + } else if (nextEntranceIndex >= ENTRANCE_GROTTO_LOAD_START && nextEntranceIndex < ENTRANCE_GROTTO_EXIT_START) { // Set the respawn data to load the correct grotto GrottoLoadInfo grotto = grottoLoadTable[grottoId]; @@ -252,8 +257,8 @@ void Grotto_OverrideActorEntrance(Actor* thisx) { if (grottoContent == grottoLoadTable[index].content && gPlayState->sceneNum == grottoLoadTable[index].scene) { // Find the override for the matching index from the grotto Load List - Entrance_SetEntranceDiscovered(ENTRANCE_RANDO_GROTTO_LOAD_START + index, false); - EntranceTracker_SetLastEntranceOverride(ENTRANCE_RANDO_GROTTO_LOAD_START + index); + Entrance_SetEntranceDiscovered(ENTRANCE_GROTTO_LOAD_START + index, false); + EntranceTracker_SetLastEntranceOverride(ENTRANCE_GROTTO_LOAD_START + index); index = grottoLoadList[index]; // Run the index through the special entrances override check @@ -268,7 +273,7 @@ void Grotto_OverrideActorEntrance(Actor* thisx) { void Grotto_ForceGrottoReturnOnSpecialEntrance(void) { if (lastEntranceType == GROTTO_RETURN && (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS))) { gSaveContext.respawnFlag = 2; - gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams = 0x4FF; + gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams = 0x04FF; gSaveContext.respawn[RESPAWN_MODE_RETURN].pos = grottoReturnTable[grottoId].pos; // Clear current temp flags gSaveContext.respawn[RESPAWN_MODE_RETURN].tempSwchFlags = 0; @@ -303,7 +308,7 @@ void Grotto_ForceRegularVoidOut(void) { // so that Sun's Song and Game Over will behave correctly void Grotto_SetupReturnInfoOnFWReturn(void) { if (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS) && - gSaveContext.fw.playerParams == 0x4FF) { + gSaveContext.fw.playerParams == 0x04FF) { gSaveContext.respawn[RESPAWN_MODE_RETURN] = gSaveContext.respawn[RESPAWN_MODE_TOP]; gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams = 0x0DFF; lastEntranceType = GROTTO_RETURN; @@ -326,9 +331,20 @@ void Grotto_SanitizeEntranceType(void) { s16 Grotto_GetRenamedGrottoIndexFromOriginal(s8 content, s8 scene) { for (s16 index = 0; index < NUM_GROTTOS; index++) { if (content == grottoLoadTable[index].content && scene == grottoLoadTable[index].scene) { - return ENTRANCE_RANDO_GROTTO_LOAD_START | index; + return ENTRANCE_GROTTO_LOAD_START | index; } } - return ENTRANCE_RANDO_GROTTO_LOAD_START; + return ENTRANCE_GROTTO_LOAD_START; +} + +s8 Grotto_CurrentGrotto() { + if (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) { + return grottoId; + } else { + s16 entrance = gSaveContext.respawn[RESPAWN_MODE_RETURN].entranceIndex; + s8 scene = gEntranceTable[entrance].scene; + s8 data = gSaveContext.respawn[RESPAWN_MODE_RETURN].data; + return Grotto_GetRenamedGrottoIndexFromOriginal(data, scene) & 0xFF; + } } diff --git a/soh/soh/Enhancements/randomizer/randomizer_grotto.h b/soh/soh/Enhancements/randomizer/randomizer_grotto.h index 938c4c6d6..8da99ac04 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_grotto.h +++ b/soh/soh/Enhancements/randomizer/randomizer_grotto.h @@ -2,6 +2,7 @@ #define _RANDO_GROTTO_H_ #include "z64math.h" +#include "z64actor.h" #define NUM_GROTTOS GROTTO_OFFSET_MAX #define NOT_GROTTO 0 @@ -21,15 +22,23 @@ typedef struct { Vec3f pos; } GrottoReturnInfo; +#ifdef __cplusplus +extern "C" { +#endif void Grotto_InitExitAndLoadLists(void); void Grotto_SetExitOverride(s16 originalIndex, s16 overrideIndex); void Grotto_SetLoadOverride(s16 originalIndex, s16 overrideIndex); s16 Grotto_GetEntranceValueHandlingGrottoRando(s16 nextEntranceIndex); s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex); +void Grotto_OverrideActorEntrance(Actor* thisx); void Grotto_ForceGrottoReturnOnSpecialEntrance(void); void Grotto_ForceGrottoReturn(void); void Grotto_ForceRegularVoidOut(void); void Grotto_SanitizeEntranceType(void); s16 Grotto_GetRenamedGrottoIndexFromOriginal(s8 content, s8 scene); +s8 Grotto_CurrentGrotto(); +#ifdef __cplusplus +}; +#endif #endif //_RANDO_GROTTO_H_ diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 20aab3032..c6f0a84f7 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -202,6 +202,550 @@ typedef enum { RAND_INF_HAS_OCARINA_C_LEFT, RAND_INF_HAS_OCARINA_C_RIGHT, + RAND_INF_KF_LINKS_HOUSE_POT, + RAND_INF_KF_TWINS_HOUSE_POT_1, + RAND_INF_KF_TWINS_HOUSE_POT_2, + RAND_INF_KF_BROTHERS_HOUSE_POT_1, + RAND_INF_KF_BROTHERS_HOUSE_POT_2, + RAND_INF_GF_BREAK_ROOM_POT_1, + RAND_INF_GF_BREAK_ROOM_POT_2, + RAND_INF_GF_KITCHEN_POT_1, + RAND_INF_GF_KITCHEN_POT_2, + RAND_INF_GF_NORTH_F1_CARPENTER_POT_1, + RAND_INF_GF_NORTH_F1_CARPENTER_POT_2, + RAND_INF_GF_NORTH_F1_CARPENTER_POT_3, + RAND_INF_GF_NORTH_F2_CARPENTER_POT_1, + RAND_INF_GF_NORTH_F2_CARPENTER_POT_2, + RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1, + RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2, + RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3, + RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1, + RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2, + RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3, + RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4, + RAND_INF_WASTELAND_NEAR_GS_POT_1, + RAND_INF_WASTELAND_NEAR_GS_POT_2, + RAND_INF_WASTELAND_NEAR_GS_POT_3, + RAND_INF_WASTELAND_NEAR_GS_POT_4, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43, + RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10, + RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11, + RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1, + RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2, + RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3, + RAND_INF_KAK_NEAR_POTION_SHOP_POT_1, + RAND_INF_KAK_NEAR_POTION_SHOP_POT_2, + RAND_INF_KAK_NEAR_POTION_SHOP_POT_3, + RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1, + RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2, + RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3, + RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1, + RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2, + RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3, + RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1, + RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2, + RAND_INF_GY_DAMPES_GRAVE_POT_1, + RAND_INF_GY_DAMPES_GRAVE_POT_2, + RAND_INF_GY_DAMPES_GRAVE_POT_3, + RAND_INF_GY_DAMPES_GRAVE_POT_4, + RAND_INF_GY_DAMPES_GRAVE_POT_5, + RAND_INF_GY_DAMPES_GRAVE_POT_6, + RAND_INF_GC_LOWER_STAIRCASE_POT_1, + RAND_INF_GC_LOWER_STAIRCASE_POT_2, + RAND_INF_GC_UPPER_STAIRCASE_POT_1, + RAND_INF_GC_UPPER_STAIRCASE_POT_2, + RAND_INF_GC_UPPER_STAIRCASE_POT_3, + RAND_INF_GC_MEDIGORON_POT_1, + RAND_INF_GC_DARUNIA_POT_1, + RAND_INF_GC_DARUNIA_POT_2, + RAND_INF_GC_DARUNIA_POT_3, + RAND_INF_DMC_NEAR_GC_POT_1, + RAND_INF_DMC_NEAR_GC_POT_2, + RAND_INF_DMC_NEAR_GC_POT_3, + RAND_INF_DMC_NEAR_GC_POT_4, + RAND_INF_ZD_NEAR_SHOP_POT_1, + RAND_INF_ZD_NEAR_SHOP_POT_2, + RAND_INF_ZD_NEAR_SHOP_POT_3, + RAND_INF_ZD_NEAR_SHOP_POT_4, + RAND_INF_ZD_NEAR_SHOP_POT_5, + RAND_INF_ZF_HIDDEN_CAVE_POT_1, + RAND_INF_ZF_HIDDEN_CAVE_POT_2, + RAND_INF_ZF_HIDDEN_CAVE_POT_3, + RAND_INF_ZF_NEAR_JABU_POT_1, + RAND_INF_ZF_NEAR_JABU_POT_2, + RAND_INF_ZF_NEAR_JABU_POT_3, + RAND_INF_ZF_NEAR_JABU_POT_4, + RAND_INF_LLR_FRONT_POT_1, + RAND_INF_LLR_FRONT_POT_2, + RAND_INF_LLR_FRONT_POT_3, + RAND_INF_LLR_FRONT_POT_4, + RAND_INF_LLR_RAIN_SHED_POT_1, + RAND_INF_LLR_RAIN_SHED_POT_2, + RAND_INF_LLR_RAIN_SHED_POT_3, + RAND_INF_LLR_TALONS_HOUSE_POT_1, + RAND_INF_LLR_TALONS_HOUSE_POT_2, + RAND_INF_LLR_TALONS_HOUSE_POT_3, + RAND_INF_HF_COW_GROTTO_POT_1, + RAND_INF_HF_COW_GROTTO_POT_2, + RAND_INF_HC_STORMS_GROTTO_POT_1, + RAND_INF_HC_STORMS_GROTTO_POT_2, + RAND_INF_HC_STORMS_GROTTO_POT_3, + RAND_INF_HC_STORMS_GROTTO_POT_4, + + RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1, + RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2, + RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3, + RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4, + RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1, + RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2, + RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3, + RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4, + RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5, + RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6, + RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1, + RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2, + RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3, + RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4, + RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1, + RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2, + RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3, + RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4, + RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1, + RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2, + RAND_INF_DODONGOS_CAVERN_BLADE_POT_1, + RAND_INF_DODONGOS_CAVERN_BLADE_POT_2, + RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, + RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, + RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1, + RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2, + RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3, + RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4, + RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, + RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, + RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, + RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1, + RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2, + RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3, + RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4, + RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5, + RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6, + RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1, + RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2, + RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3, + RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, + RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, + RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, + RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, + RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, + RAND_INF_FOREST_TEMPLE_LOBBY_POT_1, + RAND_INF_FOREST_TEMPLE_LOBBY_POT_2, + RAND_INF_FOREST_TEMPLE_LOBBY_POT_3, + RAND_INF_FOREST_TEMPLE_LOBBY_POT_4, + RAND_INF_FOREST_TEMPLE_LOBBY_POT_5, + RAND_INF_FOREST_TEMPLE_LOBBY_POT_6, + RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1, + RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2, + RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1, + RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2, + RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1, + RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2, + RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3, + RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4, + RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1, + RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2, + RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3, + RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1, + RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2, + RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1, + RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2, + RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3, + RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4, + RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1, + RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2, + RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3, + RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, + RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, + RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, + RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, + RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, + RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, + RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, + RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, + RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, + RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, + RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, + RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, + RAND_INF_WATER_TEMPLE_TORCH_POT_1, + RAND_INF_WATER_TEMPLE_TORCH_POT_2, + RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1, + RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2, + RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3, + RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1, + RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2, + RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1, + RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2, + RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3, + RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4, + RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, + RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, + RAND_INF_WATER_TEMPLE_RIVER_POT_1, + RAND_INF_WATER_TEMPLE_RIVER_POT_2, + RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1, + RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2, + RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1, + RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2, + RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, + RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, + RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, + RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, + RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, + RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, + RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1, + RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2, + RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, + RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, + RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, + RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, + RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1, + RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2, + RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, + RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1, + RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2, + RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1, + RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2, + RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3, + RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4, + RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1, + RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2, + RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1, + RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2, + RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3, + RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4, + RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, + RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, + RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, + RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, + RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, + RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, + RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, + RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, + RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, + RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, + RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3, + RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3, + RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4, + RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, + RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17, + RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, + RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, + RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, + RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, + RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, + RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, + RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, + RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT, + RAND_INF_ICE_CAVERN_HALL_POT_1, + RAND_INF_ICE_CAVERN_HALL_POT_2, + RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1, + RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2, + RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3, + RAND_INF_ICE_CAVERN_NEAR_END_POT_1, + RAND_INF_ICE_CAVERN_NEAR_END_POT_2, + RAND_INF_ICE_CAVERN_FROZEN_POT_1, + + RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, + RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, + RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, + RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, + RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, + RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, + RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, + RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, + RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, + RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1, + RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2, + RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3, + RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4, + RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5, + RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6, + RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1, + RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2, + RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, + RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, + RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, + RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, + RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, + RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, + RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, + RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, + RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, + RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1, + RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2, + RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3, + RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4, + RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, + RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, + RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, + RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, + RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, + RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, + RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, + RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, + RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1, + RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2, + RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, + RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, + RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1, + RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, + RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1, + RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2, + RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3, + RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4, + RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1, + RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2, + RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, + RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, + RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, + RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, + RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, + RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, + RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, + RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, + RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, + RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1, + RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2, + RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3, + RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4, + RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, + RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, + RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1, + RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2, + RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3, + RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4, + RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, + RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, + RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3, + RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, + RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, + RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, + RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, + RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, + RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, + RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6, + RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, + RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, + RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, + RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, + RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, + RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, + RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, + RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, + RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT, + RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, + RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, + RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, + RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, + RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, + RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, + RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, + RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, + RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1, + RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2, + RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, + RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, + RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, + RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, + RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1, + RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2, + RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3, + RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4, + RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5, + RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, + RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, + RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, + RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, + RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, + RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, + RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, + RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, + RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, + RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, + RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3, + RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4, + RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5, + RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, + RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, + RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1, + RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2, + RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, + RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, + RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, + RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, + RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, + RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, + RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, + RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, + RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, + + RAND_INF_CAUGHT_LOACH, RAND_INF_CAN_SWIM, @@ -306,6 +850,426 @@ typedef enum { RAND_INF_CHILD_TRADES_MASK_ZORA, RAND_INF_CHILD_TRADES_MASK_GERUDO, RAND_INF_CHILD_TRADES_MASK_TRUTH, + + RAND_INF_KF_BOULDER_RUPEE_2, + RAND_INF_KF_BOULDER_RUPEE_1, + RAND_INF_KF_BRIDGE_RUPEE, + RAND_INF_KF_BEHIND_MIDOS_RUPEE, + RAND_INF_KF_SARIAS_ROOF_WEST_HEART, + RAND_INF_KF_SARIAS_ROOF_EAST_HEART, + RAND_INF_KF_SARIAS_ROOF_NORTH_HEART, + RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE, + RAND_INF_KF_NORTH_GRASS_WEST_RUPEE, + RAND_INF_KF_NORTH_GRASS_EAST_RUPEE, + RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE, + RAND_INF_KF_SARIAS_TOP_LEFT_HEART, + RAND_INF_KF_SARIAS_TOP_RIGHT_HEART, + RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART, + RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART, + RAND_INF_KF_BEAN_RUPEE_1, + RAND_INF_KF_BEAN_RUPEE_2, + RAND_INF_KF_BEAN_RUPEE_3, + RAND_INF_KF_BEAN_RUPEE_4, + RAND_INF_KF_BEAN_RUPEE_5, + RAND_INF_KF_BEAN_RUPEE_6, + RAND_INF_KF_BEAN_RED_RUPEE, + RAND_INF_LW_SHORTCUT_RUPEE_1, + RAND_INF_LW_SHORTCUT_RUPEE_2, + RAND_INF_LW_SHORTCUT_RUPEE_3, + RAND_INF_LW_SHORTCUT_RUPEE_4, + RAND_INF_LW_SHORTCUT_RUPEE_5, + RAND_INF_LW_SHORTCUT_RUPEE_6, + RAND_INF_LW_SHORTCUT_RUPEE_7, + RAND_INF_LW_SHORTCUT_RUPEE_8, + RAND_INF_LH_FRONT_RUPEE, + RAND_INF_LH_MIDDLE_RUPEE, + RAND_INF_LH_BACK_RUPEE, + RAND_INF_LH_LAB_FRONT_RUPEE, + RAND_INF_LH_LAB_LEFT_RUPEE, + RAND_INF_LH_LAB_RIGHT_RUPEE, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7, + RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8, + + RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, + RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE, + + RAND_INF_DMT_RED_RUPEE, + RAND_INF_DMT_BLUE_RUPEE, + RAND_INF_DMT_COW_GROTTO_LEFT_HEART, + RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, + RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, + RAND_INF_DMT_COW_GROTTO_RIGHT_HEART, + RAND_INF_DMT_COW_GROTTO_RUPEE_1, + RAND_INF_DMT_COW_GROTTO_RUPEE_2, + RAND_INF_DMT_COW_GROTTO_RUPEE_3, + RAND_INF_DMT_COW_GROTTO_RUPEE_4, + RAND_INF_DMT_COW_GROTTO_RUPEE_5, + RAND_INF_DMT_COW_GROTTO_RUPEE_6, + RAND_INF_DMT_COW_GROTTO_RED_RUPEE, + + RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE, + RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, + RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5, + RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6, + RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE, + + RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE, + RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, + RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, + RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, + RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, + RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, + RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE, + RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, + RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, + + RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART, + RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART, + RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, + RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, + RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, + RAND_INF_DODONGOS_CAVERN_LOWER_LIZALFOS_HEART, + RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART, + RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, + RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, + RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, + RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART, + RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART, + RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, + RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, + RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, + RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, + RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, + RAND_INF_WATER_TEMPLE_RIVER_HEART_1, + RAND_INF_WATER_TEMPLE_RIVER_HEART_2, + RAND_INF_WATER_TEMPLE_RIVER_HEART_3, + RAND_INF_WATER_TEMPLE_RIVER_HEART_4, + RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, + RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, + RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, + RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, + RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, + RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, + RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, + RAND_INF_SPIRIT_TEMPLE_ADULT_CLIMB_LEFT_HEART, + RAND_INF_SPIRIT_TEMPLE_ADULT_CLIMB_RIGHT_HEART, + RAND_INF_ICE_CAVERN_LOBBY_RUPEE, + RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART, + RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, + RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, + RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, + RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, + RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_LEFT_RUPEE, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_LEFT_RUPEE, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_MIDDLE_RUPEE, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_BACK_RIGHT_RUPEE, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM_RIGHT_RUPEE, + RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_FRONT_LEFT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, + RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, + RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, + RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, + RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, + RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, + RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART, + RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART, + + RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART, + RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART, + RAND_INF_DEKU_TREE_MQ_LOBBY_HEART, + RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, + RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, + RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, + RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, + RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, + RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, + RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_1, + RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_2, + RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_RUPEE_3, + RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, + RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, + RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, + RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, + RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, + RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART, + RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART, + RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, + RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, + RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, + RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, + RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, + RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, + RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, + + RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1, + RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2, + RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3, + RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4, + RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5, + RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6, + RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7, + RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8, + RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1, + RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2, + RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3, + RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4, + RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5, + RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6, + RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7, + RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8, + RAND_INF_HF_FAIRY_GROTTO_FAIRY_1, + RAND_INF_HF_FAIRY_GROTTO_FAIRY_2, + RAND_INF_HF_FAIRY_GROTTO_FAIRY_3, + RAND_INF_HF_FAIRY_GROTTO_FAIRY_4, + RAND_INF_HF_FAIRY_GROTTO_FAIRY_5, + RAND_INF_HF_FAIRY_GROTTO_FAIRY_6, + RAND_INF_HF_FAIRY_GROTTO_FAIRY_7, + RAND_INF_HF_FAIRY_GROTTO_FAIRY_8, + RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1, + RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2, + RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3, + RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4, + RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5, + RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6, + RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7, + RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8, + RAND_INF_GF_FAIRY_GROTTO_FAIRY_1, + RAND_INF_GF_FAIRY_GROTTO_FAIRY_2, + RAND_INF_GF_FAIRY_GROTTO_FAIRY_3, + RAND_INF_GF_FAIRY_GROTTO_FAIRY_4, + RAND_INF_GF_FAIRY_GROTTO_FAIRY_5, + RAND_INF_GF_FAIRY_GROTTO_FAIRY_6, + RAND_INF_GF_FAIRY_GROTTO_FAIRY_7, + RAND_INF_GF_FAIRY_GROTTO_FAIRY_8, + RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, + RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, + RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, + RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, + RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, + RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, + RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, + RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, + RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1, + RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2, + RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3, + RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4, + RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5, + RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6, + RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7, + RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8, + RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, + RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, + RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, + RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, + RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, + RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, + RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, + RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, + RAND_INF_COLOSSUS_OASIS_FAIRY_1, + RAND_INF_COLOSSUS_OASIS_FAIRY_2, + RAND_INF_COLOSSUS_OASIS_FAIRY_3, + RAND_INF_COLOSSUS_OASIS_FAIRY_4, + RAND_INF_COLOSSUS_OASIS_FAIRY_5, + RAND_INF_COLOSSUS_OASIS_FAIRY_6, + RAND_INF_COLOSSUS_OASIS_FAIRY_7, + RAND_INF_COLOSSUS_OASIS_FAIRY_8, + + RAND_INF_ZR_BEAN_SPROUT_FAIRY_1, + RAND_INF_ZR_BEAN_SPROUT_FAIRY_2, + RAND_INF_ZR_BEAN_SPROUT_FAIRY_3, + RAND_INF_KF_BEAN_SPROUT_FAIRY_1, + RAND_INF_KF_BEAN_SPROUT_FAIRY_2, + RAND_INF_KF_BEAN_SPROUT_FAIRY_3, + RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, + RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, + RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, + RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, + RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, + RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, + RAND_INF_LH_BEAN_SPROUT_FAIRY_1, + RAND_INF_LH_BEAN_SPROUT_FAIRY_2, + RAND_INF_LH_BEAN_SPROUT_FAIRY_3, + RAND_INF_GV_BEAN_SPROUT_FAIRY_1, + RAND_INF_GV_BEAN_SPROUT_FAIRY_2, + RAND_INF_GV_BEAN_SPROUT_FAIRY_3, + RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1, + RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2, + RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3, + RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1, + RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2, + RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3, + RAND_INF_DMC_BEAN_SPROUT_FAIRY_1, + RAND_INF_DMC_BEAN_SPROUT_FAIRY_2, + RAND_INF_DMC_BEAN_SPROUT_FAIRY_3, + RAND_INF_DMT_BEAN_SPROUT_FAIRY_1, + RAND_INF_DMT_BEAN_SPROUT_FAIRY_2, + RAND_INF_DMT_BEAN_SPROUT_FAIRY_3, + + RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, + RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, + RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, + RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, + RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_DMC_GOSSIP_STONE_FAIRY, + RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_DMT_GOSSIP_STONE_FAIRY, + RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY, + RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, + RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, + RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_GV_GOSSIP_STONE_FAIRY, + RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY, + RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY, + RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY, + RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY, + RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, + RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, + RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, + RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_KF_GOSSIP_STONE_FAIRY, + RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY, + RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, + RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, + RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_LW_GOSSIP_STONE_FAIRY, + RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, + RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, + RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY, + RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_ZD_GOSSIP_STONE_FAIRY, + RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY, + RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY, + RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, + RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, + RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, + RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, + + RAND_INF_LH_ISLAND_SUN_FAIRY, + RAND_INF_HF_POND_STORMS_FAIRY, + RAND_INF_DMT_FLAG_SUN_FAIRY, + RAND_INF_LW_SHORTCUT_STORMS_FAIRY, + RAND_INF_GF_KITCHEN_SUN_FAIRY, + RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, + RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, + RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, + RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY, + RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, + RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, + RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, + RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, + RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, + RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, + RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, + RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, + RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, + RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, + RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, + RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, + RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, + RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, + RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) RAND_INF_MAX, diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index e07503b20..4c5ba4714 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -1,7 +1,10 @@ #include "randomizer_item_tracker.h" -#include "../../util.h" -#include "../../OTRGlobals.h" -#include "../../UIWidgets.hpp" +#include "soh/util.h" +#include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" +#include "soh/SaveManager.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/UIWidgets.hpp" #include "randomizerTypes.h" #include @@ -22,7 +25,6 @@ extern PlayState* gPlayState; #include "textures/icon_item_static/icon_item_static.h" #include "textures/icon_item_24_static/icon_item_24_static.h" } -extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum); void DrawEquip(ItemTrackerItem item); void DrawItem(ItemTrackerItem item); @@ -440,7 +442,7 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) { result.maxCapacity = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; break; case SCENE_GERUDO_TRAINING_GROUND: - result.maxCapacity = GERUDO_TRAINING_GROUNDS_SMALL_KEY_MAX; + result.maxCapacity = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; break; case SCENE_THIEVES_HIDEOUT: result.maxCapacity = GERUDO_FORTRESS_SMALL_KEY_MAX; @@ -598,11 +600,11 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { ImGui::SetCursorScreenPos( ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize((currentString + maxString).c_str()).x / 2), p.y - 14)); ImGui::PushStyleColor(ImGuiCol_Text, currentColor); - ImGui::Text(currentString.c_str()); + ImGui::Text("%s", currentString.c_str()); ImGui::PopStyleColor(); ImGui::SameLine(0, 0.0f); ImGui::PushStyleColor(ImGuiCol_Text, maxColor); - ImGui::Text(maxString.c_str()); + ImGui::Text("%s", maxString.c_str()); ImGui::PopStyleColor(); } else { ImGui::SetCursorScreenPos(ImVec2(p.x, p.y - 14)); @@ -1222,7 +1224,7 @@ void ItemTrackerWindow::DrawElement() { int iconSpacing = CVarGetInteger(CVAR_TRACKER_ITEM("IconSpacing"), 12); int comboButton1Mask = buttonMap[CVarGetInteger(CVAR_TRACKER_ITEM("ComboButton1"), TRACKER_COMBO_BUTTON_L)]; int comboButton2Mask = buttonMap[CVarGetInteger(CVAR_TRACKER_ITEM("ComboButton2"), TRACKER_COMBO_BUTTON_R)]; - OSContPad* buttonsPressed = Ship::Context::GetInstance()->GetControlDeck()->GetPads(); + OSContPad* buttonsPressed = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); bool comboButtonsHeld = buttonsPressed != nullptr && buttonsPressed[0].button & comboButton1Mask && buttonsPressed[0].button & comboButton2Mask; bool isPaused = CVarGetInteger(CVAR_TRACKER_ITEM("ShowOnlyPaused"), 0) == 0 || gPlayState != nullptr && gPlayState->pauseCtx.state > 0; @@ -1374,7 +1376,7 @@ void ItemTrackerSettingsWindow::DrawElement() { CVarSetFloat(CVAR_TRACKER_ITEM("BgColorG"), ChromaKeyBackground.y); CVarSetFloat(CVAR_TRACKER_ITEM("BgColorB"), ChromaKeyBackground.z); CVarSetFloat(CVAR_TRACKER_ITEM("BgColorA"), ChromaKeyBackground.w); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::PopItemWidth(); diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 15424960d..eb081552f 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -1,6 +1,8 @@ #include "savefile.h" #include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/randomizer/logic.h" extern "C" { #include @@ -8,12 +10,14 @@ extern "C" { #include "functions.h" #include "macros.h" -uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum); uint8_t Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId); } -void StartingItemGive(GetItemEntry getItemEntry) { +void StartingItemGive(GetItemEntry getItemEntry, RandomizerCheck randomizerCheck) { + if (randomizerCheck != RC_MAX) { + OTRGlobals::Instance->gRandoContext->GetItemLocation(randomizerCheck)->SetCheckStatus(RCSHOW_SAVED); + } if (getItemEntry.modIndex == MOD_NONE) { if (getItemEntry.getItemId == GI_SWORD_BGS) { gSaveContext.bgsFlag = true; @@ -32,7 +36,7 @@ void StartingItemGive(GetItemEntry getItemEntry) { // Item_Give in z_parameter, we'll need to update Item_Give to ensure // nothing breaks when calling it without a valid play first void GiveLinkRupees(int numOfRupees) { - int maxRupeeCount; + int maxRupeeCount = 0; if (CUR_UPG_VALUE(UPG_WALLET) == 0) { maxRupeeCount = 99; } else if (CUR_UPG_VALUE(UPG_WALLET) == 1) { @@ -52,7 +56,7 @@ void GiveLinkRupees(int numOfRupees) { } void GiveLinkDekuSticks(int howManySticks) { - int maxStickCount; + int maxStickCount = 0; if (CUR_UPG_VALUE(UPG_STICKS) == 0) { INV_CONTENT(ITEM_STICK) = ITEM_STICK; Inventory_ChangeUpgrade(UPG_STICKS, 1); @@ -73,7 +77,7 @@ void GiveLinkDekuSticks(int howManySticks) { } void GiveLinkDekuNuts(int howManyNuts) { - int maxNutCount; + int maxNutCount = 0; if (CUR_UPG_VALUE(UPG_NUTS) == 0) { INV_CONTENT(ITEM_NUT) = ITEM_NUT; Inventory_ChangeUpgrade(UPG_NUTS, 1); @@ -96,13 +100,13 @@ void GiveLinkDekuNuts(int howManyNuts) { void GiveLinksPocketItem() { if (Randomizer_GetSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_LINKS_POCKET, (GetItemID)RG_NONE); - StartingItemGive(getItemEntry); - Rando::Context::GetInstance()->GetItemLocation(RC_LINKS_POCKET)->SetCheckStatus(RCSHOW_SAVED); + StartingItemGive(getItemEntry, RC_LINKS_POCKET); // If we re-add the above, we'll get the item on save creation, now it's given on first load Flags_SetRandomizerInf(RAND_INF_LINKS_POCKET); } } + void SetStartingItems() { if (Randomizer_GetSettingValue(RSK_STARTING_KOKIRI_SWORD)) Item_Give(NULL, ITEM_SWORD_KOKIRI); @@ -149,13 +153,11 @@ void SetStartingItems() { INV_CONTENT(ITEM_OCARINA_FAIRY) = ITEM_OCARINA_FAIRY; } - if (Randomizer_GetSettingValue(RSK_STARTING_CONSUMABLES)) { - if (!Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG)) { - GiveLinkDekuSticks(10); - } - if (!Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG)) { - GiveLinkDekuNuts(20); - } + if (Randomizer_GetSettingValue(RSK_STARTING_STICKS) && !Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_STICK_BAG)) { + GiveLinkDekuSticks(10); + } + if (Randomizer_GetSettingValue(RSK_STARTING_NUTS) && !Randomizer_GetSettingValue(RSK_SHUFFLE_DEKU_NUT_BAG)) { + GiveLinkDekuNuts(20); } if (Randomizer_GetSettingValue(RSK_FULL_WALLETS)) { @@ -184,8 +186,8 @@ void SetStartingItems() { gSaveContext.sohStats.dungeonKeys[SCENE_SHADOW_TEMPLE] = SHADOW_TEMPLE_SMALL_KEY_MAX; // Shadow gSaveContext.inventory.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; // BotW gSaveContext.sohStats.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; // BotW - gSaveContext.inventory.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] = GERUDO_TRAINING_GROUNDS_SMALL_KEY_MAX; // GTG - gSaveContext.sohStats.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] = GERUDO_TRAINING_GROUNDS_SMALL_KEY_MAX; // GTG + gSaveContext.inventory.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; // GTG + gSaveContext.sohStats.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; // GTG gSaveContext.inventory.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon gSaveContext.sohStats.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon } else if (Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_VANILLA) { @@ -214,8 +216,9 @@ void SetStartingItems() { } extern "C" void Randomizer_InitSaveFile() { - // Now handled by cutscene skips - // gSaveContext.cutsceneIndex = 0; // no intro cutscene + auto ctx = Rando::Context::GetInstance(); + ctx->GetLogic()->SetSaveContext(&gSaveContext); + // Starts pending ice traps out at 0 before potentially incrementing them down the line. gSaveContext.pendingIceTrapCount = 0; @@ -223,94 +226,17 @@ extern "C" void Randomizer_InitSaveFile() { gSaveContext.triforcePiecesCollected = 0; // Set Cutscene flags and texts to skip them - // Now handled by cutscene skips - // Flags_SetInfTable(INFTABLE_GREETED_BY_SARIA); Flags_SetEventChkInf(EVENTCHKINF_FIRST_SPOKE_TO_MIDO); - // Now handled by cutscene skips - // Flags_SetEventChkInf(EVENTCHKINF_MET_DEKU_TREE); - // Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH); Flags_SetInfTable(INFTABLE_SPOKE_TO_KAEPORA_IN_LAKE_HYLIA); - // Now handled by cutscene skips - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_MASTER_SWORD_CHAMBER); - // Now using this to grant master sword check - // Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL); Flags_SetEventChkInf(EVENTCHKINF_SHEIK_SPAWNED_AT_MASTER_SWORD_PEDESTAL); - // Now used to give player LACS rewards - // Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); Flags_SetEventChkInf(EVENTCHKINF_RENTED_HORSE_FROM_INGO); Flags_SetInfTable(INFTABLE_SPOKE_TO_POE_COLLECTOR_IN_RUINED_MARKET); Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_NABOORU_IN_SPIRIT_TEMPLE); - // Now handled by cutscene skips - // Flags_SetInfTable(INFTABLE_MET_CHILD_MALON_AT_CASTLE_OR_MARKET); - // Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_CASTLE_OR_MARKET); - // Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_INGO_AT_RANCH_BEFORE_TALON_RETURNS); - // Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_CHILD_MALON_AT_RANCH); - // Flags_SetEventChkInf(EVENTCHKINF_INVITED_TO_SING_WITH_CHILD_MALON); - // Flags_SetInfTable(INFTABLE_CHILD_MALON_SAID_EPONA_WAS_AFRAID_OF_YOU); - // Flags_SetInfTable(INFTABLE_SPOKE_TO_INGO_ONCE_AS_ADULT); - - // Ruto already met in jabu and spawns down the hole immediately - Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_MEET_RUTO); - Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME); - Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE); - - // Now handled by cutscene skips - // Skip cutscenes before Nabooru fight - // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_NABOORU_BATTLE); - // Flags_SetEventChkInf(EVENTCHKINF_NABOORU_ORDERED_TO_FIGHT_BY_TWINROVA); - - // Now handled by cutscene skips - // Skip boss cutscenes - // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_GOHMA_BATTLE); - // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_KING_DODONGO_BATTLE); - // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_PHANTOM_GANON_BATTLE); - // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE); - // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_MORPHA_BATTLE); - // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_TWINROVA_BATTLE); - // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BARINA_BATTLE); - // Flags_SetEventChkInf(EVENTCHKINF_BEGAN_BONGO_BONGO_BATTLE); - - // Now handled by cutscene skips - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_HYRULE_FIELD); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_TRAIL); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_KAKARIKO_VILLAGE); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_ZORAS_DOMAIN); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_HYRULE_CASTLE); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GORON_CITY); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_TEMPLE_OF_TIME); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEKU_TREE); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DODONGOS_CAVERN); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LAKE_HYLIA); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GERUDO_VALLEY); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GERUDOS_FORTRESS); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LON_LON_RANCH); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_JABU_JABUS_BELLY); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GRAVEYARD); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_ZORAS_FOUNTAIN); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DESERT_COLOSSUS); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_CRATER); - // Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GANONS_CASTLE_EXTERIOR); - // Ensure Malon appears at castle first time you enter - // Flags_SetInfTable(INFTABLE_ENTERED_HYRULE_CASTLE); - - // skip the z target talk instructions by the kokiri shop - // Now handled by cutscene skips - // gSaveContext.sceneFlags[SCENE_KOKIRI_FOREST].swch |= (1 << 0x1F); - // Go away ruto (water temple first cutscene) gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x10); - // Now handled by cutscene skips - // no more kaepora - // gSaveContext.sceneFlags[SCENE_HYRULE_FIELD].swch |= (1 << 0xC); // hyrule field kaepora outside kokiri forest - // gSaveContext.sceneFlags[SCENE_HYRULE_FIELD].swch |= (1 << 0xB); // hyrule field kaepora outside lake hylia - // gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 0x7); // lost woods kaepora pre-saria - // gSaveContext.sceneFlags[SCENE_LOST_WOODS].swch |= (1 << 0x8); // lost woods kaepora post-saria - // gSaveContext.sceneFlags[SCENE_DESERT_COLOSSUS].swch |= (1 << 0x1F); // desert colossus kaepora - // gSaveContext.sceneFlags[SCENE_HYRULE_CASTLE].swch |= (1 << 0x5); // hyrule castle kaepora - if (Randomizer_GetSettingValue(RSK_SHUFFLE_OCARINA_BUTTONS) == RO_GENERIC_OFF) { Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_A); Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT); @@ -350,7 +276,7 @@ extern "C" void Randomizer_InitSaveFile() { switch (startingAge) { case RO_AGE_ADULT: // Adult gSaveContext.linkAge = LINK_AGE_ADULT; - gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_7; + gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_WARP_PAD; gSaveContext.savedSceneNum = SCENE_LON_LON_RANCH; // Set scene num manually to ToT break; case RO_AGE_CHILD: // Child @@ -381,7 +307,7 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SKIP_CHILD_ZELDA)) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_SONG_FROM_IMPA, (GetItemID)RG_ZELDAS_LULLABY); - StartingItemGive(getItemEntry); + StartingItemGive(getItemEntry, RC_SONG_FROM_IMPA); // malon/talon back at ranch Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_POCKET_EGG); @@ -403,7 +329,7 @@ extern "C" void Randomizer_InitSaveFile() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && startingAge == RO_AGE_ADULT) { GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_MASTER_SWORD, GI_NONE); - StartingItemGive(getItemEntry); + StartingItemGive(getItemEntry, RC_TOT_MASTER_SWORD); Flags_SetRandomizerInf(RAND_INF_TOT_MASTER_SWORD); } @@ -432,10 +358,10 @@ extern "C" void Randomizer_InitSaveFile() { // Now handled on the fly // int openForest = Randomizer_GetSettingValue(RSK_FOREST); // switch (openForest) { - // case RO_FOREST_OPEN: + // case RO_CLOSED_FOREST_OFF: // Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD); // // Fallthrough - // case RO_FOREST_CLOSED_DEKU: + // case RO_CLOSED_FOREST_DEKU_ONLY: // Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD); // break; // } @@ -451,8 +377,8 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetInfTable(INFTABLE_SHOWED_ZELDAS_LETTER_TO_GATE_GUARD); } - if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_FAST || - Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_OPEN) { + if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FAST || + Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FREE) { Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(1)); Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(2)); Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(3)); @@ -470,7 +396,7 @@ extern "C" void Randomizer_InitSaveFile() { gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].collect |= (1 << 0x0F); } - if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_OPEN) { + if (Randomizer_GetSettingValue(RSK_GERUDO_FORTRESS) == RO_GF_CARPENTERS_FREE) { Flags_SetEventChkInf(EVENTCHKINF_CARPENTERS_FREE(0)); gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x01); // heard yell and unlocked door gSaveContext.sceneFlags[SCENE_THIEVES_HIDEOUT].swch |= (1 << 0x05); diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index e56d2a5c0..952d3e3d2 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -105,17 +105,23 @@ Settings::Settings() : mExcludeLocationsOptionsAreas(RCAREA_INVALID) { void Settings::CreateOptions() { CreateOptionDescriptions(); // clang-format off - mOptions[RSK_FOREST] = Option::U8("Forest", {"Closed", "Closed Deku", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Forest"), mOptionDescriptions[RSK_FOREST], WidgetType::Combobox, RO_FOREST_CLOSED); + mOptions[RSK_FOREST] = Option::U8("Closed Forest", {"On", "Deku Only", "Off"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ClosedForest"), mOptionDescriptions[RSK_FOREST], WidgetType::Combobox, RO_CLOSED_FOREST_ON); mOptions[RSK_KAK_GATE] = Option::U8("Kakariko Gate", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("KakarikoGate"), mOptionDescriptions[RSK_KAK_GATE]); mOptions[RSK_DOOR_OF_TIME] = Option::U8("Door of Time", {"Closed", "Song only", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DoorOfTime"), mOptionDescriptions[RSK_DOOR_OF_TIME], WidgetType::Combobox); mOptions[RSK_ZORAS_FOUNTAIN] = Option::U8("Zora's Fountain", {"Closed", "Closed as child", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ZorasFountain"), mOptionDescriptions[RSK_ZORAS_FOUNTAIN]); - mOptions[RSK_GERUDO_FORTRESS] = Option::U8("Gerudo Fortress", {"Normal", "Fast", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoFortress"), mOptionDescriptions[RSK_GERUDO_FORTRESS]); + mOptions[RSK_SLEEPING_WATERFALL] = Option::U8("Sleeping Waterfall", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), mOptionDescriptions[RSK_SLEEPING_WATERFALL]); + mOptions[RSK_GERUDO_FORTRESS] = Option::U8("Fortress Carpenters", {"Normal", "Fast", "Free"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FortressCarpenters"), mOptionDescriptions[RSK_GERUDO_FORTRESS]); mOptions[RSK_RAINBOW_BRIDGE] = Option::U8("Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Greg"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RainbowBridge"), mOptionDescriptions[RSK_RAINBOW_BRIDGE], WidgetType::Combobox, RO_BRIDGE_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT] = Option::U8("Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StoneCount"), "", WidgetType::Slider, 3, true); - mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT] = Option::U8("Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MedallionCount"), "", WidgetType::Slider, 6, true); - mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT] = Option::U8("Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RewardCount"), "", WidgetType::Slider, 9, true); - mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT] = Option::U8("Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DungeonCount"), "", WidgetType::Slider, 8, true); - mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT] = Option::U8("Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TokenCount"), "", WidgetType::Slider, 100, true); + mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT] = Option::U8("Bridge Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StoneCount"), "", WidgetType::Slider, 3, true); + mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT] = Option::U8("Bridge Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MedallionCount"), "", WidgetType::Slider, 6, true); + mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT] = Option::U8("Bridge Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RewardCount"), "", WidgetType::Slider, 9, true); + mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT] = Option::U8("Bridge Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DungeonCount"), "", WidgetType::Slider, 8, true); + mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT] = Option::U8("Bridge Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TokenCount"), "", WidgetType::Slider, 100, true); + mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT] = Option::U8("Bridge Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StoneCount"), "", WidgetType::Slider, 3, true); + mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT] = Option::U8("Bridge Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MedallionCount"), "", WidgetType::Slider, 6, true); + mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT] = Option::U8("Bridge Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RewardCount"), "", WidgetType::Slider, 9, true); + mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT] = Option::U8("Bridge Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DungeonCount"), "", WidgetType::Slider, 8, true); + mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT] = Option::U8("Bridge Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("TokenCount"), "", WidgetType::Slider, 100, true); mOptions[RSK_BRIDGE_OPTIONS] = Option::U8("Bridge Reward Options", {"Standard Rewards", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BridgeRewardOptions"), mOptionDescriptions[RSK_BRIDGE_OPTIONS], WidgetType::Combobox, RO_BRIDGE_STANDARD_REWARD, false, IMFLAG_NONE); mOptions[RSK_GANONS_TRIALS] = Option::U8("Ganon's Trials", {"Skip", "Set Number", "Random Number"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrial"), mOptionDescriptions[RSK_GANONS_TRIALS], WidgetType::Combobox, RO_GANONS_TRIALS_SET_NUMBER); mOptions[RSK_TRIAL_COUNT] = Option::U8("Ganon's Trials Count", {NumOpts(0, 6)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GanonTrialCount"), mOptionDescriptions[RSK_TRIAL_COUNT], WidgetType::Slider, 6, true); @@ -145,44 +151,44 @@ void Settings::CreateOptions() { mOptions[RSK_MQ_DUNGEON_RANDOM] = Option::U8("MQ Dungeon Setting", {"None", "Set Number", "Random", "Selection Only"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeons"), mOptionDescriptions[RSK_MQ_DUNGEON_RANDOM], WidgetType::Combobox, RO_MQ_DUNGEONS_NONE, true, IMFLAG_NONE); mOptions[RSK_MQ_DUNGEON_COUNT] = Option::U8("MQ Dungeon Count", {NumOpts(0, 12)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonCount"), "", WidgetType::Slider, 12, true, IMFLAG_NONE); mOptions[RSK_MQ_DUNGEON_SET] = Option::Bool("Set Dungeon Quests", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsSelection"), mOptionDescriptions[RSK_MQ_DUNGEON_SET], WidgetType::Checkbox, false, false, IMFLAG_NONE); - mOptions[RSK_MQ_DEKU_TREE] = Option::U8("Deku Tree", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDekuTree"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_DODONGOS_CAVERN] = Option::U8("Dodongo's Cavern", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDodongosCavern"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_JABU_JABU] = Option::U8("Jabu-Jabu's Belly", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsJabuJabu"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_FOREST_TEMPLE] = Option::U8("Forest Temple", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsForestTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_FIRE_TEMPLE] = Option::U8("Fire Temple", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsFireTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_WATER_TEMPLE] = Option::U8("Water Temple", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsWaterTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_SPIRIT_TEMPLE] = Option::U8("Spirit Temple", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsSpiritTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_SHADOW_TEMPLE] = Option::U8("Shadow Temple", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsShadowTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_BOTTOM_OF_THE_WELL] = Option::U8("Bottom of the Well", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsBottomOfTheWell"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_ICE_CAVERN] = Option::U8("Ice Cavern", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsIceCavern"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_GTG] = Option::U8("Gerudo Training Grounds", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGTG"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MQ_GANONS_CASTLE] = Option::U8("Ganon's Castle", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGanonsCastle"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA); + mOptions[RSK_MQ_DEKU_TREE] = Option::U8("Deku Tree Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDekuTree"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_DODONGOS_CAVERN] = Option::U8("Dodongo's Cavern Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsDodongosCavern"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_JABU_JABU] = Option::U8("Jabu-Jabu's Belly Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsJabuJabu"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_FOREST_TEMPLE] = Option::U8("Forest Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsForestTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_FIRE_TEMPLE] = Option::U8("Fire Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsFireTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_WATER_TEMPLE] = Option::U8("Water Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsWaterTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_SPIRIT_TEMPLE] = Option::U8("Spirit Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsSpiritTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_SHADOW_TEMPLE] = Option::U8("Shadow Temple Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsShadowTemple"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_BOTTOM_OF_THE_WELL] = Option::U8("Bottom of the Well Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsBottomOfTheWell"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_ICE_CAVERN] = Option::U8("Ice Cavern Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsIceCavern"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_GTG] = Option::U8("Gerudo Training Ground Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGTG"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_MQ_GANONS_CASTLE] = Option::U8("Ganon's Castle Quest", {"Vanilla", "Master Quest", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MQDungeonsGanonsCastle"), "", WidgetType::Combobox, RO_MQ_SET_VANILLA); mOptions[RSK_SHUFFLE_DUNGEON_REWARDS] = Option::U8("Shuffle Dungeon Rewards", {"End of Dungeons", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS], WidgetType::Combobox, RO_DUNGEON_REWARDS_END_OF_DUNGEON); mOptions[RSK_LINKS_POCKET] = Option::U8("Link's Pocket", {"Dungeon Reward", "Advancement", "Anything", "Nothing"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocket"), "", WidgetType::Combobox, RO_LINKS_POCKET_DUNGEON_REWARD); mOptions[RSK_SHUFFLE_SONGS] = Option::U8("Shuffle Songs", {"Song Locations", "Dungeon Rewards", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSongs"), mOptionDescriptions[RSK_SHUFFLE_SONGS], WidgetType::Combobox, RO_SONG_SHUFFLE_SONG_LOCATIONS); - mOptions[RSK_SHOPSANITY] = Option::U8("Shopsanity", {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WidgetType::Combobox, RO_SHOPSANITY_OFF); - mOptions[RSK_SHOPSANITY_COUNT] = Option::U8("Shopsanity Item Count", {NumOpts(0, 7/*8*/)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), mOptionDescriptions[RSK_SHOPSANITY_COUNT], WidgetType::Slider, 0, false, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES] = Option::U8("Shopsanity Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), mOptionDescriptions[RSK_SHOPSANITY_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE] = Option::U8("Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); - mOptions[RSK_SHOPSANITY_PRICES_RANGE_1] = Option::U8("Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_RANGE_2] = Option::U8("Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT] = Option::U8("No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY] = Option::U8("Shop Shuffle", {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WidgetType::Combobox, RO_SHOPSANITY_OFF); + mOptions[RSK_SHOPSANITY_COUNT] = Option::U8("Shops Item Count", {NumOpts(0, 7/*8*/)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), mOptionDescriptions[RSK_SHOPSANITY_COUNT], WidgetType::Slider, 0, false, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES] = Option::U8("Shops Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), mOptionDescriptions[RSK_SHOPSANITY_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE] = Option::U8("Shops Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); + mOptions[RSK_SHOPSANITY_PRICES_RANGE_1] = Option::U8("Shops Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_RANGE_2] = Option::U8("Shops Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT] = Option::U8("Shops No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Shops Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Shops Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Shops Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Shops Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE] = Option::Bool("Shops Affordable Prices", CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE]); - mOptions[RSK_SHUFFLE_TOKENS] = Option::U8("Tokensanity", {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleTokens"), mOptionDescriptions[RSK_SHUFFLE_TOKENS], WidgetType::Combobox, RO_TOKENSANITY_OFF); - mOptions[RSK_SHUFFLE_SCRUBS] = Option::U8("Scrub Shuffle", {"Off", "One-Time Only", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), mOptionDescriptions[RSK_SHUFFLE_SCRUBS], WidgetType::Combobox, RO_SCRUBS_OFF); - mOptions[RSK_SCRUBS_PRICES] = Option::U8("Scrub Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPrices"), mOptionDescriptions[RSK_SCRUBS_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE] = Option::U8("Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); - mOptions[RSK_SCRUBS_PRICES_RANGE_1] = Option::U8("Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_RANGE_2] = Option::U8("Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT] = Option::U8("No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsGiantWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SHUFFLE_TOKENS] = Option::U8("Token Shuffle", {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleTokens"), mOptionDescriptions[RSK_SHUFFLE_TOKENS], WidgetType::Combobox, RO_TOKENSANITY_OFF); + mOptions[RSK_SHUFFLE_SCRUBS] = Option::U8("Scrubs Shuffle", {"Off", "One-Time Only", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), mOptionDescriptions[RSK_SHUFFLE_SCRUBS], WidgetType::Combobox, RO_SCRUBS_OFF); + mOptions[RSK_SCRUBS_PRICES] = Option::U8("Scrubs Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPrices"), mOptionDescriptions[RSK_SCRUBS_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE] = Option::U8("Scrubs Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); + mOptions[RSK_SCRUBS_PRICES_RANGE_1] = Option::U8("Scrubs Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_RANGE_2] = Option::U8("Scrubs Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT] = Option::U8("Scrubs No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Scrubs Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Scrubs Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Scrubs Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsGiantWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Scrubs Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); mOptions[RSK_SCRUBS_PRICES_AFFORDABLE] = Option::Bool("Scrubs Affordable Prices", CVAR_RANDOMIZER_SETTING("ScrubsPricesAffordable"), mOptionDescriptions[RSK_SCRUBS_PRICES_AFFORDABLE]); mOptions[RSK_SHUFFLE_BEEHIVES] = Option::Bool("Shuffle Beehives", CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), mOptionDescriptions[RSK_SHUFFLE_BEEHIVES]); mOptions[RSK_SHUFFLE_COWS] = Option::Bool("Shuffle Cows", CVAR_RANDOMIZER_SETTING("ShuffleCows"), mOptionDescriptions[RSK_SHUFFLE_COWS]); @@ -195,17 +201,18 @@ void Settings::CreateOptions() { mOptions[RSK_SHUFFLE_SWIM] = Option::Bool("Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]); mOptions[RSK_SHUFFLE_WEIRD_EGG] = Option::Bool("Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]); mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD] = Option::Bool("Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]); + mOptions[RSK_SHUFFLE_POTS] = Option::U8("Shuffle Pots", {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), mOptionDescriptions[RSK_SHUFFLE_POTS], WidgetType::Combobox, RO_SHUFFLE_POTS_OFF); mOptions[RSK_SHUFFLE_FISHING_POLE] = Option::Bool("Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); mOptions[RSK_SHUFFLE_MERCHANTS] = Option::U8("Shuffle Merchants", {"Off", "Bean Merchant Only", "All But Beans", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WidgetType::Combobox, RO_SHUFFLE_MERCHANTS_OFF, IMFLAG_NONE); mOptions[RSK_MERCHANT_PRICES] = Option::U8("Merchant Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPrices"), mOptionDescriptions[RSK_MERCHANT_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE] = Option::U8("Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"), mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); - mOptions[RSK_MERCHANT_PRICES_RANGE_1] = Option::U8("Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_RANGE_2] = Option::U8("Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT] = Option::U8("No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); - mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE] = Option::U8("Merchant Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"), mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true); + mOptions[RSK_MERCHANT_PRICES_RANGE_1] = Option::U8("Merchant Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_RANGE_2] = Option::U8("Merchant Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT] = Option::U8("Merchant No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Merchant Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Merchant Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Merchant Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); + mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Merchant Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE); mOptions[RSK_MERCHANT_PRICES_AFFORDABLE] = Option::Bool("Merchant Affordable Prices", CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE]); mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES] = Option::Bool("Shuffle Frog Song Rupees", CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES]); mOptions[RSK_SHUFFLE_ADULT_TRADE] = Option::Bool("Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]); @@ -214,20 +221,22 @@ void Settings::CreateOptions() { mOptions[RSK_SHUFFLE_BOSS_SOULS] = Option::U8("Shuffle Boss Souls", {"Off", "On", "On + Ganon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS], WidgetType::Combobox); mOptions[RSK_SHUFFLE_DEKU_STICK_BAG] = Option::Bool("Shuffle Deku Stick Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); mOptions[RSK_SHUFFLE_DEKU_NUT_BAG] = Option::Bool("Shuffle Deku Nut Bag", CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG], IMFLAG_SEPARATOR_BOTTOM, WidgetType::Checkbox, RO_GENERIC_OFF); + mOptions[RSK_SHUFFLE_FREESTANDING] = Option::U8("Shuffle Freestanding Items", {"Off", "Dungeons", "Overworld", "All Items"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), mOptionDescriptions[RSK_SHUFFLE_FREESTANDING], WidgetType::Combobox, RO_SHUFFLE_FREESTANDING_OFF); mOptions[RSK_FISHSANITY] = Option::U8("Fishsanity", {"Off", "Shuffle only Hyrule Loach", "Shuffle Fishing Pond", "Shuffle Overworld Fish", "Shuffle Both"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Fishsanity"), mOptionDescriptions[RSK_FISHSANITY], WidgetType::Combobox, RO_FISHSANITY_OFF); mOptions[RSK_FISHSANITY_POND_COUNT] = Option::U8("Pond Fish Count", {NumOpts(0,17,1)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), mOptionDescriptions[RSK_FISHSANITY_POND_COUNT], WidgetType::Slider, 0, true, IMFLAG_NONE); mOptions[RSK_FISHSANITY_AGE_SPLIT] = Option::Bool("Pond Age Split", CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT]); + mOptions[RSK_SHUFFLE_FAIRIES] = Option::Bool("Shuffle Fairies", CVAR_RANDOMIZER_SETTING("ShuffleFairies"), mOptionDescriptions[RSK_SHUFFLE_FAIRIES]); mOptions[RSK_SHUFFLE_MAPANDCOMPASS] = Option::U8("Maps/Compasses", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), mOptionDescriptions[RSK_SHUFFLE_MAPANDCOMPASS], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); - mOptions[RSK_KEYSANITY] = Option::U8("Small Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), mOptionDescriptions[RSK_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); + mOptions[RSK_KEYSANITY] = Option::U8("Small Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), mOptionDescriptions[RSK_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); mOptions[RSK_GERUDO_KEYS] = Option::U8("Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoKeys"), mOptionDescriptions[RSK_GERUDO_KEYS], WidgetType::Combobox, RO_GERUDO_KEYS_VANILLA); - mOptions[RSK_BOSS_KEYSANITY] = Option::U8("Boss Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BossKeysanity"), mOptionDescriptions[RSK_BOSS_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); + mOptions[RSK_BOSS_KEYSANITY] = Option::U8("Boss Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BossKeysanity"), mOptionDescriptions[RSK_BOSS_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); mOptions[RSK_GANONS_BOSS_KEY] = Option::U8("Ganon's Boss Key", {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Stones", "LACS-Medallions", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens", "100 GS Reward", "Triforce Hunt"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), mOptionDescriptions[RSK_GANONS_BOSS_KEY], WidgetType::Combobox, RO_GANON_BOSS_KEY_VANILLA); - mOptions[RSK_LACS_STONE_COUNT] = Option::U8("Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsStoneCount"), "", WidgetType::Slider, 3, true); - mOptions[RSK_LACS_MEDALLION_COUNT] = Option::U8("Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), "", WidgetType::Slider, 6, true); - mOptions[RSK_LACS_REWARD_COUNT] = Option::U8("Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardCount"), "", WidgetType::Slider, 9, true); - mOptions[RSK_LACS_DUNGEON_COUNT] = Option::U8("Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsDungeonCount"), "", WidgetType::Slider, 8, true); - mOptions[RSK_LACS_TOKEN_COUNT] = Option::U8("Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsTokenCount"), "", WidgetType::Slider, 100, true); - mOptions[RSK_LACS_OPTIONS] = Option::U8("LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), "", WidgetType::Combobox, RO_LACS_STANDARD_REWARD); + mOptions[RSK_LACS_STONE_COUNT] = Option::U8("GCBK Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsStoneCount"), "", WidgetType::Slider, 3, true); + mOptions[RSK_LACS_MEDALLION_COUNT] = Option::U8("GCBK Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), "", WidgetType::Slider, 6, true); + mOptions[RSK_LACS_REWARD_COUNT] = Option::U8("GCBK Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardCount"), "", WidgetType::Slider, 9, true); + mOptions[RSK_LACS_DUNGEON_COUNT] = Option::U8("GCBK Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsDungeonCount"), "", WidgetType::Slider, 8, true); + mOptions[RSK_LACS_TOKEN_COUNT] = Option::U8("GCBK Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsTokenCount"), "", WidgetType::Slider, 100, true); + mOptions[RSK_LACS_OPTIONS] = Option::U8("GCBK LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), "", WidgetType::Combobox, RO_LACS_STANDARD_REWARD); mOptions[RSK_KEYRINGS] = Option::U8("Key Rings", {"Off", "Random", "Count", "Selection"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), mOptionDescriptions[RSK_KEYRINGS], WidgetType::Combobox, RO_KEYRINGS_OFF); mOptions[RSK_KEYRINGS_RANDOM_COUNT] = Option::U8("Keyring Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), "", WidgetType::Slider, 8); mOptions[RSK_KEYRINGS_GERUDO_FORTRESS] = Option::U8("Gerudo Fortress Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), "", WidgetType::TristateCheckbox, 0); @@ -237,7 +246,7 @@ void Settings::CreateOptions() { mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE] = Option::U8("Spirit Temple Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsSpiritTemple"), "", WidgetType::TristateCheckbox, 0); mOptions[RSK_KEYRINGS_SHADOW_TEMPLE] = Option::U8("Shadow Temple Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsShadowTemple"), "", WidgetType::TristateCheckbox, 0); mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL] = Option::U8("Bottom of the Well Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsBottomOfTheWell"), "", WidgetType::TristateCheckbox, 0); - mOptions[RSK_KEYRINGS_GTG] = Option::U8("Gerudo Training Grounds Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGTG"), "", WidgetType::TristateCheckbox, 0); + mOptions[RSK_KEYRINGS_GTG] = Option::U8("Gerudo Training Ground Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGTG"), "", WidgetType::TristateCheckbox, 0); mOptions[RSK_KEYRINGS_GANONS_CASTLE] = Option::U8("Ganon's Castle Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGanonsCastle"), "", WidgetType::TristateCheckbox, 0); mOptions[RSK_SKIP_CHILD_STEALTH] = Option::Bool("Skip Child Stealth", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipChildStealth"), mOptionDescriptions[RSK_SKIP_CHILD_STEALTH], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); mOptions[RSK_SKIP_CHILD_ZELDA] = Option::Bool("Skip Child Zelda", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipChildZelda"), mOptionDescriptions[RSK_SKIP_CHILD_ZELDA], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); @@ -287,7 +296,8 @@ void Settings::CreateOptions() { mOptions[RSK_STARTING_DEKU_SHIELD] = Option::Bool("Start with Deku Shield", CVAR_RANDOMIZER_SETTING("StartingDekuShield")); mOptions[RSK_STARTING_KOKIRI_SWORD] = Option::Bool("Start with Kokiri Sword", CVAR_RANDOMIZER_SETTING("StartingKokiriSword")); mOptions[RSK_STARTING_MASTER_SWORD] = Option::Bool("Start with Master Sword", CVAR_RANDOMIZER_SETTING("StartingMasterSword")); - mOptions[RSK_STARTING_CONSUMABLES] = Option::Bool("Start with Consumables", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingConsumables"), "", WidgetType::Checkbox, RO_GENERIC_OFF); + mOptions[RSK_STARTING_STICKS] = Option::Bool("Start with Stick Ammo", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSticks"), "", WidgetType::Checkbox, RO_GENERIC_OFF); + mOptions[RSK_STARTING_NUTS] = Option::Bool("Start with Nut Ammo", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingNuts"), "", WidgetType::Checkbox, RO_GENERIC_OFF); mOptions[RSK_FULL_WALLETS] = Option::Bool("Full Wallets", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FullWallets"), mOptionDescriptions[RSK_FULL_WALLETS], WidgetType::Checkbox, RO_GENERIC_OFF); mOptions[RSK_STARTING_ZELDAS_LULLABY] = Option::Bool("Start with Zelda's Lullaby", CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), "", IMFLAG_NONE); mOptions[RSK_STARTING_EPONAS_SONG] = Option::Bool("Start with Epona's Song", CVAR_RANDOMIZER_SETTING("StartingEponasSong"), "", IMFLAG_NONE); @@ -302,7 +312,7 @@ void Settings::CreateOptions() { mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW] = Option::Bool("Start with Nocturne of Shadow", CVAR_RANDOMIZER_SETTING("StartingNocturneOfShadow"), "", IMFLAG_NONE); mOptions[RSK_STARTING_PRELUDE_OF_LIGHT] = Option::Bool("Start with Prelude of Light", CVAR_RANDOMIZER_SETTING("StartingPreludeOfLight")); mOptions[RSK_STARTING_SKULLTULA_TOKEN] = Option::U8("Gold Skulltula Tokens", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSkulltulaToken"), "", WidgetType::Slider); - mOptions[RSK_STARTING_HEARTS] = Option::U8("Hearts", {NumOpts(1, 20)}, OptionCategory::Setting, "gRandomizeStartingHearts", "", WidgetType::Slider, 2); + mOptions[RSK_STARTING_HEARTS] = Option::U8("Starting Hearts", {NumOpts(1, 20)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingHearts"), "", WidgetType::Slider, 2); // TODO: Remainder of Starting Items mOptions[RSK_LOGIC_RULES] = Option::U8("Logic", {"Glitchless", "Glitched", "No Logic", "Vanilla"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LogicRules"), mOptionDescriptions[RSK_LOGIC_RULES], WidgetType::Combobox, RO_LOGIC_GLITCHLESS); mOptions[RSK_ALL_LOCATIONS_REACHABLE] = Option::Bool("All Locations Reachable", {"Off", "On"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("AllLocationsReachable"), mOptionDescriptions[RSK_ALL_LOCATIONS_REACHABLE], WidgetType::Checkbox, RO_GENERIC_ON); @@ -310,197 +320,209 @@ void Settings::CreateOptions() { mOptions[RSK_DAMAGE_MULTIPLIER] = Option::U8("Damage Multiplier", {"x1/2", "x1", "x2", "x4", "x8", "x16", "OHKO"}, OptionCategory::Setting, "", "", WidgetType::Slider, RO_DAMAGE_MULTIPLIER_DEFAULT); // clang-format on + StaticData::optionNameToEnum = PopulateOptionNameToEnum(); + mExcludeLocationsOptionsAreas.reserve(RCAREA_INVALID); - mTrickOptions[RT_ACUTE_ANGLE_CLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Acute angle clip", "Enables locations requiring jumpslash clips through walls which meet at an acute angle."); - mTrickOptions[RT_ADVANCED_CLIPS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Advanced clips", "Enables locations requiring clips through walls and objects requiring precise jumps or other tricks."); - mTrickOptions[RT_BLANK_A] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Blank A", "Enables locations requiring blank A button; NOTE: this requires the 'Quick Putaway' restoration."); - mTrickOptions[RT_DOOM_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Doom Jump", "Enables locations requiring doom jumps."); - mTrickOptions[RT_EPG] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "EPG", "Enables locations requiring use of the Entrance Point Glitch."); - mTrickOptions[RT_EQUIP_SWAP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Equip Swap", "Enables locations requiring use of equip swap; NOTE: this may expect the 'Allow cursor to be over any slot' enhancement to be turned off."); - mTrickOptions[RT_EQUIP_SWAP_EXPECTS_DINS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Equip Swap Require's Din's Fire", "Enables locations requiring use of equip swap once din's fire is found."); - mTrickOptions[RT_FLAME_STORAGE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Flame Storage", "Enables locations requiring flame storage."); - mTrickOptions[RT_GROUND_CLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Ground Clip", "Enables locations requiring ground clips."); - mTrickOptions[RT_GROUND_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Ground Jump", "Enables locations requiring ground jumps."); - mTrickOptions[RT_HESS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "HESS", "Enables locations requiring a Hyper Extended Super Slide."); - mTrickOptions[RT_HOOKSHOT_CLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Hookshot Clip", "Enables locations requiring hookshot clips."); - mTrickOptions[RT_HOOKSHOT_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "Hookshot Jump", "Enables locations requiring hookshot jumps."); - mTrickOptions[RT_ISG] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, true, "ISG", "Enables locations requiring use of the infinite sword glitch."); - mTrickOptions[RT_VISIBLE_COLLISION] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, false, "Pass Through Visible One-Way Collision", "Allows climbing through the platform to reach Impa's House Back as adult with no items and going through the Kakariko Village Gate as child when coming from the Mountain Trail side."); - mTrickOptions[RT_GROTTOS_WITHOUT_AGONY] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, false, "Hidden Grottos without Stone of Agony", "Allows entering hidden grottos without the Stone of Agony."); - mTrickOptions[RT_FEWER_TUNIC_REQUIREMENTS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::INTERMEDIATE}, false, "Fewer Tunic Requirements", "Allows the following possible without Tunics:\n- Enter Water Temple. The area below the center pillar still requires Zora Tunic. Applies to MQ also.\n- Enter Fire Temple. Volvagia still requires Goron tunic. Applies to MQ also, and includes child access to first floor with dungeon shuffle."); - mTrickOptions[RT_RUSTED_SWITCHES] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, false, "Hammer Rusted Switches Through Walls", "Applies to: - Fire Temple Highest Goron Chest. - MQ Fire Temple Lizalfos Maze. - MQ Spirit Trial."); - mTrickOptions[RT_FLAMING_CHESTS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::INTERMEDIATE}, false, "Flaming Chests", "The chests encircled in flames in Gerudo Training Grounds and in Spirit Temple can be opened by running into the flames while Link is invincible after taking damage."); - // mTrickOptions[RT_BUNNY_HOOD_JUMPS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, false, "Bunny Hood Jumps", "Allows reaching locations using Bunny Hood's extended jumps."); - // mTrickOptions[RT_DAMAGE_BOOST_SIMPLE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, false, "Simple damage boosts", "Allows damage boosts to reach Hyrule Castle guards, the bomb bag area in DC and the Gerudo Valley crate Piece of Heart. Can be combined with \"Simple hover boosts\" for reaching far distances."); - // mTrickOptions[RT_HOVER_BOOST_SIMPLE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, false, "Simple hover boosts", "Allows equipping of hover boots when link is moving at high speeds to extend distance covered. Can be combined with \"Simple damage boosts\" for greater uses."); - mTrickOptions[RT_BOMBCHU_BEEHIVES] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, false, "Bombchu Beehives", "Allows exploding beehives with bombchus"), - mTrickOptions[RT_KF_ADULT_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KOKIRI_FOREST, {Tricks::Tag::NOVICE}, false, "Adult Kokiri Forest GS with Hover Boots", "Can be obtained without Hookshot by using the Hover Boots off of one of the roots."); - mTrickOptions[RT_LW_BRIDGE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::EXPERT}, false, "Jump onto the Lost Woods Bridge as Adult with Nothing", "With very precise movement it's possible for adult to jump onto the bridge without needing Longshot, Hover Boots, or Bean."); - mTrickOptions[RT_LW_MIDO_BACKFLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::NOVICE}, false, "Backflip over Mido as Adult", "With a specific position and angle, you can backflip over Mido."); - mTrickOptions[RT_LW_GS_BEAN] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::INTERMEDIATE}, false, "Lost Woods Adult GS without Bean", "You can collect the token with a precise Hookshot use, as long as you can kill the Skulltula somehow first. It can be killed using Longshot, Bow, Bombchus or Din's Fire."); - mTrickOptions[RT_HC_STORMS_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_HYRULE_CASTLE, {Tricks::Tag::INTERMEDIATE}, false, "Hyrule Castle Storms Grotto GS with Just Boomerang", "With precise throws, the Boomerang alone can kill the Skulltula and collect the token, without first needing to blow up the wall."); - mTrickOptions[RT_KAK_MAN_ON_ROOF] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::NOVICE}, false, "Man on Roof without Hookshot", "Can be reached by side-hopping off the watchtower as either age, or by jumping onto the potion shop's roof from the ledge as adult."); - mTrickOptions[RT_KAK_TOWER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::INTERMEDIATE}, false, "Kakariko Tower GS with Jump Slash", "Climb the tower as high as you can without touching the Gold Skulltula, then let go and jump slash immediately. By jump-slashing from as low on the ladder as possible to still hit the Skulltula, this trick can be done without taking fall damage."); - mTrickOptions[RT_KAK_ADULT_WINDMILL_POH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::NOVICE}, false, "Windmill PoH as Adult with Nothing", "Can jump up to the spinning platform from below as adult."); - // mTrickOptions[RT_KAK_CHILD_WINDMILL_POH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::EXTREME}, false, "Windmill PoH as Child with Precise Jump Slash", "Can jump up to the spinning platform from below as child with a precise jumpslash timed with the platforms rotation."); - mTrickOptions[RT_KAK_ROOFTOP_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::ADVANCED}, false, "Kakariko Rooftop GS with Hover Boots", "Take the Hover Boots from the entrance to Impa's House over to the rooftop of Skulltula House. From there, a precise Hover Boots backwalk with backflip can be used to get onto a hill above the side of the village. And then from there you can Hover onto Impa's rooftop to kill the Skulltula and backflip into the token."); - mTrickOptions[RT_GY_POH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_GRAVEYARD, {Tricks::Tag::INTERMEDIATE}, false, "Graveyard Freestanding PoH with Boomerang", "Using a precise moving setup you can obtain the Piece of Heart by having the Boomerang interact with it along the return path."); - mTrickOptions[RT_GY_CHILD_DAMPE_RACE_POH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_GRAVEYARD, {Tricks::Tag::NOVICE}, false, "Second Dampe Race as Child", "It is possible to complete the second dampe race as child in under a minute, but it is a strict time limit."); - mTrickOptions[RT_GY_SHADOW_FIRE_ARROWS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_GRAVEYARD, {Tricks::Tag::EXPERT}, false, "Shadow Temple Entry with Fire Arrows", "It is possible to light all of the torches to open the Shadow Temple entrance with just Fire Arrows, but you must be very quick, precise, and strategic with how you take your shots."); - mTrickOptions[RT_DMT_SOIL_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, false, "Death Mountain Trail Soil GS without Destroying Boulder", "Bugs will go into the soft soil even while the boulder is still blocking the entrance. Then, using a precise moving setup you can kill the Gold Skulltula and obtain the token by having the Boomerang interact with it along the return path."); - mTrickOptions[RT_DMT_BOMBABLE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, false, "Death Mountain Trail Chest with Strength", "Child Link can blow up the wall using a nearby bomb flower. You must backwalk with the flower and then quickly throw it toward the wall."); - mTrickOptions[RT_DMT_HOOKSHOT_LOWER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, false, "Death Mountain Trail Lower Red Rock GS with Hookshot", "After killing the Skulltula, the token can be fished out of the rock without needing to destroy it, by using the Hookshot in the correct way."); - mTrickOptions[RT_DMT_HOVERS_LOWER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::ADVANCED}, false, "Death Mountain Trail Lower Red Rock GS with Hover Boots", "After killing the Skulltula, the token can be collected without needing to destroy the rock by backflipping down onto it with the Hover Boots. First use the Hover Boots to stand on a nearby fence, and go for the Skulltula Token from there."); - mTrickOptions[RT_DMT_BEAN_LOWER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::EXPERT}, false, "Death Mountain Trail Lower Red Rock GS with Magic Bean", "After killing the Skulltula, the token can be collected without needing to destroy the rock by jumping down onto it from the bean plant, midflight, with precise timing and positioning."); - mTrickOptions[RT_DMT_JS_LOWER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, false, "Death Mountain Trail Lower Red Rock GS with Jump Slash", "After killing the Skulltula, the token can be collected without needing to destroy the rock by jump slashing from a precise angle."); - mTrickOptions[RT_DMT_CLIMB_HOVERS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::ADVANCED}, false, "Death Mountain Trail Climb with Hover Boots", "It is possible to use the Hover Boots to bypass needing to destroy the boulders blocking the path to the top of Death Mountain."); - mTrickOptions[RT_DMT_UPPER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::NOVICE}, false, "Death Mountain Trail Upper Red Rock GS without Hammer", "After killing the Skulltula, the token can be collected by backflipping into the rock at the correct angle."); - // mTrickOptions[RT_DMT_BOLERO_BIGGORON] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, false, "Deliver Eye Drops with Bolero of Fire", "Playing a warp song normally causes a trade item to spoil immediately, however, it is possible use Bolero to reach Biggoron and still deliver the Eye Drops before they spoil. If you do not wear the Goron Tunic, the heat timer inside the crater will override the trade item\'s timer. When you exit to Death Mountain Trail you will have one second to show the Eye Drops before they expire. You can get extra time to show the Eye Drops if you warp immediately upon receiving them. If you don't have many hearts, you may have to reset the heat timer by quickly dipping in and out of Darunia\'s chamber or quickly equipping and unequipping the Goron Tunic. This trick does not apply if \"Randomize Warp Song Destinations\" is enabled, or if the settings are such that trade items do not need to be delivered within a time limit."); - mTrickOptions[RT_GC_POT] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::ADVANCED}, false, "Goron City Spinning Pot PoH with Bombchu", "A Bombchu can be used to stop the spinning pot, but it can be quite finicky to get it to work."); - mTrickOptions[RT_GC_POT_STRENGTH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::INTERMEDIATE}, false, "Goron City Spinning Pot PoH with Strength", "Allows for stopping the Goron City Spinning Pot using a bomb flower alone, requiring strength in lieu of inventory explosives."); - mTrickOptions[RT_GC_ROLLING_STRENGTH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::INTERMEDIATE}, false, "Rolling Goron (Hot Rodder Goron) as Child with Strength", "Use the bombflower on the stairs or near Medigoron. Timing is tight, especially without backwalking."); - mTrickOptions[RT_GC_LEFTMOST] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::ADVANCED}, false, "Goron City Maze Left Chest with Hover Boots", "A precise backwalk starting from on top of the crate and ending with a precisely-timed backflip can reach this chest without needing either the Hammer or Silver Gauntlets."); - mTrickOptions[RT_GC_GROTTO] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::ADVANCED}, false, "Goron City Grotto with Hookshot While Taking Damage", "It is possible to reach the Goron City Grotto by quickly using the Hookshot while in the midst of taking damage from the lava floor."); - mTrickOptions[RT_GC_LINK_GORON_DINS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::NOVICE}, false, "Stop Link the Goron with Din\'s Fire", "The timing is quite awkward."); - mTrickOptions[RT_DMC_HOVER_BEAN_POH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::NOVICE}, false, "Crater\'s Bean PoH with Hover Boots", "Hover from the base of the bridge near Goron City and walk up the very steep slope."); - mTrickOptions[RT_DMC_BOLERO_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::EXTREME}, false, "Death Mountain Crater Jump to Bolero", "As Adult , using a shield to drop a pot while you have the perfect speed and position, the pot can push you that little extra distance you need to jump across the gap in the bridge."); - mTrickOptions[RT_DMC_BOULDER_JS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::NOVICE}, false, "Death Mountain Crater Upper to Lower with Hammer", "With the Hammer, you can jump slash the rock twice in the same jump in order to destroy it before you fall into the lava."); - mTrickOptions[RT_DMC_BOULDER_SKIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::INTERMEDIATE}, false, "Death Mountain Crater Upper to Lower Boulder Skip", "As adult, With careful positioning, you can jump to the ledge where the boulder is, then use repeated ledge grabs to shimmy to a climbable ledge. This trick supersedes \"Death Mountain Crater Upper to Lower with Hammer\"."); - mTrickOptions[RT_ZR_LOWER] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::INTERMEDIATE}, false, "Zora\'s River Lower Freestanding PoH as Adult with Nothing", "Adult can reach this PoH with a precise jump, no Hover Boots required."); - mTrickOptions[RT_ZR_UPPER] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::INTERMEDIATE}, false, "Zora\'s River Upper Freestanding PoH as Adult with Nothing", "Adult can reach this PoH with a precise jump, no Hover Boots required."); - mTrickOptions[RT_ZR_HOVERS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::NOVICE}, false, "Zora\'s Domain Entry with Hover Boots", "Can hover behind the waterfall as adult."); - mTrickOptions[RT_ZR_CUCCO] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::NOVICE}, false, "Zora\'s Domain Entry with Cucco", "You can fly behind the waterfall with a Cucco as child."); - mTrickOptions[RT_ZD_KING_ZORA_SKIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_DOMAIN, {Tricks::Tag::INTERMEDIATE}, false, "Skip King Zora as Adult with Nothing", "With a precise jump as adult, it is possible to get on the fence next to King Zora from the front to access Zora's Fountain."); - mTrickOptions[RT_ZD_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_DOMAIN, {Tricks::Tag::INTERMEDIATE}, false, "Zora\'s Domain GS with No Additional Items", "A precise jump slash can kill the Skulltula and recoil back onto the top of the frozen waterfall. To kill it, the logic normally guarantees one of Hookshot, Bow, or Magic."); - mTrickOptions[RT_LH_LAB_WALL_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_LAKE_HYLIA, {Tricks::Tag::NOVICE}, false, "Lake Hylia Lab Wall GS with Jump Slash", "The jump slash to actually collect the token is somewhat precise."); - mTrickOptions[RT_LH_LAB_DIVING] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_LAKE_HYLIA, {Tricks::Tag::NOVICE}, false, "Lake Hylia Lab Dive without Gold Scale", "Remove the Iron Boots in the midst of Hookshotting the underwater crate."); - mTrickOptions[RT_LH_WATER_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_LAKE_HYLIA, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple Entry without Iron Boots using Hookshot", "When entering Water Temple using Gold Scale instead of Iron Boots, the Longshot is usually used to be able to hit the switch and open the gate. But, by standing in a particular spot, the switch can be hit with only the reach of the Hookshot."); - mTrickOptions[RT_GV_CRATE_HOVERS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GERUDO_VALLEY, {Tricks::Tag::INTERMEDIATE}, false, "Gerudo Valley Crate PoH as Adult with Hover Boots", "From the far side of Gerudo Valley, a precise Hover Boots movement and jump-slash recoil can allow adult to reach the ledge with the crate PoH without needing Longshot. You will take fall damage."); - mTrickOptions[RT_GF_KITCHEN] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GERUDO_FORTRESS, {Tricks::Tag::NOVICE}, false, "Thieves\' Hideout \"Kitchen\" with No Additional Items", "Allows passing through the kitchen by avoiding being seen by the guards. The logic normally guarantees Bow or Hookshot to stun them from a distance, or Hover Boots to cross the room without needing to deal with the guards."); - mTrickOptions[RT_GF_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GERUDO_FORTRESS, {Tricks::Tag::NOVICE}, false, "Gerudo\'s Fortress Ledge Jumps", "Adult can jump onto the top roof of the fortress without going through the interior of the hideout."); - // mTrickOptions[RT_HW_BUNNY_CROSSING] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::NOVICE}, false, "Wasteland Crossing with Bunny Hood", "You can beat the quicksand by using the increased speed of the Bunny Hood. Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash."); - mTrickOptions[RT_HW_CROSSING] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::INTERMEDIATE}, false, "Wasteland Crossing without Hover Boots or Longshot", "You can beat the quicksand by backwalking across it in a specific way. Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash."); - mTrickOptions[RT_LENS_HW] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::INTERMEDIATE}, false, "Lensless Wasteland", "By memorizing the path, you can travel through the Wasteland without using the Lens of Truth to see the Poe. The equivalent trick for going in reverse through the Wasteland is \"Reverse Wasteland\"."); - mTrickOptions[RT_HW_REVERSE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::INTERMEDIATE}, false, "Reverse Wasteland", "By memorizing the path, you can travel through the Wasteland in reverse. Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash. The equivalent trick for going forward through the Wasteland is \"Lensless Wasteland\". To cross the river of sand with no additional items, be sure to also enable \"Wasteland Crossing without Hover Boots or Longshot\". Unless all overworld entrances are randomized, child Link will not be expected to do anything at Gerudo's Fortress."); - mTrickOptions[RT_COLOSSUS_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DESERT_COLOSSUS, {Tricks::Tag::NOVICE}, false, "Colossus Hill GS with Hookshot", "Somewhat precise. If you kill enough Leevers you can get enough of a break to take some time to aim more carefully."); - mTrickOptions[RT_DEKU_BASEMENT_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, false, "Deku Tree Basement Vines GS with Jump Slash", "Can be defeated by doing a precise jump slash."); - mTrickOptions[RT_DEKU_B1_SKIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEKU_TREE, {Tricks::Tag::INTERMEDIATE}, false, "Deku Tree Basement without Slingshot", "A precise jump can be used to skip needing to use the Slingshot to go around B1 of the Deku Tree. If used with the \"Closed Forest\" setting, a Slingshot will not be guaranteed to exist somewhere inside the Forest. This trick applies to both Vanilla and Master Quest."); - mTrickOptions[RT_DEKU_B1_BOW_WEBS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, false, "Deku Tree Basement Web to Gohma with Bow", "All spider web walls in the Deku Tree basement can be burnt as adult with just a bow by shooting through torches. This trick only applies to the circular web leading to Gohma; the two vertical webs are always in logic. Backflip onto the chest near the torch at the bottom of the vine wall. With precise positioning you can shoot through the torch to the right edge of the circular web. This allows completion of adult Deku Tree with no fire source."); - mTrickOptions[RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, false, "Deku Tree Basement Backflip over Spiked Log", "Allows backflipping over the spiked log in the deku tree basement in vanilla. Only relevant if \"Shuffle Swim\" is enabled."); - mTrickOptions[RT_DEKU_MQ_COMPASS_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, false, "Deku Tree MQ Compass Room GS Boulders with Just Hammer", "Climb to the top of the vines, then let go and jump slash immediately to destroy the boulders using the Hammer, without needing to spawn a Song of Time block."); - mTrickOptions[RT_DEKU_MQ_LOG] = TrickOption::LogicTrick(RCQUEST_MQ, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, false, "Deku Tree MQ Roll Under the Spiked Log", "You can get past the spiked log by rolling to briefly shrink your hitbox. As adult, the timing is a bit more precise."); - mTrickOptions[RT_DC_SCARECROW_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, false, "Dodongo\'s Cavern Scarecrow GS with Armos Statue", "You can jump off an Armos Statue to reach the alcove with the Gold Skulltula. It takes quite a long time to pull the statue the entire way. The jump to the alcove can be a bit picky when done as child."); - mTrickOptions[RT_DC_VINES_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, false, "Dodongo\'s Cavern Vines GS from Below with Longshot", "The vines upon which this Skulltula rests are one- sided collision. You can use the Longshot to get it from below, by shooting it through the vines, bypassing the need to lower the staircase."); - mTrickOptions[RT_DC_STAIRCASE] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, false, "Dodongo\'s Cavern Staircase with Bow", "The Bow can be used to knock down the stairs with two well-timed shots."); - mTrickOptions[RT_DC_SLINGSHOT_SKIP] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::EXPERT}, false, "Dodongo\'s Cavern Child Slingshot Skips", "With precise platforming, child can cross the platforms while the flame circles are there. When enabling this trick, it's recommended that you also enable the Adult variant: \"Dodongo's Cavern Spike Trap Room Jump without Hover Boots\"."); - mTrickOptions[RT_DC_SCRUB_ROOM] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, false, "Dodongo\'s Cavern Two Scrub Room with Strength", "With help from a conveniently-positioned block, Adult can quickly carry a bomb flower over to destroy the mud wall blocking the room with two Deku Scrubs."); - mTrickOptions[RT_DC_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, false, "Dodongo\'s Cavern Spike Trap Room Jump without Hover Boots", "The jump is adult Link only. Applies to both Vanilla and MQ."); - mTrickOptions[RT_DC_HAMMER_FLOOR] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, false, "Dodongo\'s Cavern Smash the Boss Lobby Floor", "The bombable floor before King Dodongo can be destroyed with Hammer if hit in the very center. This is only relevant with Shuffle Boss Entrances or if Dodongo's Cavern is MQ and either variant of \"Dodongo's Cavern MQ Light the Eyes with Strength\" is on."); - mTrickOptions[RT_DC_MQ_CHILD_BOMBS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_DODONGOS_CAVERN, {Tricks::Tag::ADVANCED}, false, "Dodongo\'s Cavern MQ Early Bomb Bag Area as Child", "With a precise jump slash from above, you can reach the Bomb Bag area as only child without needing a Slingshot. You will take fall damage."); - mTrickOptions[RT_DC_MQ_CHILD_EYES] = TrickOption::LogicTrick(RCQUEST_MQ, RA_DODONGOS_CAVERN, {Tricks::Tag::EXPERT}, false, "Dodongo\'s Cavern MQ Light the Eyes with Strength as Child", "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the eyes. To perform this trick as child is significantly more difficult than adult. The player is also expected to complete the DC back area without explosives, including getting past the Armos wall to the switch for the boss door."); - mTrickOptions[RT_DC_MQ_ADULT_EYES] = TrickOption::LogicTrick(RCQUEST_MQ, RA_DODONGOS_CAVERN, {Tricks::Tag::ADVANCED}, false, "Dodongo\'s Cavern MQ Light the Eyes with Strength as Adult", "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the eyes."); - mTrickOptions[RT_JABU_ALCOVE_JUMP_DIVE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_JABU_JABUS_BELLY, {Tricks::Tag::NOVICE}, false, "Jabu Underwater Alcove as Adult with Jump Dive", "Standing above the underwater tunnel leading to the scrub, jump down and swim through the tunnel. This allows adult to access the alcove with no Scale or Iron Boots. In vanilla Jabu, this alcove has a business scrub. In MQ Jabu, it has the compass chest and a door switch for the main floor."); - mTrickOptions[RT_JABU_BOSS_HOVER] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, {Tricks::Tag::INTERMEDIATE}, false, "Jabu Near Boss Room with Hover Boots", "A box for the blue switch can be carried over by backwalking with one while the elevator is at its peak. Alternatively, you can skip transporting a box by quickly rolling from the switch and opening the door before it closes. However, the timing for this is very tight."); - mTrickOptions[RT_JABU_NEAR_BOSS_RANGED] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_JABU_JABUS_BELLY, {Tricks::Tag::NOVICE}, false, "Jabu Near Boss Ceiling Switch/GS without Boomerang or Explosives", "Vanilla Jabu: From near the entrance into the room, you can hit the switch that opens the door to the boss room using a precisely-aimed use of the Slingshot, Bow, or Longshot. As well, if you climb to the top of the vines you can stand on the right edge of the platform and shoot around the glass. From this distance, even the Hookshot can reach the switch. This trick is only relevant if \"Shuffle Boss Entrances\" is enabled. MQ Jabu: A Gold Skulltula Token can be collected with the Hookshot or Longshot using the same methods as hitting the switch in vanilla. This MQ trick is not currently relevant in logic."); - mTrickOptions[RT_JABU_NEAR_BOSS_EXPLOSIVES] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, {Tricks::Tag::INTERMEDIATE}, false, "Jabu Near Boss Ceiling Switch with Explosives", "You can hit the switch that opens the door to the boss room using a precisely-aimed Bombchu. Also, using the Hover Boots, adult can throw a Bomb at the switch. This trick is only relevant if \"Shuffle Boss Entrances\" is enabled."); - mTrickOptions[RT_LENS_JABU_MQ] = TrickOption::LogicTrick(RCQUEST_MQ, RA_JABU_JABUS_BELLY, {Tricks::Tag::NOVICE}, false, "Jabu MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Jabu MQ."); - // mTrickOptions[RT_JABU_MQ_RANG_JUMP] = TrickOption::LogicTrick(RCQUEST_MQ, RA_JABU_JABUS_BELLY, {Tricks::Tag::ADVANCED}, false, "Jabu MQ Compass Chest with Boomerang", "Boomerang can reach the cow switch to spawn the chest by targeting the cow, jumping off of the ledge where the chest spawns, and throwing the Boomerang in midair. This is only relevant with Jabu Jabu's Belly dungeon shortcuts enabled."); - mTrickOptions[RT_JABU_MQ_SOT_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_JABU_JABUS_BELLY, {Tricks::Tag::INTERMEDIATE}, false, "Jabu MQ Song of Time Block GS with Boomerang", "Allow the Boomerang to return to you through the Song of Time block to grab the token."); - mTrickOptions[RT_LENS_BOTW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, false, "Bottom of the Well without Lens of Truth", "Removes the requirements for the Lens of Truth in Bottom of the Well."); - mTrickOptions[RT_BOTW_CHILD_DEADHAND] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, false, "Child Dead Hand without Kokiri Sword", "Requires 9 sticks or 5 jump slashes."); - mTrickOptions[RT_BOTW_BASEMENT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, false, "Bottom of the Well Map Chest with Strength & Sticks", "The chest in the basement can be reached with strength by doing a jump slash with a lit stick to access the bomb flowers."); - mTrickOptions[RT_BOTW_MQ_PITS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, false, "Bottom of the Well MQ Jump Over the Pits", "While the pits in Bottom of the Well don't allow you to jump just by running straight at them, you can still get over them by side-hopping or backflipping across. With explosives, this allows you to access the central areas without Zelda's Lullaby. With Zelda's Lullaby, it allows you to access the west inner room without explosives."); - mTrickOptions[RT_BOTW_MQ_DEADHAND_KEY] = TrickOption::LogicTrick(RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, false, "Bottom of the Well MQ Dead Hand Freestanding Key with Boomerang", "Boomerang can fish the item out of the rubble without needing explosives to blow it up."); - mTrickOptions[RT_FOREST_FIRST_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, false, "Forest Temple First Room GS with Difficult-to-Use Weapons", "Allows killing this Skulltula with Sword or Sticks by jump slashing it as you let go from the vines. You can avoid taking fall damage by recoiling onto the tree. Also allows killing it as Child with a Bomb throw. It's much more difficult to use a Bomb as child due to Child Link's shorter height."); - mTrickOptions[RT_FOREST_OUTDOORS_EAST_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, false, "Forest Temple East Courtyard GS with Boomerang", "Precise Boomerang throws can allow child to kill the Skulltula and collect the token."); - mTrickOptions[RT_FOREST_VINES] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, false, "Forest Temple East Courtyard Vines with Hookshot", "The vines in Forest Temple leading to where the well drain switch is in the standard form can be barely reached with just the Hookshot. Applies to MQ also."); - mTrickOptions[RT_FOREST_OUTDOORS_LEDGE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, false, "Forest Temple NE Outdoors Ledge with Hover Boots", "With precise Hover Boots movement you can fall down to this ledge from upper balconies. If done precisely enough, it is not necessary to take fall damage. In MQ, this skips a Longshot requirement. In Vanilla, this can skip a Hookshot requirement in entrance randomizer."); - mTrickOptions[RT_FOREST_DOORFRAME] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Forest Temple East Courtyard Door Frame with Hover Boots", "A precise Hover Boots movement from the upper balconies in this courtyard can be used to get on top of the door frame. Applies to both Vanilla and Master Quest. In Vanilla, from on top the door frame you can summon Pierre, allowing you to access the falling ceiling room early. In Master Quest, this allows you to obtain the GS on the door frame as adult without Hookshot or Song of Time."); - mTrickOptions[RT_FOREST_OUTSIDE_BACKDOOR] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Forest Temple Outside Backdoor with Jump Slash", "A jump slash recoil can be used to reach the ledge in the block puzzle room that leads to the west courtyard. This skips a potential Hover Boots requirement in vanilla, and it can sometimes apply in MQ as well. This trick can be performed as both ages."); - mTrickOptions[RT_FOREST_MQ_WELL_SWIM] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Swim Through Forest Temple MQ Well with Hookshot", "Shoot the vines in the well as low and as far to the right as possible, and then immediately swim under the ceiling to the right. This can only be required if Forest Temple is in its Master Quest form."); - mTrickOptions[RT_FOREST_MQ_BLOCK_PUZZLE] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, false, "Skip Forest Temple MQ Block Puzzle with Bombchu", "Send the Bombchu straight up the center of the wall directly to the left upon entering the room."); - //Child with hovers cannot do this from the lower floor, and most go to the upper floor which needs goron bracelet. Adult can do this with hammer and KSword, But child cannot. - mTrickOptions[RT_FOREST_MQ_JS_HALLWAY_SWITCH] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, false, "Forest Temple MQ Twisted Hallway Switch with Jump Slash", "The switch to twist the hallway can be hit with a jump slash through the glass block. To get in front of the switch, either use the Hover Boots or hit the shortcut switch at the top of the room and jump from the glass blocks that spawn. Sticks can be used as child, but the Kokiri Sword is too short to reach through the glass."); - // mTrickOptions[RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Forest Temple MQ Twisted Hallway Switch with Hookshot", "There's a very small gap between the glass block and the wall. Through that gap you can hookshot the target on the ceiling."); - mTrickOptions[RT_FOREST_MQ_RANG_HALLWAY_SWITCH] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Forest Temple MQ Twisted Hallway Switch with Boomerang", "The Boomerang can return to Link through walls, allowing child to hit the hallway switch. This can be used to allow adult to pass through later, or in conjuction with \"Forest Temple Outside Backdoor with Jump Slash\"."); - mTrickOptions[RT_FIRE_BOSS_DOOR_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, false, "Fire Temple Boss Door without Hover Boots or Pillar", "The Fire Temple Boss Door can be reached as adult with a precise jump. You must be touching the side wall of the room so that Link will grab the ledge from farther away than is normally possible."); + // the following are glitches and are currently disabled + // mTrickOptions[RT_ACUTE_ANGLE_CLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Acute angle clip", "Enables locations requiring jumpslash clips through walls which meet at an acute angle."); + // mTrickOptions[RT_ADVANCED_CLIPS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Advanced clips", "Enables locations requiring clips through walls and objects requiring precise jumps or other tricks."); + // mTrickOptions[RT_BLANK_A] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Blank A", "Enables locations requiring blank A button; NOTE: this requires the 'Quick Putaway' restoration."); + // mTrickOptions[RT_DOOM_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Doom Jump", "Enables locations requiring doom jumps."); + // mTrickOptions[RT_EPG] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "EPG", "Enables locations requiring use of the Entrance Point Glitch."); + // mTrickOptions[RT_EQUIP_SWAP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Equip Swap", "Enables locations requiring use of equip swap; NOTE: this may expect the 'Allow cursor to be over any slot' enhancement to be turned off."); + // mTrickOptions[RT_EQUIP_SWAP_EXPECTS_DINS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Equip Swap Require's Din's Fire", "Enables locations requiring use of equip swap once Din's Fire is found."); + // mTrickOptions[RT_FLAME_STORAGE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Flame Storage", "Enables locations requiring flame storage."); + // mTrickOptions[RT_GROUND_CLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Clip", "Enables locations requiring ground clips."); + // mTrickOptions[RT_GROUND_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Jump", "Enables locations requiring ground jumps."); + // mTrickOptions[RT_HESS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "HESS", "Enables locations requiring a Hyper Extended Super Slide."); + // mTrickOptions[RT_HOOKSHOT_CLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Hookshot Clip", "Enables locations requiring hookshot clips."); + // mTrickOptions[RT_HOOKSHOT_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Hookshot Jump", "Enables locations requiring hookshot jumps."); + // mTrickOptions[RT_ISG] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "ISG", "Enables locations requiring use of the infinite sword glitch."); + + mTrickOptions[RT_VISIBLE_COLLISION] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, "Pass Through Visible One-Way Collision", "Allows climbing through the platform to reach Impa's House Back as adult with no items and going through the Kakariko Village Gate as child when coming from the Mountain Trail side."); + mTrickOptions[RT_GROTTOS_WITHOUT_AGONY] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, "Hidden Grottos without Stone of Agony", "Allows entering hidden grottos without the Stone of Agony."); + mTrickOptions[RT_FEWER_TUNIC_REQUIREMENTS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::INTERMEDIATE}, "Fewer Tunic Requirements", "Allows the following possible without Tunics:\n- Enter Water Temple. The area below the center pillar still requires Zora Tunic. Applies to MQ also.\n- Enter Fire Temple. Volvagia still requires Goron tunic. Applies to MQ also, and includes child access to first floor with dungeon shuffle."); + mTrickOptions[RT_RUSTED_SWITCHES] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, "Hammer Rusted Switches Through Walls", "Applies to:\n- Fire Temple Highest Goron Chest.\n- MQ Fire Temple Lizalfos Maze.\n- MQ Spirit Trial."); + mTrickOptions[RT_FLAMING_CHESTS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::INTERMEDIATE}, "Flaming Chests", "The chests encircled in flames in Gerudo Training Ground and in Spirit Temple can be opened by running into the flames while Link is invincible after taking damage."); + // disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely decoupled from rando + // mTrickOptions[RT_BUNNY_HOOD_JUMPS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, "Bunny Hood Jumps", "Allows reaching locations using Bunny Hood's extended jumps."); + mTrickOptions[RT_DAMAGE_BOOST_SIMPLE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL}, "Simple damage boosts", "Allows damage boosts in order to reach further locations. Can be combined with \"Simple hover boosts\" for reaching far distances."); + mTrickOptions[RT_HOVER_BOOST_SIMPLE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL}, "Simple hover boosts", "Allows equipping of hover boots when link is moving at high speeds to extend distance covered. Can be combined with \"Simple damage boosts\" for greater uses."); + mTrickOptions[RT_BOMBCHU_BEEHIVES] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, "Bombchu Beehives", "Allows exploding beehives with bombchus."); + mTrickOptions[RT_KF_ADULT_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KOKIRI_FOREST, {Tricks::Tag::NOVICE}, "Adult Kokiri Forest GS with Hover Boots", "Can be obtained without Hookshot by using the Hover Boots off of one of the roots."); + mTrickOptions[RT_LW_BRIDGE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::EXPERT}, "Jump onto the Lost Woods Bridge as Adult with Nothing", "With very precise movement it's possible for adult to jump onto the bridge without needing Longshot, Hover Boots, or Bean."); + mTrickOptions[RT_LW_MIDO_BACKFLIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::NOVICE}, "Backflip over Mido as Adult", "With a specific position and angle, you can backflip over Mido."); + mTrickOptions[RT_LW_GS_BEAN] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::INTERMEDIATE}, "Lost Woods Adult GS without Bean", "You can collect the token with a precise Hookshot use, as long as you can kill the Skulltula somehow first. It can be killed using Longshot, Bow, Bombchus or Din's Fire."); + mTrickOptions[RT_HC_STORMS_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_HYRULE_CASTLE, {Tricks::Tag::INTERMEDIATE}, "Hyrule Castle Storms Grotto GS with Just Boomerang", "With precise throws, the Boomerang alone can kill the Skulltula and collect the token, without first needing to blow up the wall."); + mTrickOptions[RT_KAK_MAN_ON_ROOF] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::NOVICE}, "Man on Roof without Hookshot", "Can be reached by side-hopping off the watchtower as either age, or by jumping onto the potion shop's roof from the ledge as adult."); + mTrickOptions[RT_KAK_TOWER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::INTERMEDIATE}, "Kakariko Tower GS with Jump Slash", "Climb the tower as high as you can without touching the Gold Skulltula, then let go and jump slash immediately. By jump-slashing from as low on the ladder as possible to still hit the Skulltula, this trick can be done without taking fall damage."); + mTrickOptions[RT_KAK_ADULT_WINDMILL_POH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::NOVICE}, "Windmill PoH as Adult with Nothing", "Can jump up to the spinning platform from below as adult."); + mTrickOptions[RT_KAK_CHILD_WINDMILL_POH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::EXTREME}, "Windmill PoH as Child with Precise Jump Slash", "Can jump up to the spinning platform from below as child with a precise jumpslash timed with the platforms rotation."); + mTrickOptions[RT_KAK_ROOFTOP_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::ADVANCED}, "Kakariko Rooftop GS with Hover Boots", "Take the Hover Boots from the entrance to Impa's House over to the rooftop of Skulltula House. From there, a precise Hover Boots backwalk with backflip can be used to get onto a hill above the side of the village. And then from there you can Hover onto Impa's rooftop to kill the Skulltula and backflip into the token."); + mTrickOptions[RT_GY_POH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_GRAVEYARD, {Tricks::Tag::INTERMEDIATE}, "Graveyard Freestanding PoH with Boomerang", "Using a precise moving setup you can obtain the Piece of Heart by having the Boomerang interact with it along the return path."); + mTrickOptions[RT_GY_CHILD_DAMPE_RACE_POH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_GRAVEYARD, {Tricks::Tag::NOVICE}, "Second Dampe Race as Child", "It is possible to complete the second dampe race as child in under a minute, but it is a strict time limit."); + mTrickOptions[RT_GY_SHADOW_FIRE_ARROWS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_THE_GRAVEYARD, {Tricks::Tag::EXPERT}, "Shadow Temple Entry with Fire Arrows", "It is possible to light all of the torches to open the Shadow Temple entrance with just Fire Arrows, but you must be very quick, precise, and strategic with how you take your shots."); + mTrickOptions[RT_DMT_SOIL_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, "Death Mountain Trail Soil GS without Destroying Boulder", "Bugs will go into the soft soil even while the boulder is still blocking the entrance. Then, using a precise moving setup you can kill the Gold Skulltula and obtain the token by having the Boomerang interact with it along the return path."); + mTrickOptions[RT_DMT_BOMBABLE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, "Death Mountain Trail Chest with Strength", "Child Link can blow up the wall using a nearby bomb flower. You must backwalk with the flower and then quickly throw it toward the wall."); + mTrickOptions[RT_DMT_HOOKSHOT_LOWER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, "Death Mountain Trail Lower Red Rock GS with Hookshot", "After killing the Skulltula, the token can be fished out of the rock without needing to destroy it, by using the Hookshot in the correct way."); + mTrickOptions[RT_DMT_HOVERS_LOWER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::ADVANCED}, "Death Mountain Trail Lower Red Rock GS with Hover Boots", "After killing the Skulltula, the token can be collected without needing to destroy the rock by backflipping down onto it with the Hover Boots. First use the Hover Boots to stand on a nearby fence, and go for the Skulltula Token from there."); + mTrickOptions[RT_DMT_BEAN_LOWER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::EXPERT}, "Death Mountain Trail Lower Red Rock GS with Magic Bean", "After killing the Skulltula, the token can be collected without needing to destroy the rock by jumping down onto it from the bean plant, midflight, with precise timing and positioning."); + mTrickOptions[RT_DMT_JS_LOWER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, "Death Mountain Trail Lower Red Rock GS with Jump Slash", "After killing the Skulltula, the token can be collected without needing to destroy the rock by jump slashing from a precise angle."); + mTrickOptions[RT_DMT_CLIMB_HOVERS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::ADVANCED}, "Death Mountain Trail Climb with Hover Boots", "It is possible to use the Hover Boots to bypass needing to destroy the boulders blocking the path to the top of Death Mountain."); + mTrickOptions[RT_DMT_UPPER_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::NOVICE}, "Death Mountain Trail Upper Red Rock GS without Hammer", "After killing the Skulltula, the token can be collected by backflipping into the rock at the correct angle."); + // disabled for now, only applies when trade quest is not shuffled so there's a timer (currently not considered in logic) + // mTrickOptions[RT_DMT_BOLERO_BIGGORON] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, "Deliver Eye Drops with Bolero of Fire", "Playing a warp song normally causes a trade item to spoil immediately, however, it is possible use Bolero to reach Biggoron and still deliver the Eye Drops before they spoil. If you do not wear the Goron Tunic, the heat timer inside the crater will override the trade item\'s timer. When you exit to Death Mountain Trail you will have one second to show the Eye Drops before they expire. You can get extra time to show the Eye Drops if you warp immediately upon receiving them. If you don't have many hearts, you may have to reset the heat timer by quickly dipping in and out of Darunia\'s chamber or quickly equipping and unequipping the Goron Tunic. This trick does not apply if \"Randomize Warp Song Destinations\" is enabled, or if the settings are such that trade items do not need to be delivered within a time limit."); + mTrickOptions[RT_GC_POT] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::ADVANCED}, "Goron City Spinning Pot PoH with Bombchu", "A Bombchu can be used to stop the spinning pot, but it can be quite finicky to get it to work."); + mTrickOptions[RT_GC_POT_STRENGTH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::INTERMEDIATE}, "Goron City Spinning Pot PoH with Strength", "Allows for stopping the Goron City Spinning Pot using a bomb flower alone, requiring strength in lieu of inventory explosives."); + mTrickOptions[RT_GC_ROLLING_STRENGTH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::INTERMEDIATE}, "Rolling Goron (Hot Rodder Goron) as Child with Strength", "Use the bombflower on the stairs or near Medigoron. Timing is tight, especially without backwalking."); + mTrickOptions[RT_GC_LEFTMOST] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::ADVANCED}, "Goron City Maze Left Chest with Hover Boots", "A precise backwalk starting from on top of the crate and ending with a precisely-timed backflip can reach this chest without needing either the Hammer or Silver Gauntlets."); + mTrickOptions[RT_GC_GROTTO] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::ADVANCED}, "Goron City Grotto with Hookshot While Taking Damage", "It is possible to reach the Goron City Grotto by quickly using the Hookshot while in the midst of taking damage from the lava floor."); + mTrickOptions[RT_GC_LINK_GORON_DINS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::NOVICE}, "Stop Link the Goron with Din\'s Fire", "The timing is quite awkward."); + mTrickOptions[RT_DMC_HOVER_BEAN_POH] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::NOVICE}, "Crater\'s Bean PoH with Hover Boots", "Hover from the base of the bridge near Goron City and walk up the very steep slope."); + mTrickOptions[RT_DMC_BOLERO_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::EXTREME}, "Death Mountain Crater Jump to Bolero", "As Adult, using a shield to drop a pot while you have the perfect speed and position, the pot can push you that little extra distance you need to jump across the gap in the bridge."); + mTrickOptions[RT_DMC_BOULDER_JS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::NOVICE}, "Death Mountain Crater Upper to Lower with Hammer", "With the Hammer, you can jump slash the rock twice in the same jump in order to destroy it before you fall into the lava."); + mTrickOptions[RT_DMC_BOULDER_SKIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::INTERMEDIATE}, "Death Mountain Crater Upper to Lower Boulder Skip", "As adult, With careful positioning, you can jump to the ledge where the boulder is, then use repeated ledge grabs to shimmy to a climbable ledge. This trick supersedes \"Death Mountain Crater Upper to Lower with Hammer\"."); + mTrickOptions[RT_ZR_LOWER] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::INTERMEDIATE}, "Zora\'s River Lower Freestanding PoH as Adult with Nothing", "Adult can reach this PoH with a precise jump, no Hover Boots required."); + mTrickOptions[RT_ZR_UPPER] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::INTERMEDIATE}, "Zora\'s River Upper Freestanding PoH as Adult with Nothing", "Adult can reach this PoH with a precise jump, no Hover Boots required."); + mTrickOptions[RT_ZR_HOVERS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::NOVICE}, "Zora\'s Domain Entry with Hover Boots", "Can hover behind the waterfall as adult."); + mTrickOptions[RT_ZR_CUCCO] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::NOVICE}, "Zora\'s Domain Entry with Cucco", "You can fly behind the waterfall with a Cucco as child."); + mTrickOptions[RT_ZD_KING_ZORA_SKIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_DOMAIN, {Tricks::Tag::INTERMEDIATE}, "Skip King Zora as Adult with Nothing", "With a precise jump as adult, it is possible to get on the fence next to King Zora from the front to access Zora's Fountain."); + mTrickOptions[RT_ZD_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_DOMAIN, {Tricks::Tag::INTERMEDIATE}, "Zora\'s Domain GS with No Additional Items", "A precise jump slash can kill the Skulltula and recoil back onto the top of the frozen waterfall. To kill it, the logic normally guarantees one of Hookshot, Bow, or Magic."); + mTrickOptions[RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_ZORAS_FOUNTAIN, {Tricks::Tag::NOVICE}, "Zora\'s Fountain Great Fairy Without Explosives", "It's possible to use silver gauntlets to pick up the silver rock and hammer to break the rock below it, allowing you to ledge grab the edge of the hole and get past the breakable wall (hammer can't break the wall itself)."); + mTrickOptions[RT_LH_LAB_WALL_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_LAKE_HYLIA, {Tricks::Tag::NOVICE}, "Lake Hylia Lab Wall GS with Jump Slash", "The jump slash to actually collect the token is somewhat precise."); + mTrickOptions[RT_LH_LAB_DIVING] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_LAKE_HYLIA, {Tricks::Tag::NOVICE}, "Lake Hylia Lab Dive without Gold Scale", "Remove the Iron Boots in the midst of Hookshotting the underwater crate."); + mTrickOptions[RT_LH_WATER_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_LAKE_HYLIA, {Tricks::Tag::INTERMEDIATE}, "Water Temple Entry without Iron Boots using Hookshot", "When entering Water Temple using Gold Scale instead of Iron Boots, the Longshot is usually used to be able to hit the switch and open the gate. But, by standing in a particular spot, the switch can be hit with only the reach of the Hookshot."); + mTrickOptions[RT_GV_CRATE_HOVERS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GERUDO_VALLEY, {Tricks::Tag::INTERMEDIATE}, "Gerudo Valley Crate PoH as Adult with Hover Boots", "From the far side of Gerudo Valley, a precise Hover Boots movement and jump-slash recoil can allow adult to reach the ledge with the crate PoH without needing Longshot. You will take fall damage."); + mTrickOptions[RT_GF_KITCHEN] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GERUDO_FORTRESS, {Tricks::Tag::NOVICE}, "Thieves\' Hideout \"Kitchen\" with No Additional Items", "Allows passing through the kitchen by avoiding being seen by the guards. The logic normally guarantees Bow or Hookshot to stun them from a distance, or Hover Boots to cross the room without needing to deal with the guards."); + mTrickOptions[RT_GF_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GERUDO_FORTRESS, {Tricks::Tag::NOVICE}, "Gerudo\'s Fortress Ledge Jumps", "Adult can jump onto the top roof of the fortress without going through the interior of the hideout."); + mTrickOptions[RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GERUDO_FORTRESS, {Tricks::Tag::NOVICE}, "Gerudo\'s Fortress Warriors with Difficult Weapons", "Warriors can be defeated with slingshot or bombchus."); + // disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely decoupled from rando + // mTrickOptions[RT_HW_BUNNY_CROSSING] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::NOVICE}, "Wasteland Crossing with Bunny Hood", "You can beat the quicksand by using the increased speed of the Bunny Hood. Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash."); + mTrickOptions[RT_HW_CROSSING] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::INTERMEDIATE}, "Wasteland Crossing without Hover Boots or Longshot", "You can beat the quicksand by backwalking across it in a specific way. Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash."); + mTrickOptions[RT_LENS_HW] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::INTERMEDIATE}, "Lensless Wasteland", "By memorizing the path, you can travel through the Wasteland without using the Lens of Truth to see the Poe. The equivalent trick for going in reverse through the Wasteland is \"Reverse Wasteland\"."); + mTrickOptions[RT_HW_REVERSE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::INTERMEDIATE}, "Reverse Wasteland", "By memorizing the path, you can travel through the Wasteland in reverse. Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash. The equivalent trick for going forward through the Wasteland is \"Lensless Wasteland\". To cross the river of sand with no additional items, be sure to also enable \"Wasteland Crossing without Hover Boots or Longshot\". Unless all overworld entrances are randomized, child Link will not be expected to do anything at Gerudo's Fortress."); + mTrickOptions[RT_COLOSSUS_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DESERT_COLOSSUS, {Tricks::Tag::NOVICE}, "Colossus Hill GS with Hookshot", "Somewhat precise. If you kill enough Leevers you can get enough of a break to take some time to aim more carefully."); + mTrickOptions[RT_DEKU_BASEMENT_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, "Deku Tree Basement Vines GS with Jump Slash", "Can be defeated by doing a precise jump slash."); + mTrickOptions[RT_DEKU_B1_SKIP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DEKU_TREE, {Tricks::Tag::INTERMEDIATE}, "Deku Tree Basement without Slingshot", "A precise jump can be used to skip needing to use the Slingshot to go around B1 of the Deku Tree. If used with the \"Closed Forest\" setting, a Slingshot will not be guaranteed to exist somewhere inside the Forest. This trick applies to both Vanilla and Master Quest."); + mTrickOptions[RT_DEKU_B1_BOW_WEBS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, "Deku Tree Basement Web to Gohma with Bow", "All spider web walls in the Deku Tree basement can be burnt as adult with just a bow by shooting through torches. This trick only applies to the circular web leading to Gohma; the two vertical webs are always in logic. Backflip onto the chest near the torch at the bottom of the vine wall. With precise positioning you can shoot through the torch to the right edge of the circular web. This allows completion of adult Deku Tree with no fire source."); + mTrickOptions[RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, "Deku Tree Basement Backflip over Spiked Log", "Allows backflipping over the spiked log in the Deku Tree basement in vanilla. Only relevant if \"Shuffle Swim\" is enabled."); + mTrickOptions[RT_DEKU_MQ_COMPASS_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, "Deku Tree MQ Compass Room GS Boulders with Just Hammer", "Climb to the top of the vines, then let go and jump slash immediately to destroy the boulders using the Hammer, without needing to spawn a Song of Time block."); + mTrickOptions[RT_DEKU_MQ_LOG] = TrickOption::LogicTrick(RCQUEST_MQ, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, "Deku Tree MQ Roll Under the Spiked Log", "You can get past the spiked log by rolling to briefly shrink your hitbox. As adult, the timing is a bit more precise."); + mTrickOptions[RT_DC_SCARECROW_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Scarecrow GS with Armos Statue", "You can jump off an Armos Statue to reach the alcove with the Gold Skulltula. It takes quite a long time to pull the statue the entire way. The jump to the alcove can be a bit picky when done as child."); + mTrickOptions[RT_DC_VINES_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Vines GS from Below with Longshot", "The vines upon which this Skulltula rests are one-sided collision. You can use the Longshot to get it from below, by shooting it through the vines, bypassing the need to lower the staircase."); + mTrickOptions[RT_DC_STAIRCASE] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Staircase with Bow", "The Bow can be used to knock down the stairs with two well-timed shots."); + mTrickOptions[RT_DC_SLINGSHOT_SKIP] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::EXPERT}, "Dodongo\'s Cavern Child Slingshot Skips", "With precise platforming, child can cross the platforms while the flame circles are there. When enabling this trick, it's recommended that you also enable the Adult variant: \"Dodongo's Cavern Spike Trap Room Jump without Hover Boots\"."); + mTrickOptions[RT_DC_SCRUB_ROOM] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Two Scrub Room with Strength", "With help from a conveniently-positioned block, Adult can quickly carry a bomb flower over to destroy the mud wall blocking the room with two Deku Scrubs."); + mTrickOptions[RT_DC_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Spike Trap Room Jump without Hover Boots", "The jump is adult Link only. Applies to both Vanilla and MQ."); + mTrickOptions[RT_DC_HAMMER_FLOOR] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Smash the Boss Lobby Floor", "The bombable floor before King Dodongo can be destroyed with Hammer if hit in the very center. This is only relevant with Shuffle Boss Entrances or if Dodongo's Cavern is MQ and either variant of \"Dodongo's Cavern MQ Light the Eyes with Strength\" is on."); + mTrickOptions[RT_DC_MQ_CHILD_BOMBS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_DODONGOS_CAVERN, {Tricks::Tag::ADVANCED}, "Dodongo\'s Cavern MQ Early Bomb Bag Area as Child", "With a precise jump slash from above, you can reach the Bomb Bag area as only child without needing a Slingshot. You will take fall damage."); + mTrickOptions[RT_DC_MQ_CHILD_EYES] = TrickOption::LogicTrick(RCQUEST_MQ, RA_DODONGOS_CAVERN, {Tricks::Tag::EXPERT}, "Dodongo\'s Cavern MQ Light the Eyes with Strength as Child", "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the eyes. To perform this trick as child is significantly more difficult than adult. The player is also expected to complete the DC back area without explosives, including getting past the Armos wall to the switch for the boss door."); + mTrickOptions[RT_DC_MQ_ADULT_EYES] = TrickOption::LogicTrick(RCQUEST_MQ, RA_DODONGOS_CAVERN, {Tricks::Tag::ADVANCED}, "Dodongo\'s Cavern MQ Light the Eyes with Strength as Adult", "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the eyes."); + mTrickOptions[RT_JABU_ALCOVE_JUMP_DIVE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_JABU_JABUS_BELLY, {Tricks::Tag::NOVICE}, "Jabu Underwater Alcove as Adult with Jump Dive", "Standing above the underwater tunnel leading to the scrub, jump down and swim through the tunnel. This allows adult to access the alcove with no Scale or Iron Boots. In vanilla Jabu, this alcove has a business scrub. In MQ Jabu, it has the compass chest and a door switch for the main floor."); + mTrickOptions[RT_JABU_BOSS_HOVER] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, {Tricks::Tag::INTERMEDIATE}, "Jabu Near Boss Room with Hover Boots", "A box for the blue switch can be carried over by backwalking with one while the elevator is at its peak. Alternatively, you can skip transporting a box by quickly rolling from the switch and opening the door before it closes. However, the timing for this is very tight."); + mTrickOptions[RT_JABU_NEAR_BOSS_RANGED] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_JABU_JABUS_BELLY, {Tricks::Tag::NOVICE}, "Jabu Near Boss Ceiling Switch/GS without Boomerang or Explosives", "Vanilla Jabu: From near the entrance into the room, you can hit the switch that opens the door to the boss room using a precisely-aimed use of the Slingshot, Bow, or Longshot. As well, if you climb to the top of the vines you can stand on the right edge of the platform and shoot around the glass. From this distance, even the Hookshot can reach the switch. This trick is only relevant if \"Shuffle Boss Entrances\" is enabled. MQ Jabu: A Gold Skulltula Token can be collected with the Hookshot or Longshot using the same methods as hitting the switch in vanilla. This MQ trick is not currently relevant in logic."); + mTrickOptions[RT_JABU_NEAR_BOSS_EXPLOSIVES] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, {Tricks::Tag::INTERMEDIATE}, "Jabu Near Boss Ceiling Switch with Explosives", "You can hit the switch that opens the door to the boss room using a precisely-aimed Bombchu. Also, using the Hover Boots, adult can throw a Bomb at the switch. This trick is only relevant if \"Shuffle Boss Entrances\" is enabled."); + mTrickOptions[RT_LENS_JABU_MQ] = TrickOption::LogicTrick(RCQUEST_MQ, RA_JABU_JABUS_BELLY, {Tricks::Tag::NOVICE}, "Jabu MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Jabu MQ."); + mTrickOptions[RT_JABU_MQ_RANG_JUMP] = TrickOption::LogicTrick(RCQUEST_MQ, RA_JABU_JABUS_BELLY, {Tricks::Tag::ADVANCED}, "Jabu MQ Compass Chest with Boomerang", "Boomerang can reach the cow switch to spawn the chest by targeting the cow, jumping off of the ledge where the chest spawns, and throwing the Boomerang in midair."); + mTrickOptions[RT_JABU_MQ_SOT_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_JABU_JABUS_BELLY, {Tricks::Tag::INTERMEDIATE}, "Jabu MQ Song of Time Block GS with Boomerang", "Allow the Boomerang to return to you through the Song of Time block to grab the token."); + mTrickOptions[RT_LENS_BOTW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, "Bottom of the Well without Lens of Truth", "Removes the requirements for the Lens of Truth in Bottom of the Well."); + mTrickOptions[RT_BOTW_CHILD_DEADHAND] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, "Child Dead Hand without Kokiri Sword", "Requires 9 sticks or 5 jump slashes."); + mTrickOptions[RT_BOTW_BASEMENT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, "Bottom of the Well Map Chest with Strength & Sticks", "The chest in the basement can be reached with strength by doing a jump slash with a lit stick to access the bomb flowers."); + mTrickOptions[RT_BOTW_MQ_PITS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, "Bottom of the Well MQ Jump Over the Pits", "While the pits in Bottom of the Well don't allow you to jump just by running straight at them, you can still get over them by side-hopping or backflipping across. With explosives, this allows you to access the central areas without Zelda's Lullaby. With Zelda's Lullaby, it allows you to access the west inner room without explosives."); + mTrickOptions[RT_BOTW_MQ_DEADHAND_KEY] = TrickOption::LogicTrick(RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, "Bottom of the Well MQ Dead Hand Freestanding Key with Boomerang", "Boomerang can fish the item out of the rubble without needing explosives to blow it up."); + mTrickOptions[RT_FOREST_FIRST_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple First Room GS with Difficult-to-Use Weapons", "Allows killing this Skulltula with Sword or Sticks by jump slashing it as you let go from the vines. You can avoid taking fall damage by recoiling onto the tree. Also allows killing it as Child with a Bomb throw. It's much more difficult to use a Bomb as child due to Child Link's shorter height."); + mTrickOptions[RT_FOREST_OUTDOORS_EAST_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple East Courtyard GS with Boomerang", "Precise Boomerang throws can allow child to kill the Skulltula and collect the token."); + mTrickOptions[RT_FOREST_VINES] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple East Courtyard Vines with Hookshot", "The vines in Forest Temple leading to where the well drain switch is in the standard form can be barely reached with just the Hookshot. Applies to MQ also."); + mTrickOptions[RT_FOREST_OUTDOORS_LEDGE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple NE Outdoors Ledge with Hover Boots", "With precise Hover Boots movement you can fall down to this ledge from upper balconies. If done precisely enough, it is not necessary to take fall damage. In MQ, this skips a Longshot requirement. In Vanilla, this can skip a Hookshot requirement in entrance randomizer."); + mTrickOptions[RT_FOREST_DOORFRAME] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, "Forest Temple East Courtyard Door Frame with Hover Boots", "A precise Hover Boots movement from the upper balconies in this courtyard can be used to get on top of the door frame. Applies to both Vanilla and Master Quest. In Vanilla, from on top the door frame you can summon Pierre, allowing you to access the falling ceiling room early. In Master Quest, this allows you to obtain the GS on the door frame as adult without Hookshot or Song of Time."); + mTrickOptions[RT_FOREST_OUTSIDE_BACKDOOR] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, "Forest Temple Outside Backdoor with Jump Slash", "A jump slash recoil can be used to reach the ledge in the block puzzle room that leads to the west courtyard. This skips a potential Hover Boots requirement in vanilla, and it can sometimes apply in MQ as well. This trick can be performed as both ages."); + mTrickOptions[RT_FOREST_OUTDOORS_HEARTS_BOOMERANG] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple Outside Hearts with Boomerang", "A well aimed boomerang from the water's edge can reach the hearts from ground level. If unable to swim, you can back away from the water while the boomerang is returning so the hearts land on the ground."); + mTrickOptions[RT_FOREST_MQ_WELL_SWIM] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, "Swim Through Forest Temple MQ Well with Hookshot", "Shoot the vines in the well as low and as far to the right as possible, and then immediately swim under the ceiling to the right. This can only be required if Forest Temple is in its Master Quest form."); + mTrickOptions[RT_FOREST_MQ_BLOCK_PUZZLE] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Skip Forest Temple MQ Block Puzzle with Bombchu", "Send the Bombchu straight up the center of the wall directly to the left upon entering the room."); + //Child with hovers cannot do this from the lower floor, and most go to the upper floor which needs goron bracelet. Adult can do this with hammer and KSword, But child cannot. + mTrickOptions[RT_FOREST_MQ_JS_HALLWAY_SWITCH] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple MQ Twisted Hallway Switch with Jump Slash", "The switch to twist the hallway can be hit with a jump slash through the glass block. To get in front of the switch, either use the Hover Boots or hit the shortcut switch at the top of the room and jump from the glass blocks that spawn. Sticks can be used as child, but the Kokiri Sword is too short to reach through the glass."); + mTrickOptions[RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Forest Temple MQ Twisted Hallway Switch with Hookshot", "There's a very small gap between the glass block and the wall. Through that gap you can hookshot the target on the ceiling."); + mTrickOptions[RT_FOREST_MQ_RANG_HALLWAY_SWITCH] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Forest Temple MQ Twisted Hallway Switch with Boomerang", "The Boomerang can return to Link through walls, allowing child to hit the hallway switch. This can be used to allow adult to pass through later, or in conjuction with \"Forest Temple Outside Backdoor with Jump Slash\"."); + mTrickOptions[RT_FIRE_BOSS_DOOR_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, "Fire Temple Boss Door without Hover Boots or Pillar", "The Fire Temple Boss Door can be reached as adult with a precise jump. You must be touching the side wall of the room so that Link will grab the ledge from farther away than is normally possible."); //Is also used in MQ logic, but has no practical effect there as of now - mTrickOptions[RT_FIRE_SOT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple Song of Time Room GS without Song of Time", "A precise jump can be used to reach this room."); - mTrickOptions[RT_FIRE_STRENGTH] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple Climb without Strength", "A precise jump can be used to skip pushing the block."); - mTrickOptions[RT_FIRE_SCARECROW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::EXPERT}, false, "Fire Temple East Tower without Scarecrow\'s Song", "Also known as \"Pixelshot\". The Longshot can reach the target on the elevator itself, allowing you to skip needing to spawn the scarecrow."); - mTrickOptions[RT_FIRE_FLAME_MAZE] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple Flame Wall Maze Skip", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do it without taking damage is more precise. Allows you to progress without needing either a Small Key or Hover Boots."); - mTrickOptions[RT_FIRE_MQ_NEAR_BOSS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, false, "Fire Temple MQ Chest Near Boss without Breaking Crate", "The hitbox for the torch extends a bit outside of the crate. Shoot a flaming arrow at the side of the crate to light the torch without needing to get over there and break the crate."); - mTrickOptions[RT_FIRE_MQ_BLOCKED_CHEST] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple MQ Big Lava Room Blocked Door without Hookshot", "There is a gap between the hitboxes of the flame wall in the big lava room. If you know where this gap is located, you can jump through it and skip needing to use the Hookshot. To do this without taking damage is more precise."); - mTrickOptions[RT_FIRE_MQ_BK_CHEST] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple MQ Boss Key Chest without Bow", "It is possible to light both of the timed torches to unbar the door to the boss key chest's room with just Din's Fire if you move very quickly between the two torches. It is also possible to unbar the door with just Din's by abusing an oversight in the way the game counts how many torches have been lit."); - mTrickOptions[RT_FIRE_MQ_CLIMB] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, false, "Fire Temple MQ Climb without Fire Source", "You can use the Hover Boots to hover around to the climbable wall, skipping the need to use a fire source and spawn a Hookshot target."); - mTrickOptions[RT_FIRE_MQ_MAZE_SIDE_ROOM] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, false, "Fire Temple MQ Lizalfos Maze Side Room without Box", "You can walk from the blue switch to the door and quickly open the door before the bars reclose. This skips needing to reach the upper sections of the maze to get a box to place on the switch."); - mTrickOptions[RT_FIRE_MQ_MAZE_HOVERS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, false, "Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots", "Use the Hover Boots off of a crate to climb to the upper maze without needing to spawn and use the Hookshot targets."); - mTrickOptions[RT_FIRE_MQ_MAZE_JUMP] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple MQ Lower to Upper Lizalfos Maze with Precise Jump", "A precise jump off of a crate can be used to climb to the upper maze without needing to spawn and use the Hookshot targets. This trick supersedes both \"Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots\" and \"Fire Temple MQ Lizalfos Maze Side Room without Box\"."); - mTrickOptions[RT_FIRE_MQ_ABOVE_MAZE_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple MQ Above Flame Wall Maze GS from Below with Longshot", "The floor of the room that contains this Skulltula is only solid from above. From the maze below, the Longshot can be shot through the ceiling to obtain the token with two fewer small keys than normal."); - mTrickOptions[RT_FIRE_MQ_FLAME_MAZE] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Fire Temple MQ Flame Wall Maze Skip", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do it without taking damage is more precise. Allows you to reach the side room GS without needing Song of Time or Hover Boots. If either of \"Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots\" or \"with Precise Jump\" are enabled, this also allows you to progress deeper into the dungeon without Hookshot."); - mTrickOptions[RT_WATER_LONGSHOT_TORCH] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Torch Longshot", "Stand on the eastern side of the central pillar and longshot the torches on the bottom level. Swim through the corridor and float up to the top level. This allows access to this area and lower water levels without Iron Boots. The majority of the tricks that allow you to skip Iron Boots in the Water Temple are not going to be relevant unless this trick is first enabled."); - mTrickOptions[RT_WATER_CRACKED_WALL_HOVERS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Cracked Wall with Hover Boots", "With a midair side-hop while wearing the Hover Boots, you can reach the cracked wall without needing to raise the water up to the middle level."); - mTrickOptions[RT_WATER_CRACKED_WALL] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple Cracked Wall with No Additional Items", "A precise jump slash (among other methods) will get you to the cracked wall without needing the Hover Boots or to raise the water to the middle level. This trick supersedes \"Water Temple Cracked Wall with Hover Boots\"."); - mTrickOptions[RT_WATER_BK_REGION] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple Boss Key Region with Hover Boots", "With precise Hover Boots movement it is possible to reach the boss key chest's region without needing the Longshot. It is not necessary to take damage from the spikes. The Gold Skulltula Token in the following room can also be obtained with just the Hover Boots."); - mTrickOptions[RT_WATER_NORTH_BASEMENT_LEDGE_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple North Basement Ledge with Precise Jump", "In the northern basement there's a ledge from where, in vanilla Water Temple, boulders roll out into the room. Normally to jump directly to this ledge logically requires the Hover Boots, but with precise jump, it can be done without them. This trick applies to both Vanilla and Master Quest."); - mTrickOptions[RT_WATER_BK_JUMP_DIVE] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Boss Key Jump Dive", "Stand on the very edge of the raised corridor leading from the push block room to the rolling boulder corridor. Face the gold skulltula on the waterfall and jump over the boulder corridor floor into the pool of water, swimming right once underwater. This allows access to the boss key room without Iron boots."); - mTrickOptions[RT_WATER_FW_CENTRAL_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Central Pillar GS with Farore\'s Wind", "If you set Farore's Wind inside the central pillar and then return to that warp point after raising the water to the highest level, you can obtain this Skulltula Token with Hookshot or Boomerang."); - mTrickOptions[RT_WATER_IRONS_CENTRAL_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Central Pillar GS with Iron Boots", "After opening the middle water level door into the central pillar, the door will stay unbarred so long as you do not leave the room -- even if you were to raise the water up to the highest level. With the Iron Boots to go through the door after the water has been raised, you can obtain the Skulltula Token with the Hookshot."); - mTrickOptions[RT_WATER_CENTRAL_BOW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Water Temple Central Bow Target without Longshot or Hover Boots", "A very precise Bow shot can hit the eye switch from the floor above. Then, you can jump down into the hallway and make through it before the gate closes. It can also be done as child, using the Slingshot instead of the Bow."); - mTrickOptions[RT_WATER_HOOKSHOT_FALLING_PLATFORM_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Falling Platform Room GS with Hookshot", "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Hookshot."); - mTrickOptions[RT_WATER_RANG_FALLING_PLATFORM_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple Falling Platform Room GS with Boomerang", "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Boomerang."); - mTrickOptions[RT_WATER_RIVER_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple River GS without Iron Boots", "Standing on the exposed ground toward the end of the river, a precise Longshot use can obtain the token. The Longshot cannot normally reach far enough to kill the Skulltula, however. You'll first have to find some other way of killing it."); - mTrickOptions[RT_WATER_DRAGON_JUMP_DIVE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Dragon Statue Jump Dive", "If you come into the dragon statue room from the serpent river, you can jump down from above and get into the tunnel without needing either Iron Boots or a Scale. This trick applies to both Vanilla and Master Quest. In Vanilla, you must shoot the switch from above with the Bow, and then quickly get through the tunnel before the gate closes."); - mTrickOptions[RT_WATER_ADULT_DRAGON] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Dragon Statue Switch from Above the Water as Adult", "Normally you need both Hookshot and Iron Boots to hit the switch and swim through the tunnel to get to the chest. But by hitting the switch from dry land, using one of Bombchus, Hookshot, or Bow, it is possible to skip one or both of those requirements. After the gate has been opened, besides just using the Iron Boots, a well-timed dive with at least the Silver Scale could be used to swim through the tunnel. If coming from the serpent river, a jump dive can also be used to get into the tunnel."); - mTrickOptions[RT_WATER_CHILD_DRAGON] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Water Temple Dragon Statue Switch from Above the Water as Child", "It is possible for child to hit the switch from dry land using one of Bombchus, Slingshot or Boomerang. Then, to get to the chest, child can dive through the tunnel using at least the Silver Scale. The timing and positioning of this dive needs to be perfect to actually make it under the gate, and it all needs to be done very quickly to be able to get through before the gate closes. Be sure to enable \"Water Temple Dragon Statue Switch from Above the Water as Adult\" for adult's variant of this trick."); - mTrickOptions[RT_WATER_MQ_CENTRAL_PILLAR] = TrickOption::LogicTrick(RCQUEST_MQ, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple MQ Central Pillar with Fire Arrows", "Slanted torches have misleading hitboxes. Whenever you see a slanted torch jutting out of the wall, you can expect most or all of its hitbox is actually on the other side that wall. This can make slanted torches very finicky to light when using arrows. The torches in the central pillar of MQ Water Temple are a particularly egregious example. Logic normally expects Din's Fire and Song of Time."); - mTrickOptions[RT_WATER_MQ_LOCKED_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple MQ North Basement GS without Small Key", "There is an invisible Hookshot target that can be used to get over the gate that blocks you from going to this Skulltula early, skipping a small key as well as needing Hovers or Scarecrow to reach the locked door."); - mTrickOptions[RT_LENS_SHADOW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, false, "Shadow Temple Stationary Objects without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple for most areas in the dungeon except for crossing the moving platform in the huge pit room and for fighting Bongo Bongo."); - mTrickOptions[RT_LENS_SHADOW_PLATFORM] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, false, "Shadow Temple Invisible Moving Platform without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple to cross the invisible moving platform in the huge pit room in either direction."); - mTrickOptions[RT_LENS_BONGO] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, false, "Shadow Temple Bongo Bongo without Lens of Truth", "Bongo Bongo can be defeated without the use of Lens of Truth, as the hands give a pretty good idea of where the eye is."); - mTrickOptions[RT_SHADOW_UMBRELLA] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::EXPERT}, false, "Shadow Temple Stone Umbrella Skip", "A very precise Hover Boots movement from off of the lower chest can get you on top of the crushing spikes without needing to pull the block. Applies to both Vanilla and Master Quest."); - mTrickOptions[RT_SHADOW_UMBRELLA_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::EXPERT}, false, "Shadow Temple Falling Spikes GS with Hover Boots", "After killing the Skulltula, a very precise Hover Boots movement from off of the lower chest can get you on top of the crushing spikes without needing to pull the block. From there, another very precise Hover Boots movement can be used to obtain the token without needing the Hookshot. Applies to both Vanilla and Master Quest. For obtaining the chests in this room with just Hover Boots, be sure to enable \"Shadow Temple Stone Umbrella Skip\"."); - mTrickOptions[RT_SHADOW_FREESTANDING_KEY] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, false, "Shadow Temple Freestanding Key with Bombchu", "Release the Bombchu with good timing so that it explodes near the bottom of the pot."); - mTrickOptions[RT_SHADOW_STATUE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Shadow Temple River Statue with Bombchu", "By sending a Bombchu around the edge of the gorge, you can knock down the statue without needing a Bow. Applies in both vanilla and MQ Shadow."); - mTrickOptions[RT_SHADOW_BONGO] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Shadow Temple Bongo Bongo without projectiles", "Using precise sword slashes, Bongo Bongo can be defeated without using projectiles. This is only relevant in conjunction with Shadow Temple dungeon shortcuts or shuffled boss entrances."); - mTrickOptions[RT_LENS_SHADOW_MQ] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, false, "Shadow Temple MQ Stationary Objects without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple MQ for most areas in the dungeon. See \"Shadow Temple MQ Invisible Moving Platform without Lens of Truth\", \"Shadow Temple MQ Invisible Blades Silver Rupees without Lens of Truth\", \"Shadow Temple MQ 2nd Dead Hand without Lens of Truth\", and \"Shadow Temple Bongo Bongo without Lens of Truth\" for exceptions."); - mTrickOptions[RT_LENS_SHADOW_MQ_INVISIBLE_BLADES] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, false, "Shadow Temple MQ Invisible Blades Silver Rupees without Lens of Truth", "Removes the requirement for the Lens of Truth or Nayru's Love in Shadow Temple MQ for the Invisible Blades room silver rupee collection."); - mTrickOptions[RT_LENS_SHADOW_MQ_PLATFORM] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, false, "Shadow Temple MQ Invisible Moving Platform without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple MQ to cross the invisible moving platform in the huge pit room in either direction."); - mTrickOptions[RT_LENS_SHADOW_MQ_DEADHAND] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, false, "Shadow Temple MQ 2nd Dead Hand without Lens of Truth", "Dead Hand spawns in a random spot within the room. Having Lens removes the hassle of having to comb the room looking for his spawn location."); - mTrickOptions[RT_SHADOW_MQ_GAP] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Shadow Temple MQ Truth Spinner Gap with Longshot", "You can Longshot a torch and jump-slash recoil onto the tongue. It works best if you Longshot the right torch from the left side of the room."); - mTrickOptions[RT_SHADOW_MQ_INVISIBLE_BLADES] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Shadow Temple MQ Invisible Blades without Song of Time", "The Like Like can be used to boost you into the silver rupee or recovery hearts that normally require Song of Time. This cannot be performed on OHKO since the Like Like does not boost you high enough if you die."); - mTrickOptions[RT_SHADOW_MQ_HUGE_PIT] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Shadow Temple MQ Lower Huge Pit without Fire Source", "Normally a frozen eye switch spawns some platforms that you can use to climb down, but there's actually a small piece of ground that you can stand on that you can just jump down to."); - // mTrickOptions[RT_SHADOW_MQ_WINDY_WALKWAY] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Shadow Temple MQ Windy Walkway Reverse without Hover Boots", "With shadow dungeon shortcuts enabled, it is possible to jump from the alcove in the windy hallway to the middle platform. There are two methods: wait out the fan opposite the door and hold forward, or jump to the right to be pushed by the fan there towards the platform ledge. Note that jumps of this distance are inconsistent, but still possible."); - mTrickOptions[RT_LENS_SPIRIT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, false, "Spirit Temple without Lens of Truth", "Removes the requirements for the Lens of Truth in Spirit Temple."); - mTrickOptions[RT_SPIRIT_CHILD_CHU] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, false, "Spirit Temple Child Side Bridge with Bombchu", "A carefully-timed Bombchu can hit the switch."); - mTrickOptions[RT_SPIRIT_LOBBY_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, false, "Spirit Temple Main Room GS with Boomerang", "Standing on the highest part of the arm of the statue, a precise Boomerang throw can kill and obtain this Gold Skulltula. You must throw the Boomerang slightly off to the side so that it curves into the Skulltula, as aiming directly at it will clank off of the wall in front."); - mTrickOptions[RT_SPIRIT_LOWER_ADULT_SWITCH] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Spirit Temple Lower Adult Switch with Bombs", "A bomb can be used to hit the switch on the ceiling, but it must be thrown from a particular distance away and with precise timing."); - mTrickOptions[RT_SPIRIT_LOBBY_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Spirit Temple Main Room Jump from Hands to Upper Ledges", "A precise jump to obtain the following as adult without needing one of Hover Boots, or Hookshot (in vanilla) or Song of Time (in MQ): - Spirit Temple Statue Room Northeast Chest - Spirit Temple GS Lobby - Spirit Temple MQ Central Chamber Top Left Pot (Left) - Spirit Temple MQ Central Chamber Top Left Pot (Right)"); - // mTrickOptions[RT_SPIRIT_PLATFORM_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Spirit Temple Main Room Hookshot to Boss Platform", "Precise hookshot aiming at the platform chains can be used to reach the boss platform from the middle landings. Using a jump slash immediately after reaching a chain makes aiming more lenient. Relevant only when Spirit Temple boss shortcuts are on."); - mTrickOptions[RT_SPIRIT_MAP_CHEST] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, false, "Spirit Temple Map Chest with Bow", "To get a line of sight from the upper torch to the map chest torches, you must pull an Armos statue all the way up the stairs."); - mTrickOptions[RT_SPIRIT_SUN_CHEST] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Spirit Temple Sun Block Room Chest with Bow", "Using the blocks in the room as platforms you can get lines of sight to all three torches. The timer on the torches is quite short so you must move quickly in order to light all three."); - mTrickOptions[RT_SPIRIT_WALL] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Spirit Temple Shifting Wall with No Additional Items", "Logic normally guarantees a way of dealing with both the Beamos and the Walltula before climbing the wall."); - mTrickOptions[RT_LENS_SPIRIT_MQ] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, false, "Spirit Temple MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Spirit Temple MQ."); - mTrickOptions[RT_SPIRIT_MQ_SUN_BLOCK_SOT] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Spirit Temple MQ Sun Block Room as Child without Song of Time", "While adult can easily jump directly to the switch that unbars the door to the sun block room, child Link cannot make the jump without spawning a Song of Time block to jump from. You can skip this by throwing the crate down onto the switch from above, which does unbar the door, however the crate immediately breaks, so you must move quickly to get through the door before it closes back up."); - mTrickOptions[RT_SPIRIT_MQ_SUN_BLOCK_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Spirit Temple MQ Sun Block Room GS with Boomerang", "Throw the Boomerang in such a way that it curves through the side of the glass block to hit the Gold Skulltula."); - mTrickOptions[RT_SPIRIT_MQ_LOWER_ADULT] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Spirit Temple MQ Lower Adult without Fire Arrows", "By standing in a precise position it is possible to light two of the torches with a single use of Din\'s Fire. This saves enough time to be able to light all three torches with only Din\'s."); - mTrickOptions[RT_SPIRIT_MQ_FROZEN_EYE] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, false, "Spirit Temple MQ Frozen Eye Switch without Fire", "You can melt the ice by shooting an arrow through a torch. The only way to find a line of sight for this shot is to first spawn a Song of Time block, and then stand on the very edge of it."); - mTrickOptions[RT_ICE_BLOCK_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Ice Cavern Block Room GS with Hover Boots", "The Hover Boots can be used to get in front of the Skulltula to kill it with a jump slash. Then, the Hover Boots can again be used to obtain the Token, all without Hookshot or Boomerang."); - mTrickOptions[RT_ICE_MQ_RED_ICE_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Ice Cavern MQ Red Ice GS without Song of Time", "If you side-hop into the perfect position, you can briefly stand on the platform with the red ice just long enough to dump some blue fire."); - mTrickOptions[RT_ICE_MQ_SCARECROW] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Ice Cavern MQ Scarecrow GS with No Additional Items", "As adult a precise jump can be used to reach this alcove."); - mTrickOptions[RT_LENS_GTG] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, false, "Gerudo Training Ground without Lens of Truth", "Removes the requirements for the Lens of Truth in Gerudo Training Ground."); - mTrickOptions[RT_GTG_WITHOUT_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::INTERMEDIATE}, false, "Gerudo Training Ground Left Side Silver Rupees without Hookshot", "After collecting the rest of the silver rupees in the room, you can reach the final silver rupee on the ceiling by being pulled up into it after getting grabbed by the Wallmaster. Then, you must also reach the exit of the room without the use of the Hookshot. If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do so without taking damage is more precise."); - mTrickOptions[RT_GTG_FAKE_WALL] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, false, "Reach Gerudo Training Ground Fake Wall Ledge with Hover Boots", "A precise Hover Boots use from the top of the chest can allow you to grab the ledge without needing the usual requirements. In Master Quest, this always skips a Song of Time requirement. In Vanilla, this skips a Hookshot requirement, but is only relevant if \"Gerudo Training Ground Left Side Silver Rupees without Hookshot\" is enabled."); - mTrickOptions[RT_LENS_GTG_MQ] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, false, "Gerudo Training Ground MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Gerudo Training Ground MQ."); - mTrickOptions[RT_GTG_MQ_WITH_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, false, "Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot", "The highest silver rupee can be obtained by hookshotting the target and then immediately jump slashing toward the rupee."); - mTrickOptions[RT_GTG_MQ_WIHTOUT_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::INTERMEDIATE}, false, "Gerudo Training Ground MQ Left Side Silver Rupees without Hookshot", "After collecting the rest of the silver rupees in the room, you can reach the final silver rupee on the ceiling by being pulled up into it after getting grabbed by the Wallmaster. The Wallmaster will not track you to directly underneath the rupee. You should take the last step to be under the rupee after the Wallmaster has begun its attempt to grab you. Also included with this trick is that fact that the switch that unbars the door to the final chest of GTG can be hit without a projectile, using a precise jump slash. This trick supersedes \"Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot\"."); - mTrickOptions[RT_LENS_GANON] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, false, "Ganon\'s Castle without Lens of Truth", "Removes the requirements for the Lens of Truth in Ganon's Castle."); - mTrickOptions[RT_GANON_SPIRIT_TRIAL_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, false, "Spirit Trial without Hookshot", "The highest rupee can be obtained as either age by performing a precise jump and a well-timed jumpslash off of an Armos."); - mTrickOptions[RT_LENS_GANON_MQ] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, false, "Ganon\'s Castle MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Ganon's Castle MQ."); - mTrickOptions[RT_GANON_MQ_FIRE_TRIAL] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::ADVANCED}, false, "Fire Trial MQ with Hookshot", "It's possible to hook the target at the end of fire trial with just Hookshot, but it requires precise aim and perfect positioning. The main difficulty comes from getting on the very corner of the obelisk without falling into the lava."); - mTrickOptions[RT_GANON_MQ_SHADOW_TRIAL] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, false, "Shadow Trial MQ Torch with Bow", "You can light the torch in this room without a fire source by shooting an arrow through the lit torch at the beginning of the room. Because the room is so dark and the unlit torch is so far away, it can be difficult to aim the shot correctly."); - mTrickOptions[RT_GANON_MQ_LIGHT_TRIAL] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::INTERMEDIATE}, false, "Light Trial MQ without Hookshot", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. In this case to do it without taking damage is especially precise."); + mTrickOptions[RT_FIRE_SOT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple Song of Time Room GS without Song of Time", "A precise jump can be used to reach this room."); + mTrickOptions[RT_FIRE_STRENGTH] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple Climb without Strength", "A precise jump can be used to skip pushing the block."); + mTrickOptions[RT_FIRE_SCARECROW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::EXPERT}, "Fire Temple East Tower without Scarecrow\'s Song", "Also known as \"Pixelshot\". The Longshot can reach the target on the elevator itself, allowing you to skip needing to spawn the scarecrow."); + mTrickOptions[RT_FIRE_FLAME_MAZE] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple Flame Wall Maze Skip", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do it without taking damage is more precise. Allows you to progress without needing either a Small Key or Hover Boots."); + mTrickOptions[RT_FIRE_MQ_NEAR_BOSS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, "Fire Temple MQ Chest Near Boss without Breaking Crate", "The hitbox for the torch extends a bit outside of the crate. Shoot a flaming arrow at the side of the crate to light the torch without needing to get over there and break the crate."); + mTrickOptions[RT_FIRE_MQ_BLOCKED_CHEST] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple MQ Big Lava Room Blocked Door without Hookshot", "There is a gap between the hitboxes of the flame wall in the big lava room. If you know where this gap is located, you can jump through it and skip needing to use the Hookshot. To do this without taking damage is more precise."); + mTrickOptions[RT_FIRE_MQ_BK_CHEST] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple MQ Boss Key Chest without Bow", "It is possible to light both of the timed torches to unbar the door to the boss key chest's room with just Din's Fire if you move very quickly between the two torches. It is also possible to unbar the door with just Din's by abusing an oversight in the way the game counts how many torches have been lit."); + mTrickOptions[RT_FIRE_MQ_CLIMB] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, "Fire Temple MQ Climb without Fire Source", "You can use the Hover Boots to hover around to the climbable wall, skipping the need to use a fire source and spawn a Hookshot target."); + mTrickOptions[RT_FIRE_MQ_MAZE_SIDE_ROOM] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, "Fire Temple MQ Lizalfos Maze Side Room without Box", "You can walk from the blue switch to the door and quickly open the door before the bars reclose. This skips needing to reach the upper sections of the maze to get a box to place on the switch."); + mTrickOptions[RT_FIRE_MQ_MAZE_HOVERS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, "Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots", "Use the Hover Boots off of a crate to climb to the upper maze without needing to spawn and use the Hookshot targets."); + mTrickOptions[RT_FIRE_MQ_MAZE_JUMP] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple MQ Lower to Upper Lizalfos Maze with Precise Jump", "A precise jump off of a crate can be used to climb to the upper maze without needing to spawn and use the Hookshot targets. This trick supersedes both \"Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots\" and \"Fire Temple MQ Lizalfos Maze Side Room without Box\"."); + mTrickOptions[RT_FIRE_MQ_ABOVE_MAZE_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple MQ Above Flame Wall Maze GS from Below with Longshot", "The floor of the room that contains this Skulltula is only solid from above. From the maze below, the Longshot can be shot through the ceiling to obtain the token with two fewer small keys than normal."); + mTrickOptions[RT_FIRE_MQ_FLAME_MAZE] = TrickOption::LogicTrick(RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple MQ Flame Wall Maze Skip", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do it without taking damage is more precise. Allows you to reach the side room GS without needing Song of Time or Hover Boots. If either of \"Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots\" or \"with Precise Jump\" are enabled, this also allows you to progress deeper into the dungeon without Hookshot."); + mTrickOptions[RT_WATER_LONGSHOT_TORCH] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Torch Longshot", "Stand on the eastern side of the central pillar and longshot the torches on the bottom level. Swim through the corridor and float up to the top level. This allows access to this area and lower water levels without Iron Boots. The majority of the tricks that allow you to skip Iron Boots in the Water Temple are not going to be relevant unless this trick is first enabled."); + mTrickOptions[RT_WATER_CRACKED_WALL_HOVERS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Cracked Wall with Hover Boots", "With a midair side-hop while wearing the Hover Boots, you can reach the cracked wall without needing to raise the water up to the middle level."); + mTrickOptions[RT_WATER_CRACKED_WALL] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Water Temple Cracked Wall with No Additional Items", "A precise jump slash (among other methods) will get you to the cracked wall without needing the Hover Boots or to raise the water to the middle level. This trick supersedes \"Water Temple Cracked Wall with Hover Boots\"."); + mTrickOptions[RT_WATER_BK_REGION] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Water Temple Boss Key Region with Hover Boots", "With precise Hover Boots movement it is possible to reach the boss key chest's region without needing the Longshot. It is not necessary to take damage from the spikes. The Gold Skulltula Token in the following room can also be obtained with just the Hover Boots."); + mTrickOptions[RT_WATER_NORTH_BASEMENT_LEDGE_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Water Temple North Basement Ledge with Precise Jump", "In the northern basement there's a ledge from where, in vanilla Water Temple, boulders roll out into the room. Normally to jump directly to this ledge logically requires the Hover Boots, but with precise jump, it can be done without them. This trick applies to both Vanilla and Master Quest."); + mTrickOptions[RT_WATER_BK_JUMP_DIVE] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Boss Key Jump Dive", "Stand on the very edge of the raised corridor leading from the push block room to the rolling boulder corridor. Face the Gold Skulltula on the waterfall and jump over the boulder corridor floor into the pool of water, swimming right once underwater. This allows access to the boss key room without Iron boots."); + //Also used in MQ logic, but won't be relevent unless a way to enter tower without irons exists (likely a clip + swim) + mTrickOptions[RT_WATER_FW_CENTRAL_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Central Pillar GS with Farore\'s Wind", "If you set Farore's Wind inside the central pillar and then return to that warp point after raising the water to the highest level, you can obtain this Skulltula Token with Hookshot or Boomerang."); + mTrickOptions[RT_WATER_IRONS_CENTRAL_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Central Pillar GS with Iron Boots", "After opening the middle water level door into the central pillar, the door will stay unbarred so long as you do not leave the room -- even if you were to raise the water up to the highest level. With the Iron Boots to go through the door after the water has been raised, you can obtain the Skulltula Token with the Hookshot."); + mTrickOptions[RT_WATER_CENTRAL_BOW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::ADVANCED}, "Water Temple Central Bow Target without Longshot or Hover Boots", "A very precise Bow shot can hit the eye switch from the floor above. Then, you can jump down into the hallway and make through it before the gate closes. It can also be done as child, using the Slingshot instead of the Bow."); + mTrickOptions[RT_WATER_HOOKSHOT_FALLING_PLATFORM_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Falling Platform Room GS with Hookshot", "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Hookshot."); + mTrickOptions[RT_WATER_RANG_FALLING_PLATFORM_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Water Temple Falling Platform Room GS with Boomerang", "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Boomerang."); + mTrickOptions[RT_WATER_RIVER_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Water Temple River GS without Iron Boots", "Standing on the exposed ground toward the end of the river, a precise Longshot use can obtain the token. The Longshot cannot normally reach far enough to kill the Skulltula, however. You'll first have to find some other way of killing it."); + mTrickOptions[RT_WATER_DRAGON_JUMP_DIVE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Dragon Statue Jump Dive", "If you come into the dragon statue room from the serpent river, you can jump down from above and get into the tunnel without needing either Iron Boots or a Scale. This trick applies to both Vanilla and Master Quest. In Vanilla, you must shoot the switch from above with the Bow, and then quickly get through the tunnel before the gate closes."); + mTrickOptions[RT_WATER_ADULT_DRAGON] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Dragon Statue Switch from Above the Water as Adult", "Normally you need both Hookshot and Iron Boots to hit the switch and swim through the tunnel to get to the chest. But by hitting the switch from dry land, using one of Bombchus, Hookshot, or Bow, it is possible to skip one or both of those requirements. After the gate has been opened, besides just using the Iron Boots, a well-timed dive with at least the Silver Scale could be used to swim through the tunnel. If coming from the serpent river, a jump dive can also be used to get into the tunnel."); + mTrickOptions[RT_WATER_CHILD_DRAGON] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::ADVANCED}, "Water Temple Dragon Statue Switch from Above the Water as Child", "It is possible for child to hit the switch from dry land using one of Bombchus, Slingshot or Boomerang. Then, to get to the chest, child can dive through the tunnel using at least the Silver Scale. The timing and positioning of this dive needs to be perfect to actually make it under the gate, and it all needs to be done very quickly to be able to get through before the gate closes. Be sure to enable \"Water Temple Dragon Statue Switch from Above the Water as Adult\" for adult's variant of this trick."); + mTrickOptions[RT_WATER_MQ_CENTRAL_PILLAR] = TrickOption::LogicTrick(RCQUEST_MQ, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple MQ Central Pillar with Fire Arrows", "Slanted torches have misleading hitboxes. Whenever you see a slanted torch jutting out of the wall, you can expect most or all of its hitbox is actually on the other side that wall. This can make slanted torches very finicky to light when using arrows. The torches in the central pillar of MQ Water Temple are a particularly egregious example. Logic normally expects Din's Fire and Song of Time."); + mTrickOptions[RT_WATER_MQ_LOCKED_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple MQ North Basement GS without Small Key", "There is an invisible Hookshot target that can be used to get over the gate that blocks you from going to this Skulltula early, skipping a small key as well as needing Hovers or Scarecrow to reach the locked door."); + mTrickOptions[RT_LENS_SHADOW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple Stationary Objects without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple for most areas in the dungeon except for crossing the moving platform in the huge pit room and for fighting Bongo Bongo."); + mTrickOptions[RT_LENS_SHADOW_PLATFORM] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple Invisible Moving Platform without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple to cross the invisible moving platform in the huge pit room in either direction."); + mTrickOptions[RT_LENS_BONGO] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple Bongo Bongo without Lens of Truth", "Bongo Bongo can be defeated without the use of Lens of Truth, as the hands give a pretty good idea of where the eye is."); + mTrickOptions[RT_SHADOW_UMBRELLA] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::EXPERT}, "Shadow Temple Stone Umbrella Skip", "A very precise Hover Boots movement from off of the lower chest can get you on top of the crushing spikes without needing to pull the block. Applies to both Vanilla and Master Quest."); + mTrickOptions[RT_SHADOW_UMBRELLA_GS] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::EXPERT}, "Shadow Temple Falling Spikes GS with Hover Boots", "After killing the Skulltula, a very precise Hover Boots movement from off of the lower chest can get you on top of the crushing spikes without needing to pull the block. From there, another very precise Hover Boots movement can be used to obtain the token without needing the Hookshot. Applies to both Vanilla and Master Quest. For obtaining the chests in this room with just Hover Boots, be sure to enable \"Shadow Temple Stone Umbrella Skip\"."); + mTrickOptions[RT_SHADOW_FREESTANDING_KEY] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple Freestanding Key with Bombchu", "Release the Bombchu with good timing so that it explodes near the bottom of the pot."); + mTrickOptions[RT_SHADOW_STATUE] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple River Statue with Bombchu", "By sending a Bombchu around the edge of the gorge, you can knock down the statue without needing a Bow. Applies in both vanilla and MQ Shadow."); + mTrickOptions[RT_SHADOW_BONGO] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple Bongo Bongo without projectiles", "Using precise sword slashes, Bongo Bongo can be defeated without using projectiles. This is only relevant in conjunction with Shadow Temple dungeon shortcuts or shuffled boss entrances."); + mTrickOptions[RT_LENS_SHADOW_MQ] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple MQ Stationary Objects without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple MQ for most areas in the dungeon. See \"Shadow Temple MQ Invisible Moving Platform without Lens of Truth\", \"Shadow Temple MQ Invisible Blades Silver Rupees without Lens of Truth\", \"Shadow Temple MQ 2nd Dead Hand without Lens of Truth\", and \"Shadow Temple Bongo Bongo without Lens of Truth\" for exceptions."); + mTrickOptions[RT_LENS_SHADOW_MQ_INVISIBLE_BLADES] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple MQ Invisible Blades Silver Rupees without Lens of Truth", "Removes the requirement for the Lens of Truth or Nayru's Love in Shadow Temple MQ for the Invisible Blades room silver rupee collection."); + mTrickOptions[RT_LENS_SHADOW_MQ_PLATFORM] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple MQ Invisible Moving Platform without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple MQ to cross the invisible moving platform in the huge pit room in either direction."); + mTrickOptions[RT_LENS_SHADOW_MQ_DEADHAND] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple MQ 2nd Dead Hand without Lens of Truth", "Dead Hand spawns in a random spot within the room. Having Lens removes the hassle of having to comb the room looking for his spawn location."); + mTrickOptions[RT_SHADOW_MQ_GAP] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple MQ Truth Spinner Gap with Longshot", "You can Longshot a torch and jump-slash recoil onto the tongue. It works best if you Longshot the right torch from the left side of the room."); + mTrickOptions[RT_SHADOW_MQ_INVISIBLE_BLADES] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple MQ Invisible Blades without Song of Time", "The Like Like can be used to boost you into the silver rupee or recovery hearts that normally require Song of Time. This cannot be performed on OHKO since the Like Like does not boost you high enough if you die."); + mTrickOptions[RT_SHADOW_MQ_HUGE_PIT] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple MQ Lower Huge Pit without Fire Source", "Normally a frozen eye switch spawns some platforms that you can use to climb down, but there's actually a small piece of ground that you can stand on that you can just jump down to."); + mTrickOptions[RT_SHADOW_MQ_WINDY_WALKWAY] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple MQ Windy Walkway Reverse without Hover Boots", "It is possible to jump from the alcove in the windy hallway to the middle platform. There are two methods: wait out the fan opposite the door and hold forward, or jump to the right to be pushed by the fan there towards the platform ledge. Note that jumps of this distance are inconsistent, but still possible."); + mTrickOptions[RT_LENS_SPIRIT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple without Lens of Truth", "Removes the requirements for the Lens of Truth in Spirit Temple."); + mTrickOptions[RT_SPIRIT_CHILD_CHU] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple Child Side Bridge with Bombchu", "A carefully-timed Bombchu can hit the switch."); + mTrickOptions[RT_SPIRIT_LOBBY_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple Main Room GS with Boomerang", "Standing on the highest part of the arm of the statue, a precise Boomerang throw can kill and obtain this Gold Skulltula. You must throw the Boomerang slightly off to the side so that it curves into the Skulltula, as aiming directly at it will clank off of the wall in front."); + mTrickOptions[RT_SPIRIT_LOWER_ADULT_SWITCH] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::ADVANCED}, "Spirit Temple Lower Adult Switch with Bombs", "A bomb can be used to hit the switch on the ceiling, but it must be thrown from a particular distance away and with precise timing."); + mTrickOptions[RT_SPIRIT_LOBBY_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple Main Room Jump from Hands to Upper Ledges", "A precise jump to obtain the following as adult without needing one of Hover Boots, or Hookshot (in vanilla) or Song of Time (in MQ): - Spirit Temple Statue Room Northeast Chest - Spirit Temple GS Lobby - Spirit Temple MQ Central Chamber Top Left Pot (Left) - Spirit Temple MQ Central Chamber Top Left Pot (Right)"); + // disabled since "Spirit Temple boss shortcuts" (pre-lowers the platform where you break the statues face) isn't a setting in ship + // mTrickOptions[RT_SPIRIT_PLATFORM_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple Main Room Hookshot to Boss Platform", "Precise hookshot aiming at the platform chains can be used to reach the boss platform from the middle landings. Using a jump slash immediately after reaching a chain makes aiming more lenient. Relevant only when Spirit Temple boss shortcuts are on."); + mTrickOptions[RT_SPIRIT_MAP_CHEST] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple Map Chest with Bow", "To get a line of sight from the upper torch to the map chest torches, you must pull an Armos statue all the way up the stairs."); + mTrickOptions[RT_SPIRIT_SUN_CHEST] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::ADVANCED}, "Spirit Temple Sun Block Room Chest with Bow", "Using the blocks in the room as platforms you can get lines of sight to all three torches. The timer on the torches is quite short so you must move quickly in order to light all three."); + mTrickOptions[RT_SPIRIT_WALL] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple Shifting Wall with No Additional Items", "Logic normally guarantees a way of dealing with both the Beamos and the Walltula before climbing the wall."); + mTrickOptions[RT_LENS_SPIRIT_MQ] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Spirit Temple MQ."); + mTrickOptions[RT_SPIRIT_MQ_SUN_BLOCK_SOT] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple MQ Sun Block Room as Child without Song of Time", "While adult can easily jump directly to the switch that unbars the door to the sun block room, child Link cannot make the jump without spawning a Song of Time block to jump from. You can skip this by throwing the crate down onto the switch from above, which does unbar the door, however the crate immediately breaks, so you must move quickly to get through the door before it closes back up."); + mTrickOptions[RT_SPIRIT_MQ_SUN_BLOCK_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple MQ Sun Block Room GS with Boomerang", "Throw the Boomerang in such a way that it curves through the side of the glass block to hit the Gold Skulltula."); + mTrickOptions[RT_SPIRIT_MQ_LOWER_ADULT] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple MQ Lower Adult without Fire Arrows", "By standing in a precise position it is possible to light two of the torches with a single use of Din\'s Fire. This saves enough time to be able to light all three torches with only Din\'s."); + mTrickOptions[RT_SPIRIT_MQ_FROZEN_EYE] = TrickOption::LogicTrick(RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple MQ Frozen Eye Switch without Fire", "You can melt the ice by shooting an arrow through a torch. The only way to find a line of sight for this shot is to first spawn a Song of Time block, and then stand on the very edge of it."); + mTrickOptions[RT_ICE_BLOCK_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_ICE_CAVERN, {Tricks::Tag::INTERMEDIATE}, "Ice Cavern Block Room GS with Hover Boots", "The Hover Boots can be used to get in front of the Skulltula to kill it with a jump slash. Then, the Hover Boots can again be used to obtain the Token, all without Hookshot or Boomerang."); + mTrickOptions[RT_ICE_MQ_RED_ICE_GS] = TrickOption::LogicTrick(RCQUEST_MQ, RA_ICE_CAVERN, {Tricks::Tag::INTERMEDIATE}, "Ice Cavern MQ Red Ice GS without Song of Time", "If you side-hop into the perfect position, you can briefly stand on the platform with the red ice just long enough to dump some blue fire."); + mTrickOptions[RT_ICE_MQ_SCARECROW] = TrickOption::LogicTrick(RCQUEST_MQ, RA_ICE_CAVERN, {Tricks::Tag::INTERMEDIATE}, "Ice Cavern MQ Scarecrow GS with No Additional Items", "As adult a precise jump can be used to reach this alcove."); + mTrickOptions[RT_LENS_GTG] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, "Gerudo Training Ground without Lens of Truth", "Removes the requirements for the Lens of Truth in Gerudo Training Ground."); + mTrickOptions[RT_GTG_WITHOUT_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::INTERMEDIATE}, "Gerudo Training Ground Left Side Silver Rupees without Hookshot", "After collecting the rest of the silver rupees in the room, you can reach the final silver rupee on the ceiling by being pulled up into it after getting grabbed by the Wallmaster. Then, you must also reach the exit of the room without the use of the Hookshot. If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do so without taking damage is more precise."); + mTrickOptions[RT_GTG_FAKE_WALL] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, "Reach Gerudo Training Ground Fake Wall Ledge with Hover Boots", "A precise Hover Boots use from the top of the chest can allow you to grab the ledge without needing the usual requirements. In Master Quest, this always skips a Song of Time requirement. In Vanilla, this skips a Hookshot requirement, but is only relevant if \"Gerudo Training Ground Left Side Silver Rupees without Hookshot\" is enabled."); + mTrickOptions[RT_LENS_GTG_MQ] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, "Gerudo Training Ground MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Gerudo Training Ground MQ."); + mTrickOptions[RT_GTG_MQ_WITH_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, "Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot", "The highest silver rupee can be obtained by hookshotting the target and then immediately jump slashing toward the rupee."); + mTrickOptions[RT_GTG_MQ_WIHTOUT_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::INTERMEDIATE}, "Gerudo Training Ground MQ Left Side Silver Rupees without Hookshot", "After collecting the rest of the silver rupees in the room, you can reach the final silver rupee on the ceiling by being pulled up into it after getting grabbed by the Wallmaster. The Wallmaster will not track you to directly underneath the rupee. You should take the last step to be under the rupee after the Wallmaster has begun its attempt to grab you. Also included with this trick is that fact that the switch that unbars the door to the final chest of GTG can be hit without a projectile, using a precise jump slash. This trick supersedes \"Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot\"."); + mTrickOptions[RT_LENS_GANON] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, "Ganon\'s Castle without Lens of Truth", "Removes the requirements for the Lens of Truth in Ganon's Castle."); + mTrickOptions[RT_GANON_SPIRIT_TRIAL_HOOKSHOT] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, "Spirit Trial without Hookshot", "The highest rupee can be obtained as either age by performing a precise jump and a well-timed jumpslash off of an Armos."); + mTrickOptions[RT_LENS_GANON_MQ] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, "Ganon\'s Castle MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Ganon's Castle MQ."); + mTrickOptions[RT_GANON_MQ_FIRE_TRIAL] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::ADVANCED}, "Fire Trial MQ with Hookshot", "It's possible to hook the target at the end of fire trial with just Hookshot, but it requires precise aim and perfect positioning. The main difficulty comes from getting on the very corner of the obelisk without falling into the lava."); + mTrickOptions[RT_GANON_MQ_SHADOW_TRIAL] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, "Shadow Trial MQ Torch with Bow", "You can light the torch in this room without a fire source by shooting an arrow through the lit torch at the beginning of the room. Because the room is so dark and the unlit torch is so far away, it can be difficult to aim the shot correctly."); + mTrickOptions[RT_GANON_MQ_LIGHT_TRIAL] = TrickOption::LogicTrick(RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::INTERMEDIATE}, "Light Trial MQ without Hookshot", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. In this case to do it without taking damage is especially precise."); mOptionGroups[RSG_LOGIC] = OptionGroup::SubGroup("Logic Options", { &mOptions[RSK_LOGIC_RULES], @@ -555,6 +577,7 @@ void Settings::CreateOptions() { &mTrickOptions[RT_ZR_CUCCO], &mTrickOptions[RT_ZD_KING_ZORA_SKIP], &mTrickOptions[RT_ZD_GS], + &mTrickOptions[RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES], &mTrickOptions[RT_LH_LAB_WALL_GS], &mTrickOptions[RT_LH_LAB_DIVING], &mTrickOptions[RT_LH_WATER_HOOKSHOT], @@ -600,6 +623,7 @@ void Settings::CreateOptions() { &mTrickOptions[RT_FOREST_OUTDOORS_LEDGE], &mTrickOptions[RT_FOREST_DOORFRAME], &mTrickOptions[RT_FOREST_OUTSIDE_BACKDOOR], + &mTrickOptions[RT_FOREST_OUTDOORS_HEARTS_BOOMERANG], &mTrickOptions[RT_FOREST_MQ_WELL_SWIM], &mTrickOptions[RT_FOREST_MQ_BLOCK_PUZZLE], &mTrickOptions[RT_FOREST_MQ_JS_HALLWAY_SWITCH], @@ -681,7 +705,7 @@ void Settings::CreateOptions() { &mTrickOptions[RT_GANON_MQ_FIRE_TRIAL], &mTrickOptions[RT_GANON_MQ_SHADOW_TRIAL], &mTrickOptions[RT_GANON_MQ_LIGHT_TRIAL], - }, false); + }); for (int i = 0; i < RT_MAX; i++) { auto& trick = mTrickOptions[i]; if (!trick.GetName().empty()) { @@ -695,7 +719,8 @@ void Settings::CreateOptions() { &mOptions[RSK_KAK_GATE], &mOptions[RSK_DOOR_OF_TIME], &mOptions[RSK_ZORAS_FOUNTAIN], - }, false, WidgetContainerType::COLUMN); + &mOptions[RSK_SLEEPING_WATERFALL], + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_WORLD_IMGUI] = OptionGroup::SubGroup("World Settings", { &mOptions[RSK_STARTING_AGE], &mOptions[RSK_GERUDO_FORTRESS], @@ -726,7 +751,7 @@ void Settings::CreateOptions() { &mOptions[RSK_TRIFORCE_HUNT], &mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], &mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED] - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_ENTRANCES_IMGUI] = OptionGroup::SubGroup("Shuffle Entrances", { &mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], &mOptions[RSK_SHUFFLE_BOSS_ENTRANCES], @@ -743,12 +768,12 @@ void Settings::CreateOptions() { &mOptions[RSK_MIX_OVERWORLD_ENTRANCES], &mOptions[RSK_MIX_INTERIOR_ENTRANCES], &mOptions[RSK_MIX_GROTTO_ENTRANCES] - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_WORLD_IMGUI_TABLE] = OptionGroup::SubGroup("World", { &mOptionGroups[RSG_AREA_ACCESS_IMGUI], &mOptionGroups[RSG_WORLD_IMGUI], &mOptionGroups[RSG_SHUFFLE_ENTRANCES_IMGUI], - }, false, WidgetContainerType::TABLE); + }, WidgetContainerType::TABLE); mOptionGroups[RSG_SHUFFLE_ITEMS_IMGUI] = OptionGroup::SubGroup("Shuffle Items", { &mOptions[RSK_SHUFFLE_SONGS], &mOptions[RSK_SHUFFLE_TOKENS], @@ -765,7 +790,8 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_FISHING_POLE], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], - }, false, WidgetContainerType::COLUMN); + &mOptions[RSK_SHUFFLE_FREESTANDING], + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = OptionGroup::SubGroup("Shuffle NPCs & Merchants", { &mOptions[RSK_SHOPSANITY], &mOptions[RSK_SHOPSANITY_COUNT], @@ -795,6 +821,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SCRUBS_PRICES_AFFORDABLE], &mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_COWS], + &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_MERCHANT_PRICES], &mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE], @@ -810,7 +837,8 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BOSS_SOULS], - }, false, WidgetContainerType::COLUMN); + &mOptions[RSK_SHUFFLE_FAIRIES], + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI] = OptionGroup::SubGroup("Shuffle Dungeon Items", { &mOptions[RSK_SHUFFLE_DUNGEON_REWARDS], &mOptions[RSK_SHUFFLE_MAPANDCOMPASS], @@ -835,12 +863,12 @@ void Settings::CreateOptions() { &mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL], &mOptions[RSK_KEYRINGS_GTG], &mOptions[RSK_KEYRINGS_GANONS_CASTLE], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_ITEMS_IMGUI_TABLE] = OptionGroup::SubGroup("Items", { &mOptionGroups[RSG_SHUFFLE_ITEMS_IMGUI], &mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI], &mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI], - }, false, WidgetContainerType::TABLE); + }, WidgetContainerType::TABLE); mOptionGroups[RSG_TIMESAVERS_IMGUI] = OptionGroup::SubGroup("Timesavers", { &mOptions[RSK_CUCCO_COUNT], &mOptions[RSK_BIG_POE_COUNT], @@ -849,14 +877,14 @@ void Settings::CreateOptions() { &mOptions[RSK_SKIP_EPONA_RACE], &mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG] - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI] = OptionGroup::SubGroup("", { &mOptions[RSK_ITEM_POOL], &mOptions[RSK_ICE_TRAPS], &mOptions[RSK_GOSSIP_STONE_HINTS], &mOptions[RSK_HINT_CLARITY], &mOptions[RSK_HINT_DISTRIBUTION], - }, false, WidgetContainerType::SECTION); + }, WidgetContainerType::SECTION); mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup("Extra Hints", { &mOptions[RSK_TOT_ALTAR_HINT], &mOptions[RSK_GANONDORF_HINT], @@ -883,11 +911,11 @@ void Settings::CreateOptions() { &mOptions[RSK_KAK_50_SKULLS_HINT], &mOptions[RSK_KAK_100_SKULLS_HINT], &mOptions[RSK_MASK_SHOP_HINT] - }, false, WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones."); + }, WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones."); mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN] = OptionGroup::SubGroup("Item Pool & Hints", std::initializer_list{ &mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI], &mOptionGroups[RSG_EXTRA_HINTS_IMGUI], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_ADDITIONAL_FEATURES_IMGUI] = OptionGroup::SubGroup("Additional Features", { &mOptions[RSK_FULL_WALLETS], &mOptions[RSK_BOMBCHUS_IN_LOGIC], @@ -896,24 +924,25 @@ void Settings::CreateOptions() { &mOptions[RSK_SUNLIGHT_ARROWS], &mOptions[RSK_INFINITE_UPGRADES], &mOptions[RSK_SKELETON_KEY], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_GAMEPLAY_IMGUI_TABLE] = OptionGroup::SubGroup("Gameplay", { &mOptionGroups[RSG_TIMESAVERS_IMGUI], &mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN], &mOptionGroups[RSG_ADDITIONAL_FEATURES_IMGUI] - }, false, WidgetContainerType::TABLE); + }, WidgetContainerType::TABLE); mOptionGroups[RSG_STARTING_EQUIPMENT_IMGUI] = OptionGroup::SubGroup("Starting Equipment", { &mOptions[RSK_LINKS_POCKET], &mOptions[RSK_STARTING_KOKIRI_SWORD], &mOptions[RSK_STARTING_MASTER_SWORD], &mOptions[RSK_STARTING_DEKU_SHIELD] - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_STARTING_ITEMS_IMGUI] = OptionGroup::SubGroup("Starting Items", { &mOptions[RSK_STARTING_OCARINA], - &mOptions[RSK_STARTING_CONSUMABLES], + &mOptions[RSK_STARTING_STICKS], + &mOptions[RSK_STARTING_NUTS], &mOptions[RSK_STARTING_SKULLTULA_TOKEN], &mOptions[RSK_STARTING_HEARTS], - }, false, WidgetContainerType::COLUMN); + }, WidgetContainerType::COLUMN); mOptionGroups[RSG_STARTING_NORMAL_SONGS_IMGUI] = OptionGroup::SubGroup("Normal Songs", { &mOptions[RSK_STARTING_ZELDAS_LULLABY], &mOptions[RSK_STARTING_EPONAS_SONG], @@ -921,7 +950,7 @@ void Settings::CreateOptions() { &mOptions[RSK_STARTING_SUNS_SONG], &mOptions[RSK_STARTING_SONG_OF_TIME], &mOptions[RSK_STARTING_SONG_OF_STORMS], - }, false, WidgetContainerType::SECTION); + }, WidgetContainerType::SECTION); mOptionGroups[RSG_STARTING_WARP_SONGS_IMGUI] = OptionGroup::SubGroup("Warp Songs", { &mOptions[RSK_STARTING_MINUET_OF_FOREST], &mOptions[RSK_STARTING_BOLERO_OF_FIRE], @@ -929,21 +958,22 @@ void Settings::CreateOptions() { &mOptions[RSK_STARTING_REQUIEM_OF_SPIRIT], &mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW], &mOptions[RSK_STARTING_PRELUDE_OF_LIGHT] - }, false, WidgetContainerType::SECTION); + }, WidgetContainerType::SECTION); mOptionGroups[RSG_STARTING_SONGS_IMGUI] = OptionGroup::SubGroup("Starting Songs", std::initializer_list({ &mOptionGroups[RSG_STARTING_NORMAL_SONGS_IMGUI], &mOptionGroups[RSG_STARTING_WARP_SONGS_IMGUI], - }), false, WidgetContainerType::COLUMN); + }), WidgetContainerType::COLUMN); mOptionGroups[RSG_STARTING_INVENTORY_IMGUI_TABLE] = OptionGroup::SubGroup("Starting Inventory", { &mOptionGroups[RSG_STARTING_EQUIPMENT_IMGUI], &mOptionGroups[RSG_STARTING_ITEMS_IMGUI], &mOptionGroups[RSG_STARTING_SONGS_IMGUI] - }, false, WidgetContainerType::TABLE); + }, WidgetContainerType::TABLE); mOptionGroups[RSG_OPEN] = OptionGroup("Open Settings", { &mOptions[RSK_FOREST], &mOptions[RSK_KAK_GATE], &mOptions[RSK_DOOR_OF_TIME], &mOptions[RSK_ZORAS_FOUNTAIN], + &mOptions[RSK_SLEEPING_WATERFALL], &mOptions[RSK_GERUDO_FORTRESS], &mOptions[RSK_RAINBOW_BRIDGE], &mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT], @@ -1030,6 +1060,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SCRUBS_PRICES_AFFORDABLE], &mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_COWS], + &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], @@ -1054,6 +1085,8 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_BOSS_SOULS], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], + &mOptions[RSK_SHUFFLE_FREESTANDING], + &mOptions[RSK_SHUFFLE_FAIRIES], }); mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { &mOptions[RSK_SHUFFLE_MAPANDCOMPASS], @@ -1083,7 +1116,7 @@ void Settings::CreateOptions() { &mOptions[RSK_STARTING_OCARINA], &mOptions[RSK_STARTING_KOKIRI_SWORD], &mOptions[RSK_STARTING_DEKU_SHIELD] - }, false); + }); mOptionGroups[RSG_STARTING_SONGS] = OptionGroup::SubGroup("Ocarina Songs", { &mOptions[RSK_STARTING_ZELDAS_LULLABY], &mOptions[RSK_STARTING_EPONAS_SONG], @@ -1098,18 +1131,19 @@ void Settings::CreateOptions() { &mOptions[RSK_STARTING_REQUIEM_OF_SPIRIT], &mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW], &mOptions[RSK_STARTING_PRELUDE_OF_LIGHT], - }, false); + }); mOptionGroups[RSG_STARTING_OTHER] = OptionGroup::SubGroup("Other", { - &mOptions[RSK_STARTING_CONSUMABLES], + &mOptions[RSK_STARTING_STICKS], + &mOptions[RSK_STARTING_NUTS], &mOptions[RSK_FULL_WALLETS], &mOptions[RSK_STARTING_SKULLTULA_TOKEN], &mOptions[RSK_STARTING_HEARTS], - }, false); + }); mOptionGroups[RSG_STARTING_INVENTORY] = OptionGroup("Starting Inventory", { &mOptionGroups[RSG_STARTING_ITEMS], &mOptionGroups[RSG_STARTING_SONGS], &mOptionGroups[RSG_STARTING_OTHER], - }, OptionGroupType::DEFAULT, false); + }, OptionGroupType::DEFAULT); mOptionGroups[RSG_TIMESAVERS] = OptionGroup("Timesaver Settings", { &mOptions[RSK_SKIP_CHILD_STEALTH], &mOptions[RSK_SKIP_CHILD_ZELDA], @@ -1161,38 +1195,38 @@ void Settings::CreateOptions() { &mOptions[RSK_ICE_TRAPS] })); // TODO: Progressive Goron Sword, Remove Double Defense - mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST] = OptionGroup::SubGroup("Kokiri Forest", mExcludeLocationsOptionsAreas[RCAREA_KOKIRI_FOREST], false); - mOptionGroups[RSG_EXCLUDES_LOST_WOODS] = OptionGroup::SubGroup("Lost Woods", mExcludeLocationsOptionsAreas[RCAREA_LOST_WOODS], false); - mOptionGroups[RSG_EXCLUDES_SACRED_FOREST_MEADOW] = OptionGroup::SubGroup("Sacred Forest Meadow", mExcludeLocationsOptionsAreas[RCAREA_SACRED_FOREST_MEADOW], false); - mOptionGroups[RSG_EXCLUDES_DEKU_TREE] = OptionGroup::SubGroup("Deku Tree", mExcludeLocationsOptionsAreas[RCAREA_DEKU_TREE], false); - mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE] = OptionGroup::SubGroup("Forest Temple", mExcludeLocationsOptionsAreas[RCAREA_FOREST_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE] = OptionGroup::SubGroup("Kakariko Village", mExcludeLocationsOptionsAreas[RCAREA_KAKARIKO_VILLAGE], false); - mOptionGroups[RSG_EXCLUDES_GRAVEYARD] = OptionGroup::SubGroup("Graveyard", mExcludeLocationsOptionsAreas[RCAREA_GRAVEYARD], false); - mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL] = OptionGroup::SubGroup("Bottom of the Well", mExcludeLocationsOptionsAreas[RCAREA_BOTTOM_OF_THE_WELL], false); - mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE] = OptionGroup::SubGroup("Shadow Temple", mExcludeLocationsOptionsAreas[RCAREA_SHADOW_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL] = OptionGroup::SubGroup("Death Mountain Trail", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_TRAIL], false); - mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER] = OptionGroup::SubGroup("Death Mountain Crater", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_CRATER], false); - mOptionGroups[RSG_EXCLUDES_GORON_CITY] = OptionGroup::SubGroup("Goron City", mExcludeLocationsOptionsAreas[RCAREA_GORON_CITY], false); - mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN] = OptionGroup::SubGroup("Dodongo's Cavern", mExcludeLocationsOptionsAreas[RCAREA_DODONGOS_CAVERN], false); - mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE] = OptionGroup::SubGroup("Fire Temple", mExcludeLocationsOptionsAreas[RCAREA_FIRE_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER] = OptionGroup::SubGroup("Zora's River", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_RIVER], false); - mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN] = OptionGroup::SubGroup("Zora's Domain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_DOMAIN], false); - mOptionGroups[RSG_EXCLUDES_ZORAS_FOUNTAIN] = OptionGroup::SubGroup("Zora's Fountain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_FOUNTAIN], false); - mOptionGroups[RSG_EXCLUDES_JABU_JABU] = OptionGroup::SubGroup("Jabu Jabu's Belly", mExcludeLocationsOptionsAreas[RCAREA_JABU_JABUS_BELLY], false); - mOptionGroups[RSG_EXCLUDES_ICE_CAVERN] = OptionGroup::SubGroup("Ice Cavern", mExcludeLocationsOptionsAreas[RCAREA_ICE_CAVERN], false); - mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD] = OptionGroup::SubGroup("Hyrule Field", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_FIELD], false); - mOptionGroups[RSG_EXCLUDES_LON_LON_RANCH] = OptionGroup::SubGroup("Lon Lon Ranch", mExcludeLocationsOptionsAreas[RCAREA_LON_LON_RANCH], false); - mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA] = OptionGroup::SubGroup("Lake Hylia", mExcludeLocationsOptionsAreas[RCAREA_LAKE_HYLIA], false); - mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE] = OptionGroup::SubGroup("Water Temple", mExcludeLocationsOptionsAreas[RCAREA_WATER_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY] = OptionGroup::SubGroup("Gerudo Valley", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_VALLEY], false); - mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS] = OptionGroup::SubGroup("Gerudo Fortress", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_FORTRESS], false); - mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND] = OptionGroup::SubGroup("Haunted Wasteland", mExcludeLocationsOptionsAreas[RCAREA_WASTELAND], false); - mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS] = OptionGroup::SubGroup("Desert Colossus", mExcludeLocationsOptionsAreas[RCAREA_DESERT_COLOSSUS], false); - mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUNDS] = OptionGroup::SubGroup("Gerudo Training Grounds", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_TRAINING_GROUND], false); - mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE] = OptionGroup::SubGroup("Spirit Temple", mExcludeLocationsOptionsAreas[RCAREA_SPIRIT_TEMPLE], false); - mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE] = OptionGroup::SubGroup("Hyrule Castle", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_CASTLE], false); - mOptionGroups[RSG_EXCLUDES_MARKET] = OptionGroup::SubGroup("Market", mExcludeLocationsOptionsAreas[RCAREA_MARKET], false); - mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE] = OptionGroup::SubGroup("Ganon's Castle", mExcludeLocationsOptionsAreas[RCAREA_GANONS_CASTLE], false); + mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST] = OptionGroup::SubGroup("Kokiri Forest", mExcludeLocationsOptionsAreas[RCAREA_KOKIRI_FOREST]); + mOptionGroups[RSG_EXCLUDES_LOST_WOODS] = OptionGroup::SubGroup("Lost Woods", mExcludeLocationsOptionsAreas[RCAREA_LOST_WOODS]); + mOptionGroups[RSG_EXCLUDES_SACRED_FOREST_MEADOW] = OptionGroup::SubGroup("Sacred Forest Meadow", mExcludeLocationsOptionsAreas[RCAREA_SACRED_FOREST_MEADOW]); + mOptionGroups[RSG_EXCLUDES_DEKU_TREE] = OptionGroup::SubGroup("Deku Tree", mExcludeLocationsOptionsAreas[RCAREA_DEKU_TREE]); + mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE] = OptionGroup::SubGroup("Forest Temple", mExcludeLocationsOptionsAreas[RCAREA_FOREST_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE] = OptionGroup::SubGroup("Kakariko Village", mExcludeLocationsOptionsAreas[RCAREA_KAKARIKO_VILLAGE]); + mOptionGroups[RSG_EXCLUDES_GRAVEYARD] = OptionGroup::SubGroup("Graveyard", mExcludeLocationsOptionsAreas[RCAREA_GRAVEYARD]); + mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL] = OptionGroup::SubGroup("Bottom of the Well", mExcludeLocationsOptionsAreas[RCAREA_BOTTOM_OF_THE_WELL]); + mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE] = OptionGroup::SubGroup("Shadow Temple", mExcludeLocationsOptionsAreas[RCAREA_SHADOW_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL] = OptionGroup::SubGroup("Death Mountain Trail", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_TRAIL]); + mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER] = OptionGroup::SubGroup("Death Mountain Crater", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_CRATER]); + mOptionGroups[RSG_EXCLUDES_GORON_CITY] = OptionGroup::SubGroup("Goron City", mExcludeLocationsOptionsAreas[RCAREA_GORON_CITY]); + mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN] = OptionGroup::SubGroup("Dodongo's Cavern", mExcludeLocationsOptionsAreas[RCAREA_DODONGOS_CAVERN]); + mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE] = OptionGroup::SubGroup("Fire Temple", mExcludeLocationsOptionsAreas[RCAREA_FIRE_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER] = OptionGroup::SubGroup("Zora's River", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_RIVER]); + mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN] = OptionGroup::SubGroup("Zora's Domain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_DOMAIN]); + mOptionGroups[RSG_EXCLUDES_ZORAS_FOUNTAIN] = OptionGroup::SubGroup("Zora's Fountain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_FOUNTAIN]); + mOptionGroups[RSG_EXCLUDES_JABU_JABU] = OptionGroup::SubGroup("Jabu Jabu's Belly", mExcludeLocationsOptionsAreas[RCAREA_JABU_JABUS_BELLY]); + mOptionGroups[RSG_EXCLUDES_ICE_CAVERN] = OptionGroup::SubGroup("Ice Cavern", mExcludeLocationsOptionsAreas[RCAREA_ICE_CAVERN]); + mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD] = OptionGroup::SubGroup("Hyrule Field", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_FIELD]); + mOptionGroups[RSG_EXCLUDES_LON_LON_RANCH] = OptionGroup::SubGroup("Lon Lon Ranch", mExcludeLocationsOptionsAreas[RCAREA_LON_LON_RANCH]); + mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA] = OptionGroup::SubGroup("Lake Hylia", mExcludeLocationsOptionsAreas[RCAREA_LAKE_HYLIA]); + mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE] = OptionGroup::SubGroup("Water Temple", mExcludeLocationsOptionsAreas[RCAREA_WATER_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY] = OptionGroup::SubGroup("Gerudo Valley", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_VALLEY]); + mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS] = OptionGroup::SubGroup("Gerudo Fortress", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_FORTRESS]); + mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND] = OptionGroup::SubGroup("Haunted Wasteland", mExcludeLocationsOptionsAreas[RCAREA_WASTELAND]); + mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS] = OptionGroup::SubGroup("Desert Colossus", mExcludeLocationsOptionsAreas[RCAREA_DESERT_COLOSSUS]); + mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUND] = OptionGroup::SubGroup("Gerudo Training Ground", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_TRAINING_GROUND]); + mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE] = OptionGroup::SubGroup("Spirit Temple", mExcludeLocationsOptionsAreas[RCAREA_SPIRIT_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE] = OptionGroup::SubGroup("Hyrule Castle", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_CASTLE]); + mOptionGroups[RSG_EXCLUDES_MARKET] = OptionGroup::SubGroup("Market", mExcludeLocationsOptionsAreas[RCAREA_MARKET]); + mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE] = OptionGroup::SubGroup("Ganon's Castle", mExcludeLocationsOptionsAreas[RCAREA_GANONS_CASTLE]); mOptionGroups[RSG_EXCLUDES] = OptionGroup::SubGroup("Exclude Locations", { &mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST], &mOptionGroups[RSG_EXCLUDES_LOST_WOODS], @@ -1221,12 +1255,12 @@ void Settings::CreateOptions() { &mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS], &mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND], &mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS], - &mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUNDS], + &mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUND], &mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE], &mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE], &mOptionGroups[RSG_EXCLUDES_MARKET], &mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE], - }, false); + }); mOptionGroups[RSG_DETAILED_LOGIC] = OptionGroup("Detailed Logic Settings", { &mOptionGroups[RSG_LOGIC], &mOptionGroups[RSG_TRICKS], @@ -1247,214 +1281,23 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_SCRUBS], &mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_COWS], + &mOptions[RSK_SHUFFLE_POTS], + &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_100_GS_REWARD], + &mOptions[RSK_SHUFFLE_FAIRIES], &mOptions[RSK_GOSSIP_STONE_HINTS], }; +} -//RANDOTODO refactor OptionGroups so we can actually make maintainable enum conversion. - mSpoilerfileSettingNameToEnum = { - { "Logic Options:Logic", RSK_LOGIC_RULES }, - { "Open Settings:Forest", RSK_FOREST }, - { "Open Settings:Kakariko Gate", RSK_KAK_GATE }, - { "Open Settings:Door of Time", RSK_DOOR_OF_TIME }, - { "Open Settings:Zora's Fountain", RSK_ZORAS_FOUNTAIN }, - { "World Settings:Starting Age", RSK_STARTING_AGE }, - { "Open Settings:Gerudo Fortress", RSK_GERUDO_FORTRESS }, - { "Open Settings:Rainbow Bridge", RSK_RAINBOW_BRIDGE }, - { "Open Settings:Stone Count", RSK_RAINBOW_BRIDGE_STONE_COUNT }, - { "Open Settings:Medallion Count", RSK_RAINBOW_BRIDGE_MEDALLION_COUNT }, - { "Open Settings:Reward Count", RSK_RAINBOW_BRIDGE_REWARD_COUNT }, - { "Open Settings:Dungeon Count", RSK_RAINBOW_BRIDGE_DUNGEON_COUNT }, - { "Open Settings:Token Count", RSK_RAINBOW_BRIDGE_TOKEN_COUNT }, - { "Open Settings:Bridge Reward Options", RSK_BRIDGE_OPTIONS }, - { "Open Settings:Ganon's Trials", RSK_GANONS_TRIALS }, - { "Open Settings:Ganon's Trials Count", RSK_TRIAL_COUNT }, - { "Start with Ocarina", RSK_STARTING_OCARINA }, - { "Shuffle Settings:Shuffle Ocarinas", RSK_SHUFFLE_OCARINA }, - { "Shuffle Settings:Shuffle Ocarina Buttons", RSK_SHUFFLE_OCARINA_BUTTONS }, - { "Shuffle Settings:Shuffle Swim", RSK_SHUFFLE_SWIM }, - { "Start with Deku Shield", RSK_STARTING_DEKU_SHIELD }, - { "Start with Kokiri Sword", RSK_STARTING_KOKIRI_SWORD }, - { "Start with Master Sword", RSK_STARTING_MASTER_SWORD }, - { "Start with Zelda's Lullaby", RSK_STARTING_ZELDAS_LULLABY }, - { "Start with Epona's Song", RSK_STARTING_EPONAS_SONG }, - { "Start with Saria's Song", RSK_STARTING_SARIAS_SONG }, - { "Start with Sun's Song", RSK_STARTING_SUNS_SONG }, - { "Start with Song of Time", RSK_STARTING_SONG_OF_TIME }, - { "Start with Song of Storms", RSK_STARTING_SONG_OF_STORMS }, - { "Start with Minuet of Forest", RSK_STARTING_MINUET_OF_FOREST }, - { "Start with Bolero of Fire", RSK_STARTING_BOLERO_OF_FIRE }, - { "Start with Serenade of Water", RSK_STARTING_SERENADE_OF_WATER }, - { "Start with Requiem of Spirit", RSK_STARTING_REQUIEM_OF_SPIRIT }, - { "Start with Nocturne of Shadow", RSK_STARTING_NOCTURNE_OF_SHADOW }, - { "Start with Prelude of Light", RSK_STARTING_PRELUDE_OF_LIGHT }, - { "Shuffle Settings:Shuffle Kokiri Sword", RSK_SHUFFLE_KOKIRI_SWORD }, - { "Shuffle Settings:Shuffle Master Sword", RSK_SHUFFLE_MASTER_SWORD }, - { "Shuffle Settings:Shuffle Child's Wallet", RSK_SHUFFLE_CHILD_WALLET }, - { "Shuffle Settings:Include Tycoon Wallet", RSK_INCLUDE_TYCOON_WALLET }, - { "Shuffle Settings:Shuffle Dungeon Rewards", RSK_SHUFFLE_DUNGEON_REWARDS }, - { "Shuffle Settings:Shuffle Songs", RSK_SHUFFLE_SONGS }, - { "Shuffle Settings:Tokensanity", RSK_SHUFFLE_TOKENS }, - { "Shuffle Settings:Shopsanity", RSK_SHOPSANITY }, - { "Shuffle Settings:Shopsanity Specific Count", RSK_SHOPSANITY_COUNT }, - { "Shuffle Settings:Shopsanity Prices", RSK_SHOPSANITY_PRICES }, - { "Shuffle Settings:Shopsanity Fixed Amount", RSK_SHOPSANITY_PRICES_FIXED_PRICE }, - { "Shuffle Settings:Shopsanity Range 1", RSK_SHOPSANITY_PRICES_RANGE_1 }, - { "Shuffle Settings:Shopsanity Range 2", RSK_SHOPSANITY_PRICES_RANGE_2 }, - { "Shuffle Settings:Shopsanity No Wallet Weight", RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT }, - { "Shuffle Settings:Shopsanity Child Wallet Weight", RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT }, - { "Shuffle Settings:Shopsanity Adult Wallet Weight", RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT }, - { "Shuffle Settings:Shopsanity Giants Wallet Weight", RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT }, - { "Shuffle Settings:Shopsanity Tycoon Wallet Weight", RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT }, - { "Shuffle Settings:Shopsanity Affordable Prices", RSK_SHOPSANITY_PRICES_AFFORDABLE }, - { "Shuffle Settings:Scrub Shuffle", RSK_SHUFFLE_SCRUBS }, - { "Shuffle Settings:Scrubs Prices", RSK_SCRUBS_PRICES }, - { "Shuffle Settings:Scrubs Fixed Amount", RSK_SCRUBS_PRICES_FIXED_PRICE }, - { "Shuffle Settings:Scrubs Range 1", RSK_SCRUBS_PRICES_RANGE_1 }, - { "Shuffle Settings:Scrubs Range 2", RSK_SCRUBS_PRICES_RANGE_2 }, - { "Shuffle Settings:Scrubs No Wallet Weight", RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT }, - { "Shuffle Settings:Scrubs Child Wallet Weight", RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT }, - { "Shuffle Settings:Scrubs Adult Wallet Weight", RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT }, - { "Shuffle Settings:Scrubs Giants Wallet Weight", RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT }, - { "Shuffle Settings:Scrubs Tycoon Wallet Weight", RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT }, - { "Shuffle Settings:Scrubs Affordable Prices", RSK_SCRUBS_PRICES_AFFORDABLE }, - { "Shuffle Settings:Beehive Shuffle", RSK_SHUFFLE_BEEHIVES }, - { "Shuffle Settings:Shuffle Cows", RSK_SHUFFLE_COWS }, - { "Shuffle Settings:Shuffle Weird Egg", RSK_SHUFFLE_WEIRD_EGG }, - { "Shuffle Settings:Shuffle Gerudo Membership Card", RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD }, - { "Shuffle Settings:Shuffle Frog Song Rupees", RSK_SHUFFLE_FROG_SONG_RUPEES }, - { "Item Pool Settings:Item Pool", RSK_ITEM_POOL }, - { "Item Pool Settings:Ice Traps", RSK_ICE_TRAPS }, - { "Miscellaneous Settings:Gossip Stone Hints", RSK_GOSSIP_STONE_HINTS }, - { "Miscellaneous Settings:ToT Altar Hint", RSK_TOT_ALTAR_HINT }, - { "Miscellaneous Settings:Ganondorf Hint", RSK_GANONDORF_HINT }, - { "Miscellaneous Settings:Sheik Light Arrow Hint", RSK_SHEIK_LA_HINT }, - { "Miscellaneous Settings:Dampe's Diary Hint", RSK_DAMPES_DIARY_HINT }, - { "Miscellaneous Settings:Greg the Rupee Hint", RSK_GREG_HINT }, - { "Miscellaneous Settings:Hyrule Loach Hint", RSK_LOACH_HINT }, - { "Miscellaneous Settings:Saria's Hint", RSK_SARIA_HINT }, - { "Miscellaneous Settings:Frog Ocarina Game Hint", RSK_FROGS_HINT }, - { "Miscellaneous Settings:Ocarina of Time Hint", RSK_OOT_HINT }, - { "Miscellaneous Settings:10 GS Hint", RSK_KAK_10_SKULLS_HINT }, - { "Miscellaneous Settings:20 GS Hint", RSK_KAK_20_SKULLS_HINT }, - { "Miscellaneous Settings:30 GS Hint", RSK_KAK_30_SKULLS_HINT }, - { "Miscellaneous Settings:40 GS Hint", RSK_KAK_40_SKULLS_HINT }, - { "Miscellaneous Settings:50 GS Hint", RSK_KAK_50_SKULLS_HINT }, - { "Miscellaneous Settings:100 GS Hint", RSK_KAK_100_SKULLS_HINT }, - { "Miscellaneous Settings:Mask Shop Hint", RSK_MASK_SHOP_HINT }, - { "Miscellaneous Settings:Biggoron's Hint", RSK_BIGGORON_HINT }, - { "Miscellaneous Settings:Big Poes Hint", RSK_BIG_POES_HINT }, - { "Miscellaneous Settings:Chickens Hint", RSK_CHICKENS_HINT }, - { "Miscellaneous Settings:Malon Hint", RSK_MALON_HINT }, - { "Miscellaneous Settings:Horseback Archery Hint", RSK_HBA_HINT }, - { "Miscellaneous Settings:Warp Song Hints", RSK_WARP_SONG_HINTS }, - { "Miscellaneous Settings:Scrub Hint Text", RSK_SCRUB_TEXT_HINT }, - { "Miscellaneous Settings:Merchant Hint Text", RSK_MERCHANT_TEXT_HINT }, - { "Miscellaneous Settings:Fishing Pole Hint", RSK_FISHING_POLE_HINT }, - { "Miscellaneous Settings:Hint Clarity", RSK_HINT_CLARITY }, - { "Miscellaneous Settings:Hint Distribution", RSK_HINT_DISTRIBUTION }, - { "Shuffle Dungeon Items:Maps/Compasses", RSK_SHUFFLE_MAPANDCOMPASS }, - { "Shuffle Dungeon Items:Small Keys", RSK_KEYSANITY }, - { "Shuffle Dungeon Items:Gerudo Fortress Keys", RSK_GERUDO_KEYS }, - { "Shuffle Dungeon Items:Boss Keys", RSK_BOSS_KEYSANITY }, - { "Shuffle Dungeon Items:Ganon's Boss Key", RSK_GANONS_BOSS_KEY }, - { "Timesaver Settings:Skip Child Stealth", RSK_SKIP_CHILD_STEALTH }, - { "Timesaver Settings:Skip Child Zelda", RSK_SKIP_CHILD_ZELDA }, - { "Start with Consumables", RSK_STARTING_CONSUMABLES }, - { "Full Wallets", RSK_FULL_WALLETS }, - { "Timesaver Settings:Cuccos to return", RSK_CUCCO_COUNT }, - { "Timesaver Settings:Big Poe Target Count", RSK_BIG_POE_COUNT }, - { "Timesaver Settings:Skip Epona Race", RSK_SKIP_EPONA_RACE }, - { "Timesaver Settings:Complete Mask Quest", RSK_COMPLETE_MASK_QUEST }, - { "Timesaver Settings:Skip Scarecrow's Song", RSK_SKIP_SCARECROWS_SONG }, - { "Timesaver Settings:Enable Glitch-Useful Cutscenes", RSK_ENABLE_GLITCH_CUTSCENES }, - { "Logic Options:Night Skulltula's Expect Sun's Song", RSK_SKULLS_SUNS_SONG }, - { "Shuffle Settings:Shuffle Adult Trade", RSK_SHUFFLE_ADULT_TRADE }, - { "Shuffle Settings:Shuffle Merchants", RSK_SHUFFLE_MERCHANTS }, - { "Shuffle Settings:Merchant Prices", RSK_MERCHANT_PRICES }, - { "Shuffle Settings:Merchant Fixed Amount", RSK_MERCHANT_PRICES_FIXED_PRICE }, - { "Shuffle Settings:Merchant Range 1", RSK_MERCHANT_PRICES_RANGE_1 }, - { "Shuffle Settings:Merchant Range 2", RSK_MERCHANT_PRICES_RANGE_2 }, - { "Shuffle Settings:Merchant No Wallet Weight", RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT }, - { "Shuffle Settings:Merchant Child Wallet Weight", RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT }, - { "Shuffle Settings:Merchant Adult Wallet Weight", RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT }, - { "Shuffle Settings:Merchant Giants Wallet Weight", RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT }, - { "Shuffle Settings:Merchant Tycoon Wallet Weight", RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT }, - { "Shuffle Settings:Merchant Affordable Prices", RSK_MERCHANT_PRICES_AFFORDABLE }, - { "Miscellaneous Settings:Blue Fire Arrows", RSK_BLUE_FIRE_ARROWS }, - { "Miscellaneous Settings:Sunlight Arrows", RSK_SUNLIGHT_ARROWS }, - // TODO: Ammo Drop settings - { "World Settings:Bombchu Drops", RSK_ENABLE_BOMBCHU_DROPS }, - { "World Settings:Bombchus in Logic", RSK_BOMBCHUS_IN_LOGIC }, - { "Shuffle Settings:Link's Pocket", RSK_LINKS_POCKET }, - { "World Settings:MQ Dungeon Setting", RSK_MQ_DUNGEON_RANDOM }, - { "World Settings:MQ Dungeon Count", RSK_MQ_DUNGEON_COUNT }, - { "World Settings:Set Dungeon Quests", RSK_MQ_DUNGEON_SET }, - { "Shuffle Dungeon Quest:Deku Tree", RSK_MQ_DEKU_TREE }, - { "Shuffle Dungeon Quest:Dodongo's Cavern", RSK_MQ_DODONGOS_CAVERN }, - { "Shuffle Dungeon Quest:Jabu-Jabu's Belly", RSK_MQ_JABU_JABU }, - { "Shuffle Dungeon Quest:Forest Temple", RSK_MQ_FOREST_TEMPLE }, - { "Shuffle Dungeon Quest:Fire Temple", RSK_MQ_FIRE_TEMPLE }, - { "Shuffle Dungeon Quest:Water Temple", RSK_MQ_WATER_TEMPLE }, - { "Shuffle Dungeon Quest:Spirit Temple", RSK_MQ_SPIRIT_TEMPLE }, - { "Shuffle Dungeon Quest:Shadow Temple", RSK_MQ_SHADOW_TEMPLE }, - { "Shuffle Dungeon Quest:Bottom of the Well", RSK_MQ_BOTTOM_OF_THE_WELL }, - { "Shuffle Dungeon Quest:Ice Cavern", RSK_MQ_ICE_CAVERN }, - { "Shuffle Dungeon Quest:GTG", RSK_MQ_GTG }, - { "Shuffle Dungeon Quest:Ganon's Castle", RSK_MQ_GANONS_CASTLE }, - { "Shuffle Dungeon Items:Stone Count", RSK_LACS_STONE_COUNT }, - { "Shuffle Dungeon Items:Medallion Count", RSK_LACS_MEDALLION_COUNT }, - { "Shuffle Dungeon Items:Reward Count", RSK_LACS_REWARD_COUNT }, - { "Shuffle Dungeon Items:Dungeon Count", RSK_LACS_DUNGEON_COUNT }, - { "Shuffle Dungeon Items:Token Count", RSK_LACS_TOKEN_COUNT }, - { "Shuffle Dungeon Items:LACS Reward Options", RSK_LACS_OPTIONS }, - { "Shuffle Dungeon Items:Key Rings", RSK_KEYRINGS }, - { "Shuffle Dungeon Items:Keyring Dungeon Count", RSK_KEYRINGS_RANDOM_COUNT }, - { "Shuffle Dungeon Items:Gerudo Fortress Keyring", RSK_KEYRINGS_GERUDO_FORTRESS }, - { "Shuffle Dungeon Items:Forest Temple Keyring", RSK_KEYRINGS_FOREST_TEMPLE }, - { "Shuffle Dungeon Items:Fire Temple Keyring", RSK_KEYRINGS_FIRE_TEMPLE }, - { "Shuffle Dungeon Items:Water Temple Keyring", RSK_KEYRINGS_WATER_TEMPLE }, - { "Shuffle Dungeon Items:Spirit Temple Keyring", RSK_KEYRINGS_SPIRIT_TEMPLE }, - { "Shuffle Dungeon Items:Shadow Temple Keyring", RSK_KEYRINGS_SHADOW_TEMPLE }, - { "Shuffle Dungeon Items:Bottom of the Well Keyring", RSK_KEYRINGS_BOTTOM_OF_THE_WELL }, - { "Shuffle Dungeon Items:GTG Keyring", RSK_KEYRINGS_GTG }, - { "Shuffle Dungeon Items:Ganon's Castle Keyring", RSK_KEYRINGS_GANONS_CASTLE }, - { "World Settings:Shuffle Entrances", RSK_SHUFFLE_ENTRANCES }, - { "World Settings:Dungeon Entrances", RSK_SHUFFLE_DUNGEON_ENTRANCES }, - { "World Settings:Overworld Entrances", RSK_SHUFFLE_OVERWORLD_ENTRANCES }, - { "World Settings:Interior Entrances", RSK_SHUFFLE_INTERIOR_ENTRANCES }, - { "World Settings:Grottos Entrances", RSK_SHUFFLE_GROTTO_ENTRANCES }, - { "World Settings:Owl Drops", RSK_SHUFFLE_OWL_DROPS }, - { "World Settings:Warp Songs", RSK_SHUFFLE_WARP_SONGS }, - { "World Settings:Overworld Spawns", RSK_SHUFFLE_OVERWORLD_SPAWNS }, - { "World Settings:Mixed Entrance Pools", RSK_MIXED_ENTRANCE_POOLS }, - { "World Settings:Mix Dungeons", RSK_MIX_DUNGEON_ENTRANCES }, - { "World Settings:Mix Bosses", RSK_MIX_BOSS_ENTRANCES }, - { "World Settings:Mix Overworld", RSK_MIX_OVERWORLD_ENTRANCES }, - { "World Settings:Mix Interiors", RSK_MIX_INTERIOR_ENTRANCES }, - { "World Settings:Mix Grottos", RSK_MIX_GROTTO_ENTRANCES }, - { "World Settings:Decouple Entrances", RSK_DECOUPLED_ENTRANCES }, - { "Gold Skulltula Tokens", RSK_STARTING_SKULLTULA_TOKEN }, - { "Hearts", RSK_STARTING_HEARTS }, - { "Logic Options:All Locations Reachable", RSK_ALL_LOCATIONS_REACHABLE }, - { "World Settings:Boss Entrances", RSK_SHUFFLE_BOSS_ENTRANCES }, - { "Shuffle Settings:Shuffle 100 GS Reward", RSK_SHUFFLE_100_GS_REWARD }, - { "World Settings:Triforce Hunt", RSK_TRIFORCE_HUNT }, - { "World Settings:Triforce Hunt Total Pieces", RSK_TRIFORCE_HUNT_PIECES_TOTAL }, - { "World Settings:Triforce Hunt Required Pieces", RSK_TRIFORCE_HUNT_PIECES_REQUIRED }, - { "Shuffle Settings:Shuffle Boss Souls", RSK_SHUFFLE_BOSS_SOULS }, - { "Shuffle Settings:Fishsanity", RSK_FISHSANITY }, - { "Shuffle Settings:Pond Fish Count", RSK_FISHSANITY_POND_COUNT }, - { "Shuffle Settings:Split Pond Fish", RSK_FISHSANITY_AGE_SPLIT }, - { "Shuffle Settings:Shuffle Fishing Pole", RSK_SHUFFLE_FISHING_POLE }, - { "Miscellaneous Settings:Infinite Upgrades", RSK_INFINITE_UPGRADES }, - { "Miscellaneous Settings:Skeleton Key", RSK_SKELETON_KEY }, - { "Shuffle Settings:Shuffle Deku Stick Bag", RSK_SHUFFLE_DEKU_STICK_BAG }, - { "Shuffle Settings:Shuffle Deku Nut Bag", RSK_SHUFFLE_DEKU_NUT_BAG }, - }; +std::unordered_map Settings::PopulateOptionNameToEnum(){ + std::unordered_map output = {}; + for (size_t count = 0; count < RSK_MAX; count++) { + output[mOptions[count].GetName()] = static_cast(count); + } + return output; } Option& Settings::GetOption(const RandomizerSettingKey key) { @@ -1467,7 +1310,7 @@ TrickOption& Settings::GetTrickOption(const RandomizerTrick key) { void Settings::ResetTrickOptions() { for (int count = 0; count < RT_MAX; count++){ - mTrickOptions[count].SetSelectedIndex(0); //RANDOTODO this can probably be done better + mTrickOptions[count].SetContextIndex(0); //RANDOTODO this can probably be done better }; } @@ -1561,7 +1404,7 @@ void Settings::UpdateOptionProperties() { } else { mOptionGroups[RSG_AREA_ACCESS_IMGUI].Enable(); // Starting Age - Disabled when Forest is set to Closed or under very specific conditions - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Forest"), RO_FOREST_CLOSED) == RO_FOREST_CLOSED || + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_ON) == RO_CLOSED_FOREST_ON || (CVarGetInteger(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_CLOSED) == RO_DOOROFTIME_CLOSED && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), RO_GENERIC_OFF) == RO_GENERIC_OFF)) /* closed door of time with ocarina shuffle off */ { mOptions[RSK_STARTING_AGE].Disable("This option is disabled due to other options making the game unbeatable"); @@ -1772,22 +1615,78 @@ void Settings::UpdateOptionProperties() { } } - // Show mixed entrance pool options if mixed entrance pools are enabled at all. - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MixedEntrances"), RO_GENERIC_OFF)) { - mOptions[RSK_MIXED_ENTRANCE_POOLS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); - mOptions[RSK_MIX_DUNGEON_ENTRANCES].Unhide(); - mOptions[RSK_MIX_BOSS_ENTRANCES].Unhide(); - mOptions[RSK_MIX_OVERWORLD_ENTRANCES].Unhide(); - mOptions[RSK_MIX_INTERIOR_ENTRANCES].Unhide(); - mOptions[RSK_MIX_GROTTO_ENTRANCES].Unhide(); + int dungeonShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), RO_DUNGEON_ENTRANCE_SHUFFLE_OFF); + int bossShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF); + int overworldShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), RO_GENERIC_OFF); + int interiorShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), RO_GENERIC_OFF); + int grottoShuffle = CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), RO_GENERIC_OFF); + + // Hide Mixed Entrances option if no applicable entrance shuffles are visible + if (!dungeonShuffle && !bossShuffle && !overworldShuffle && !interiorShuffle && !grottoShuffle) { + mOptions[RSK_MIXED_ENTRANCE_POOLS].Hide(); } else { + mOptions[RSK_MIXED_ENTRANCE_POOLS].Unhide(); + } + // Show mixed entrance pool options if mixed entrance pools are enabled, but only the ones that aren't off + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MixedEntrances"), RO_GENERIC_OFF) == RO_GENERIC_OFF || mOptions[RSK_MIXED_ENTRANCE_POOLS].IsHidden()) { mOptions[RSK_MIXED_ENTRANCE_POOLS].AddFlag(IMFLAG_SEPARATOR_BOTTOM); mOptions[RSK_MIX_DUNGEON_ENTRANCES].Hide(); mOptions[RSK_MIX_BOSS_ENTRANCES].Hide(); mOptions[RSK_MIX_OVERWORLD_ENTRANCES].Hide(); mOptions[RSK_MIX_INTERIOR_ENTRANCES].Hide(); mOptions[RSK_MIX_GROTTO_ENTRANCES].Hide(); + } else { + mOptions[RSK_MIXED_ENTRANCE_POOLS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_MIX_DUNGEON_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_MIX_BOSS_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_MIX_OVERWORLD_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_MIX_INTERIOR_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + mOptions[RSK_MIX_GROTTO_ENTRANCES].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); + RandomizerSettingKey lastKey = RSK_MIXED_ENTRANCE_POOLS; + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) == RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) { + mOptions[RSK_MIX_DUNGEON_ENTRANCES].Hide(); + } else { + mOptions[RSK_MIX_DUNGEON_ENTRANCES].Unhide(); + lastKey = RSK_MIX_DUNGEON_ENTRANCES; + } + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) == RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) { + mOptions[RSK_MIX_BOSS_ENTRANCES].Hide(); + } else { + mOptions[RSK_MIX_BOSS_ENTRANCES].Unhide(); + lastKey = RSK_MIX_BOSS_ENTRANCES; + } + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), RO_GENERIC_OFF) == RO_GENERIC_OFF) { + mOptions[RSK_MIX_OVERWORLD_ENTRANCES].Hide(); + } else { + mOptions[RSK_MIX_OVERWORLD_ENTRANCES].Unhide(); + lastKey = RSK_MIX_OVERWORLD_ENTRANCES; + } + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), RO_GENERIC_OFF) == RO_GENERIC_OFF) { + mOptions[RSK_MIX_INTERIOR_ENTRANCES].Hide(); + } else { + mOptions[RSK_MIX_INTERIOR_ENTRANCES].Unhide(); + lastKey = RSK_MIX_INTERIOR_ENTRANCES; + } + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), RO_GENERIC_OFF) == RO_GENERIC_OFF) { + mOptions[RSK_MIX_GROTTO_ENTRANCES].Hide(); + } else { + mOptions[RSK_MIX_GROTTO_ENTRANCES].Unhide(); + lastKey = RSK_MIX_GROTTO_ENTRANCES; + } + mOptions[lastKey].AddFlag(IMFLAG_SEPARATOR_BOTTOM); } + + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), 0)) { + mOptions[RSK_STARTING_STICKS].Disable("Disabled because Shuffle Deku Stick Bag is On"); + } else { + mOptions[RSK_STARTING_STICKS].Enable(); + } + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), 0)) { + mOptions[RSK_STARTING_NUTS].Disable("Disabled because Shuffle Deku Nut Bag is On"); + } else { + mOptions[RSK_STARTING_NUTS].Enable(); + } + // Shuffle Weird Egg - Disabled when Skip Child Zelda is active if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), RO_GENERIC_DONT_SKIP)) { mOptions[RSK_SHUFFLE_WEIRD_EGG].Disable("This option is disabled because \"Skip Child Zelda\" is enabled."); @@ -2031,12 +1930,12 @@ void Settings::UpdateOptionProperties() { default: break; } - const uint8_t maxKeyringCount = (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) == RO_GF_NORMAL && + const uint8_t maxKeyringCount = (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == RO_GF_CARPENTERS_NORMAL && CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) != RO_GERUDO_KEYS_VANILLA) ? 9 : 8; if (mOptions[RSK_KEYRINGS_RANDOM_COUNT].GetOptionCount() != maxKeyringCount + 1) { mOptions[RSK_KEYRINGS_RANDOM_COUNT].ChangeOptions(NumOpts(0, maxKeyringCount)); } - if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoFortress"), RO_GF_NORMAL) != RO_GF_NORMAL || + if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) != RO_GF_CARPENTERS_NORMAL || CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) == RO_GERUDO_KEYS_VANILLA) { mOptions[RSK_KEYRINGS_GERUDO_FORTRESS].Disable("Disabled because the currently selected Gerudo Fortress Carpenters\n" "setting and/or Gerudo Fortress Keys setting is incompatible with\n" @@ -2165,103 +2064,107 @@ void Settings::UpdateOptionProperties() { void Settings::FinalizeSettings(const std::set& excludedLocations, const std::set& enabledTricks) { const auto ctx = Rando::Context::GetInstance(); - if (!ctx->IsSpoilerLoaded()) { - // If we've loaded a spoiler file, the settings have already been populated, so we - // only need to do things like resolve the starting age or determine MQ dungeons. - // Any logic dependent on cvarSettings should go in this if statement - - // if we skip child zelda, we start with zelda's letter, and malon starts - // at the ranch, so we should *not* shuffle the weird egg - if (mOptions[RSK_SKIP_CHILD_ZELDA]) { - mOptions[RSK_SHUFFLE_WEIRD_EGG].SetSelectedIndex(RO_GENERIC_OFF); - } + for (Option& option : mOptions) { + option.SetContextIndex(option.GetMenuOptionIndex()); + } + + // if we skip child zelda, we start with zelda's letter, and malon starts + // at the ranch, so we should *not* shuffle the weird egg + if (mOptions[RSK_SKIP_CHILD_ZELDA]) { + mOptions[RSK_SHUFFLE_WEIRD_EGG].SetContextIndex(RO_GENERIC_OFF); + } - // With certain access settings, the seed is only beatable if Starting Age is set to Child. - if (mOptions[RSK_FOREST].Is(RO_FOREST_CLOSED) || (mOptions[RSK_DOOR_OF_TIME].Is(RO_DOOROFTIME_CLOSED) && - !mOptions[RSK_SHUFFLE_OCARINA])) { - mOptions[RSK_STARTING_AGE].SetSelectedIndex(RO_AGE_CHILD); - } + // With certain access settings, the seed is only beatable if Starting Age is set to Child. + if (mOptions[RSK_FOREST].Is(RO_CLOSED_FOREST_ON) || (mOptions[RSK_DOOR_OF_TIME].Is(RO_DOOROFTIME_CLOSED) && + !mOptions[RSK_SHUFFLE_OCARINA])) { + mOptions[RSK_STARTING_AGE].SetContextIndex(RO_AGE_CHILD); + } - if (mOptions[RSK_TRIFORCE_HUNT]) { - mOptions[RSK_GANONS_BOSS_KEY].SetSelectedIndex(RO_GANON_BOSS_KEY_TRIFORCE_HUNT); - } + if (mOptions[RSK_TRIFORCE_HUNT]) { + mOptions[RSK_GANONS_BOSS_KEY].SetContextIndex(RO_GANON_BOSS_KEY_TRIFORCE_HUNT); + } - // Force 100 GS Shuffle if that's where Ganon's Boss Key is - if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) { - mOptions[RSK_SHUFFLE_100_GS_REWARD].SetSelectedIndex(1); - } + // Force 100 GS Shuffle if that's where Ganon's Boss Key is + if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) { + mOptions[RSK_SHUFFLE_100_GS_REWARD].SetContextIndex(1); + } - // If we only have MQ, set all dungeons to MQ - if (OTRGlobals::Instance->HasMasterQuest() && !OTRGlobals::Instance->HasOriginal()) { - mOptions[RSK_MQ_DUNGEON_RANDOM].SetSelectedIndex(RO_MQ_DUNGEONS_SET_NUMBER); - mOptions[RSK_MQ_DUNGEON_COUNT].SetSelectedIndex(12); - mOptions[RSK_MQ_DUNGEON_SET].SetSelectedIndex(RO_GENERIC_OFF); - } + // If we only have MQ, set all dungeons to MQ + if (OTRGlobals::Instance->HasMasterQuest() && !OTRGlobals::Instance->HasOriginal()) { + mOptions[RSK_MQ_DUNGEON_RANDOM].SetContextIndex(RO_MQ_DUNGEONS_SET_NUMBER); + mOptions[RSK_MQ_DUNGEON_COUNT].SetContextIndex(12); + mOptions[RSK_MQ_DUNGEON_SET].SetContextIndex(RO_GENERIC_OFF); + } - // If we don't have MQ, set all dungeons to Vanilla - if (OTRGlobals::Instance->HasOriginal() && !OTRGlobals::Instance->HasMasterQuest()) { - mOptions[RSK_MQ_DUNGEON_RANDOM].SetSelectedIndex(RO_MQ_DUNGEONS_NONE); - } + // If we don't have MQ, set all dungeons to Vanilla + if (OTRGlobals::Instance->HasOriginal() && !OTRGlobals::Instance->HasMasterQuest()) { + mOptions[RSK_MQ_DUNGEON_RANDOM].SetContextIndex(RO_MQ_DUNGEONS_NONE); + } - if (mOptions[RSK_MQ_DUNGEON_RANDOM].Is(RO_MQ_DUNGEONS_NONE)) { - mOptions[RSK_MQ_DUNGEON_COUNT].SetSelectedIndex(0); - mOptions[RSK_MQ_DUNGEON_SET].SetSelectedIndex(RO_GENERIC_OFF); - } + if (mOptions[RSK_MQ_DUNGEON_RANDOM].Is(RO_MQ_DUNGEONS_NONE)) { + mOptions[RSK_MQ_DUNGEON_COUNT].SetContextIndex(0); + mOptions[RSK_MQ_DUNGEON_SET].SetContextIndex(RO_GENERIC_OFF); + } - // If any of the individual shuffle settings are on, turn on the main Shuffle Entrances option - if (mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES].IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) - || mOptions[RSK_SHUFFLE_BOSS_ENTRANCES].IsNot(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) - || mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES] - || mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES].IsNot(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF) - || mOptions[RSK_SHUFFLE_GROTTO_ENTRANCES] || mOptions[RSK_SHUFFLE_OWL_DROPS] - || mOptions[RSK_SHUFFLE_WARP_SONGS] || mOptions[RSK_SHUFFLE_OVERWORLD_SPAWNS]) { - mOptions[RSK_SHUFFLE_ENTRANCES].SetSelectedIndex(RO_GENERIC_ON); + // If any of the individual shuffle settings are on, turn on the main Shuffle Entrances option + if (mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES].IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF) + || mOptions[RSK_SHUFFLE_BOSS_ENTRANCES].IsNot(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) + || mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES] + || mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES].IsNot(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF) + || mOptions[RSK_SHUFFLE_GROTTO_ENTRANCES] || mOptions[RSK_SHUFFLE_OWL_DROPS] + || mOptions[RSK_SHUFFLE_WARP_SONGS] || mOptions[RSK_SHUFFLE_OVERWORLD_SPAWNS]) { + mOptions[RSK_SHUFFLE_ENTRANCES].SetContextIndex(RO_GENERIC_ON); + } else { + mOptions[RSK_SHUFFLE_ENTRANCES].SetContextIndex(RO_GENERIC_OFF); + } + + if (mOptions[RSK_SHUFFLE_DUNGEON_REWARDS].Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { + mOptions[RSK_LINKS_POCKET].SetContextIndex(RO_LINKS_POCKET_DUNGEON_REWARD); + } + + ctx->AddExcludedOptions(); + for (const auto locationKey : ctx->everyPossibleLocation) { + if (const auto location = ctx->GetItemLocation(locationKey); excludedLocations.contains(location->GetRandomizerCheck())) { + location->GetExcludedOption()->SetContextIndex(1); } else { - mOptions[RSK_SHUFFLE_ENTRANCES].SetSelectedIndex(RO_GENERIC_OFF); + location->GetExcludedOption()->SetContextIndex(0); } - - if (mOptions[RSK_SHUFFLE_DUNGEON_REWARDS].Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { - mOptions[RSK_LINKS_POCKET].SetSelectedIndex(RO_LINKS_POCKET_DUNGEON_REWARD); + } + // Tricks + ResetTrickOptions(); + for (const auto randomizerTrick : enabledTricks) { + mTrickOptions[randomizerTrick].SetContextIndex(1); + } + if (!mOptions[RSK_SHUFFLE_KOKIRI_SWORD]) { + if (mOptions[RSK_STARTING_KOKIRI_SWORD]) { + ctx->GetItemLocation(RC_KF_KOKIRI_SWORD_CHEST)->GetExcludedOption()->SetContextIndex(1); } - - if (!ctx->IsSpoilerLoaded()) { - ctx->AddExcludedOptions(); - for (const auto locationKey : ctx->everyPossibleLocation) { - if (const auto location = ctx->GetItemLocation(locationKey); excludedLocations.contains(location->GetRandomizerCheck())) { - location->GetExcludedOption()->SetSelectedIndex(1); - } else { - location->GetExcludedOption()->SetSelectedIndex(0); - } - } - // Tricks - ResetTrickOptions(); - for (const auto randomizerTrick : enabledTricks) { - mTrickOptions[randomizerTrick].SetSelectedIndex(1); - } + } + if (!mOptions[RSK_SHUFFLE_MASTER_SWORD]) { + if (mOptions[RSK_STARTING_MASTER_SWORD]) { + ctx->GetItemLocation(RC_MASTER_SWORD_PEDESTAL)->GetExcludedOption()->SetContextIndex(1); } - if (!mOptions[RSK_SHUFFLE_KOKIRI_SWORD]) { - if (mOptions[RSK_STARTING_KOKIRI_SWORD]) { - ctx->GetItemLocation(RC_KF_KOKIRI_SWORD_CHEST)->GetExcludedOption()->SetSelectedIndex(1); - } - } - if (!mOptions[RSK_SHUFFLE_MASTER_SWORD]) { - if (mOptions[RSK_STARTING_MASTER_SWORD]) { - ctx->GetItemLocation(RC_MASTER_SWORD_PEDESTAL)->GetExcludedOption()->SetSelectedIndex(1); - } - } - if (!mOptions[RSK_SHUFFLE_OCARINA]) { - if (mOptions[RSK_STARTING_OCARINA].IsNot(RO_STARTING_OCARINA_OFF)) { - ctx->GetItemLocation(RC_LW_GIFT_FROM_SARIA)->GetExcludedOption()->SetSelectedIndex(1); - if (mOptions[RSK_STARTING_OCARINA].Is(RO_STARTING_OCARINA_TIME)) { - ctx->GetItemLocation(RC_HF_OCARINA_OF_TIME_ITEM)->GetExcludedOption()->SetSelectedIndex(1); - } + } + if (!mOptions[RSK_SHUFFLE_OCARINA]) { + if (mOptions[RSK_STARTING_OCARINA].IsNot(RO_STARTING_OCARINA_OFF)) { + ctx->GetItemLocation(RC_LW_GIFT_FROM_SARIA)->GetExcludedOption()->SetContextIndex(1); + if (mOptions[RSK_STARTING_OCARINA].Is(RO_STARTING_OCARINA_TIME)) { + ctx->GetItemLocation(RC_HF_OCARINA_OF_TIME_ITEM)->GetExcludedOption()->SetContextIndex(1); } } } + + + if (mOptions[RSK_SHUFFLE_DEKU_STICK_BAG]) { + mOptions[RSK_STARTING_STICKS].SetContextIndex(false); + } + if (mOptions[RSK_SHUFFLE_DEKU_NUT_BAG]) { + mOptions[RSK_STARTING_NUTS].SetContextIndex(false); + } // RANDOTODO implement chest shuffle with keysanity - // ShuffleChestMinigame.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_CHEST_MINIGAME]); - mOptions[RSK_SHUFFLE_CHEST_MINIGAME].SetSelectedIndex(RO_CHEST_GAME_OFF); + // ShuffleChestMinigame.SetContextIndex(cvarSettings[RSK_SHUFFLE_CHEST_MINIGAME]); + mOptions[RSK_SHUFFLE_CHEST_MINIGAME].SetContextIndex(RO_CHEST_GAME_OFF); //TODO: RandomizeAllSettings(true) when implementing the ability to randomize the options themselves. std::array dungeons = ctx->GetDungeons()->GetDungeonList(); @@ -2272,12 +2175,12 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio dungeon->SetDungeonKnown(true); } //if it's selection mode, process the selection directly - if (mOptions[RSK_MQ_DUNGEON_RANDOM].Value() == RO_MQ_DUNGEONS_SELECTION){ - mOptions[RSK_MQ_DUNGEON_SET].SetSelectedIndex(RO_GENERIC_ON); + if (mOptions[RSK_MQ_DUNGEON_RANDOM].GetContextOptionIndex() == RO_MQ_DUNGEONS_SELECTION){ + mOptions[RSK_MQ_DUNGEON_SET].SetContextIndex(RO_GENERIC_ON); //How many dungeons are set to MQ in selection uint8_t mqSet = 0; for (auto dungeon: dungeons) { - switch (mOptions[dungeon->GetMQSetting()].Value()) { + switch (mOptions[dungeon->GetMQSetting()].GetContextOptionIndex()) { case RO_MQ_SET_MQ: dungeon->SetMQ(); mqSet += 1; @@ -2296,11 +2199,11 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio } } //override the dungeons set with the ones set by selection, so it's accurate for anything that wants to know MQ dungeon count - mOptions[RSK_MQ_DUNGEON_COUNT].SetSelectedIndex(mqSet); + mOptions[RSK_MQ_DUNGEON_COUNT].SetContextIndex(mqSet); //handling set number and random number together - } else if (mOptions[RSK_MQ_DUNGEON_RANDOM].Value() != RO_MQ_DUNGEONS_NONE){ + } else if (mOptions[RSK_MQ_DUNGEON_RANDOM].GetContextOptionIndex() != RO_MQ_DUNGEONS_NONE){ // so we don't have to call this repeatedly - uint8_t mqCount = mOptions[RSK_MQ_DUNGEON_COUNT].Value(); + uint8_t mqCount = mOptions[RSK_MQ_DUNGEON_COUNT].GetContextOptionIndex(); //How many dungeons are set to MQ in selection uint8_t mqSet = 0; //the number of random @@ -2310,7 +2213,7 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio //if dungeons have been preset, process them if (mOptions[RSK_MQ_DUNGEON_SET]){ for (size_t i = 0; i < dungeons.size(); i++) { - switch (mOptions[dungeons[i]->GetMQSetting()].Value()) { + switch (mOptions[dungeons[i]->GetMQSetting()].GetContextOptionIndex()) { case RO_MQ_SET_MQ: dungeons[i]->SetMQ(); mqSet += 1; @@ -2326,22 +2229,22 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio //otherwise, every dungeon is possible } else { //if the count is fixed to 12, we know everything is MQ, so can skip some setps and do not set Known - if (mOptions[RSK_MQ_DUNGEON_RANDOM].Value() == RO_MQ_DUNGEONS_SET_NUMBER && + if (mOptions[RSK_MQ_DUNGEON_RANDOM].GetContextOptionIndex() == RO_MQ_DUNGEONS_SET_NUMBER && mqCount == 12) { randMQOption = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; for (auto dungeon: dungeons) { - mOptions[dungeon->GetMQSetting()].SetSelectedIndex(RO_MQ_SET_MQ); + mOptions[dungeon->GetMQSetting()].SetContextIndex(RO_MQ_SET_MQ); } //if it's fixed to zero, set it to None instead. the rest is processed after - } else if (mOptions[RSK_MQ_DUNGEON_RANDOM].Value() == RO_MQ_DUNGEONS_SET_NUMBER && + } else if (mOptions[RSK_MQ_DUNGEON_RANDOM].GetContextOptionIndex() == RO_MQ_DUNGEONS_SET_NUMBER && mqCount == 0){ - mOptions[RSK_MQ_DUNGEON_RANDOM].SetSelectedIndex(RO_MQ_DUNGEONS_NONE); + mOptions[RSK_MQ_DUNGEON_RANDOM].SetContextIndex(RO_MQ_DUNGEONS_NONE); //otherwise, make everything a possibility and unknown } else { for (size_t i = 0; i < dungeons.size(); i++) { randMQOption.push_back(i); dungeons[i]->SetDungeonKnown(false); - mOptions[dungeons[i]->GetMQSetting()].SetSelectedIndex(RO_MQ_SET_RANDOM); + mOptions[dungeons[i]->GetMQSetting()].SetContextIndex(RO_MQ_SET_RANDOM); } } } @@ -2363,20 +2266,20 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio } else { //if there's no random options, check if we can collapse the setting into None or Selection if (mqSet == 0){ - mOptions[RSK_MQ_DUNGEON_RANDOM].SetSelectedIndex(RO_MQ_DUNGEONS_NONE); + mOptions[RSK_MQ_DUNGEON_RANDOM].SetContextIndex(RO_MQ_DUNGEONS_NONE); } else { - mOptions[RSK_MQ_DUNGEON_RANDOM].SetSelectedIndex(RO_MQ_DUNGEONS_SELECTION); + mOptions[RSK_MQ_DUNGEON_RANDOM].SetContextIndex(RO_MQ_DUNGEONS_SELECTION); } } //reset the value set based on what was actually set - mOptions[RSK_MQ_DUNGEON_COUNT].SetSelectedIndex(mqToSet + mqSet); + mOptions[RSK_MQ_DUNGEON_COUNT].SetContextIndex(mqToSet + mqSet); } //Not an if else as other settings can become None in processing - if (mOptions[RSK_MQ_DUNGEON_RANDOM].Value() == RO_MQ_DUNGEONS_NONE) { - mOptions[RSK_MQ_DUNGEON_SET].SetSelectedIndex(RO_GENERIC_OFF); - mOptions[RSK_MQ_DUNGEON_COUNT].SetSelectedIndex(0); + if (mOptions[RSK_MQ_DUNGEON_RANDOM].GetContextOptionIndex() == RO_MQ_DUNGEONS_NONE) { + mOptions[RSK_MQ_DUNGEON_SET].SetContextIndex(RO_GENERIC_OFF); + mOptions[RSK_MQ_DUNGEON_COUNT].SetContextIndex(0); for (auto dungeon: dungeons) { - mOptions[dungeon->GetMQSetting()].SetSelectedIndex(RO_MQ_SET_VANILLA); + mOptions[dungeon->GetMQSetting()].SetContextIndex(RO_MQ_SET_VANILLA); } } @@ -2399,19 +2302,19 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio if (mOptions[RSK_KEYRINGS]) { // Random Key Rings auto keyrings = keyRingOptions; - if (mOptions[RSK_GERUDO_FORTRESS].Is(RO_GF_NORMAL) && mOptions[RSK_GERUDO_KEYS].IsNot(RO_GERUDO_KEYS_VANILLA)) { + if (mOptions[RSK_GERUDO_FORTRESS].Is(RO_GF_CARPENTERS_NORMAL) && mOptions[RSK_GERUDO_KEYS].IsNot(RO_GERUDO_KEYS_VANILLA)) { keyrings.push_back(&mOptions[RSK_KEYRINGS_GERUDO_FORTRESS]); } else { - mOptions[RSK_KEYRINGS_GERUDO_FORTRESS].SetSelectedIndex(RO_KEYRING_FOR_DUNGEON_OFF); + mOptions[RSK_KEYRINGS_GERUDO_FORTRESS].SetContextIndex(RO_KEYRING_FOR_DUNGEON_OFF); } if (mOptions[RSK_KEYRINGS].Is(RO_KEYRINGS_RANDOM) || mOptions[RSK_KEYRINGS].Is(RO_KEYRINGS_COUNT)) { - const uint32_t keyRingCount = mOptions[RSK_KEYRINGS].Is(RO_KEYRINGS_COUNT) ? mOptions[RSK_KEYRINGS_RANDOM_COUNT].Value() : Random(0, static_cast(keyrings.size())); + const uint32_t keyRingCount = mOptions[RSK_KEYRINGS].Is(RO_KEYRINGS_COUNT) ? mOptions[RSK_KEYRINGS_RANDOM_COUNT].GetContextOptionIndex() : Random(0, static_cast(keyrings.size())); Shuffle(keyrings); for (size_t i = 0; i < keyRingCount; i++) { - keyrings[i]->SetSelectedIndex(RO_KEYRING_FOR_DUNGEON_ON); + keyrings[i]->SetContextIndex(RO_KEYRING_FOR_DUNGEON_ON); } for (size_t i = keyRingCount; i < keyrings.size(); i++) { - keyrings[i]->SetSelectedIndex(RO_KEYRING_FOR_DUNGEON_OFF); + keyrings[i]->SetContextIndex(RO_KEYRING_FOR_DUNGEON_OFF); } } if (mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Is(RO_KEYRING_FOR_DUNGEON_ON) || (mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { @@ -2433,7 +2336,7 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio ctx->GetDungeon(SHADOW_TEMPLE)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_GTG].Is(RO_KEYRING_FOR_DUNGEON_ON) || (mOptions[RSK_KEYRINGS_GTG].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { - ctx->GetDungeon(GERUDO_TRAINING_GROUNDS)->SetKeyRing(); + ctx->GetDungeon(GERUDO_TRAINING_GROUND)->SetKeyRing(); } if (mOptions[RSK_KEYRINGS_GANONS_CASTLE].Is(RO_KEYRING_FOR_DUNGEON_ON) || (mOptions[RSK_KEYRINGS_GANONS_CASTLE].Is(RO_KEYRING_FOR_DUNGEON_RANDOM) && Random(0, 2) == 1)) { ctx->GetDungeon(GANONS_CASTLE)->SetKeyRing(); @@ -2446,19 +2349,19 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio trial->SetAsSkipped(); } if(mOptions[RSK_GANONS_TRIALS].Is(RO_GANONS_TRIALS_SKIP)){ - mOptions[RSK_TRIAL_COUNT].SetSelectedIndex(0); + mOptions[RSK_TRIAL_COUNT].SetContextIndex(0); } else if(mOptions[RSK_GANONS_TRIALS].Is(RO_GANONS_TRIALS_RANDOM_NUMBER)) { - mOptions[RSK_TRIAL_COUNT].SetSelectedIndex(Random(0, static_cast(mOptions[RSK_TRIAL_COUNT].GetOptionCount()))); + mOptions[RSK_TRIAL_COUNT].SetContextIndex(Random(0, static_cast(mOptions[RSK_TRIAL_COUNT].GetOptionCount()))); } - for (uint8_t i = 0; i < mOptions[RSK_TRIAL_COUNT].Value(); i++) { + for (uint8_t i = 0; i < mOptions[RSK_TRIAL_COUNT].GetContextOptionIndex(); i++) { trials[i]->SetAsRequired(); } - if (mOptions[RSK_FOREST].Is(RO_FOREST_CLOSED) && + if (mOptions[RSK_FOREST].Is(RO_CLOSED_FOREST_ON) && (mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES].Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL) || mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES] || mOptions[RSK_SHUFFLE_OVERWORLD_SPAWNS] || mOptions[RSK_DECOUPLED_ENTRANCES] || mOptions[RSK_MIXED_ENTRANCE_POOLS])) { - mOptions[RSK_FOREST].SetSelectedIndex(RO_FOREST_CLOSED_DEKU); + mOptions[RSK_FOREST].SetContextIndex(RO_CLOSED_FOREST_DEKU_ONLY); } if (mOptions[RSK_STARTING_AGE].Is(RO_AGE_RANDOM)) { @@ -2468,7 +2371,7 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio mResolvedStartingAge = RO_AGE_ADULT; } } else { - mResolvedStartingAge = static_cast(mOptions[RSK_STARTING_AGE].Value()); + mResolvedStartingAge = static_cast(mOptions[RSK_STARTING_AGE].GetContextOptionIndex()); } // TODO: Random Starting Time @@ -2489,35 +2392,35 @@ void Settings::FinalizeSettings(const std::set& excludedLocatio if (mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_VANILLA)) { for (Option* setting : VanillaLogicDefaults) { - setting->SetDelayedOption(); - setting->SetSelectedIndex(0); + //setting->SetDelayedOption(); + setting->SetContextIndex(0); } - mOptions[RSK_KEYSANITY].SetDelayedOption(); - mOptions[RSK_KEYSANITY].SetSelectedIndex(3); + //mOptions[RSK_KEYSANITY].SetDelayedOption(); + mOptions[RSK_KEYSANITY].SetContextIndex(3); } if (!mOptions[RSK_SHUFFLE_WARP_SONGS]) { - mOptions[RSK_WARP_SONG_HINTS].SetSelectedIndex(RO_GENERIC_OFF); + mOptions[RSK_WARP_SONG_HINTS].SetContextIndex(RO_GENERIC_OFF); } if (!mOptions[RSK_SHUFFLE_COWS]) { - mOptions[RSK_MALON_HINT].SetSelectedIndex(RO_GENERIC_OFF); + mOptions[RSK_MALON_HINT].SetContextIndex(RO_GENERIC_OFF); } if (!mOptions[RSK_SHUFFLE_100_GS_REWARD]) { - mOptions[RSK_KAK_100_SKULLS_HINT].SetSelectedIndex(RO_GENERIC_OFF); + mOptions[RSK_KAK_100_SKULLS_HINT].SetContextIndex(RO_GENERIC_OFF); } if (!mOptions[RSK_SHUFFLE_FISHING_POLE]) { - mOptions[RSK_FISHING_POLE_HINT].SetSelectedIndex(RO_GENERIC_OFF); + mOptions[RSK_FISHING_POLE_HINT].SetContextIndex(RO_GENERIC_OFF); } if (mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_HYRULE_LOACH)) { - mOptions[RSK_LOACH_HINT].SetSelectedIndex(RO_GENERIC_OFF); + mOptions[RSK_LOACH_HINT].SetContextIndex(RO_GENERIC_OFF); } if (mOptions[RSK_CUCCO_COUNT].Is(0)) { - mOptions[RSK_CHICKENS_HINT].SetSelectedIndex(RO_GENERIC_OFF); + mOptions[RSK_CHICKENS_HINT].SetContextIndex(RO_GENERIC_OFF); } } void Settings::ParseJson(nlohmann::json spoilerFileJson) { @@ -2526,611 +2429,10 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) { nlohmann::json settingsJson = spoilerFileJson["settings"]; for (auto it = settingsJson.begin(); it != settingsJson.end(); ++it) { // todo load into cvars for UI - - if (mSpoilerfileSettingNameToEnum.contains(it.key())) { - std::string numericValueString; - // this is annoying but the same strings are used in different orders - // and i don't want the spoilerfile to just have numbers instead of - // human readable settings values so it'll have to do for now - switch (const RandomizerSettingKey index = mSpoilerfileSettingNameToEnum[it.key()]) { - case RSK_LOGIC_RULES: - if (it.value() == "Glitchless") { - mOptions[index].SetSelectedIndex(RO_LOGIC_GLITCHLESS); - } else if (it.value() == "No Logic") { - mOptions[index].SetSelectedIndex(RO_LOGIC_NO_LOGIC); - } else if (it.value() == "Vanilla") { - mOptions[index].SetSelectedIndex(RO_LOGIC_VANILLA); - } - break; - case RSK_FOREST: - if (it.value() == "Closed") { - mOptions[index].SetSelectedIndex(RO_FOREST_CLOSED); - } else if (it.value() == "Open") { - mOptions[index].SetSelectedIndex(RO_FOREST_OPEN); - } else if (it.value() == "Closed Deku") { - mOptions[index].SetSelectedIndex(RO_FOREST_CLOSED_DEKU); - } - break; - case RSK_KAK_GATE: - if (it.value() == "Closed") { - mOptions[index].SetSelectedIndex(RO_KAK_GATE_CLOSED); - } else if (it.value() == "Open") { - mOptions[index].SetSelectedIndex(RO_KAK_GATE_OPEN); - } - break; - case RSK_DOOR_OF_TIME: - if (it.value() == "Open") { - mOptions[index].SetSelectedIndex(RO_DOOROFTIME_OPEN); - } else if (it.value() == "Song only") { - mOptions[index].SetSelectedIndex(RO_DOOROFTIME_SONGONLY); - } else if (it.value() == "Closed") { - mOptions[index].SetSelectedIndex(RO_DOOROFTIME_CLOSED); - } - break; - case RSK_ZORAS_FOUNTAIN: - if (it.value() == "Closed") { - mOptions[index].SetSelectedIndex(RO_ZF_CLOSED); - } else if (it.value() == "Closed as child") { - mOptions[index].SetSelectedIndex(RO_ZF_CLOSED_CHILD); - } else if (it.value() == "Open") { - mOptions[index].SetSelectedIndex(RO_ZF_OPEN); - } - break; - case RSK_STARTING_AGE: - if (it.value() == "Child") { - mOptions[index].SetSelectedIndex(RO_AGE_CHILD); - } else if (it.value() == "Adult") { - mOptions[index].SetSelectedIndex(RO_AGE_ADULT); - } - break; - case RSK_GERUDO_FORTRESS: - if (it.value() == "Normal") { - mOptions[index].SetSelectedIndex(RO_GF_NORMAL); - } else if (it.value() == "Fast") { - mOptions[index].SetSelectedIndex(RO_GF_FAST); - } else if (it.value() == "Open") { - mOptions[index].SetSelectedIndex(RO_GF_OPEN); - } - break; - case RSK_RAINBOW_BRIDGE: - if (it.value() == "Vanilla") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_VANILLA); - } else if (it.value() == "Always open") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_ALWAYS_OPEN); - } else if (it.value() == "Stones") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_STONES); - } else if (it.value() == "Medallions") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_MEDALLIONS); - } else if (it.value() == "Dungeon rewards") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_DUNGEON_REWARDS); - } else if (it.value() == "Dungeons") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_DUNGEONS); - } else if (it.value() == "Tokens") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_TOKENS); - } else if (it.value() == "Greg") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_GREG); - } - break; - case RSK_BRIDGE_OPTIONS: - if (it.value() == "Standard Rewards") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_STANDARD_REWARD); - } else if (it.value() == "Greg as Reward") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_GREG_REWARD); - } else if (it.value() == "Greg as Wildcard") { - mOptions[index].SetSelectedIndex(RO_BRIDGE_WILDCARD_REWARD); - } - break; - case RSK_LACS_OPTIONS: - if (it.value() == "Standard Reward") { - mOptions[index].SetSelectedIndex(RO_LACS_STANDARD_REWARD); - } else if (it.value() == "Greg as Reward") { - mOptions[index].SetSelectedIndex(RO_LACS_GREG_REWARD); - } else if (it.value() == "Greg as Wildcard") { - mOptions[index].SetSelectedIndex(RO_LACS_WILDCARD_REWARD); - } - break; - case RSK_DAMAGE_MULTIPLIER: - if (it.value() == "x1/2") { - mOptions[index].SetSelectedIndex(RO_DAMAGE_MULTIPLIER_HALF); - } else if (it.value() == "x1") { - mOptions[index].SetSelectedIndex(RO_DAMAGE_MULTIPLIER_DEFAULT); - } else if (it.value() == "x2") { - mOptions[index].SetSelectedIndex(RO_DAMAGE_MULTIPLIER_DOUBLE); - } else if (it.value() == "x4") { - mOptions[index].SetSelectedIndex(RO_DAMAGE_MULTIPLIER_QUADRUPLE); - } else if (it.value() == "x8") { - mOptions[index].SetSelectedIndex(RO_DAMAGE_MULTIPLIER_OCTUPLE); - } else if (it.value() == "x16") { - mOptions[index].SetSelectedIndex(RO_DAMAGE_MULTIPLIER_SEXDECUPLE); - } else if (it.value() == "OHKO") { - mOptions[index].SetSelectedIndex(RO_DAMAGE_MULTIPLIER_OHKO); - } - break; - case RSK_RAINBOW_BRIDGE_STONE_COUNT: - case RSK_RAINBOW_BRIDGE_MEDALLION_COUNT: - case RSK_RAINBOW_BRIDGE_REWARD_COUNT: - case RSK_RAINBOW_BRIDGE_DUNGEON_COUNT: - case RSK_RAINBOW_BRIDGE_TOKEN_COUNT: - case RSK_TRIAL_COUNT: - case RSK_LACS_STONE_COUNT: - case RSK_LACS_MEDALLION_COUNT: - case RSK_LACS_REWARD_COUNT: - case RSK_LACS_DUNGEON_COUNT: - case RSK_LACS_TOKEN_COUNT: - case RSK_KEYRINGS_RANDOM_COUNT: - case RSK_CUCCO_COUNT: - case RSK_FISHSANITY_POND_COUNT: - case RSK_STARTING_SKULLTULA_TOKEN: - case RSK_SHOPSANITY_COUNT: - numericValueString = it.value(); - mOptions[index].SetSelectedIndex(std::stoi(numericValueString)); - break; - // Same as the above section, but the indexes are off by one from the text - // (i.e. 10 Big Poes is index 9). - case RSK_BIG_POE_COUNT: - case RSK_TRIFORCE_HUNT_PIECES_TOTAL: - case RSK_TRIFORCE_HUNT_PIECES_REQUIRED: - case RSK_STARTING_HEARTS: - numericValueString = it.value(); - mOptions[index].SetSelectedIndex(std::stoi(numericValueString) - 1); - break; - case RSK_GANONS_TRIALS: - if (it.value() == "Skip") { - mOptions[index].SetSelectedIndex(RO_GANONS_TRIALS_SKIP); - } else if (it.value() == "Set Number") { - mOptions[index].SetSelectedIndex(RO_GANONS_TRIALS_SET_NUMBER); - } else if (it.value() == "Random Number") { - mOptions[index].SetSelectedIndex(RO_GANONS_TRIALS_RANDOM_NUMBER); - } - case RSK_SHOPSANITY: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_SHOPSANITY_OFF); - } else if (it.value() == "Specific Count") { - mOptions[index].SetSelectedIndex(RO_SHOPSANITY_SPECIFIC_COUNT); - } else if (it.value() == "Random") { - mOptions[index].SetSelectedIndex(RO_SHOPSANITY_RANDOM); - } - break; - case RSK_SHOPSANITY_PRICES: - case RSK_SCRUBS_PRICES: - case RSK_MERCHANT_PRICES: - if (it.value() == "Vanilla") { - mOptions[index].SetSelectedIndex(RO_PRICE_VANILLA); - } else if (it.value() == "Cheap Balanced") { - mOptions[index].SetSelectedIndex(RO_PRICE_CHEAP_BALANCED); - } else if (it.value() == "Balanced") { - mOptions[index].SetSelectedIndex(RO_PRICE_BALANCED); - } else if (it.value() == "Fixed") { - mOptions[index].SetSelectedIndex(RO_PRICE_FIXED); - } else if (it.value() == "Range") { - mOptions[index].SetSelectedIndex(RO_PRICE_RANGE); - } else if (it.value() == "Set By Wallet") { - mOptions[index].SetSelectedIndex(RO_PRICE_SET_BY_WALLET); - } - break; - case RSK_SHUFFLE_SCRUBS: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_SCRUBS_OFF); - } else if (it.value() == "Major Items Only") { - mOptions[index].SetSelectedIndex(RO_SCRUBS_MAJOR_ONLY); - } else if (it.value() == "All") { - mOptions[index].SetSelectedIndex(RO_SCRUBS_ALL); - } - break; - case RSK_SHUFFLE_FISHING_POLE: - case RSK_FISHSANITY_AGE_SPLIT: - case RSK_FISHING_POLE_HINT: - case RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD: - case RSK_SHUFFLE_BEEHIVES: - case RSK_SHUFFLE_COWS: - case RSK_SHUFFLE_ADULT_TRADE: - case RSK_SHUFFLE_KOKIRI_SWORD: - case RSK_SHUFFLE_WEIRD_EGG: - case RSK_SHUFFLE_FROG_SONG_RUPEES: - case RSK_SHUFFLE_100_GS_REWARD: - case RSK_SHUFFLE_OCARINA: - case RSK_SHUFFLE_OCARINA_BUTTONS: - case RSK_SHUFFLE_SWIM: - case RSK_SHUFFLE_CHILD_WALLET: - case RSK_INCLUDE_TYCOON_WALLET: - case RSK_STARTING_DEKU_SHIELD: - case RSK_STARTING_KOKIRI_SWORD: - case RSK_STARTING_ZELDAS_LULLABY: - case RSK_STARTING_EPONAS_SONG: - case RSK_STARTING_SARIAS_SONG: - case RSK_STARTING_SUNS_SONG: - case RSK_STARTING_SONG_OF_TIME: - case RSK_STARTING_SONG_OF_STORMS: - case RSK_STARTING_MINUET_OF_FOREST: - case RSK_STARTING_BOLERO_OF_FIRE: - case RSK_STARTING_SERENADE_OF_WATER: - case RSK_STARTING_REQUIEM_OF_SPIRIT: - case RSK_STARTING_NOCTURNE_OF_SHADOW: - case RSK_STARTING_PRELUDE_OF_LIGHT: - case RSK_COMPLETE_MASK_QUEST: - case RSK_SKIP_SCARECROWS_SONG: - case RSK_ENABLE_GLITCH_CUTSCENES: - case RSK_SKULLS_SUNS_SONG: - case RSK_BLUE_FIRE_ARROWS: - case RSK_SUNLIGHT_ARROWS: - case RSK_INFINITE_UPGRADES: - case RSK_SKELETON_KEY: - case RSK_BOMBCHUS_IN_LOGIC: - case RSK_TOT_ALTAR_HINT: - case RSK_GANONDORF_HINT: - case RSK_SHEIK_LA_HINT: - case RSK_DAMPES_DIARY_HINT: - case RSK_GREG_HINT: - case RSK_LOACH_HINT: - case RSK_SARIA_HINT: - case RSK_FROGS_HINT: - case RSK_OOT_HINT: - case RSK_KAK_10_SKULLS_HINT: - case RSK_KAK_20_SKULLS_HINT: - case RSK_KAK_30_SKULLS_HINT: - case RSK_KAK_40_SKULLS_HINT: - case RSK_KAK_50_SKULLS_HINT: - case RSK_KAK_100_SKULLS_HINT: - case RSK_MASK_SHOP_HINT: - case RSK_BIGGORON_HINT: - case RSK_BIG_POES_HINT: - case RSK_CHICKENS_HINT: - case RSK_MALON_HINT: - case RSK_HBA_HINT: - case RSK_WARP_SONG_HINTS: - case RSK_SCRUB_TEXT_HINT: - case RSK_MERCHANT_TEXT_HINT: - case RSK_SHUFFLE_ENTRANCES: - case RSK_SHUFFLE_OVERWORLD_ENTRANCES: - case RSK_SHUFFLE_GROTTO_ENTRANCES: - case RSK_SHUFFLE_OWL_DROPS: - case RSK_SHUFFLE_WARP_SONGS: - case RSK_SHUFFLE_OVERWORLD_SPAWNS: - case RSK_MIXED_ENTRANCE_POOLS: - case RSK_MIX_DUNGEON_ENTRANCES: - case RSK_MIX_BOSS_ENTRANCES: - case RSK_MIX_OVERWORLD_ENTRANCES: - case RSK_MIX_INTERIOR_ENTRANCES: - case RSK_MIX_GROTTO_ENTRANCES: - case RSK_DECOUPLED_ENTRANCES: - case RSK_SHOPSANITY_PRICES_AFFORDABLE: - case RSK_SCRUBS_PRICES_AFFORDABLE: - case RSK_MERCHANT_PRICES_AFFORDABLE: - case RSK_ALL_LOCATIONS_REACHABLE: - case RSK_TRIFORCE_HUNT: - case RSK_MQ_DUNGEON_SET: - case RSK_SHUFFLE_DEKU_NUT_BAG: - case RSK_SHUFFLE_DEKU_STICK_BAG: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_GENERIC_OFF); - } else if (it.value() == "On") { - mOptions[index].SetSelectedIndex(RO_GENERIC_ON); - } - break; - case RSK_KEYRINGS: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_KEYRINGS_OFF); - } else if (it.value() == "Random") { - mOptions[index].SetSelectedIndex(RO_KEYRINGS_RANDOM); - } else if (it.value() == "Count") { - mOptions[index].SetSelectedIndex(RO_KEYRINGS_COUNT); - } else if (it.value() == "Selection") { - mOptions[index].SetSelectedIndex(RO_KEYRINGS_SELECTION); - } - break; - case RSK_KEYRINGS_GERUDO_FORTRESS: - case RSK_KEYRINGS_FOREST_TEMPLE: - case RSK_KEYRINGS_FIRE_TEMPLE: - case RSK_KEYRINGS_WATER_TEMPLE: - case RSK_KEYRINGS_SHADOW_TEMPLE: - case RSK_KEYRINGS_SPIRIT_TEMPLE: - case RSK_KEYRINGS_BOTTOM_OF_THE_WELL: - case RSK_KEYRINGS_GTG: - case RSK_KEYRINGS_GANONS_CASTLE: - if (it.value() == "No") { - mOptions[index].SetSelectedIndex(RO_KEYRING_FOR_DUNGEON_OFF); - } else if (it.value() == "Random") { - mOptions[index].SetSelectedIndex(RO_KEYRING_FOR_DUNGEON_RANDOM); - } else if (it.value() == "Yes") { - mOptions[index].SetSelectedIndex(RO_KEYRING_FOR_DUNGEON_ON); - } - break; - case RSK_SHUFFLE_MERCHANTS: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_OFF); - } else if (it.value() == "Beans Only") { - mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_BEANS_ONLY); - } else if (it.value() == "All but Beans") { - mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS); - } else if (it.value() == "All") { - mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_ALL); - } - break; - // Uses Ammo Drops option for now. "Off" not yet implemented - // TODO: Change to Ammo Drops - case RSK_ENABLE_BOMBCHU_DROPS: - if (it.value() == "Yes") { - mOptions[index].SetSelectedIndex(RO_AMMO_DROPS_ON); - // } else if (it.value() == "On + Bombchu") { - // mOptions[index].SetSelectedIndex(RO_AMMO_DROPS_ON_PLUS_BOMBCHU); - } else if (it.value() == "No") { - mOptions[index].SetSelectedIndex(RO_AMMO_DROPS_OFF); - } - break; - case RSK_FISHSANITY: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_FISHSANITY_OFF); - } else if (it.value() == "Shuffle Fishing Pond") { - mOptions[index].SetSelectedIndex(RO_FISHSANITY_POND); - } else if (it.value() == "Shuffle Overworld Fish") { - mOptions[index].SetSelectedIndex(RO_FISHSANITY_OVERWORLD); - } else if (it.value() == "Shuffle Both") { - mOptions[index].SetSelectedIndex(RO_FISHSANITY_BOTH); - } - break; - case RSK_SHUFFLE_BOSS_SOULS: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_BOSS_SOULS_OFF); - } else if (it.value() == "On") { - mOptions[index].SetSelectedIndex(RO_BOSS_SOULS_ON); - } else if (it.value() == "On + Ganon") { - mOptions[index].SetSelectedIndex(RO_BOSS_SOULS_ON_PLUS_GANON); - } - case RSK_STARTING_OCARINA: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_STARTING_OCARINA_OFF); - } else if (it.value() == "Fairy Ocarina") { - mOptions[index].SetSelectedIndex(RO_STARTING_OCARINA_FAIRY); - } - break; - case RSK_ITEM_POOL: - if (it.value() == "Plentiful") { - mOptions[index].SetSelectedIndex(RO_ITEM_POOL_PLENTIFUL); - } else if (it.value() == "Balanced") { - mOptions[index].SetSelectedIndex(RO_ITEM_POOL_BALANCED); - } else if (it.value() == "Scarce") { - mOptions[index].SetSelectedIndex(RO_ITEM_POOL_SCARCE); - } else if (it.value() == "Minimal") { - mOptions[index].SetSelectedIndex(RO_ITEM_POOL_MINIMAL); - } - break; - case RSK_ICE_TRAPS: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_ICE_TRAPS_OFF); - } else if (it.value() == "Normal") { - mOptions[index].SetSelectedIndex(RO_ICE_TRAPS_NORMAL); - } else if (it.value() == "Extra") { - mOptions[index].SetSelectedIndex(RO_ICE_TRAPS_EXTRA); - } else if (it.value() == "Mayhem") { - mOptions[index].SetSelectedIndex(RO_ICE_TRAPS_MAYHEM); - } else if (it.value() == "Onslaught") { - mOptions[index].SetSelectedIndex(RO_ICE_TRAPS_ONSLAUGHT); - } - break; - case RSK_GOSSIP_STONE_HINTS: - if (it.value() == "No Hints") { - mOptions[index].SetSelectedIndex(RO_GOSSIP_STONES_NONE); - } else if (it.value() == "Need Nothing") { - mOptions[index].SetSelectedIndex(RO_GOSSIP_STONES_NEED_NOTHING); - } else if (it.value() == "Mask of Truth") { - mOptions[index].SetSelectedIndex(RO_GOSSIP_STONES_NEED_TRUTH); - } else if (it.value() == "Stone of Agony") { - mOptions[index].SetSelectedIndex(RO_GOSSIP_STONES_NEED_STONE); - } - break; - case RSK_HINT_CLARITY: - if (it.value() == "Obscure") { - mOptions[index].SetSelectedIndex(RO_HINT_CLARITY_OBSCURE); - } else if (it.value() == "Ambiguous") { - mOptions[index].SetSelectedIndex(RO_HINT_CLARITY_AMBIGUOUS); - } else if (it.value() == "Clear") { - mOptions[index].SetSelectedIndex(RO_HINT_CLARITY_CLEAR); - } - break; - case RSK_HINT_DISTRIBUTION: - if (it.value() == "Useless") { - mOptions[index].SetSelectedIndex(RO_HINT_DIST_USELESS); - } else if (it.value() == "Balanced") { - mOptions[index].SetSelectedIndex(RO_HINT_DIST_BALANCED); - } else if (it.value() == "Strong") { - mOptions[index].SetSelectedIndex(RO_HINT_DIST_STRONG); - } else if (it.value() == "Very Strong") { - mOptions[index].SetSelectedIndex(RO_HINT_DIST_VERY_STRONG); - } - break; - case RSK_GERUDO_KEYS: - if (it.value() == "Vanilla") { - mOptions[index].SetSelectedIndex(RO_GERUDO_KEYS_VANILLA); - } else if (it.value() == "Any Dungeon") { - mOptions[index].SetSelectedIndex(RO_GERUDO_KEYS_ANY_DUNGEON); - } else if (it.value() == "Overworld") { - mOptions[index].SetSelectedIndex(RO_GERUDO_KEYS_OVERWORLD); - } else if (it.value() == "Anywhere") { - mOptions[index].SetSelectedIndex(RO_GERUDO_KEYS_ANYWHERE); - } - break; - case RSK_KEYSANITY: - case RSK_BOSS_KEYSANITY: - case RSK_SHUFFLE_MAPANDCOMPASS: - if (it.value() == "Start With") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_ITEM_LOC_STARTWITH); - } else if (it.value() == "Vanilla") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_ITEM_LOC_VANILLA); - } else if (it.value() == "Own Dungeon") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON); - } else if (it.value() == "Any Dungeon") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON); - } else if (it.value() == "Overworld") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_ITEM_LOC_OVERWORLD); - } else if (it.value() == "Anywhere") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_ITEM_LOC_ANYWHERE); - } - break; - case RSK_GANONS_BOSS_KEY: - if (it.value() == "Vanilla") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_VANILLA); - } else if (it.value() == "Own dungeon") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_OWN_DUNGEON); - } else if (it.value() == "Start with") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_STARTWITH); - } else if (it.value() == "Any Dungeon") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_ANY_DUNGEON); - } else if (it.value() == "Overworld") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_OVERWORLD); - } else if (it.value() == "Anywhere") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_ANYWHERE); - } else if (it.value() == "LACS-Vanilla") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_LACS_VANILLA); - } else if (it.value() == "LACS-Stones") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_LACS_STONES); - } else if (it.value() == "LACS-Medallions") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_LACS_MEDALLIONS); - } else if (it.value() == "LACS-Rewards") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_LACS_REWARDS); - } else if (it.value() == "LACS-Dungeons") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_LACS_DUNGEONS); - } else if (it.value() == "LACS-Tokens") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_LACS_TOKENS); - } else if (it.value() == "100 GS Reward") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_KAK_TOKENS); - } else if (it.value() == "Triforce Hunt") { - mOptions[index].SetSelectedIndex(RO_GANON_BOSS_KEY_TRIFORCE_HUNT); - } - break; - case RSK_MQ_DUNGEON_RANDOM: - if (it.value() == "None") { - mOptions[index].SetSelectedIndex(RO_MQ_DUNGEONS_NONE); - } else if (it.value() == "Random Number") { - mOptions[index].SetSelectedIndex(RO_MQ_DUNGEONS_RANDOM_NUMBER); - } else if (it.value() == "Set Number") { - mOptions[index].SetSelectedIndex(RO_MQ_DUNGEONS_SET_NUMBER); - } else if (it.value() == "Selection Only") { - mOptions[index].SetSelectedIndex(RO_MQ_DUNGEONS_SELECTION); - } - break; - case RSK_STARTING_CONSUMABLES: - case RSK_FULL_WALLETS: - if (it.value() == "No") { - mOptions[index].SetSelectedIndex(RO_GENERIC_NO); - } else if (it.value() == "Yes") { - mOptions[index].SetSelectedIndex(RO_GENERIC_YES); - } - break; - case RSK_SKIP_CHILD_ZELDA: - case RSK_SKIP_CHILD_STEALTH: - case RSK_SKIP_EPONA_RACE: - if (it.value() == "Don't Skip") { - mOptions[index].SetSelectedIndex(RO_GENERIC_DONT_SKIP); - } else if (it.value() == "Skip") { - mOptions[index].SetSelectedIndex(RO_GENERIC_SKIP); - } - break; - case RSK_SHUFFLE_DUNGEON_REWARDS: - if (it.value() == "End of dungeons") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_REWARDS_END_OF_DUNGEON); - } else if (it.value() == "Any dungeon") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_REWARDS_ANY_DUNGEON); - } else if (it.value() == "Overworld") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_REWARDS_OVERWORLD); - } else if (it.value() == "Anywhere") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_REWARDS_ANYWHERE); - } - break; - case RSK_SHUFFLE_SONGS: - if (it.value() == "Song locations") { - mOptions[index].SetSelectedIndex(RO_SONG_SHUFFLE_SONG_LOCATIONS); - } else if (it.value() == "Dungeon rewards") { - mOptions[index].SetSelectedIndex(RO_SONG_SHUFFLE_DUNGEON_REWARDS); - } else if (it.value() == "Anywhere") { - mOptions[index].SetSelectedIndex(RO_SONG_SHUFFLE_ANYWHERE); - } - break; - case RSK_SHUFFLE_TOKENS: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_TOKENSANITY_OFF); - } else if (it.value() == "Dungeons") { - mOptions[index].SetSelectedIndex(RO_TOKENSANITY_DUNGEONS); - } else if (it.value() == "Overworld") { - mOptions[index].SetSelectedIndex(RO_TOKENSANITY_OVERWORLD); - } else if (it.value() == "All Tokens") { - mOptions[index].SetSelectedIndex(RO_TOKENSANITY_ALL); - } - break; - case RSK_LINKS_POCKET: - if (it.value() == "Dungeon Reward") { - mOptions[index].SetSelectedIndex(RO_LINKS_POCKET_DUNGEON_REWARD); - } else if (it.value() == "Advancement") { - mOptions[index].SetSelectedIndex(RO_LINKS_POCKET_ADVANCEMENT); - } else if (it.value() == "Anything") { - mOptions[index].SetSelectedIndex(RO_LINKS_POCKET_ANYTHING); - } else if (it.value() == "Nothing") { - mOptions[index].SetSelectedIndex(RO_LINKS_POCKET_NOTHING); - } - break; - case RSK_MQ_DUNGEON_COUNT: - numericValueString = it.value(); - mOptions[index].SetSelectedIndex(std::stoi(numericValueString)); - break; - case RSK_SHUFFLE_DUNGEON_ENTRANCES: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF); - } else if (it.value() == "On") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_ENTRANCE_SHUFFLE_ON); - } else if (it.value() == "On + Ganon") { - mOptions[index].SetSelectedIndex(RO_DUNGEON_ENTRANCE_SHUFFLE_ON_PLUS_GANON); - } - break; - case RSK_SHUFFLE_BOSS_ENTRANCES: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF); - } else if (it.value() == "Age Restricted") { - mOptions[index].SetSelectedIndex(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_AGE_RESTRICTED); - } else if (it.value() == "Full") { - mOptions[index].SetSelectedIndex(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_FULL); - } - break; - case RSK_SHUFFLE_INTERIOR_ENTRANCES: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF); - } else if (it.value() == "Simple") { - mOptions[index].SetSelectedIndex(RO_INTERIOR_ENTRANCE_SHUFFLE_SIMPLE); - } else if (it.value() == "All") { - mOptions[index].SetSelectedIndex(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL); - } - break; - case RSK_SHUFFLE_CHEST_MINIGAME: - if (it.value() == "Off") { - mOptions[index].SetSelectedIndex(RO_CHEST_GAME_OFF); - } else if (it.value() == "On (Separate)") { - mOptions[index].SetSelectedIndex(RO_CHEST_GAME_SINGLE_KEYS); - } else if (it.value() == "On (Pack)") { - mOptions[index].SetSelectedIndex(RO_CHEST_GAME_PACK); - } - break; - case RSK_MQ_DEKU_TREE: - case RSK_MQ_DODONGOS_CAVERN: - case RSK_MQ_JABU_JABU: - case RSK_MQ_FOREST_TEMPLE: - case RSK_MQ_FIRE_TEMPLE: - case RSK_MQ_WATER_TEMPLE: - case RSK_MQ_SPIRIT_TEMPLE: - case RSK_MQ_SHADOW_TEMPLE: - case RSK_MQ_BOTTOM_OF_THE_WELL: - case RSK_MQ_ICE_CAVERN: - case RSK_MQ_GTG: - case RSK_MQ_GANONS_CASTLE: - if (it.value() == "Vanilla") { - mOptions[index].SetSelectedIndex(RO_MQ_SET_VANILLA); - } else if (it.value() == "Master Quest") { - mOptions[index].SetSelectedIndex(RO_MQ_SET_MQ); - } else if (it.value() == "Random") { - mOptions[index].SetSelectedIndex(RO_MQ_SET_RANDOM); - } - break; - default: - SPDLOG_DEBUG("No string to enum conversion for option: %s", it.key()); - break; - } + //RANDOTODO handle numeric value to options conversion better than brute froce + if (StaticData::optionNameToEnum.contains(it.key())) { + const RandomizerSettingKey index = StaticData::optionNameToEnum[it.key()]; + mOptions[index].SetContextIndexFromText(it.value()); } } @@ -3140,13 +2442,19 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) { ctx->AddExcludedOptions(); for (auto it = jsonExcludedLocations.begin(); it != jsonExcludedLocations.end(); ++it) { const RandomizerCheck rc = Rando::StaticData::locationNameToEnum[it.value()]; - ctx->GetItemLocation(rc)->GetExcludedOption()->SetSelectedIndex(RO_GENERIC_ON); + ctx->GetItemLocation(rc)->GetExcludedOption()->SetContextIndex(RO_GENERIC_ON); } nlohmann::json enabledTricksJson = spoilerFileJson["enabledTricks"]; for (auto it = enabledTricksJson.begin(); it != enabledTricksJson.end(); ++it) { const RandomizerTrick rt = mTrickNameToEnum[it.value()]; - GetTrickOption(rt).SetSelectedIndex(RO_GENERIC_ON); + GetTrickOption(rt).SetContextIndex(RO_GENERIC_ON); + } +} + +void Settings::ReloadOptions() { + for (int i = 0; i < RSK_MAX; i++) { + mOptions[i].SetFromCVar(); } } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/settings.h b/soh/soh/Enhancements/randomizer/settings.h index 197d074bd..90613cf14 100644 --- a/soh/soh/Enhancements/randomizer/settings.h +++ b/soh/soh/Enhancements/randomizer/settings.h @@ -25,6 +25,14 @@ class Settings { */ void CreateOptions(); + /** + * @brief Populates the map used to translate strings into RandomiserSettingKeys + * + * @return std::unordered_map + */ + + std::unordered_map PopulateOptionNameToEnum(); + /** * @brief Get a reference to the `Option` corresponding to the provided RandomizerSettingKey. * @@ -180,6 +188,7 @@ class Settings { void ParseJson(nlohmann::json spoilerFileJson); std::vector VanillaLogicDefaults = {}; std::map> mTricksByArea = {}; + void ReloadOptions(); private: /** @@ -191,7 +200,6 @@ class Settings { std::array mOptionGroups = {}; std::array mTrickOptions = {}; std::vector> mExcludeLocationsOptionsAreas = {}; - std::unordered_map mSpoilerfileSettingNameToEnum; RandoOptionStartingAge mResolvedStartingAge = RO_AGE_CHILD; RandoOptionLACSCondition mLACSCondition = RO_LACS_VANILLA; std::string mHash; diff --git a/soh/soh/Enhancements/randomizer/static_data.cpp b/soh/soh/Enhancements/randomizer/static_data.cpp index 5c6f7903b..84da0d3c1 100644 --- a/soh/soh/Enhancements/randomizer/static_data.cpp +++ b/soh/soh/Enhancements/randomizer/static_data.cpp @@ -13,7 +13,7 @@ std::unordered_map StaticData::hintTypeNames = { {HINT_TYPE_ITEM_AREA, CustomMessage("Item Area")}, {HINT_TYPE_ALTAR_CHILD, CustomMessage("Child Altar")}, {HINT_TYPE_ALTAR_ADULT, CustomMessage("Adult Altar")}, - {HINT_TYPE_WOTH, CustomMessage("Way of the Hero")}, + {HINT_TYPE_WOTH, CustomMessage("Way of the Hero")}, {HINT_TYPE_FOOLISH, CustomMessage("Foolish")}, {HINT_TYPE_MESSAGE, CustomMessage("Hardcoded Message")} }; @@ -60,7 +60,7 @@ std::unordered_map StaticData::hintNames = { {RH_LH_SOUTHEAST_GOSSIP_STONE, CustomMessage("LH Southeast Gossip Stone")}, {RH_LH_SOUTHWEST_GOSSIP_STONE, CustomMessage("LH Southwest Gossip Stone")}, {RH_GV_GOSSIP_STONE, CustomMessage("Gerudo Valley Gossip Stone")}, - {RH_COLOSSUS_GOSSIP_STONE, CustomMessage("Desert Collosus Gossip Stone")}, + {RH_COLOSSUS_GOSSIP_STONE, CustomMessage("Desert Colossus Gossip Stone")}, {RH_DODONGOS_CAVERN_GOSSIP_STONE, CustomMessage("Dodongo's Cavern Gossip Stone")}, {RH_GANONDORF_HINT, CustomMessage("Ganondorf Hint")}, {RH_GANONDORF_JOKE, CustomMessage("Ganondorf Joke")}, @@ -189,7 +189,7 @@ std::unordered_map StaticData::trialData = { std::unordered_map StaticData::staticHintInfoMap = { // RH_GANONDORF_HINT is special cased due to being different based on master sword shuffle // Altar hints are special cased due to special hint marking rules - // warp song hints are special cased due to entrences not being done properly yet + // warp song hints are special cased due to entrances not being done properly yet // Ganondorf Joke is special cased as the text is random {RH_SHEIK_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SHEIK_HINT_LA_ONLY}, RSK_SHEIK_LA_HINT, true, {}, {RG_LIGHT_ARROWS}, {RC_SHEIK_HINT_GC, RC_SHEIK_HINT_MQ_GC}, true)}, {RH_DAMPES_DIARY, StaticHintInfo(HINT_TYPE_AREA, {RHT_DAMPE_DIARY}, RSK_DAMPES_DIARY_HINT, true, {}, {RG_PROGRESSIVE_HOOKSHOT}, {RC_DAMPE_HINT})}, @@ -251,7 +251,8 @@ std::unordered_map StaticData::hintNameToEnum = {}; std::unordered_map StaticData::hintTypeNameToEnum = {}; std::unordered_map StaticData::areaNameToEnum = {}; std::unordered_map StaticData::trialNameToEnum = {}; -std::unordered_map StaticData::locationNameToEnum = {}; //is filled in context based on location table, not touching that because of VB +std::unordered_map StaticData::optionNameToEnum = {}; +std::unordered_map StaticData::locationNameToEnum = {}; //is filled in context based on location table std::unordered_map StaticData::stoneParamsToHint{ {0x1, RH_ZF_FAIRY_GOSSIP_STONE}, @@ -301,4 +302,4 @@ std::unordered_map StaticData::grottoChestParamsToHint{ }; std::array StaticData::hintTextTable = {}; -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index 5ff0f1d26..4a516d72f 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -46,6 +46,8 @@ class StaticData { static std::vector GetStaticHintLocations(); static std::vector GetPondFishLocations(); static std::vector GetOverworldFishLocations(); + static std::vector GetOverworldPotLocations(); + static std::vector GetOverworldFairyLocations(); static std::array, 17> randomizerFishingPondFish; static std::unordered_map randomizerGrottoFishMap; static std::vector oldVerHintOrder; @@ -61,6 +63,7 @@ class StaticData { static std::unordered_map areaNameToEnum; static std::unordered_map trialData; static std::unordered_map trialNameToEnum; + static std::unordered_map optionNameToEnum; static std::unordered_map staticHintInfoMap; static std::unordered_map stoneParamsToHint; static std::unordered_map grottoChestParamsToHint; diff --git a/soh/soh/Enhancements/randomizer/tricks.cpp b/soh/soh/Enhancements/randomizer/tricks.cpp index 4828dde7b..6008ba332 100644 --- a/soh/soh/Enhancements/randomizer/tricks.cpp +++ b/soh/soh/Enhancements/randomizer/tricks.cpp @@ -1,16 +1,53 @@ #include "tricks.h" - +#include namespace Rando { - const std::string& Tricks::GetRTAreaName(const RandomizerArea area) { + const std::unordered_map rtAreaNames = { + { RA_NONE, "General Tricks" }, + { RA_KOKIRI_FOREST, "Kokiri Forest" }, + { RA_THE_LOST_WOODS, "Lost Woods" }, + { RA_SACRED_FOREST_MEADOW, "Sacred Forest Meadow" }, + { RA_HYRULE_FIELD, "Hyrule Field" }, + { RA_LAKE_HYLIA, "Lake Hylia" }, + { RA_GERUDO_VALLEY, "Gerudo Valley" }, + { RA_GERUDO_FORTRESS, "Gerudo Fortress" }, + { RA_HAUNTED_WASTELAND, "Haunted Wasteland" }, + { RA_DESERT_COLOSSUS, "Desert Colossus" }, + { RA_THE_MARKET, "Hyrule Market" }, + { RA_HYRULE_CASTLE, "Hyrule Castle" }, + { RA_KAKARIKO_VILLAGE, "Kakariko Village" }, + { RA_THE_GRAVEYARD, "Graveyard" }, + { RA_DEATH_MOUNTAIN_TRAIL, "Death Mountain Trail" }, + { RA_GORON_CITY, "Goron City" }, + { RA_DEATH_MOUNTAIN_CRATER, "Death Mountain Crater" }, + { RA_ZORAS_RIVER, "Zora's River" }, + { RA_ZORAS_DOMAIN, "Zora's Domain" }, + { RA_ZORAS_FOUNTAIN, "Zora's Fountain" }, + { RA_LON_LON_RANCH, "Lon Lon Ranch" }, + { RA_DEKU_TREE, "Deku Tree" }, + { RA_DODONGOS_CAVERN, "Dodongo's Cavern" }, + { RA_JABU_JABUS_BELLY, "Jabu Jabu's Belly" }, + { RA_FOREST_TEMPLE, "Forest Temple" }, + { RA_FIRE_TEMPLE, "Fire Temple" }, + { RA_WATER_TEMPLE, "Water Temple" }, + { RA_SPIRIT_TEMPLE, "Spirit Temple" }, + { RA_SHADOW_TEMPLE, "Shadow Temple" }, + { RA_BOTTOM_OF_THE_WELL, "Bottom of the Well" }, + { RA_ICE_CAVERN, "Ice Cavern" }, + { RA_GERUDO_TRAINING_GROUND, "Gerudo Training Ground" }, + { RA_GANONS_CASTLE, "Ganon's Castle" }, + { RA_MAX, "Invalid" }, + }; + + const std::string& Tricks::GetAreaName(const RandomizerArea area) { return rtAreaNames.at(area); } - bool Tricks::CheckRTTags(const std::map &showTag, const std::set &rtTags) { + bool Tricks::CheckTags(const std::map& showTag, const std::set& rtTags) { if (rtTags.empty()) { return false; } - for (auto rtTag : rtTags) { + for (Tag rtTag : rtTags) { if (!showTag.at(rtTag)) { return false; } @@ -18,41 +55,60 @@ namespace Rando { return true; } - std::string Tricks::GetRTTagName(const Tag tag) { + const std::unordered_map rtTagNames = { + { Tricks::Tag::NOVICE, "Novice" }, + { Tricks::Tag::INTERMEDIATE, "Intermediate" }, + { Tricks::Tag::ADVANCED, "Advanced" }, + { Tricks::Tag::EXPERT, "Expert" }, + { Tricks::Tag::EXTREME, "Extreme" }, + { Tricks::Tag::EXPERIMENTAL, "Experimental" }, + { Tricks::Tag::GLITCH, "Glitch" }, + }; + + const std::string Tricks::GetTagName(const Tag tag) { return rtTagNames.at(tag); } - ImVec4 Tricks::GetRTTagColor(const Tag tag) { + const ImVec4 Tricks::GetTextColor(const Tag tag) { switch(tag) { - case Tag::NOVICE: - return {0.09f,0.55f,0.37f,1.0f}; - case Tag::INTERMEDIATE: - return {0.95f,0.52f,0.0f,1.0f}; - case Tag::ADVANCED: - return {0.0f,0.29f,0.71f,1.0f}; - case Tag::EXPERT: - return {0.53f,0.05f,0.14f,1.0f}; - case Tag::EXTREME: - return {0.27f,0.0f,0.27f,1.0f}; + case Tag::EXPERIMENTAL: + case Tag::GLITCH: + return { 0.00f, 0.00f, 0.00f, 1.0f }; default: - return {0.5f,0.5f,0.5f,1.0f}; - /*case RTTAG_LENS: - return ImVec4(.f,.f,.f,1.0f); - case RTTAG_BKSKIP: - return ImVec4(.f,.f,.f,1.0f); - case RTTAG_EXPERIMENTAL: - return ImVec4(.f,.f,.f,1.0f);*/ + return { 1.00f, 1.00f, 1.00f, 1.00f }; } } - void Tricks::DrawTagChips(const std::set &rtTags) { - for (const auto rtTag : rtTags) { + const ImVec4 Tricks::GetTagColor(const Tag tag) { + switch(tag) { + case Tag::NOVICE: + return { 0.09f, 0.55f, 0.37f, 1.00f }; + case Tag::INTERMEDIATE: + return { 0.95f, 0.52f, 0.00f, 1.00f }; + case Tag::ADVANCED: + return { 0.00f, 0.29f, 0.71f, 1.00f }; + case Tag::EXPERT: + return { 0.53f, 0.05f, 0.14f, 1.00f }; + case Tag::EXTREME: + return { 0.27f, 0.00f, 0.27f, 1.00f }; + case Tag::EXPERIMENTAL: + return { 0.00f, 1.00f, 1.00f, 1.00f }; + case Tag::GLITCH: + return { 1.00f, 1.00f, 1.00f, 1.00f }; + default: + assert(false); + return { 0.50f, 0.50f, 0.50f, 1.00f }; + } + } + + void Tricks::DrawTagChips(const std::set& rtTags) { + for (const Tag rtTag : rtTags) { ImGui::SameLine(); ImGui::BeginDisabled(); - ImGui::PushStyleColor(ImGuiCol_Button, GetRTTagColor(rtTag)); - ImGui::SmallButton(GetRTTagName(rtTag).c_str()); + ImGui::PushStyleColor(ImGuiCol_Button, GetTagColor(rtTag)); + ImGui::SmallButton(GetTagName(rtTag).c_str()); ImGui::PopStyleColor(); ImGui::EndDisabled(); } } -} +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/tricks.h b/soh/soh/Enhancements/randomizer/tricks.h index 77d3a0b23..b3b635555 100644 --- a/soh/soh/Enhancements/randomizer/tricks.h +++ b/soh/soh/Enhancements/randomizer/tricks.h @@ -1,86 +1,35 @@ +#pragma once + #ifndef TRICKS_H #define TRICKS_H #include -#include - #include "randomizerTypes.h" -#include #include +#include #include - namespace Rando { class Tricks { - public: - enum class Tag { - NOVICE, - INTERMEDIATE, - ADVANCED, - EXPERT, - EXTREME, - /*LENS, - *BKSKIP, - *EXPERIMENTAL*/ - }; + public: + enum class Tag { + NOVICE, + INTERMEDIATE, + ADVANCED, + EXPERT, + EXTREME, + EXPERIMENTAL, + GLITCH, + }; - static const std::string& GetRTAreaName(RandomizerArea area); - static bool CheckRTTags(const std::map &showTag, const std::set &rtTags); - static std::string GetRTTagName(Tag tag); - static ImVec4 GetRTTagColor(Tag tag); - static void DrawTagChips(const std::set &rtTags); - private: - inline static const std::unordered_map rtAreaNames = { - { RA_NONE, "General Tricks"}, - //{ RTAREA_BK_SKIPS, "Boss Key Skips"}, - { RA_KOKIRI_FOREST, "Kokiri Forest"}, - { RA_THE_LOST_WOODS, "Lost Woods"}, - { RA_SACRED_FOREST_MEADOW, "Sacred Forest Meadow"}, - { RA_HYRULE_FIELD, "Hyrule Field"}, - { RA_LAKE_HYLIA, "Lake Hylia"}, - { RA_GERUDO_VALLEY, "Gerudo Valley"}, - { RA_GERUDO_FORTRESS, "Gerudo Fortress"}, - { RA_HAUNTED_WASTELAND, "Haunted Wasteland"}, - { RA_DESERT_COLOSSUS, "Desert Colossus"}, - { RA_THE_MARKET, "Hyrule Market"}, - { RA_HYRULE_CASTLE, "Hyrule Castle"}, - { RA_KAKARIKO_VILLAGE, "Kakariko Village"}, - { RA_THE_GRAVEYARD, "Graveyard"}, - { RA_DEATH_MOUNTAIN_TRAIL, "Death Mountain Trail"}, - { RA_GORON_CITY, "Goron City"}, - { RA_DEATH_MOUNTAIN_CRATER, "Death Mountain Crater"}, - { RA_ZORAS_RIVER, "Zora's River"}, - { RA_ZORAS_DOMAIN, "Zora's Domain"}, - { RA_ZORAS_FOUNTAIN, "Zora's Fountain"}, - { RA_LON_LON_RANCH, "Lon Lon Ranch"}, - { RA_DEKU_TREE, "Deku Tree"}, - { RA_DODONGOS_CAVERN, "Dodongo's Cavern"}, - { RA_JABU_JABUS_BELLY, "Jabu Jabu's Belly"}, - { RA_FOREST_TEMPLE, "Forest Temple"}, - { RA_FIRE_TEMPLE, "Fire Temple"}, - { RA_WATER_TEMPLE, "Water Temple"}, - { RA_SPIRIT_TEMPLE, "Spirit Temple"}, - { RA_SHADOW_TEMPLE, "Shadow Temple"}, - { RA_BOTTOM_OF_THE_WELL, "Bottom of the Well"}, - { RA_ICE_CAVERN, "Ice Cavern"}, - { RA_GERUDO_TRAINING_GROUND, "Gerudo Training Grounds"}, - { RA_GANONS_CASTLE, "Ganon's Castle"}, - { RA_MAX, "Invalid"}, - }; - - inline static const std::unordered_map rtTagNames = { - {Tag::NOVICE, "Novice"}, - {Tag::INTERMEDIATE, "Intermediate"}, - {Tag::ADVANCED, "Advanced"}, - {Tag::EXPERT, "Expert"}, - {Tag::EXTREME, "Extreme"}, - /*{Rando::Tag::LENS, "Lens"}, - {Rando::Tag::BKSKIP, "Boss Key Skip"}, - {Rando::Tag::EXPERIMENTAL, "Experimental"}*/ - }; + static const std::string& GetAreaName(RandomizerArea area); + static bool CheckTags(const std::map& showTag, const std::set& rtTags); + static const std::string GetTagName(Tag tag); + static const ImVec4 GetTextColor(Tag tag); + static const ImVec4 GetTagColor(Tag tag); + static void DrawTagChips(const std::set& rtTags); }; } - -#endif //TRICKS_H +#endif //TRICKS_H \ No newline at end of file diff --git a/soh/soh/Enhancements/resolution-editor/ResolutionEditor.cpp b/soh/soh/Enhancements/resolution-editor/ResolutionEditor.cpp index 21d99194e..c15f04364 100644 --- a/soh/soh/Enhancements/resolution-editor/ResolutionEditor.cpp +++ b/soh/soh/Enhancements/resolution-editor/ResolutionEditor.cpp @@ -5,6 +5,7 @@ #include #include #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" /* Console Variables are grouped under gAdvancedResolution. (e.g. CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled") diff --git a/soh/soh/Enhancements/savestates.cpp b/soh/soh/Enhancements/savestates.cpp index 4797c27a3..24294ea8f 100644 --- a/soh/soh/Enhancements/savestates.cpp +++ b/soh/soh/Enhancements/savestates.cpp @@ -1,6 +1,6 @@ #include "savestates.h" -#include +#include #include // std::sprintf diff --git a/soh/soh/Enhancements/timesaver_hook_handlers.cpp b/soh/soh/Enhancements/timesaver_hook_handlers.cpp index 3bfd0da6f..ee9dede06 100644 --- a/soh/soh/Enhancements/timesaver_hook_handlers.cpp +++ b/soh/soh/Enhancements/timesaver_hook_handlers.cpp @@ -12,8 +12,10 @@ extern "C" { #include "src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.h" #include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" #include "src/overlays/actors/ovl_En_Owl/z_en_owl.h" +#include "src/overlays/actors/ovl_En_Go2/z_en_go2.h" #include "src/overlays/actors/ovl_En_Ko/z_en_ko.h" #include "src/overlays/actors/ovl_En_Ma1/z_en_ma1.h" +#include "src/overlays/actors/ovl_En_Ru2/z_en_ru2.h" #include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h" #include "src/overlays/actors/ovl_En_Box/z_en_box.h" #include "src/overlays/actors/ovl_Demo_Im/z_demo_im.h" @@ -33,14 +35,21 @@ extern "C" { extern SaveContext gSaveContext; extern PlayState* gPlayState; extern int32_t D_8011D3AC; + +extern void BgSpot03Taki_HandleWaterfallState(BgSpot03Taki* bgSpot03Taki, PlayState* play); +extern void BgSpot03Taki_ApplyOpeningAlpha(BgSpot03Taki* bgSpot03Taki, s32 bufferIndex); + +extern void EnGo2_CurledUp(EnGo2* enGo2, PlayState* play); + +extern void EnRu2_SetEncounterSwitchFlag(EnRu2* enRu2, PlayState* play); } -#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex() +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetContextOptionIndex() void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) { if (Message_GetState(&gPlayState->msgCtx) == TEXT_STATE_CLOSING) { Flags_SetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); enMa1->actor.flags &= ~ACTOR_FLAG_WILL_TALK; play->msgCtx.ocarinaMode = OCARINA_MODE_04; enMa1->actionFunc = func_80AA0D88; @@ -52,7 +61,7 @@ void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) { void EnFu_EndTeachSong(EnFu* enFu, PlayState* play) { if (Message_GetState(&gPlayState->msgCtx) == TEXT_STATE_CLOSING) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); enFu->actionFunc = EnFu_WaitAdult; enFu->actor.flags &= ~ACTOR_FLAG_WILL_TALK; @@ -93,6 +102,9 @@ void EnDntDemo_JudgeSkipToReward(EnDntDemo* enDntDemo, PlayState* play) { } } +void BgSpot03Taki_KeepOpen(BgSpot03Taki* bgSpot03Taki, PlayState* play) { +} + static int successChimeCooldown = 0; void RateLimitedSuccessChime() { if (successChimeCooldown == 0) { @@ -122,7 +134,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li case VB_PLAY_TRANSITION_CS: { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), IS_RANDO) || IS_RANDO) { // Song of Time - if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_0 && gSaveContext.cutsceneIndex == 0xFFF7) { + if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_ENTRANCE && gSaveContext.cutsceneIndex == 0xFFF7) { gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_16; gSaveContext.cutsceneIndex = 0; gSaveContext.nextTransitionType = 3; @@ -130,7 +142,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } // Requiem of Spirit - if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { + if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); // Normally happens in the cutscene gSaveContext.dayTime = gSaveContext.skyboxTime = 0xAC60; @@ -142,7 +154,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li u8 meetsBurningKakRequirements = LINK_IS_ADULT && - gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 && + gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) && Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) && Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) && @@ -203,10 +215,13 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li s16* csId = va_arg(args, s16*); BgSpot03Taki* taki = NULL; switch (*csId) { + case 3120: + case 3150: case 4180: case 4100: *should = false; RateLimitedSuccessChime(); + Message_CloseTextbox(gPlayState); taki = (BgSpot03Taki*)Actor_FindNearby(gPlayState, &GET_PLAYER(gPlayState)->actor, ACTOR_BG_SPOT03_TAKI, ACTORCAT_BG, 999.0f); if (taki != NULL) { @@ -257,10 +272,10 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li break; } case ACTOR_BG_BDAN_SWITCH: { - // The switch in jabu that you are intended to press with a box to reach barrinade + // The switch in jabu that you are intended to press with a box to reach barinade // can be skipped by either a frame perfect roll open or with OI // The One Point for that switch is used in common setups for the former and is required for the latter to work - if (actor->params == 14848 && gPlayState->sceneNum == SCENE_JABU_JABU && !CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)){ + if (actor->params == 14848 && gPlayState->sceneNum == SCENE_JABU_JABU && CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)){ break; } BgBdanSwitch* switchActor = (BgBdanSwitch*)actor; @@ -277,19 +292,17 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li RateLimitedSuccessChime(); break; } - case ACTOR_BG_HIDAN_FWBIG: { + case ACTOR_EN_GO2: { + EnGo2* biggoron = (EnGo2*)actor; + biggoron->isAwake = true; *should = false; break; } - case ACTOR_EN_EX_ITEM: { - *should = false; - break; - } - case ACTOR_EN_DNT_NOMAL: { - *should = false; - break; - } - case ACTOR_EN_DNT_DEMO: { + case ACTOR_BG_HIDAN_FWBIG: + case ACTOR_EN_EX_ITEM: + case ACTOR_EN_DNT_NOMAL: + case ACTOR_EN_DNT_DEMO: + case ACTOR_BG_HAKA_ZOU: { *should = false; break; } @@ -305,8 +318,14 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li case ACTOR_BG_YDAN_MARUTA: case ACTOR_BG_SPOT18_SHUTTER: case ACTOR_BG_SPOT05_SOKO: + case ACTOR_BG_SPOT06_OBJECTS: case ACTOR_BG_SPOT18_BASKET: case ACTOR_BG_HIDAN_CURTAIN: + case ACTOR_BG_MORI_HINERI: + case ACTOR_BG_MIZU_SHUTTER: + case ACTOR_SHOT_SUN: + case ACTOR_BG_HAKA_GATE: + case ACTOR_EN_KAKASI2: *should = false; RateLimitedSuccessChime(); break; @@ -333,11 +352,27 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li case VB_NAVI_TALK: { if (ForcedDialogIsDisabled(FORCED_DIALOG_SKIP_NAVI)) { ElfMsg* naviTalk = va_arg(args, ElfMsg*); - if (((naviTalk->actor.params >> 8) & 0x3F) != 0x3F) { - Flags_SetSwitch(gPlayState, (naviTalk->actor.params >> 8) & 0x3F); - Actor_Kill(&naviTalk->actor); - *should = false; + int32_t paramsHighByte = naviTalk->actor.params >> 8; + if ((paramsHighByte & 0x80) != 0) { + break; } + if ((paramsHighByte & 0x3F) != 0x3F) { + Flags_SetSwitch(gPlayState, paramsHighByte & 0x3F); + } + Actor_Kill(&naviTalk->actor); + *should = false; + } + break; + } + case VB_GORON_LINK_BE_SCARED: { + if (ForcedDialogIsDisabled(FORCED_DIALOG_SKIP_NPC)) { + EnGo2* goronLink = va_arg(args, EnGo2*); + goronLink->trackingMode = NPC_TRACKING_NONE; + goronLink->unk_211 = false; + goronLink->isAwake = false; + goronLink->actionFunc = EnGo2_CurledUp; + Flags_SetInfTable(INFTABLE_STOPPED_GORON_LINKS_ROLLING); + *should = false; } break; } @@ -399,6 +434,14 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } break; } + case VB_PLAY_MWEEP_CS: { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), 0)) { + *should = false; + Inventory_ReplaceItem(gPlayState, ITEM_LETTER_RUTO, ITEM_BOTTLE); + Flags_SetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED); + } + break; + } case VB_PLAY_EYEDROP_CREATION_ANIM: case VB_PLAY_EYEDROPS_CS: case VB_PLAY_DROP_FISH_FOR_JABU_CS: @@ -426,7 +469,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li player->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM; if (Animation_OnFrame(&demoIm->skelAnime, 25.0f)) { - Audio_PlaySoundGeneral(NA_SE_IT_DEKU, &demoIm->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_DEKU, &demoIm->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); GameInteractor::Instance->UnregisterGameHook(demoImUpdateHook); GameInteractor::Instance->UnregisterGameHook(demoImKillHook); demoImUpdateHook = 0; @@ -435,7 +478,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li Player* player = GET_PLAYER(gPlayState); // SOH [Randomizer] In entrance rando have impa bring link back to the front of castle grounds if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) { - gPlayState->nextEntranceIndex = ENTR_HYRULE_CASTLE_0; + gPlayState->nextEntranceIndex = ENTR_CASTLE_GROUNDS_SOUTH_EXIT; } else { gPlayState->nextEntranceIndex = ENTR_HYRULE_FIELD_17; } @@ -501,11 +544,24 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } break; } + case VB_PLAY_GORON_FREE_CS: { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), 0)) { + *should = false; + } + break; + } case VB_PLAY_DOOR_OF_TIME_CS: { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { *should = false; + Flags_SetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME); Flags_SetEnv(gPlayState, 2); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); + } + break; + } + case VB_PLAY_FIRE_ARROW_CS: { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), 0)) { + *should = false; } break; } @@ -610,7 +666,11 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li case VB_PLAY_RAINBOW_BRIDGE_CS: { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { *should = false; - func_800F595C(NA_BGM_BRIDGE_TO_GANONS); + if (!Flags_GetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT)) { + func_800F595C(NA_BGM_BRIDGE_TO_GANONS); + // This would have been set 2 frames later, but we're skipping now so the sound doesn't play twice + Flags_SetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT); + } } break; } @@ -677,6 +737,8 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } break; } + default: + break; } va_end(args); @@ -688,6 +750,8 @@ static uint32_t enFuUpdateHook = 0; static uint32_t enFuKillHook = 0; static uint32_t bgSpot02UpdateHook = 0; static uint32_t bgSpot02KillHook = 0; +static uint32_t bgSpot03UpdateHook = 0; +static uint32_t bgSpot03KillHook = 0; static uint32_t enPoSistersUpdateHook = 0; static uint32_t enPoSistersKillHook = 0; void TimeSaverOnActorInitHandler(void* actorRef) { @@ -743,6 +807,10 @@ void TimeSaverOnActorInitHandler(void* actorRef) { }); } + if (actor->id == ACTOR_EN_OWL && gPlayState->sceneNum == SCENE_ZORAS_RIVER && CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 0) == 2) { + Actor_Kill(actor); + } + if (actor->id == ACTOR_BG_SPOT02_OBJECTS && actor->params == 2) { bgSpot02UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { Actor* innerActor = static_cast(innerActorRef); @@ -765,6 +833,61 @@ void TimeSaverOnActorInitHandler(void* actorRef) { }); } + if (actor->id == ACTOR_BG_SPOT03_TAKI) { + bgSpot03UpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) mutable { + Actor* innerActor = static_cast(innerActorRef); + + if (innerActor->id != ACTOR_BG_SPOT03_TAKI) { + return; + } + + bool shouldKeepOpen; + switch (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 0)) { + case 1: + shouldKeepOpen = Flags_GetEventChkInf(EVENTCHKINF_OPENED_ZORAS_DOMAIN); + break; + case 2: + if (IS_RANDO && RAND_GET_OPTION(RSK_SLEEPING_WATERFALL) == RO_WATERFALL_OPEN) { + shouldKeepOpen = true; + } else { + shouldKeepOpen = CHECK_QUEST_ITEM(QUEST_SONG_LULLABY) && + (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME || + INV_CONTENT(ITEM_OCARINA_FAIRY) == ITEM_OCARINA_FAIRY); + } + break; + default: + shouldKeepOpen = false; + break; + } + + if (!shouldKeepOpen) { + return; + } + + BgSpot03Taki* bgSpot03 = static_cast(innerActorRef); + if (bgSpot03->actionFunc == BgSpot03Taki_HandleWaterfallState) { + bgSpot03->actionFunc = BgSpot03Taki_KeepOpen; + bgSpot03->state = WATERFALL_OPENED; + bgSpot03->openingAlpha = 0.0f; + Flags_SetSwitch(gPlayState, bgSpot03->switchFlag); + func_8003EBF8(gPlayState, &gPlayState->colCtx.dyna, bgSpot03->dyna.bgId); + BgSpot03Taki_ApplyOpeningAlpha(bgSpot03, 0); + BgSpot03Taki_ApplyOpeningAlpha(bgSpot03, 1); + + GameInteractor::Instance->UnregisterGameHook(bgSpot03UpdateHook); + GameInteractor::Instance->UnregisterGameHook(bgSpot03KillHook); + bgSpot03UpdateHook = 0; + bgSpot03KillHook = 0; + } + }); + bgSpot03KillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) mutable { + GameInteractor::Instance->UnregisterGameHook(bgSpot03UpdateHook); + GameInteractor::Instance->UnregisterGameHook(bgSpot03KillHook); + bgSpot03UpdateHook = 0; + bgSpot03KillHook = 0; + }); + } + if (actor->id == ACTOR_EN_DNT_DEMO && (IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO))) { EnDntDemo* enDntDemo = static_cast(actorRef); enDntDemo->actionFunc = EnDntDemo_JudgeSkipToReward; @@ -774,8 +897,8 @@ void TimeSaverOnActorInitHandler(void* actorRef) { // This is a bit of a hack, we can't effectively override the behavior of the torches // or poes from which the cutscene is triggered until we can have a "BeforeActorInit" hook. // So for now we're just going to set the flag before they get to the room the cutscene is in - if (gPlayState->sceneNum == SCENE_FOREST_TEMPLE && actor->id == ACTOR_EN_ST && !Flags_GetSwitch(gPlayState, 0x1B)) { - if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) { + if (gPlayState->sceneNum == SCENE_FOREST_TEMPLE && actor->id == ACTOR_EN_ST && !Flags_GetSwitch(gPlayState, 0x1B) && !Flags_GetSwitch(gPlayState, 0x1C)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), 0) && !CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) { Flags_SetSwitch(gPlayState, 0x1B); } } @@ -801,11 +924,20 @@ void TimeSaverOnActorInitHandler(void* actorRef) { // Fire Temple Darunia cutscene if (actor->id == ACTOR_EN_DU && gPlayState->sceneNum == SCENE_FIRE_TEMPLE) { - if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), 0) && !CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) { Flags_SetInfTable(INFTABLE_SPOKE_TO_DARUNIA_IN_FIRE_TEMPLE); Actor_Kill(actor); } } + + // Water Temple Ruto cutscene + if (actor->id == ACTOR_EN_RU2 && gPlayState->sceneNum == SCENE_WATER_TEMPLE) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + EnRu2* enRu2 = (EnRu2*)actor; + EnRu2_SetEncounterSwitchFlag(enRu2, gPlayState); + Actor_Kill(actor); + } + } } void TimeSaverOnSceneInitHandler(int16_t sceneNum) { @@ -882,120 +1014,149 @@ void TimeSaverOnSceneInitHandler(int16_t sceneNum) { } } break; + case SCENE_GANONDORF_BOSS: + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"), IS_RANDO)) { + if (!Flags_GetEventChkInf(EVENTCHKINF_BEGAN_GANONDORF_BATTLE)) { + Flags_SetEventChkInf(EVENTCHKINF_BEGAN_GANONDORF_BATTLE); + } + } + break; } } static GetItemEntry vanillaQueuedItemEntry = GET_ITEM_NONE; void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) { - if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) return; + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + switch (flagType) { + case FLAG_EVENT_CHECK_INF: + switch (flag) { + case EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FAIRY_OCARINA).GetGIEntry_Copy(); + break; + case EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_KOKIRI_EMERALD).GetGIEntry_Copy(); + break; + case EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_GORON_RUBY).GetGIEntry_Copy(); + break; + case EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_ZORA_SAPPHIRE).GetGIEntry_Copy(); + break; + case EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FOREST_MEDALLION).GetGIEntry_Copy(); + break; + case EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FIRE_MEDALLION).GetGIEntry_Copy(); + break; + case EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_WATER_MEDALLION).GetGIEntry_Copy(); + break; + case EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_LIGHT_ARROWS).GetGIEntry_Copy(); + break; + case EVENTCHKINF_TIME_TRAVELED_TO_ADULT: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_LIGHT_MEDALLION).GetGIEntry_Copy(); + break; + } + break; + case FLAG_RANDOMIZER_INF: + switch (flag) { + case RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SHADOW_MEDALLION).GetGIEntry_Copy(); + break; + case RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SPIRIT_MEDALLION).GetGIEntry_Copy(); + break; + } + break; + } + } - switch (flagType) { - case FLAG_EVENT_CHECK_INF: - switch (flag) { - case EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FAIRY_OCARINA).GetGIEntry_Copy(); - break; - case EVENTCHKINF_LEARNED_ZELDAS_LULLABY: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_ZELDAS_LULLABY).GetGIEntry_Copy(); - break; - case EVENTCHKINF_LEARNED_MINUET_OF_FOREST: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MINUET_OF_FOREST).GetGIEntry_Copy(); - break; - case EVENTCHKINF_LEARNED_BOLERO_OF_FIRE: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_BOLERO_OF_FIRE).GetGIEntry_Copy(); - break; - case EVENTCHKINF_LEARNED_SERENADE_OF_WATER: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SERENADE_OF_WATER).GetGIEntry_Copy(); - break; - case EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_REQUIEM_OF_SPIRIT).GetGIEntry_Copy(); - break; - case EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_NOCTURNE_OF_SHADOW).GetGIEntry_Copy(); - break; - case EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_PRELUDE_OF_LIGHT).GetGIEntry_Copy(); - break; - case EVENTCHKINF_LEARNED_SARIAS_SONG: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SARIAS_SONG).GetGIEntry_Copy(); - break; - case EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_KOKIRI_EMERALD).GetGIEntry_Copy(); - break; - case EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_GORON_RUBY).GetGIEntry_Copy(); - break; - case EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_ZORA_SAPPHIRE).GetGIEntry_Copy(); - break; - case EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FOREST_MEDALLION).GetGIEntry_Copy(); - break; - case EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FIRE_MEDALLION).GetGIEntry_Copy(); - break; - case EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_WATER_MEDALLION).GetGIEntry_Copy(); - break; - case EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_LIGHT_ARROWS).GetGIEntry_Copy(); - break; - case EVENTCHKINF_TIME_TRAVELED_TO_ADULT: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_LIGHT_MEDALLION).GetGIEntry_Copy(); - break; - case EVENTCHKINF_LEARNED_SONG_OF_TIME: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_TIME).GetGIEntry_Copy(); - break; - case EVENTCHKINF_LEARNED_SONG_OF_STORMS: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_STORMS).GetGIEntry_Copy(); - break; - case EVENTCHKINF_LEARNED_SUNS_SONG: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SUNS_SONG).GetGIEntry_Copy(); - break; - } - break; - case FLAG_RANDOMIZER_INF: - switch (flag) { - case RAND_INF_LEARNED_EPONA_SONG: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_EPONAS_SONG).GetGIEntry_Copy(); - break; - case RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SHADOW_MEDALLION).GetGIEntry_Copy(); - break; - case RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SPIRIT_MEDALLION).GetGIEntry_Copy(); - break; - case RAND_INF_ZF_GREAT_FAIRY_REWARD: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FARORES_WIND).GetGIEntry_Copy(); - break; - case RAND_INF_HC_GREAT_FAIRY_REWARD: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DINS_FIRE).GetGIEntry_Copy(); - break; - case RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_NAYRUS_LOVE).GetGIEntry_Copy(); - break; - case RAND_INF_DMT_GREAT_FAIRY_REWARD: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MAGIC_SINGLE).GetGIEntry_Copy(); - break; - case RAND_INF_DMC_GREAT_FAIRY_REWARD: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MAGIC_DOUBLE).GetGIEntry_Copy(); - break; - case RAND_INF_OGC_GREAT_FAIRY_REWARD: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DOUBLE_DEFENSE).GetGIEntry_Copy(); - break; - } - break; - case FLAG_ITEM_GET_INF: - switch (flag) { - case ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DEKU_STICK_CAPACITY_30).GetGIEntry_Copy(); - break; - case ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE: - vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DEKU_NUT_CAPACITY_40).GetGIEntry_Copy(); - break; - } - break; + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { + switch (flagType) { + case FLAG_RANDOMIZER_INF: + switch (flag) { + case RAND_INF_ZF_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_FARORES_WIND).GetGIEntry_Copy(); + break; + case RAND_INF_HC_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DINS_FIRE).GetGIEntry_Copy(); + break; + case RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_NAYRUS_LOVE).GetGIEntry_Copy(); + break; + case RAND_INF_DMT_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MAGIC_SINGLE).GetGIEntry_Copy(); + break; + case RAND_INF_DMC_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MAGIC_DOUBLE).GetGIEntry_Copy(); + break; + case RAND_INF_OGC_GREAT_FAIRY_REWARD: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DOUBLE_DEFENSE).GetGIEntry_Copy(); + break; + } + break; + case FLAG_ITEM_GET_INF: + switch (flag) { + case ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DEKU_STICK_CAPACITY_30).GetGIEntry_Copy(); + break; + case ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DEKU_NUT_CAPACITY_40).GetGIEntry_Copy(); + break; + } + break; + } + } + + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), IS_RANDO)) { + switch (flagType) { + case FLAG_EVENT_CHECK_INF: + switch (flag) { + case EVENTCHKINF_LEARNED_ZELDAS_LULLABY: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_ZELDAS_LULLABY).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_MINUET_OF_FOREST: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_MINUET_OF_FOREST).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_BOLERO_OF_FIRE: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_BOLERO_OF_FIRE).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_SERENADE_OF_WATER: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SERENADE_OF_WATER).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_REQUIEM_OF_SPIRIT).GetGIEntry_Copy(); + break; + case EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_NOCTURNE_OF_SHADOW).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_PRELUDE_OF_LIGHT).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_SARIAS_SONG: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SARIAS_SONG).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_SONG_OF_TIME: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_TIME).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_SONG_OF_STORMS: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SONG_OF_STORMS).GetGIEntry_Copy(); + break; + case EVENTCHKINF_LEARNED_SUNS_SONG: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_SUNS_SONG).GetGIEntry_Copy(); + break; + } + break; + case FLAG_RANDOMIZER_INF: + switch (flag) { + case RAND_INF_LEARNED_EPONA_SONG: + vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_EPONAS_SONG).GetGIEntry_Copy(); + break; + } + break; + } } } diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.cpp b/soh/soh/Enhancements/timesplits/TimeSplits.cpp index 6f47ba347..57a73dd6f 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.cpp +++ b/soh/soh/Enhancements/timesplits/TimeSplits.cpp @@ -60,148 +60,148 @@ std::vector splitList; std::vector emptyList; std::vector splitObjectList = { - { SPLIT_ITEM, ITEM_STICK, "Deku Stick", "ITEM_STICK", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_NUT, "Deku Nut", "ITEM_NUT", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_BOMB, "Bomb", "ITEM_BOMB", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_BOW, "Fairy Bow", "ITEM_BOW", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_OCARINA_TIME, "Ocarina of Time", "ITEM_OCARINA_TIME", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_LONGSHOT, "Longshot", "ITEM_LONGSHOT", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_LENS, "Lens of Truth", "ITEM_LENS", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_BEAN, "Magic Bean", "ITEM_BEAN", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_POTION_RED, "Red Potion", "ITEM_POTION_RED", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_POTION_GREEN, "Green Potion", "ITEM_POTION_GREEN", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_POTION_BLUE, "Blue Potion", "ITEM_POTION_BLUE", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_FAIRY, "Bottled Fairy", "ITEM_FAIRY", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_FISH, "Fish", "ITEM_FISH", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_MILK_BOTTLE, "Milk", "ITEM_MILK_BOTTLE", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_LETTER_RUTO, "Ruto's Letter", "ITEM_LETTER_RUTO", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_BLUE_FIRE, "Blue Fire", "ITEM_BLUE_FIRE", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_BUG, "Bug", "ITEM_BUG", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_BIG_POE, "Big Poe", "ITEM_BIG_POE", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_POE, "Poe", "ITEM_POE", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_CHICKEN, "Chicken", "ITEM_CHICKEN", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_LETTER_ZELDA, "Zelda's Letter", "ITEM_LETTER_ZELDA", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_MASK_KEATON, "Keaton Mask", "ITEM_MASK_KEATON", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_MASK_SKULL, "Skull Mask", "ITEM_MASK_SKULL", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_MASK_SPOOKY, "Spooky Mask", "ITEM_MASK_SPOOKY", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_MASK_BUNNY, "Bunny Hood", "ITEM_MASK_BUNNY", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_MASK_GORON, "Goron Mask", "ITEM_MASK_GORON", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_MASK_ZORA, "Zora Mask", "ITEM_MASK_ZORA", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_MASK_GERUDO, "Gerudo Mask", "ITEM_MASK_GERUDO", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_MASK_TRUTH, "Mask of Truth", "ITEM_MASK_TRUTH", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_POCKET_CUCCO, "Pocket Cucco", "ITEM_POCKET_CUCCO", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_COJIRO, "Cojiro", "ITEM_COJIRO", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_ODD_MUSHROOM, "Odd Mushroom", "ITEM_ODD_MUSHROOM", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_ODD_POTION, "Odd Potion", "ITEM_ODD_POTION", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_SAW, "Poacher's Saw", "ITEM_SAW", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_SWORD_BROKEN, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_PRESCRIPTION, "Prescription", "ITEM_PRESCRIPTION", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_FROG, "Eyeball Frog", "ITEM_FROG", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_EYEDROPS, "Eye Drops", "ITEM_EYEDROPS", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_CLAIM_CHECK, "Claim Check", "ITEM_CLAIM_CHECK", COLOR_WHITE }, - { SPLIT_EQUIPMENT, ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI", COLOR_WHITE }, - { SPLIT_EQUIPMENT, ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER", COLOR_WHITE }, - { SPLIT_EQUIPMENT, ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS", COLOR_WHITE }, - { SPLIT_EQUIPMENT, ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU", COLOR_WHITE }, - { SPLIT_EQUIPMENT, ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN", COLOR_WHITE }, - { SPLIT_EQUIPMENT, ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR", COLOR_WHITE }, - { SPLIT_EQUIPMENT, ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON", COLOR_WHITE }, - { SPLIT_EQUIPMENT, ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA", COLOR_WHITE }, - { SPLIT_EQUIPMENT, ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON", COLOR_WHITE }, - { SPLIT_EQUIPMENT, ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_BULLET_BAG_30, "Bullet Bag (30)", "ITEM_BULLET_BAG_30", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_BULLET_BAG_40, "Bullet Bag (40)", "ITEM_BULLET_BAG_40", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_BULLET_BAG_50, "Bullet Bag (50)", "ITEM_BULLET_BAG_50", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_QUIVER_30, "Quiver (30)", "ITEM_QUIVER_30", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_QUIVER_40, "Big Quiver (40)", "ITEM_QUIVER_40", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_QUIVER_50, "Biggest Quiver (50)", "ITEM_QUIVER_50", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_BOMB_BAG_20, "Bomb Bag (20)", "ITEM_BOMB_BAG_20", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_BOMB_BAG_30, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_BOMB_BAG_40, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_GAUNTLETS_SILVER, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_GAUNTLETS_GOLD, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_SCALE_GOLDEN, "Golden Scale", "ITEM_SCALE_GOLDEN", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_SWORD_KNIFE, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_WALLET_GIANT, "Giant's Wallet", "ITEM_WALLET_GIANT", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD", COLOR_WHITE }, - { SPLIT_QUEST, ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_SINGLE_MAGIC, "Magic Meter", "ITEM_MAGIC_SMALL", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_DOUBLE_MAGIC, "Double Magic", "ITEM_MAGIC_LARGE", COLOR_WHITE }, - { SPLIT_ITEM, ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_STICK_UPGRADE_20, "Deku Stick Upgrade (20)", "ITEM_STICK", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_NUT_UPGRADE_30, "Deku Nut Upgrade (30)", "ITEM_NUT", COLOR_WHITE }, - { SPLIT_UPGRADE, ITEM_NUT_UPGRADE_40, "Deku Nut Upgrade (40)", "ITEM_NUT", COLOR_WHITE }, - { SPLIT_BOSS, ACTOR_BOSS_GOMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_LIGHT_GREEN }, - { SPLIT_BOSS, ACTOR_BOSS_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_LIGHT_RED }, - { SPLIT_BOSS, ACTOR_BOSS_VA, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_LIGHT_BLUE }, - { SPLIT_BOSS, ACTOR_BOSS_GANONDROF, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_GREEN }, - { SPLIT_BOSS, ACTOR_BOSS_FD2, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_RED }, - { SPLIT_BOSS, ACTOR_BOSS_MO, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_BLUE }, - { SPLIT_BOSS, ACTOR_BOSS_SST, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_PURPLE }, - { SPLIT_BOSS, ACTOR_BOSS_TW, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_ORANGE }, - { SPLIT_BOSS, ACTOR_BOSS_GANON, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_GREY }, - { SPLIT_BOSS, ACTOR_BOSS_GANON2, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_YELLOW }, - { SPLIT_ENTRANCE, SCENE_DEKU_TREE, "Enter Deku Tree", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Grounds", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_ENTRANCE, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_MISC, SCENE_ZORAS_RIVER, "Lost Woods Escape", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_MISC, SCENE_LOST_WOODS, "Forest Escape", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, - { SPLIT_MISC, SCENE_KAKARIKO_VILLAGE, "Watchtower Death", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_STICK, "Deku Stick", "ITEM_STICK", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_NUT, "Deku Nut", "ITEM_NUT", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_BOMB, "Bomb", "ITEM_BOMB", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_BOW, "Fairy Bow", "ITEM_BOW", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_ARROW_FIRE, "Fire Arrow", "ITEM_ARROW_FIRE", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_DINS_FIRE, "Din's Fire", "ITEM_DINS_FIRE", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_SLINGSHOT, "Fairy Slingshot", "ITEM_SLINGSHOT", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_OCARINA_FAIRY, "Fairy Ocarina", "ITEM_OCARINA_FAIRY", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_OCARINA_TIME, "Ocarina of Time", "ITEM_OCARINA_TIME", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_BOMBCHU, "Bombchu", "ITEM_BOMBCHU", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_HOOKSHOT, "Hookshot", "ITEM_HOOKSHOT", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_LONGSHOT, "Longshot", "ITEM_LONGSHOT", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_ARROW_ICE, "Ice Arrow", "ITEM_ARROW_ICE", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_FARORES_WIND, "Farore's Wind", "ITEM_FARORES_WIND", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_BOOMERANG, "Boomerang", "ITEM_BOOMERANG", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_LENS, "Lens of Truth", "ITEM_LENS", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_BEAN, "Magic Bean", "ITEM_BEAN", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_HAMMER, "Megaton Hammer", "ITEM_HAMMER", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_ARROW_LIGHT, "Light Arrow", "ITEM_ARROW_LIGHT", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_NAYRUS_LOVE, "Nayru's Love", "ITEM_NAYRUS_LOVE", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_BOTTLE, "Empty Bottle", "ITEM_BOTTLE", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_POTION_RED, "Red Potion", "ITEM_POTION_RED", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_POTION_GREEN, "Green Potion", "ITEM_POTION_GREEN", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_POTION_BLUE, "Blue Potion", "ITEM_POTION_BLUE", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_FAIRY, "Bottled Fairy", "ITEM_FAIRY", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_FISH, "Fish", "ITEM_FISH", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_MILK_BOTTLE, "Milk", "ITEM_MILK_BOTTLE", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_LETTER_RUTO, "Ruto's Letter", "ITEM_LETTER_RUTO", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_BLUE_FIRE, "Blue Fire", "ITEM_BLUE_FIRE", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_BUG, "Bug", "ITEM_BUG", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_BIG_POE, "Big Poe", "ITEM_BIG_POE", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_POE, "Poe", "ITEM_POE", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_WEIRD_EGG, "Weird Egg", "ITEM_WEIRD_EGG", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_CHICKEN, "Chicken", "ITEM_CHICKEN", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_LETTER_ZELDA, "Zelda's Letter", "ITEM_LETTER_ZELDA", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_MASK_KEATON, "Keaton Mask", "ITEM_MASK_KEATON", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_MASK_SKULL, "Skull Mask", "ITEM_MASK_SKULL", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_MASK_SPOOKY, "Spooky Mask", "ITEM_MASK_SPOOKY", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_MASK_BUNNY, "Bunny Hood", "ITEM_MASK_BUNNY", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_MASK_GORON, "Goron Mask", "ITEM_MASK_GORON", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_MASK_ZORA, "Zora Mask", "ITEM_MASK_ZORA", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_MASK_GERUDO, "Gerudo Mask", "ITEM_MASK_GERUDO", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_MASK_TRUTH, "Mask of Truth", "ITEM_MASK_TRUTH", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_POCKET_EGG, "Pocket Egg", "ITEM_POCKET_EGG", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_POCKET_CUCCO, "Pocket Cucco", "ITEM_POCKET_CUCCO", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_COJIRO, "Cojiro", "ITEM_COJIRO", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_ODD_MUSHROOM, "Odd Mushroom", "ITEM_ODD_MUSHROOM", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_ODD_POTION, "Odd Potion", "ITEM_ODD_POTION", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_SAW, "Poacher's Saw", "ITEM_SAW", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_SWORD_BROKEN, "Goron's Sword (Broken)", "ITEM_SWORD_BROKEN", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_PRESCRIPTION, "Prescription", "ITEM_PRESCRIPTION", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_FROG, "Eyeball Frog", "ITEM_FROG", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_EYEDROPS, "Eye Drops", "ITEM_EYEDROPS", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_CLAIM_CHECK, "Claim Check", "ITEM_CLAIM_CHECK", COLOR_WHITE }, + { SPLIT_TYPE_EQUIPMENT, ITEM_SWORD_KOKIRI, "Kokiri Sword", "ITEM_SWORD_KOKIRI", COLOR_WHITE }, + { SPLIT_TYPE_EQUIPMENT, ITEM_SWORD_MASTER, "Master Sword", "ITEM_SWORD_MASTER", COLOR_WHITE }, + { SPLIT_TYPE_EQUIPMENT, ITEM_SWORD_BGS, "Giant's Knife & Biggoron's Sword", "ITEM_SWORD_BGS", COLOR_WHITE }, + { SPLIT_TYPE_EQUIPMENT, ITEM_SHIELD_DEKU, "Deku Shield", "ITEM_SHIELD_DEKU", COLOR_WHITE }, + { SPLIT_TYPE_EQUIPMENT, ITEM_SHIELD_HYLIAN, "Hylian Shield", "ITEM_SHIELD_HYLIAN", COLOR_WHITE }, + { SPLIT_TYPE_EQUIPMENT, ITEM_SHIELD_MIRROR, "Mirror Shield", "ITEM_SHIELD_MIRROR", COLOR_WHITE }, + { SPLIT_TYPE_EQUIPMENT, ITEM_TUNIC_GORON, "Goron Tunic", "ITEM_TUNIC_GORON", COLOR_WHITE }, + { SPLIT_TYPE_EQUIPMENT, ITEM_TUNIC_ZORA, "Zora Tunic", "ITEM_TUNIC_ZORA", COLOR_WHITE }, + { SPLIT_TYPE_EQUIPMENT, ITEM_BOOTS_IRON, "Iron Boots", "ITEM_BOOTS_IRON", COLOR_WHITE }, + { SPLIT_TYPE_EQUIPMENT, ITEM_BOOTS_HOVER, "Hover Boots", "ITEM_BOOTS_HOVER", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_BULLET_BAG_30, "Bullet Bag (30)", "ITEM_BULLET_BAG_30", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_BULLET_BAG_40, "Bullet Bag (40)", "ITEM_BULLET_BAG_40", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_BULLET_BAG_50, "Bullet Bag (50)", "ITEM_BULLET_BAG_50", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_QUIVER_30, "Quiver (30)", "ITEM_QUIVER_30", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_QUIVER_40, "Big Quiver (40)", "ITEM_QUIVER_40", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_QUIVER_50, "Biggest Quiver (50)", "ITEM_QUIVER_50", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_BOMB_BAG_20, "Bomb Bag (20)", "ITEM_BOMB_BAG_20", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_BOMB_BAG_30, "Big Bomb Bag (30)", "ITEM_BOMB_BAG_30", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_BOMB_BAG_40, "Biggest Bomb Bag (40)", "ITEM_BOMB_BAG_40", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_BRACELET, "Goron's Bracelet", "ITEM_BRACELET", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_GAUNTLETS_SILVER, "Silver Gauntlets", "ITEM_GAUNTLETS_SILVER", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_GAUNTLETS_GOLD, "Golden Gauntlets", "ITEM_GAUNTLETS_GOLD", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_SCALE_SILVER, "Silver Scale", "ITEM_SCALE_SILVER", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_SCALE_GOLDEN, "Golden Scale", "ITEM_SCALE_GOLDEN", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_SWORD_KNIFE, "Giant's Knife (Broken)", "ITEM_SWORD_KNIFE", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_WALLET_ADULT, "Adult's Wallet", "ITEM_WALLET_ADULT", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_WALLET_GIANT, "Giant's Wallet", "ITEM_WALLET_GIANT", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_FISHING_POLE, "Fishing Pole", "ITEM_FISHING_POLE", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_MINUET, "Minuet of Forest", "QUEST_SONG_MINUET", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_BOLERO, "Bolero of Fire", "QUEST_SONG_BOLERO", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_SERENADE, "Serenade of Water", "QUEST_SONG_SERENADE", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_REQUIEM, "Requiem of Spirit", "QUEST_SONG_REQUIEM", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_NOCTURNE, "Nocturne of Shadow", "QUEST_SONG_NOCTURNE", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_PRELUDE, "Prelude of Light", "QUEST_SONG_PRELUDE", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_LULLABY, "Zelda's Lullaby", "QUEST_SONG_LULLABY", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_EPONA, "Epona's Song", "QUEST_SONG_EPONA", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_SARIA, "Saria's Song", "QUEST_SONG_SARIA", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_SUN, "Sun's Song", "QUEST_SONG_SUN", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_TIME, "Song of Time", "QUEST_SONG_TIME", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SONG_STORMS, "Song of Storms", "QUEST_SONG_STORMS", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_MEDALLION_FOREST, "Forest Medallion", "QUEST_MEDALLION_FOREST", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_MEDALLION_FIRE, "Fire Medallion", "QUEST_MEDALLION_FIRE", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_MEDALLION_WATER, "Water Medallion", "QUEST_MEDALLION_WATER", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_MEDALLION_SPIRIT, "Spirit Medallion", "QUEST_MEDALLION_SPIRIT", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_MEDALLION_SHADOW, "Shadow Medallion", "QUEST_MEDALLION_SHADOW", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_MEDALLION_LIGHT, "Light Medallion", "QUEST_MEDALLION_LIGHT", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_KOKIRI_EMERALD, "Kokiri's Emerald", "QUEST_KOKIRI_EMERALD", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_GORON_RUBY, "Goron's Ruby", "QUEST_GORON_RUBY", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_ZORA_SAPPHIRE, "Zora's Sapphire", "QUEST_ZORA_SAPPHIRE", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_STONE_OF_AGONY, "Stone of Agony", "QUEST_STONE_OF_AGONY", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_GERUDO_CARD, "Gerudo's Card", "QUEST_GERUDO_CARD", COLOR_WHITE }, + { SPLIT_TYPE_QUEST, ITEM_SKULL_TOKEN, "Skulltula Token", "QUEST_SKULL_TOKEN", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_SINGLE_MAGIC, "Magic Meter", "ITEM_MAGIC_SMALL", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_DOUBLE_MAGIC, "Double Magic", "ITEM_MAGIC_LARGE", COLOR_WHITE }, + { SPLIT_TYPE_ITEM, ITEM_DOUBLE_DEFENSE, "Double Defense", "ITEM_HEART_CONTAINER", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_STICK_UPGRADE_20, "Deku Stick Upgrade (20)", "ITEM_STICK", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_STICK_UPGRADE_30, "Deku Stick Upgrade (30)", "ITEM_STICK", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_NUT_UPGRADE_30, "Deku Nut Upgrade (30)", "ITEM_NUT", COLOR_WHITE }, + { SPLIT_TYPE_UPGRADE, ITEM_NUT_UPGRADE_40, "Deku Nut Upgrade (40)", "ITEM_NUT", COLOR_WHITE }, + { SPLIT_TYPE_BOSS, ACTOR_BOSS_GOMA, "Queen Gohma", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_LIGHT_GREEN }, + { SPLIT_TYPE_BOSS, ACTOR_BOSS_DODONGO, "King Dodongo", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_LIGHT_RED }, + { SPLIT_TYPE_BOSS, ACTOR_BOSS_VA, "Barinade", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_LIGHT_BLUE }, + { SPLIT_TYPE_BOSS, ACTOR_BOSS_GANONDROF, "Phantom Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_GREEN }, + { SPLIT_TYPE_BOSS, ACTOR_BOSS_FD2, "Volvagia", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_RED }, + { SPLIT_TYPE_BOSS, ACTOR_BOSS_MO, "Morpha", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_BLUE }, + { SPLIT_TYPE_BOSS, ACTOR_BOSS_SST, "Bongo Bongo", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_PURPLE }, + { SPLIT_TYPE_BOSS, ACTOR_BOSS_TW, "Twinrova", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_ORANGE }, + { SPLIT_TYPE_BOSS, ACTOR_BOSS_GANON, "Ganondorf", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_GREY }, + { SPLIT_TYPE_BOSS, ACTOR_BOSS_GANON2, "Ganon", "SPECIAL_TRIFORCE_PIECE_WHITE", COLOR_YELLOW }, + { SPLIT_TYPE_ENTRANCE, SCENE_DEKU_TREE, "Enter Deku Tree", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_DODONGOS_CAVERN, "Enter Dodongos Cavern", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_JABU_JABU, "Enter Jabu Jabu's Belly", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_FOREST_TEMPLE, "Enter Forest Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_FIRE_TEMPLE, "Enter Fire Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_WATER_TEMPLE, "Enter Water Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_SPIRIT_TEMPLE, "Enter Spirit Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_SHADOW_TEMPLE, "Enter Shadow Temple", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_BOTTOM_OF_THE_WELL, "Enter Bottom of the Well", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_ICE_CAVERN, "Enter Ice Cavern", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_GANONS_TOWER, "Enter Ganons Tower", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_GERUDO_TRAINING_GROUND, "Enter Gerudo Training Ground", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_THIEVES_HIDEOUT, "Enter Thieves Hideout", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_INSIDE_GANONS_CASTLE, "Enter Ganons Castle", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, "Enter Tower Collapse Interior", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_ENTRANCE, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, "Enter Ganons Castle Collapse", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_MISC, SCENE_ZORAS_RIVER, "Lost Woods Escape", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_MISC, SCENE_LOST_WOODS, "Forest Escape", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, + { SPLIT_TYPE_MISC, SCENE_KAKARIKO_VILLAGE, "Watchtower Death", "SPECIAL_SPLIT_ENTRANCE", COLOR_WHITE }, }; std::map> popupList = { @@ -212,10 +212,10 @@ std::map> popupList = { { ITEM_SLINGSHOT, { ITEM_BULLET_BAG_30, ITEM_BULLET_BAG_40, ITEM_BULLET_BAG_50 } }, { ITEM_OCARINA_FAIRY, { ITEM_OCARINA_FAIRY, ITEM_OCARINA_TIME } }, { ITEM_HOOKSHOT, { ITEM_HOOKSHOT, ITEM_LONGSHOT } }, - { ITEM_BOTTLE, { ITEM_BOTTLE, ITEM_POTION_RED, ITEM_POTION_GREEN, ITEM_POTION_BLUE, + { ITEM_BOTTLE, { ITEM_BOTTLE, ITEM_POTION_RED, ITEM_POTION_GREEN, ITEM_POTION_BLUE, ITEM_FAIRY, ITEM_FISH, ITEM_MILK_BOTTLE, ITEM_LETTER_RUTO, ITEM_BLUE_FIRE, ITEM_BUG, ITEM_BIG_POE, ITEM_POE } }, - { ITEM_WEIRD_EGG, { ITEM_WEIRD_EGG, ITEM_CHICKEN, ITEM_LETTER_ZELDA, ITEM_MASK_KEATON, + { ITEM_WEIRD_EGG, { ITEM_WEIRD_EGG, ITEM_CHICKEN, ITEM_LETTER_ZELDA, ITEM_MASK_KEATON, ITEM_MASK_SKULL, ITEM_MASK_SPOOKY, ITEM_MASK_BUNNY, ITEM_MASK_GORON, ITEM_MASK_ZORA, ITEM_MASK_GERUDO, ITEM_MASK_TRUTH } }, { ITEM_POCKET_EGG, { ITEM_POCKET_EGG, ITEM_POCKET_CUCCO, ITEM_COJIRO, ITEM_ODD_MUSHROOM, @@ -271,7 +271,7 @@ nlohmann::json SplitObject_to_json(const SplitObject& split) { {"splitTimeCurrent", split.splitTimeCurrent}, {"splitTimeBest", split.splitTimeBest}, {"splitTimePreviousBest", split.splitTimePreviousBest}, - {"splitTimeStatus", SPLIT_INACTIVE}, + {"splitTimeStatus", SPLIT_STATUS_INACTIVE}, {"splitSkullTokenCount", split.splitSkullTokenCount} }; } @@ -301,18 +301,28 @@ void TimeSplitsGetImageSize(uint32_t item) { } } +void SplitsPushImageButtonStyle(){ + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 1.0f, 1.0f, 0.0f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 1.0f, 1.0f, 0.2f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 1.0f, 1.0f, 0.1f)); +} + +void SplitsPopImageButtonStyle(){ + ImGui::PopStyleColor(3); +} + void TimeSplitsUpdateSplitStatus() { uint32_t index = 0; for (auto& data : splitList) { - if (data.splitTimeStatus == SPLIT_INACTIVE || data.splitTimeStatus == SPLIT_ACTIVE) { - data.splitTimeStatus = SPLIT_ACTIVE; + if (data.splitTimeStatus == SPLIT_STATUS_INACTIVE || data.splitTimeStatus == SPLIT_STATUS_ACTIVE) { + data.splitTimeStatus = SPLIT_STATUS_ACTIVE; break; } index++; } - for (int i = index; i < splitList.size(); i++) { - if (splitList[i].splitTimeStatus != SPLIT_ACTIVE && splitList[i].splitTimeStatus != SPLIT_COLLECTED) { - splitList[i].splitTimeStatus = SPLIT_INACTIVE; + for (size_t i = index; i < splitList.size(); i++) { + if (splitList[i].splitTimeStatus != SPLIT_STATUS_ACTIVE && splitList[i].splitTimeStatus != SPLIT_STATUS_COLLECTED) { + splitList[i].splitTimeStatus = SPLIT_STATUS_INACTIVE; } } } @@ -340,7 +350,7 @@ void TimeSplitCompleteSplits() { } void TimeSplitsSkipSplit(uint32_t index) { - splitList[index].splitTimeStatus = SPLIT_SKIPPED; + splitList[index].splitTimeStatus = SPLIT_STATUS_SKIPPED; if (index + 1 == splitList.size()) { TimeSplitCompleteSplits(); } else { @@ -359,7 +369,7 @@ void TimeSplitsFileManagement(uint32_t action, const char* listEntry, std::vecto inputFile.close(); } - if (action == ACTION_SAVE) { + if (action == SPLIT_ACTION_SAVE) { for (auto& data : listData) { listArray.push_back(SplitObject_to_json(data)); } @@ -373,7 +383,7 @@ void TimeSplitsFileManagement(uint32_t action, const char* listEntry, std::vecto } } - if (action == ACTION_LOAD) { + if (action == SPLIT_ACTION_LOAD) { if (saveFile.contains(listEntry)) { listArray = saveFile[listEntry]; splitList.clear(); @@ -381,11 +391,11 @@ void TimeSplitsFileManagement(uint32_t action, const char* listEntry, std::vecto for (auto& data : listArray) { splitList.push_back(json_to_SplitObject(data)); } - splitList[0].splitTimeStatus = SPLIT_ACTIVE; + splitList[0].splitTimeStatus = SPLIT_STATUS_ACTIVE; } } - if (action == ACTION_UPDATE) { + if (action == SPLIT_ACTION_UPDATE) { for (auto& update : listData) { if (update.splitTimeBest < update.splitTimePreviousBest) { update.splitTimePreviousBest = update.splitTimeBest; @@ -393,7 +403,7 @@ void TimeSplitsFileManagement(uint32_t action, const char* listEntry, std::vecto } } - if (action == ACTION_COLLECT) { + if (action == SPLIT_ACTION_COLLECT) { keys.clear(); for (auto& data : saveFile.items()) { keys.push_back(data.key()); @@ -403,7 +413,7 @@ void TimeSplitsFileManagement(uint32_t action, const char* listEntry, std::vecto } } - if (action == ACTION_DELETE) { + if (action == SPLIT_ACTION_DELETE) { if (saveFile.contains(listEntry)) { saveFile.erase(listEntry); @@ -421,11 +431,28 @@ void TimeSplitsPopUpContext() { if (popupID == ITEM_SKULL_TOKEN) { ImGui::BeginTable("Token Table", 2); ImGui::TableNextColumn(); + SplitsPushImageButtonStyle(); ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("QUEST_SKULL_TOKEN"), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 2.0f, ImVec4(0, 0, 0, 0)); ImGui::TableNextColumn(); + SplitsPopImageButtonStyle(); ImGui::PushItemWidth(150.0f); + + ImGui::BeginGroup(); + std::string MinusBTNName = " - ##Set Tokens"; + ImGui::SameLine(); + if (ImGui::Button(MinusBTNName.c_str()) && skullTokenCount > 0) { + skullTokenCount--; + } + ImGui::SameLine(); ImGui::SliderInt("##count", &skullTokenCount, 0, 100, "%d Tokens"); + std::string PlusBTNName = " + ##Set Tokens"; + ImGui::SameLine(); + if (ImGui::Button(PlusBTNName.c_str()) && skullTokenCount < 100) { + skullTokenCount++; + } + ImGui::EndGroup(); + ImGui::PopItemWidth(); if (ImGui::Button("Set Tokens")) { auto findID = std::find_if(splitObjectList.begin(), splitObjectList.end(), [&](const SplitObject& obj) { return obj.splitID == ITEM_SKULL_TOKEN; }); @@ -442,6 +469,7 @@ void TimeSplitsPopUpContext() { ImGui::EndTable(); } else { int rowIndex = 0; + SplitsPushImageButtonStyle(); for (auto item : popupList[popupID]) { auto findID = std::find_if(splitObjectList.begin(), splitObjectList.end(), [&](const SplitObject& obj) { return obj.splitID == item; }); if (findID == splitObjectList.end()) { @@ -455,27 +483,27 @@ void TimeSplitsPopUpContext() { ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 2, ImVec4(0, 0, 0, 0), popupObject.splitTint)) { splitList.push_back(popupObject); if (splitList.size() == 1) { - splitList[0].splitTimeStatus = SPLIT_ACTIVE; + splitList[0].splitTimeStatus = SPLIT_STATUS_ACTIVE; } else { - splitList[splitList.size() - 1].splitTimeStatus = SPLIT_INACTIVE; + splitList[splitList.size() - 1].splitTimeStatus = SPLIT_STATUS_INACTIVE; } ImGui::CloseCurrentPopup(); popupID = -1; } ImGui::PopID(); - if (popupObject.splitType == SPLIT_UPGRADE) { + if (popupObject.splitType == SPLIT_TYPE_UPGRADE) { if (popupID <= ITEM_SLINGSHOT && popupID != -1) { ImVec2 imageMin = ImGui::GetItemRectMin(); ImVec2 imageMax = ImGui::GetItemRectMax(); - ImVec2 imageSize = ImVec2(imageMax.x - imageMin.x, imageMax.y - imageMin.y); + //ImVec2 imageSize = ImVec2(imageMax.x - imageMin.x, imageMax.y - imageMin.y); UNUSED ImVec2 textPos = ImVec2(imageMax.x - ImGui::CalcTextSize("00").x - 5, imageMax.y - ImGui::CalcTextSize("00").y - 5); ImGui::SetCursorScreenPos(textPos); std::string upgSubstr = popupObject.splitName.substr(popupObject.splitName.size() - 4); std::string upgOutput = removeSpecialCharacters(upgSubstr); - ImGui::Text(upgOutput.c_str()); + ImGui::Text("%s", upgOutput.c_str()); } } ImGui::EndGroup(); @@ -484,6 +512,7 @@ void TimeSplitsPopUpContext() { } rowIndex++; } + SplitsPopImageButtonStyle(); } ImGui::EndPopup(); } @@ -492,11 +521,11 @@ void TimeSplitsPopUpContext() { void TimeSplitsPostDragAndDrop() { if (dragTargetIndex != -1) { SplitObject tempSourceSplitObject = splitList[dragSourceIndex]; - if (tempSourceSplitObject.splitTimeStatus == SPLIT_ACTIVE) { - tempSourceSplitObject.splitTimeStatus = SPLIT_INACTIVE; + if (tempSourceSplitObject.splitTimeStatus == SPLIT_STATUS_ACTIVE) { + tempSourceSplitObject.splitTimeStatus = SPLIT_STATUS_INACTIVE; } - if (splitList[dragTargetIndex].splitTimeStatus == SPLIT_ACTIVE) { - splitList[dragTargetIndex].splitTimeStatus = SPLIT_INACTIVE; + if (splitList[dragTargetIndex].splitTimeStatus == SPLIT_STATUS_ACTIVE) { + splitList[dragTargetIndex].splitTimeStatus = SPLIT_STATUS_INACTIVE; } splitList.erase(splitList.begin() + dragSourceIndex); @@ -510,7 +539,7 @@ void TimeSplitsPostDragAndDrop() { void TimeSplitsItemSplitEvent(uint32_t type, u8 item) { uint32_t index = 0; - if (type <= SPLIT_QUEST) { + if (type <= SPLIT_TYPE_QUEST) { if (item == ITEM_NUTS_5 || item == ITEM_NUTS_10) { item = ITEM_NUT; } else if (item == ITEM_STICKS_5 || item == ITEM_STICKS_10) { @@ -529,20 +558,20 @@ void TimeSplitsItemSplitEvent(uint32_t type, u8 item) { } } } - if (type == SPLIT_ENTRANCE) { - if ((item == SCENE_ZORAS_RIVER && gSaveContext.entranceIndex == ENTR_ZORAS_RIVER_4) || + if (type == SPLIT_TYPE_ENTRANCE) { + if ((item == SCENE_ZORAS_RIVER && gSaveContext.entranceIndex == ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT) || (item == SCENE_LOST_WOODS && - (gSaveContext.entranceIndex == ENTR_LOST_WOODS_9 || gSaveContext.entranceIndex == ENTR_LOST_WOODS_0))) { - type = SPLIT_MISC; + (gSaveContext.entranceIndex == ENTR_LOST_WOODS_BRIDGE_EAST_EXIT || gSaveContext.entranceIndex == ENTR_LOST_WOODS_SOUTH_EXIT))) { + type = SPLIT_TYPE_MISC; } } for (auto& split : splitList) { if (split.splitType == type) { if (item == split.splitID) { - if (split.splitTimeStatus == SPLIT_ACTIVE) { + if (split.splitTimeStatus == SPLIT_STATUS_ACTIVE) { split.splitTimeCurrent = GAMEPLAYSTAT_TOTAL_TIME; - split.splitTimeStatus = SPLIT_COLLECTED; + split.splitTimeStatus = SPLIT_STATUS_COLLECTED; if (split.splitTimeBest > GAMEPLAYSTAT_TOTAL_TIME || split.splitTimeBest == 0) { split.splitTimeBest = GAMEPLAYSTAT_TOTAL_TIME; } @@ -552,7 +581,7 @@ void TimeSplitsItemSplitEvent(uint32_t type, u8 item) { if (index == splitList.size() - 1) { TimeSplitCompleteSplits(); } else { - splitList[index + 1].splitTimeStatus = SPLIT_ACTIVE; + splitList[index + 1].splitTimeStatus = SPLIT_STATUS_ACTIVE; } } } @@ -563,7 +592,7 @@ void TimeSplitsItemSplitEvent(uint32_t type, u8 item) { void TimeSplitsSplitBestTimeDisplay(SplitObject split) { activeSplitHighlight = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); - if (split.splitTimeStatus == SPLIT_ACTIVE) { + if (split.splitTimeStatus == SPLIT_STATUS_ACTIVE) { if (GAMEPLAYSTAT_TOTAL_TIME > split.splitTimePreviousBest) { splitTimeColor = COLOR_RED; splitBestTimeDisplay = (GAMEPLAYSTAT_TOTAL_TIME - split.splitTimePreviousBest); @@ -578,11 +607,11 @@ void TimeSplitsSplitBestTimeDisplay(SplitObject split) { } activeSplitHighlight = COLOR_LIGHT_BLUE; } - if (split.splitTimeStatus == SPLIT_INACTIVE) { + if (split.splitTimeStatus == SPLIT_STATUS_INACTIVE) { splitTimeColor = COLOR_WHITE; splitBestTimeDisplay = split.splitTimeBest; } - if (split.splitTimeStatus == SPLIT_COLLECTED) { + if (split.splitTimeStatus == SPLIT_STATUS_COLLECTED) { if (split.splitTimeCurrent > split.splitTimePreviousBest) { splitTimeColor = COLOR_RED; splitBestTimeDisplay = (split.splitTimeCurrent - split.splitTimePreviousBest); @@ -610,16 +639,14 @@ void TimeSplitsDrawSplitsList() { ImGui::TableSetupColumn("Prev. Best"); ImGui::TableHeadersRow(); - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 1.0f, 1.0f, 0.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 1.0f, 1.0f, 0.2f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 1.0f, 1.0f, 0.1f)); + SplitsPushImageButtonStyle(); for (auto& split : splitList) { ImGui::TableNextColumn(); TimeSplitsSplitBestTimeDisplay(split); ImGui::PushID(split.splitID); - if (split.splitTimeStatus == SPLIT_ACTIVE) { + if (split.splitTimeStatus == SPLIT_STATUS_ACTIVE) { ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, IM_COL32(47, 79, 90, 255)); } TimeSplitsGetImageSize(split.splitID); @@ -631,27 +658,27 @@ void TimeSplitsDrawSplitsList() { ImGui::TableNextColumn(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 5.0f)); ImGui::AlignTextToFramePadding(); - ImGui::TextWrapped(split.splitName.c_str()); + ImGui::TextWrapped("%s", split.splitName.c_str()); ImGui::TableNextColumn(); // Current Time - ImGui::Text((split.splitTimeStatus == SPLIT_ACTIVE) - ? formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str() : (split.splitTimeStatus == SPLIT_COLLECTED) + ImGui::Text("%s", (split.splitTimeStatus == SPLIT_STATUS_ACTIVE) + ? formatTimestampTimeSplit(GAMEPLAYSTAT_TOTAL_TIME).c_str() : (split.splitTimeStatus == SPLIT_STATUS_COLLECTED) ? formatTimestampTimeSplit(split.splitTimeCurrent).c_str() : "--:--:-"); ImGui::TableNextColumn(); // +/- Difference - ImGui::TextColored(splitTimeColor, formatTimestampTimeSplit(splitBestTimeDisplay).c_str()); + ImGui::TextColored(splitTimeColor, "%s", formatTimestampTimeSplit(splitBestTimeDisplay).c_str()); ImGui::TableNextColumn(); // Previous Best - ImGui::Text((split.splitTimePreviousBest != 0) ? formatTimestampTimeSplit(split.splitTimePreviousBest).c_str() : "--:--:-"); + ImGui::Text("%s", (split.splitTimePreviousBest != 0) ? formatTimestampTimeSplit(split.splitTimePreviousBest).c_str() : "--:--:-"); ImGui::PopID(); ImGui::PopStyleVar(1); dragIndex++; } + SplitsPopImageButtonStyle(); TimeSplitsPostDragAndDrop(); - ImGui::PopStyleColor(3); ImGui::PopStyleVar(1); ImGui::EndTable(); ImGui::EndChild(); @@ -659,11 +686,11 @@ void TimeSplitsDrawSplitsList() { void TimeSplitsGetTableSize(uint32_t type) { switch (type) { - case SPLIT_ITEM: - case SPLIT_QUEST: + case SPLIT_TYPE_ITEM: + case SPLIT_TYPE_QUEST: tableSize = 6; break; - case SPLIT_EQUIPMENT: + case SPLIT_TYPE_EQUIPMENT: tableSize = 3; break; default: @@ -677,11 +704,11 @@ void TimeSplitsDrawItemList(uint32_t type) { ImGui::BeginChild("Item Child"); ImGui::BeginTable("Item List", tableSize); - for (int i = 0; i < tableSize; i++) { + for (size_t i = 0; i < tableSize; i++) { if (i == 0) { ImGui::TableSetupColumn("Item Image", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 39.0f); } else { - if (type > SPLIT_QUEST) { + if (type > SPLIT_TYPE_QUEST) { ImGui::TableSetupColumn("Item Name"); } else { ImGui::TableSetupColumn(std::to_string(i).c_str(), ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 39.0f); @@ -689,19 +716,16 @@ void TimeSplitsDrawItemList(uint32_t type) { } } - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 1.0f, 1.0f, 0.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 1.0f, 1.0f, 0.2f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 1.0f, 1.0f, 0.1f)); - for (auto& split : splitObjectList) { if (split.splitType == type) { ImGui::TableNextColumn(); ImGui::PushID(split.splitID); TimeSplitsGetImageSize(split.splitID); + SplitsPushImageButtonStyle(); if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(split.splitImage), imageSize, ImVec2(0, 0), ImVec2(1, 1), imagePadding, ImVec4(0, 0, 0, 0), split.splitTint)) { - if (popupList.contains(split.splitID) && (split.splitType < SPLIT_BOSS)) { + if (popupList.contains(split.splitID) && (split.splitType < SPLIT_TYPE_BOSS)) { popupID = split.splitID; ImGui::OpenPopup("TimeSplitsPopUp"); } else { @@ -709,27 +733,27 @@ void TimeSplitsDrawItemList(uint32_t type) { if (splitList.size() == 1) { - splitList[0].splitTimeStatus = SPLIT_ACTIVE; + splitList[0].splitTimeStatus = SPLIT_STATUS_ACTIVE; } else { - splitList[splitList.size() - 1].splitTimeStatus = SPLIT_INACTIVE; + splitList[splitList.size() - 1].splitTimeStatus = SPLIT_STATUS_INACTIVE; } } } + SplitsPopImageButtonStyle(); TimeSplitsPopUpContext(); ImGui::PopID(); - if (type > SPLIT_QUEST) { + if (type > SPLIT_TYPE_QUEST) { ImGui::TableNextColumn(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 7.0f)); ImGui::AlignTextToFramePadding(); - ImGui::Text(split.splitName.c_str()); + ImGui::Text("%s", split.splitName.c_str()); ImGui::PopStyleVar(1); } } } - ImGui::PopStyleColor(3); ImGui::EndTable(); ImGui::EndChild(); } @@ -745,14 +769,18 @@ void TimeSplitsDrawOptionsMenu() { ImGui::SeparatorText("Window Options"); if (ImGui::ColorEdit4("Background Color", (float*)&windowColor, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) { Color_RGBA8 color; - color.r = windowColor.x; - color.g = windowColor.y; - color.b = windowColor.z; - color.a = windowColor.w; + color.r = windowColor.x * 255.0; + color.g = windowColor.y * 255.0; + color.b = windowColor.z * 255.0; + color.a = windowColor.w * 255.0; + CVarSetColor("TimeSplits.WindowColor", color); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); if (ImGui::Button("Reset")) { windowColor = { 0.0f, 0.0f, 0.0f, 1.0f }; + CVarSetColor("TimeSplits.WindowColor", {0, 0, 0, 1}); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (UIWidgets::PaddedEnhancementSliderFloat("Window Size: %.1fx", "##windowSize", @@ -768,11 +796,11 @@ void TimeSplitsDrawOptionsMenu() { ImGui::PopItemWidth(); ImGui::SameLine(); if (ImGui::Button("Create List")) { - TimeSplitsFileManagement(ACTION_SAVE, listNameBuf, splitList); + TimeSplitsFileManagement(SPLIT_ACTION_SAVE, listNameBuf, splitList); } UIWidgets::PaddedSeparator(); - TimeSplitsFileManagement(ACTION_COLLECT, "", emptyList); + TimeSplitsFileManagement(SPLIT_ACTION_COLLECT, "", emptyList); static uint32_t selectedItem = 0; static std::string listItem = keys[0]; ImGui::Text("Select List to Load: "); @@ -793,27 +821,27 @@ void TimeSplitsDrawOptionsMenu() { ImGui::PopItemWidth(); ImGui::SameLine(); if (ImGui::Button("Load List")) { - TimeSplitsFileManagement(ACTION_LOAD, keys[selectedItem].c_str(), emptyList); + TimeSplitsFileManagement(SPLIT_ACTION_LOAD, keys[selectedItem].c_str(), emptyList); } ImGui::SameLine(); if (ImGui::Button("Save List")) { - TimeSplitsFileManagement(ACTION_SAVE, keys[selectedItem].c_str(), splitList); + TimeSplitsFileManagement(SPLIT_ACTION_SAVE, keys[selectedItem].c_str(), splitList); } ImGui::SameLine(); if (ImGui::Button("Delete List")) { - TimeSplitsFileManagement(ACTION_DELETE, keys[selectedItem].c_str(), emptyList); + TimeSplitsFileManagement(SPLIT_ACTION_DELETE, keys[selectedItem].c_str(), emptyList); } UIWidgets::PaddedSeparator(); if (ImGui::Button("New Attempt")) { for (auto& data : splitList) { - data.splitTimeStatus = SPLIT_INACTIVE; + data.splitTimeStatus = SPLIT_STATUS_INACTIVE; } - splitList[0].splitTimeStatus = SPLIT_ACTIVE; + splitList[0].splitTimeStatus = SPLIT_STATUS_ACTIVE; } ImGui::SameLine(); if (ImGui::Button("Update Splits")) { - TimeSplitsFileManagement(ACTION_UPDATE, keys[selectedItem].c_str(), splitList); + TimeSplitsFileManagement(SPLIT_ACTION_UPDATE, keys[selectedItem].c_str(), splitList); } } @@ -864,27 +892,27 @@ void TimeSplitsDrawManageList() { ImGui::TableNextColumn(); ImGui::BeginTabBar("List Options"); if (ImGui::BeginTabItem("Equipment")) { - TimeSplitsDrawItemList(SPLIT_EQUIPMENT); + TimeSplitsDrawItemList(SPLIT_TYPE_EQUIPMENT); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Inventory")) { - TimeSplitsDrawItemList(SPLIT_ITEM); + TimeSplitsDrawItemList(SPLIT_TYPE_ITEM); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Quest")) { - TimeSplitsDrawItemList(SPLIT_QUEST); + TimeSplitsDrawItemList(SPLIT_TYPE_QUEST); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Entrances")) { - TimeSplitsDrawItemList(SPLIT_ENTRANCE); + TimeSplitsDrawItemList(SPLIT_TYPE_ENTRANCE); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Bosses")) { - TimeSplitsDrawItemList(SPLIT_BOSS); + TimeSplitsDrawItemList(SPLIT_TYPE_BOSS); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Miscellaneous")) { - TimeSplitsDrawItemList(SPLIT_MISC); + TimeSplitsDrawItemList(SPLIT_TYPE_MISC); ImGui::EndTabItem(); } @@ -914,6 +942,9 @@ static bool initialized = false; void TimeSplitWindow::DrawElement() { ImGui::SetWindowFontScale(timeSplitsWindowSize); if (!initialized) { + Color_RGBA8 defaultColour = {0, 0, 0, 255}; + Color_RGBA8 color = CVarGetColor("TimeSplits.WindowColor", defaultColour); + windowColor = {(float)color.r / 255.0f, (float)color.g / 255.0f, (float)color.b / 255.0f, (float)color.a / 255.0f}; InitializeSplitDataFile(); initialized = true; } @@ -943,7 +974,7 @@ void TimeSplitWindow::InitElement() { GameInteractor::Instance->RegisterGameHook([](u8 item) { if (item != ITEM_SKULL_TOKEN) { - uint32_t tempType = SPLIT_ITEM; + uint32_t tempType = SPLIT_TYPE_ITEM; for (auto& data : splitList) { if (data.splitID == item) { tempType = data.splitType; @@ -958,7 +989,7 @@ void TimeSplitWindow::InitElement() { GetItemEntry testItem = itemEntry; if (itemEntry.itemId == ITEM_SKULL_TOKEN || itemEntry.itemId == ITEM_BOTTLE || itemEntry.itemId == ITEM_POE || itemEntry.itemId == ITEM_BIG_POE) { - uint32_t tempType = SPLIT_ITEM; + uint32_t tempType = SPLIT_TYPE_ITEM; for (auto& data : splitList) { if (data.splitID == itemEntry.itemId) { tempType = data.splitType; @@ -970,17 +1001,17 @@ void TimeSplitWindow::InitElement() { }); GameInteractor::Instance->RegisterGameHook([](int16_t contents) { - TimeSplitsItemSplitEvent(SPLIT_UPGRADE, contents); + TimeSplitsItemSplitEvent(SPLIT_TYPE_UPGRADE, contents); }); GameInteractor::Instance->RegisterGameHook([](void* refActor) { Actor* bossActor = (Actor*)refActor; - TimeSplitsItemSplitEvent(SPLIT_BOSS, bossActor->id); + TimeSplitsItemSplitEvent(SPLIT_TYPE_BOSS, bossActor->id); }); GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { if (gPlayState->sceneNum != SCENE_KAKARIKO_VILLAGE) { - TimeSplitsItemSplitEvent(SPLIT_ENTRANCE, sceneNum); + TimeSplitsItemSplitEvent(SPLIT_TYPE_ENTRANCE, sceneNum); } }); @@ -988,8 +1019,8 @@ void TimeSplitWindow::InitElement() { if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE) { Player* player = GET_PLAYER(gPlayState); if (player->fallDistance > 500 && gSaveContext.health <= 0) { - TimeSplitsItemSplitEvent(SPLIT_MISC, gPlayState->sceneNum); + TimeSplitsItemSplitEvent(SPLIT_TYPE_MISC, gPlayState->sceneNum); } } }); -} \ No newline at end of file +} diff --git a/soh/soh/Enhancements/timesplits/TimeSplits.h b/soh/soh/Enhancements/timesplits/TimeSplits.h index e0eba37db..ba5f9cb80 100644 --- a/soh/soh/Enhancements/timesplits/TimeSplits.h +++ b/soh/soh/Enhancements/timesplits/TimeSplits.h @@ -27,30 +27,30 @@ class TimeSplitWindow : public Ship::GuiWindow { void UpdateElement() override{}; }; -typedef enum { - ACTION_SAVE, - ACTION_LOAD, - ACTION_UPDATE, - ACTION_COLLECT, - ACTION_DELETE -}; +typedef enum SplitAction { + SPLIT_ACTION_SAVE, + SPLIT_ACTION_LOAD, + SPLIT_ACTION_UPDATE, + SPLIT_ACTION_COLLECT, + SPLIT_ACTION_DELETE +} SplitAction; -typedef enum { - SPLIT_ACTIVE, - SPLIT_INACTIVE, - SPLIT_COLLECTED, - SPLIT_SKIPPED -}; +typedef enum SplitStatus { + SPLIT_STATUS_ACTIVE, + SPLIT_STATUS_INACTIVE, + SPLIT_STATUS_COLLECTED, + SPLIT_STATUS_SKIPPED +} SplitStatus; -typedef enum { - SPLIT_ITEM, - SPLIT_UPGRADE, - SPLIT_EQUIPMENT, - SPLIT_QUEST, - SPLIT_BOSS, - SPLIT_ENTRANCE, - SPLIT_MISC -}; +typedef enum SplitType { + SPLIT_TYPE_ITEM, + SPLIT_TYPE_UPGRADE, + SPLIT_TYPE_EQUIPMENT, + SPLIT_TYPE_QUEST, + SPLIT_TYPE_BOSS, + SPLIT_TYPE_ENTRANCE, + SPLIT_TYPE_MISC +} SplitType; typedef struct { uint32_t splitType; diff --git a/soh/soh/Enhancements/tts/tts.cpp b/soh/soh/Enhancements/tts/tts.cpp index 593706dd6..9d58e2d62 100644 --- a/soh/soh/Enhancements/tts/tts.cpp +++ b/soh/soh/Enhancements/tts/tts.cpp @@ -181,7 +181,7 @@ void RegisterOnInterfaceUpdateHook() { if (gPlayState->state.frames % 7 == 0) { if (lostHealth >= 16) { - Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); lostHealth -= 16; } } diff --git a/soh/soh/GameVersions.h b/soh/soh/GameVersions.h new file mode 100644 index 000000000..ce532d2eb --- /dev/null +++ b/soh/soh/GameVersions.h @@ -0,0 +1,28 @@ +#ifndef GAME_VERSION_H +#define GAME_VERSION_H + +#pragma once + +#define OOT_NTSC_US_10 0xEC7011B7 +#define OOT_NTSC_US_11 0xD43DA81F +#define OOT_NTSC_US_12 0x693BA2AE +// #define OOT_NTSC_JP_10 ? +// #define OOT_NTSC_JP_11 ? +// #define OOT_NTSC_JP_12 ? +#define OOT_PAL_10 0xB044B569 +#define OOT_PAL_11 0xB2055FBD +#define OOT_NTSC_JP_GC_CE 0xF7F52DB8 +#define OOT_NTSC_JP_GC 0xF611F4BA +#define OOT_NTSC_US_GC 0xF3DD35BA +#define OOT_PAL_GC 0x09465AC3 +#define OOT_NTSC_JP_MQ 0xF43B45BA +#define OOT_NTSC_US_MQ 0xF034001A +#define OOT_PAL_MQ 0x1D4136F3 +#define OOT_PAL_GC_DBG1 0x871E1C92 // 03-21-2002 build +#define OOT_PAL_GC_DBG2 0x87121EFE // 03-13-2002 build +#define OOT_PAL_GC_MQ_DBG 0x917D18F6 +#define OOT_IQUE_TW 0x3D81FB3E +#define OOT_IQUE_CN 0xB1E1E07B +#define UNKNOWN_GAME_VERSION 0xFFFFFFFF + +#endif diff --git a/soh/soh/ImGuiUtils.cpp b/soh/soh/ImGuiUtils.cpp index 11ad464e8..bfe1293d5 100644 --- a/soh/soh/ImGuiUtils.cpp +++ b/soh/soh/ImGuiUtils.cpp @@ -1,6 +1,7 @@ #include "ImGuiUtils.h" #include #include "assets/soh_assets.h" +#include "soh/Enhancements/randomizer/rando_hash.h" std::map itemMapping = { ITEM_MAP_ENTRY(ITEM_STICK), @@ -150,7 +151,7 @@ std::map questMapping = { QUEST_MAP_ENTRY(QUEST_SKULL_TOKEN, dgQuestIconGoldSkulltulaTex), }; -std::array songMapping = { { +std::map songMapping = { SONG_MAP_ENTRY(QUEST_SONG_LULLABY, 224, 107, 255), SONG_MAP_ENTRY(QUEST_SONG_EPONA, 255, 195, 60), SONG_MAP_ENTRY(QUEST_SONG_SARIA, 127, 255, 137), @@ -163,7 +164,7 @@ std::array songMapping = { { SONG_MAP_ENTRY(QUEST_SONG_REQUIEM, 255, 160, 0), SONG_MAP_ENTRY(QUEST_SONG_NOCTURNE, 255, 100, 255), SONG_MAP_ENTRY(QUEST_SONG_PRELUDE, 255, 240, 100), -} }; +}; std::array vanillaSongMapping = { { VANILLA_SONG_MAP_ENTRY(QUEST_SONG_LULLABY, 255, 255, 255), @@ -212,7 +213,7 @@ void RegisterImGuiItemIcons() { Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); } - for (const auto& entry : songMapping) { + for (const auto& [quest, entry] : songMapping) { Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color); ImVec4 fadedCol = entry.color; fadedCol.w = 0.3f; @@ -225,4 +226,8 @@ void RegisterImGuiItemIcons() { fadedCol.w = 0.3f; Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol); } + + for (const auto& entry : gSeedTextures) { + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.tex, entry.tex, ImVec4(1, 1, 1, 1)); + } } \ No newline at end of file diff --git a/soh/soh/ImGuiUtils.h b/soh/soh/ImGuiUtils.h index c5545ba74..ed735713a 100644 --- a/soh/soh/ImGuiUtils.h +++ b/soh/soh/ImGuiUtils.h @@ -67,11 +67,11 @@ typedef struct { #define SONG_MAP_ENTRY(id, r, g, b) \ { \ - id, #id, #id "_Faded", ImVec4(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f) \ + id, { id, #id, #id "_Faded", ImVec4(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f) } \ } // Maps song ids to info for use in ImGui -extern std::array songMapping; +extern std::map songMapping; #define VANILLA_SONG_MAP_ENTRY(id, r, g, b) \ { \ diff --git a/soh/soh/Network/CrowdControl/CrowdControl.cpp b/soh/soh/Network/CrowdControl/CrowdControl.cpp index bc8055140..184d6cad2 100644 --- a/soh/soh/Network/CrowdControl/CrowdControl.cpp +++ b/soh/soh/Network/CrowdControl/CrowdControl.cpp @@ -788,14 +788,14 @@ void CrowdControl::DrawMenu() { ImGui::Text("Host & Port"); if (UIWidgets::InputString("##Host", &host)) { CVarSetString(CVAR_REMOTE_CROWD_CONTROL("Host"), host.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); ImGui::PushItemWidth(ImGui::GetFontSize() * 5); if (ImGui::InputScalar("##Port", ImGuiDataType_U16, &port)) { CVarSetInteger(CVAR_REMOTE_CROWD_CONTROL("Port"), port); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::PopItemWidth(); ImGui::EndDisabled(); @@ -807,11 +807,11 @@ void CrowdControl::DrawMenu() { if (ImGui::Button(buttonLabel, ImVec2(-1.0f, 0.0f))) { if (isEnabled) { CVarClear(CVAR_REMOTE_CROWD_CONTROL("Enabled")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); Disable(); } else { CVarSetInteger(CVAR_REMOTE_CROWD_CONTROL("Enabled"), 1); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); Enable(); } } diff --git a/soh/soh/Network/Sail/Sail.cpp b/soh/soh/Network/Sail/Sail.cpp index bf856c8f0..1c27e1d72 100644 --- a/soh/soh/Network/Sail/Sail.cpp +++ b/soh/soh/Network/Sail/Sail.cpp @@ -514,14 +514,14 @@ void Sail::DrawMenu() { ImGui::Text("Host & Port"); if (UIWidgets::InputString("##Host", &host)) { CVarSetString(CVAR_REMOTE_SAIL("Host"), host.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); ImGui::PushItemWidth(ImGui::GetFontSize() * 5); if (ImGui::InputScalar("##Port", ImGuiDataType_U16, &port)) { CVarSetInteger(CVAR_REMOTE_SAIL("Port"), port); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::PopItemWidth(); ImGui::EndDisabled(); @@ -533,11 +533,11 @@ void Sail::DrawMenu() { if (ImGui::Button(buttonLabel, ImVec2(-1.0f, 0.0f))) { if (isEnabled) { CVarClear(CVAR_REMOTE_SAIL("Enabled")); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); Disable(); } else { CVarSetInteger(CVAR_REMOTE_SAIL("Enabled"), 1); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); Enable(); } } diff --git a/soh/soh/Notification/Notification.cpp b/soh/soh/Notification/Notification.cpp index b743fae82..ebc4e168b 100644 --- a/soh/soh/Notification/Notification.cpp +++ b/soh/soh/Notification/Notification.cpp @@ -133,7 +133,7 @@ void Emit(Options notification) { notification.remainingTime = CVarGetFloat(CVAR_SETTING("Notifications.Duration"), 10.0f); } notifications.push_back(notification); - Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } // namespace Notification diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 41cbf38b8..0e2991226 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -6,17 +6,14 @@ #include #include -#include +#include "ResourceManagerHelpers.h" #include "graphic/Fast3D/Fast3dWindow.h" #include #include #include -#include +#include -#include "z64animation.h" -#include "z64bgcheck.h" #include "Enhancements/gameconsole.h" -#include #ifdef _WIN32 #include #else @@ -27,7 +24,6 @@ #include "Enhancements/controls/SohInputEditorWindow.h" #include "Enhancements/cosmetics/CosmeticsEditor.h" #include "Enhancements/audio/AudioCollection.h" -#include "Enhancements/audio/AudioEditor.h" #include "Enhancements/enhancementTypes.h" #include "Enhancements/debugconsole.h" #include "Enhancements/randomizer/randomizer.h" @@ -56,7 +52,6 @@ #endif #include -#include #ifdef __APPLE__ #include @@ -77,6 +72,7 @@ #include "Enhancements/item-tables/ItemTableManager.h" #include "SohGui.hpp" #include "ActorDB.h" +#include "SaveManager.h" #ifdef ENABLE_REMOTE_CONTROL #include "soh/Network/CrowdControl/CrowdControl.h" @@ -131,6 +127,7 @@ Sail* Sail::Instance; #include "soh/resource/importer/BackgroundFactory.h" #include "soh/config/ConfigUpdaters.h" +#include "soh/ShipInit.hpp" extern "C" { #include "src/overlays/actors/ovl_En_Dns/z_en_dns.h" @@ -331,7 +328,7 @@ OTRGlobals::OTRGlobals() { prevAltAssets = CVarGetInteger(CVAR_ENHANCEMENT("AltAssets"), 0); context->GetResourceManager()->SetAltAssetsEnabled(prevAltAssets); - context->InitControlDeck({ + auto controlDeck = std::make_shared(std::vector({ BTN_CUSTOM_MODIFIER1, BTN_CUSTOM_MODIFIER2, BTN_CUSTOM_OCARINA_NOTE_D4, @@ -342,18 +339,20 @@ OTRGlobals::OTRGlobals() { BTN_CUSTOM_OCARINA_DISABLE_SONGS, BTN_CUSTOM_OCARINA_PITCH_UP, BTN_CUSTOM_OCARINA_PITCH_DOWN, - }); + })); + context->InitControlDeck(controlDeck); context->GetControlDeck()->SetSinglePlayerMappingMode(true); context->InitCrashHandler(); context->InitConsole(); auto sohInputEditorWindow = std::make_shared(CVAR_WINDOW("ControllerConfiguration"), "Controller Configuration"); - context->InitWindow({ sohInputEditorWindow }); + auto sohFast3dWindow = std::make_shared(std::vector>({sohInputEditorWindow})); + context->InitWindow(sohFast3dWindow); auto overlay = context->GetInstance()->GetWindow()->GetGui()->GetGameOverlay(); - overlay->LoadFont("Press Start 2P", "fonts/PressStart2P-Regular.ttf", 12.0f); - overlay->LoadFont("Fipps", "fonts/Fipps-Regular.otf", 32.0f); + overlay->LoadFont("Press Start 2P", 12.0f, "fonts/PressStart2P-Regular.ttf"); + overlay->LoadFont("Fipps", 32.0f, "fonts/Fipps-Regular.otf"); overlay->SetCurrentFont(CVarGetString(CVAR_GAME_OVERLAY_FONT, "Press Start 2P")); context->InitAudio({ .SampleRate = 44100, .SampleLength = 1024, .DesiredBuffered = 2480 }); @@ -361,14 +360,14 @@ OTRGlobals::OTRGlobals() { SPDLOG_INFO("Starting Ship of Harkinian version {} (Branch: {} | Commit: {})", (char*)gBuildVersion, (char*)gGitBranch, (char*)gGitCommitHash); auto loader = context->GetResourceManager()->GetResourceLoader(); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Texture", static_cast(LUS::ResourceType::Texture), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Texture", static_cast(LUS::ResourceType::Texture), 1); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Vertex", static_cast(LUS::ResourceType::Vertex), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, "Vertex", static_cast(LUS::ResourceType::Vertex), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "DisplayList", static_cast(LUS::ResourceType::DisplayList), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, "DisplayList", static_cast(LUS::ResourceType::DisplayList), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Matrix", static_cast(LUS::ResourceType::Matrix), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Blob", static_cast(LUS::ResourceType::Blob), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Texture", static_cast(Fast::ResourceType::Texture), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Texture", static_cast(Fast::ResourceType::Texture), 1); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Vertex", static_cast(Fast::ResourceType::Vertex), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, "Vertex", static_cast(Fast::ResourceType::Vertex), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "DisplayList", static_cast(Fast::ResourceType::DisplayList), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, "DisplayList", static_cast(Fast::ResourceType::DisplayList), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Matrix", static_cast(Fast::ResourceType::Matrix), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Blob", static_cast(Ship::ResourceType::Blob), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Array", static_cast(SOH::ResourceType::SOH_Array), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Animation", static_cast(SOH::ResourceType::SOH_Animation), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "PlayerAnimation", static_cast(SOH::ResourceType::SOH_PlayerAnimation), 0); @@ -506,18 +505,11 @@ uint32_t OTRGlobals::GetInterpolationFPS() { return std::min(Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(), CVarGetInteger(CVAR_SETTING("InterpolationFPS"), 20)); } -struct ExtensionEntry { - std::string path; - std::string ext; -}; - extern "C" void OTRMessage_Init(); extern "C" void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples); extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len); extern "C" int AudioPlayer_Buffered(void); extern "C" int AudioPlayer_GetDesiredBuffered(void); -extern "C" void ResourceMgr_LoadDirectory(const char* resName); -extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path); std::unordered_map ExtensionCache; void OTRAudio_Thread() { @@ -885,6 +877,7 @@ std::unordered_map ItemIDtoRandomizerGetMap { { ITEM_KOKIRI_EMERALD, RG_KOKIRI_EMERALD }, { ITEM_GORON_RUBY, RG_GORON_RUBY }, { ITEM_ZORA_SAPPHIRE, RG_ZORA_SAPPHIRE }, + { ITEM_SWORD_MASTER, RG_MASTER_SWORD }, }; extern "C" RandomizerGet RetrieveRandomizerGetFromItemID(ItemID itemID) { @@ -918,9 +911,9 @@ OTRVersion ReadPortVersionFromOTR(std::string otrPath) { OTRVersion version = {}; // Use a temporary archive instance to load the otr and read the version file - auto archive = Ship::OtrArchive(otrPath); - if (archive.Open()) { - auto t = archive.LoadFile("portVersion", std::make_shared()); + auto archive = std::make_shared(otrPath); + if (archive->Open()) { + auto t = archive->LoadFile("portVersion", std::make_shared()); if (t != nullptr && t->IsLoaded) { auto stream = std::make_shared(t->Buffer->data(), t->Buffer->size()); auto reader = std::make_shared(stream); @@ -930,7 +923,7 @@ OTRVersion ReadPortVersionFromOTR(std::string otrPath) { version.minor = reader->ReadUInt16(); version.patch = reader->ReadUInt16(); } - archive.Close(); + archive->Close(); } return version; @@ -1152,12 +1145,13 @@ extern "C" void InitOTR() { SaveManager::Instance = new SaveManager(); std::shared_ptr conf = OTRGlobals::Instance->context->GetConfig(); - conf->RegisterConfigVersionUpdater(std::make_shared()); - conf->RegisterConfigVersionUpdater(std::make_shared()); - conf->RegisterConfigVersionUpdater(std::make_shared()); + conf->RegisterVersionUpdater(std::make_shared()); + conf->RegisterVersionUpdater(std::make_shared()); + conf->RegisterVersionUpdater(std::make_shared()); conf->RunVersionUpdates(); SohGui::SetupGuiElements(); + ShipInit::InitAll(); AudioCollection::Instance = new AudioCollection(); ActorDB::Instance = new ActorDB(); #ifdef __APPLE__ @@ -1445,11 +1439,9 @@ extern "C" void Graph_ProcessGfxCommands(Gfx* commands) { bool curAltAssets = CVarGetInteger(CVAR_ENHANCEMENT("AltAssets"), 0); if (prevAltAssets != curAltAssets) { - UpdatePatchCustomEquipmentDlists(); prevAltAssets = curAltAssets; Ship::Context::GetInstance()->GetResourceManager()->SetAltAssetsEnabled(curAltAssets); gfx_texture_cache_clear(); - UpdatePatchCustomEquipmentDlists(); SOH::SkeletonPatcher::UpdateSkeletons(); GameInteractor::Instance->ExecuteHooks(); } @@ -1480,269 +1472,7 @@ extern "C" uint16_t OTRGetPixelDepth(float x, float y) { return wnd->GetPixelDepth(x, y); } -extern "C" uint32_t ResourceMgr_GetNumGameVersions() { - return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions().size(); -} - -extern "C" uint32_t ResourceMgr_GetGameVersion(int index) { - return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; -} - -extern "C" uint32_t ResourceMgr_GetGamePlatform(int index) { - uint32_t version = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; - - switch (version) { - case OOT_NTSC_US_10: - case OOT_NTSC_US_11: - case OOT_NTSC_US_12: - case OOT_PAL_10: - case OOT_PAL_11: - return GAME_PLATFORM_N64; - case OOT_NTSC_JP_GC: - case OOT_NTSC_US_GC: - case OOT_PAL_GC: - case OOT_NTSC_JP_MQ: - case OOT_NTSC_US_MQ: - case OOT_PAL_MQ: - case OOT_PAL_GC_DBG1: - case OOT_PAL_GC_DBG2: - case OOT_PAL_GC_MQ_DBG: - return GAME_PLATFORM_GC; - } -} - -extern "C" uint32_t ResourceMgr_GetGameRegion(int index) { - uint32_t version = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; - - switch (version) { - case OOT_NTSC_US_10: - case OOT_NTSC_US_11: - case OOT_NTSC_US_12: - case OOT_NTSC_JP_GC: - case OOT_NTSC_US_GC: - case OOT_NTSC_JP_MQ: - case OOT_NTSC_US_MQ: - return GAME_REGION_NTSC; - case OOT_PAL_10: - case OOT_PAL_11: - case OOT_PAL_GC: - case OOT_PAL_MQ: - case OOT_PAL_GC_DBG1: - case OOT_PAL_GC_DBG2: - case OOT_PAL_GC_MQ_DBG: - return GAME_REGION_PAL; - } -} - -uint32_t IsSceneMasterQuest(s16 sceneNum) { - uint32_t value = 0; - uint8_t mqMode = CVarGetInteger(CVAR_GENERAL("BetterDebugWarpScreenMQMode"), WARP_MODE_OVERRIDE_OFF); - if (mqMode == WARP_MODE_OVERRIDE_MQ_AS_VANILLA) { - return 1; - } else if (mqMode == WARP_MODE_OVERRIDE_VANILLA_AS_MQ) { - return 0; - } else { - if (OTRGlobals::Instance->HasMasterQuest()) { - if (!OTRGlobals::Instance->HasOriginal()) { - value = 1; - } else if (IS_MASTER_QUEST) { - value = 1; - } else { - value = 0; - if (IS_RANDO) { - auto dungeon = OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(sceneNum); - if (dungeon != nullptr && dungeon->IsMQ()) { - value = 1; - } - } - } - } - } - return value; -} - -uint32_t IsGameMasterQuest() { - return gPlayState != NULL ? IsSceneMasterQuest(gPlayState->sceneNum) : 0; -} - -extern "C" uint32_t ResourceMgr_GameHasMasterQuest() { - return OTRGlobals::Instance->HasMasterQuest(); -} - -extern "C" uint32_t ResourceMgr_GameHasOriginal() { - return OTRGlobals::Instance->HasOriginal(); -} - -extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum) { - return IsSceneMasterQuest(sceneNum); -} - -extern "C" uint32_t ResourceMgr_IsGameMasterQuest() { - return IsGameMasterQuest(); -} - -extern "C" void ResourceMgr_LoadDirectory(const char* resName) { - Ship::Context::GetInstance()->GetResourceManager()->LoadDirectory(resName); -} -extern "C" void ResourceMgr_DirtyDirectory(const char* resName) { - Ship::Context::GetInstance()->GetResourceManager()->DirtyDirectory(resName); -} - -extern "C" void ResourceMgr_UnloadResource(const char* resName) { - std::string path = resName; - if (path.substr(0, 7) == "__OTR__") { - path = path.substr(7); - } - auto res = Ship::Context::GetInstance()->GetResourceManager()->UnloadResource(path); -} - -// OTRTODO: There is probably a more elegant way to go about this... -// Kenix: This is definitely leaking memory when it's called. -extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) { - auto lst = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles(searchMask); - char** result = (char**)malloc(lst->size() * sizeof(char*)); - - for (size_t i = 0; i < lst->size(); i++) { - char* str = (char*)malloc(lst.get()[0][i].size() + 1); - memcpy(str, lst.get()[0][i].data(), lst.get()[0][i].size()); - str[lst.get()[0][i].size()] = '\0'; - result[i] = str; - } - *resultSize = lst->size(); - - return result; -} - -extern "C" uint8_t ResourceMgr_FileExists(const char* filePath) { - std::string path = filePath; - if(path.substr(0, 7) == "__OTR__"){ - path = path.substr(7); - } - - return ExtensionCache.contains(path); -} - -extern "C" uint8_t ResourceMgr_FileAltExists(const char* filePath) { - std::string path = filePath; - if (path.substr(0, 7) == "__OTR__") { - path = path.substr(7); - } - - if (path.substr(0, 4) != "alt/") { - path = "alt/" + path; - } - - return ExtensionCache.contains(path); -} - -extern "C" bool ResourceMgr_IsAltAssetsEnabled() { - return Ship::Context::GetInstance()->GetResourceManager()->IsAltAssetsEnabled(); -} - -// Unloads a resource if an alternate version exists when alt assets are enabled -// The resource is only removed from the internal cache to prevent it from used in the next resource lookup -extern "C" void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName) { - if (ResourceMgr_IsAltAssetsEnabled() && ResourceMgr_FileAltExists((char*)resName)) { - ResourceMgr_UnloadResource((char*) resName); - } -} - -std::shared_ptr GetResourceByNameHandlingMQ(const char* path) { - std::string Path = path; - if (ResourceMgr_IsGameMasterQuest()) { - size_t pos = 0; - if ((pos = Path.find("/nonmq/", 0)) != std::string::npos) { - Path.replace(pos, 7, "/mq/"); - } - } - return Ship::Context::GetInstance()->GetResourceManager()->LoadResource(Path.c_str()); -} - -extern "C" char* GetResourceDataByNameHandlingMQ(const char* path) { - auto res = GetResourceByNameHandlingMQ(path); - - if (res == nullptr) { - return nullptr; - } - - return (char*)res->GetRawPointer(); -} - -extern "C" uint8_t ResourceMgr_TexIsRaw(const char* texPath) { - auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(texPath)); - return res->Flags & TEX_FLAG_LOAD_AS_RAW; -} - -extern "C" uint8_t ResourceMgr_ResourceIsBackground(char* texPath) { - auto res = GetResourceByNameHandlingMQ(texPath); - return res->GetInitData()->Type == static_cast(SOH::ResourceType::SOH_Background); -} - -extern "C" char* ResourceMgr_LoadJPEG(char* data, size_t dataSize) -{ - static char* finalBuffer = 0; - - if (finalBuffer == 0) - finalBuffer = (char*)malloc(dataSize); - - int w; - int h; - int comp; - - unsigned char* pixels = stbi_load_from_memory((const unsigned char*)data, 320 * 240 * 2, &w, &h, &comp, STBI_rgb_alpha); - //unsigned char* pixels = stbi_load_from_memory((const unsigned char*)data, 480 * 240 * 2, &w, &h, &comp, STBI_rgb_alpha); - int idx = 0; - - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - uint16_t* bufferTest = (uint16_t*)finalBuffer; - int pixelIdx = ((y * w) + x) * 4; - - uint8_t r = pixels[pixelIdx + 0] / 8; - uint8_t g = pixels[pixelIdx + 1] / 8; - uint8_t b = pixels[pixelIdx + 2] / 8; - - uint8_t alphaBit = pixels[pixelIdx + 3] != 0; - - uint16_t data = (r << 11) + (g << 6) + (b << 1) + alphaBit; - - finalBuffer[idx++] = (data & 0xFF00) >> 8; - finalBuffer[idx++] = (data & 0x00FF); - } - } - - return (char*)finalBuffer; -} - -extern "C" uint16_t ResourceMgr_LoadTexWidthByName(char* texPath); - -extern "C" uint16_t ResourceMgr_LoadTexHeightByName(char* texPath); - -extern "C" char* ResourceMgr_LoadTexOrDListByName(const char* filePath) { - auto res = GetResourceByNameHandlingMQ(filePath); - - if (res->GetInitData()->Type == static_cast(LUS::ResourceType::DisplayList)) - return (char*)&((std::static_pointer_cast(res))->Instructions[0]); - else if (res->GetInitData()->Type == static_cast(SOH::ResourceType::SOH_Array)) - return (char*)(std::static_pointer_cast(res))->Vertices.data(); - else { - return (char*)GetResourceDataByNameHandlingMQ(filePath); - } -} - -extern "C" char* ResourceMgr_LoadIfDListByName(const char* filePath) { - auto res = GetResourceByNameHandlingMQ(filePath); - - if (res->GetInitData()->Type == static_cast(LUS::ResourceType::DisplayList)) - return (char*)&((std::static_pointer_cast(res))->Instructions[0]); - - return nullptr; -} - extern "C" Sprite* GetSeedTexture(uint8_t index) { - return OTRGlobals::Instance->gRandoContext->GetSeedTexture(index); } @@ -1750,170 +1480,6 @@ extern "C" uint8_t GetSeedIconIndex(uint8_t index) { return OTRGlobals::Instance->gRandoContext->hashIconIndexes[index]; } -extern "C" char* ResourceMgr_LoadPlayerAnimByName(const char* animPath) { - auto anim = std::static_pointer_cast(GetResourceByNameHandlingMQ(animPath)); - - return (char*)&anim->limbRotData[0]; -} - -extern "C" void ResourceMgr_PushCurrentDirectory(char* path) -{ - gfx_push_current_dir(path); -} - -extern "C" Gfx* ResourceMgr_LoadGfxByName(const char* path) -{ - // When an alt resource exists for the DL, we need to unload the original asset - // to clear the cache so the alt asset will be loaded instead - // OTRTODO: If Alt loading over original cache is fixed, this line can most likely be removed - ResourceMgr_UnloadOriginalWhenAltExists(path); - - auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(path)); - return (Gfx*)&res->Instructions[0]; -} - -extern "C" uint8_t ResourceMgr_FileIsCustomByName(const char* path) { - auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(path)); - return res->GetInitData()->IsCustom; -} - -typedef struct { - int index; - Gfx instruction; -} GfxPatch; - -std::unordered_map> originalGfx; - -// Attention! This is primarily for cosmetics & bug fixes. For things like mods and model replacement you should be using OTRs -// instead (When that is available). Index can be found using the commented out section below. -extern "C" void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction) { - auto res = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path)); - - // Leaving this here for people attempting to find the correct Dlist index to patch - /*if (strcmp("__OTR__objects/object_gi_longsword/gGiBiggoronSwordDL", path) == 0) { - for (int i = 0; i < res->instructions.size(); i++) { - Gfx* gfx = (Gfx*)&res->instructions[i]; - // Log all commands - // SPDLOG_INFO("index:{} command:{}", i, gfx->words.w0 >> 24); - // Log only SetPrimColors - if (gfx->words.w0 >> 24 == 250) { - SPDLOG_INFO("index:{} r:{} g:{} b:{} a:{}", i, _SHIFTR(gfx->words.w1, 24, 8), _SHIFTR(gfx->words.w1, 16, 8), _SHIFTR(gfx->words.w1, 8, 8), _SHIFTR(gfx->words.w1, 0, 8)); - } - } - }*/ - - // Index refers to individual gfx words, which are half the size on 32-bit - // if (sizeof(uintptr_t) < 8) { - // index /= 2; - // } - - // Do not patch custom assets as they most likely do not have the same instructions as authentic assets - if (res->GetInitData()->IsCustom) { - return; - } - - Gfx* gfx = (Gfx*)&res->Instructions[index]; - - if (!originalGfx.contains(path) || !originalGfx[path].contains(patchName)) { - originalGfx[path][patchName] = { - index, - *gfx - }; - } - - *gfx = instruction; -} - -extern "C" void ResourceMgr_PatchCustomGfxByName(const char* path, const char* patchName, int index, Gfx instruction) { - auto res = std::static_pointer_cast( - Ship ::Context::GetInstance()->GetResourceManager()->LoadResource(path)); - - Gfx* gfx = (Gfx*)&res->Instructions[index]; - - if (!originalGfx.contains(path) || !originalGfx[path].contains(patchName)) { - originalGfx[path][patchName] = { index, *gfx }; - } - - *gfx = instruction; -} - -extern "C" void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex, int sourceIndex) { - auto res = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path)); - - // Do not patch custom assets as they most likely do not have the same instructions as authentic assets - if (res->GetInitData()->IsCustom) { - return; - } - - Gfx* destinationGfx = (Gfx*)&res->Instructions[destinationIndex]; - Gfx sourceGfx = *(Gfx*)&res->Instructions[sourceIndex]; - - if (!originalGfx.contains(path) || !originalGfx[path].contains(patchName)) { - originalGfx[path][patchName] = { - destinationIndex, - *destinationGfx - }; - } - - *destinationGfx = sourceGfx; -} - -extern "C" void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName) { - if (originalGfx.contains(path) && originalGfx[path].contains(patchName)) { - auto res = std::static_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path)); - - Gfx* gfx = (Gfx*)&res->Instructions[originalGfx[path][patchName].index]; - *gfx = originalGfx[path][patchName].instruction; - - originalGfx[path].erase(patchName); - } -} - -extern "C" char* ResourceMgr_LoadArrayByName(const char* path) -{ - auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(path)); - - return (char*)res->Scalars.data(); -} - -// Return of LoadArrayByNameAsVec3s must be freed by the caller -extern "C" char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path) { - auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(path)); - - // if (res->CachedGameAsset != nullptr) - // return (char*)res->CachedGameAsset; - // else - // { - Vec3s* data = (Vec3s*)malloc(sizeof(Vec3s) * res->Scalars.size()); - - for (size_t i = 0; i < res->Scalars.size(); i += 3) { - data[(i / 3)].x = res->Scalars[i + 0].s16; - data[(i / 3)].y = res->Scalars[i + 1].s16; - data[(i / 3)].z = res->Scalars[i + 2].s16; - } - - // res->CachedGameAsset = data; - - return (char*)data; - // } -} - -extern "C" CollisionHeader* ResourceMgr_LoadColByName(const char* path) { - return (CollisionHeader*) ResourceGetDataByName(path); -} - -extern "C" Vtx* ResourceMgr_LoadVtxByName(char* path) { - return (Vtx*) ResourceGetDataByName(path); -} - -extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path) { - SequenceData* sequence = (SequenceData*) ResourceGetDataByName(path); - return *sequence; -} - std::map cachedCustomSFs; extern "C" SoundFontSample* ReadCustomSample(const char* path) { @@ -1974,81 +1540,6 @@ extern "C" SoundFontSample* ReadCustomSample(const char* path) { */ } -extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(const char* path) { - return (SoundFontSample*) ResourceGetDataByName(path); -} - -extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path) { - return (SoundFont*) ResourceGetDataByName(path); -} - -extern "C" int ResourceMgr_OTRSigCheck(char* imgData) -{ - uintptr_t i = (uintptr_t)(imgData); - -// if (i == 0xD9000000 || i == 0xE7000000 || (i & 1) == 1) - if ((i & 1) == 1) - return 0; - -// if ((i & 0xFF000000) != 0xAB000000 && (i & 0xFF000000) != 0xCD000000 && i != 0) { - if (i != 0) { - if (imgData[0] == '_' && imgData[1] == '_' && imgData[2] == 'O' && imgData[3] == 'T' && imgData[4] == 'R' && - imgData[5] == '_' && imgData[6] == '_') - return 1; - } - - return 0; -} - -extern "C" AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path) { - return (AnimationHeaderCommon*) ResourceGetDataByName(path); -} - -extern "C" SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path, SkelAnime* skelAnime) { - std::string pathStr = std::string(path); - static const std::string sOtr = "__OTR__"; - - if (pathStr.starts_with(sOtr)) { - pathStr = pathStr.substr(sOtr.length()); - } - - bool isAlt = ResourceMgr_IsAltAssetsEnabled(); - - if (isAlt) { - pathStr = Ship::IResource::gAltAssetPrefix + pathStr; - } - - SkeletonHeader* skelHeader = (SkeletonHeader*) ResourceGetDataByName(pathStr.c_str()); - - // If there isn't an alternate model, load the regular one - if (isAlt && skelHeader == NULL) { - skelHeader = (SkeletonHeader*) ResourceGetDataByName(path); - } - - // This function is only called when a skeleton is initialized. - // Therefore we can take this oppurtunity to take note of the Skeleton that is created... - if (skelAnime != nullptr) { - auto stringPath = std::string(path); - SOH::SkeletonPatcher::RegisterSkeleton(stringPath, skelAnime); - } - - return skelHeader; -} - -extern "C" void ResourceMgr_UnregisterSkeleton(SkelAnime* skelAnime) { - if (skelAnime != nullptr) - SOH::SkeletonPatcher::UnregisterSkeleton(skelAnime); -} - -extern "C" void ResourceMgr_ClearSkeletons(SkelAnime* skelAnime) { - if (skelAnime != nullptr) - SOH::SkeletonPatcher::ClearSkeletons(); -} - -extern "C" s32* ResourceMgr_LoadCSByName(const char* path) { - return (s32*)GetResourceDataByNameHandlingMQ(path); -} - std::filesystem::path GetSaveFile(std::shared_ptr Conf) { const std::string fileName = Conf->GetString("Game.SaveName", Ship::Context::GetPathRelativeToAppDirectory("oot_save.sav")); std::filesystem::path saveFile = std::filesystem::absolute(fileName); @@ -2093,7 +1584,7 @@ std::wstring StringToU16(const std::string& s) { size_t i = 0; while (i < s.size()) { unsigned long uni; - size_t nbytes; + size_t nbytes = 0; bool error = false; unsigned char c = s[i++]; if (c < 0x80) { // ascii @@ -2413,7 +1904,7 @@ extern "C" int GetEquipNowMessage(char* buffer, char* src, const int maxBufferSi } extern "C" void Randomizer_ParseSpoiler(const char* fileLoc) { - OTRGlobals::Instance->gRandoContext->ParseSpoiler(fileLoc, CVarGetInteger(CVAR_GENERAL("PlandoMode"), 0)); + OTRGlobals::Instance->gRandoContext->ParseSpoiler(fileLoc); } extern "C" void Randomizer_LoadHintMessages() { @@ -2433,7 +1924,7 @@ extern "C" u32 SpoilerFileExists(const char* spoilerFileName) { } extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey) { - return OTRGlobals::Instance->gRandoContext->GetOption(randoSettingKey).GetSelectedOptionIndex(); + return OTRGlobals::Instance->gRandoContext->GetOption(randoSettingKey).GetContextOptionIndex(); } extern "C" RandomizerCheck Randomizer_GetCheckFromActor(s16 actorId, s16 sceneNum, s16 actorParams) { @@ -2459,6 +1950,7 @@ extern "C" CowIdentity Randomizer_IdentifyCow(s32 sceneNum, s32 posX, s32 posZ) extern "C" FishIdentity Randomizer_IdentifyFish(s32 sceneNum, s32 actorParams) { return OTRGlobals::Instance->gRandomizer->IdentifyFish(sceneNum, actorParams); } + extern "C" GetItemEntry ItemTable_Retrieve(int16_t getItemID) { GetItemEntry giEntry = ItemTableManager::Instance->RetrieveItemEntry(MOD_NONE, getItemID); return giEntry; @@ -2503,14 +1995,6 @@ extern "C" GetItemEntry GetItemMystery() { return { ITEM_NONE_FE, 0, 0, 0, 0, 0, 0, ITEM_NONE_FE, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, NULL, MOD_RANDOMIZER, (CustomDrawFunc)Randomizer_DrawMysteryItem }; } -extern "C" void Randomizer_GenerateSeed() { - std::string seed = ""; - if (OTRGlobals::Instance->gRandoContext->IsSpoilerLoaded()) { - seed = OTRGlobals::Instance->gRandoContext->GetSettings()->GetSeedString(); - } - GenerateRandomizer(seed); -} - extern "C" uint8_t Randomizer_IsSeedGenerated() { return OTRGlobals::Instance->gRandoContext->IsSeedGenerated() ? 1 : 0; } @@ -2527,12 +2011,12 @@ extern "C" void Randomizer_SetSpoilerLoaded(bool spoilerLoaded) { OTRGlobals::Instance->gRandoContext->SetSpoilerLoaded(spoilerLoaded); } -extern "C" uint8_t Randomizer_IsPlandoLoaded() { - return OTRGlobals::Instance->gRandoContext->IsPlandoLoaded() ? 1 : 0; +extern "C" uint8_t Randomizer_GenerateRandomizer() { + return GenerateRandomizer() ? 1 : 0; } -extern "C" void Randomizer_SetPlandoLoaded(bool plandoLoaded) { - OTRGlobals::Instance->gRandoContext->SetPlandoLoaded(plandoLoaded); +extern "C" void Randomizer_ShowRandomizerMenu() { + SohGui::ShowRandomizerSettingsMenu(); } CustomMessage Randomizer_GetCustomGetItemMessage(Player* player) { @@ -2653,7 +2137,6 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { } else if (textId >= TEXT_SHOP_ITEM_RANDOM_CONFIRM && textId <= TEXT_SHOP_ITEM_RANDOM_CONFIRM_END){ RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)((textId - TEXT_SHOP_ITEM_RANDOM_CONFIRM) + RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1)); messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(rc, TEXT_SHOP_ITEM_RANDOM_CONFIRM); - // textId: TEXT_SCRUB_RANDOM + (randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT) } else if (textId == TEXT_SCRUB_RANDOM) { EnDns* enDns = (EnDns*)GET_PLAYER(play)->talkActor; RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)enDns->sohScrubIdentity.randomizerInf); @@ -2875,14 +2358,6 @@ extern "C" void Overlay_DisplayText_Seconds(int seconds, const char* text) { Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->TextDrawNotification(duration, true, text); } -extern "C" void Entrance_ClearEntranceTrackingData(void) { - ClearEntranceTrackingData(); -} - -extern "C" void Entrance_InitEntranceTrackingData(void) { - InitEntranceTrackingData(); -} - extern "C" void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex) { SetCurrentGrottoIDForTracker(entranceIndex); } @@ -2907,7 +2382,7 @@ extern "C" void Gfx_TextureCacheDelete(const uint8_t* texAddr) { } if (ResourceMgr_OTRSigCheck(imgName)) { - texAddr = (const uint8_t*)GetResourceDataByNameHandlingMQ(imgName); + texAddr = (const uint8_t*)ResourceMgr_GetResourceDataByNameHandlingMQ(imgName); } gfx_texture_cache_delete(texAddr); @@ -2967,7 +2442,7 @@ void SoH_ProcessDroppedFiles(std::string filePath) { gui->GetGuiWindow("Stats")->Hide(); std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->ClearBindings(); - gui->SaveConsoleVariablesOnNextTick(); + gui->SaveConsoleVariablesNextFrame(); uint32_t finalHash = boost::hash_32{}(configJson.dump()); gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Configuration Loaded. Hash: %d", finalHash); diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 17b2295ee..6945d8339 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -3,15 +3,6 @@ #pragma once -#include "SaveManager.h" -#include - -#define GAME_REGION_NTSC 0 -#define GAME_REGION_PAL 1 - -#define GAME_PLATFORM_N64 0 -#define GAME_PLATFORM_GC 1 - #define BTN_CUSTOM_MODIFIER1 0x0040 #define BTN_CUSTOM_MODIFIER2 0x0080 @@ -29,6 +20,14 @@ #include "Enhancements/savestates.h" #include "Enhancements/randomizer/randomizer.h" #include +#include + +struct ExtensionEntry { + std::string path; + std::string ext; +}; + +extern std::unordered_map ExtensionCache; #include "Enhancements/randomizer/context.h" const std::string customMessageTableID = "BaseGameOverrides"; @@ -42,60 +41,39 @@ const uint32_t defaultImGuiScale = 1; const float imguiScaleOptionToValue[4] = { 0.75f, 1.0f, 1.5f, 2.0f }; -class OTRGlobals -{ -public: - static OTRGlobals* Instance; +class OTRGlobals { + public: + static OTRGlobals* Instance; std::shared_ptr context; std::shared_ptr gSaveStateMgr; std::shared_ptr gRandomizer; std::shared_ptr gRandoContext; - ImFont* defaultFontSmaller; - ImFont* defaultFontLarger; - ImFont* defaultFontLargest; + ImFont* defaultFontSmaller; + ImFont* defaultFontLarger; + ImFont* defaultFontLargest; - OTRGlobals(); - ~OTRGlobals(); - - void ScaleImGui(); + OTRGlobals(); + ~OTRGlobals(); - bool HasMasterQuest(); - bool HasOriginal(); - uint32_t GetInterpolationFPS(); - std::shared_ptr> ListFiles(std::string path); + void ScaleImGui(); -private: - void CheckSaveFile(size_t sramSize) const; - bool hasMasterQuest; - bool hasOriginal; - ImFont* CreateDefaultFontWithSize(float size); + bool HasMasterQuest(); + bool HasOriginal(); + uint32_t GetInterpolationFPS(); + std::shared_ptr> ListFiles(std::string path); + + private: + void CheckSaveFile(size_t sramSize) const; + bool hasMasterQuest; + bool hasOriginal; + ImFont* CreateDefaultFontWithSize(float size); }; - -uint32_t IsGameMasterQuest(); #endif -#define CVAR_RANDOMIZER_ENHANCEMENT(var) CVAR_PREFIX_RANDOMIZER_ENHANCEMENT "." var -#define CVAR_RANDOMIZER_SETTING(var) CVAR_PREFIX_RANDOMIZER_SETTING "." var -#define CVAR_COSMETIC(var) CVAR_PREFIX_COSMETIC "." var -#define CVAR_AUDIO(var) CVAR_PREFIX_AUDIO "." var -#define CVAR_CHEAT(var) CVAR_PREFIX_CHEAT "." var -#define CVAR_ENHANCEMENT(var) CVAR_PREFIX_ENHANCEMENT "." var -#define CVAR_SETTING(var) CVAR_PREFIX_SETTING "." var -#define CVAR_WINDOW(var) CVAR_PREFIX_WINDOW "." var -#define CVAR_TRACKER(var) CVAR_PREFIX_TRACKER "." var -#define CVAR_TRACKER_ITEM(var) CVAR_TRACKER(".ItemTracker." var) -#define CVAR_TRACKER_CHECK(var) CVAR_TRACKER(".CheckTracker." var) -#define CVAR_TRACKER_ENTRANCE(var) CVAR_TRACKER(".EntranceTracker." var) -#define CVAR_DEVELOPER_TOOLS(var) CVAR_PREFIX_DEVELOPER_TOOLS "." var -#define CVAR_GENERAL(var) CVAR_PREFIX_GENERAL "." var -#define CVAR_REMOTE(var) CVAR_PREFIX_REMOTE "." var -#define CVAR_REMOTE_CROWD_CONTROL(var) CVAR_REMOTE(".CrowdControl." var) -#define CVAR_REMOTE_SAIL(var) CVAR_REMOTE(".Sail." var) - #ifndef __cplusplus - void InitOTR(void); +void InitOTR(void); void DeinitOTR(void); void VanillaItemTable_Init(); void OTRAudio_Init(); @@ -109,54 +87,12 @@ void OTRGfxPrint(const char* str, void* printer, void (*printImpl)(void*, char)) void OTRGetPixelDepthPrepare(float x, float y); uint16_t OTRGetPixelDepth(float x, float y); int32_t OTRGetLastScancode(); -uint32_t ResourceMgr_IsGameMasterQuest(); -uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum); -uint32_t ResourceMgr_GameHasMasterQuest(); -uint32_t ResourceMgr_GameHasOriginal(); -uint32_t ResourceMgr_GetNumGameVersions(); -uint32_t ResourceMgr_GetGameVersion(int index); -uint32_t ResourceMgr_GetGamePlatform(int index); -uint32_t ResourceMgr_GetGameRegion(int index); -void ResourceMgr_LoadDirectory(const char* resName); -void ResourceMgr_UnloadResource(const char* resName); -char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize); -uint8_t ResourceMgr_FileExists(const char* resName); -uint8_t ResourceMgr_FileAltExists(const char* resName); -void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName); char* GetResourceDataByNameHandlingMQ(const char* path); -uint8_t ResourceMgr_TexIsRaw(const char* texPath); -uint8_t ResourceMgr_ResourceIsBackground(char* texPath); -char* ResourceMgr_LoadJPEG(char* data, size_t dataSize); -uint16_t ResourceMgr_LoadTexWidthByName(char* texPath); -uint16_t ResourceMgr_LoadTexHeightByName(char* texPath); -char* ResourceMgr_LoadTexOrDListByName(const char* filePath); -char* ResourceMgr_LoadPlayerAnimByName(const char* animPath); -AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path); -char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc); -Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc); -Gfx* ResourceMgr_LoadGfxByName(const char* path); -uint8_t ResourceMgr_FileIsCustomByName(const char* path); -void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction); -void ResourceMgr_PatchCustomGfxByName(const char* path, const char* patchName, int index, Gfx instruction); -void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName); -char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path); -Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc); -Vtx* ResourceMgr_LoadVtxByName(char* path); -SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path); -SequenceData ResourceMgr_LoadSeqByName(const char* path); -SoundFontSample* ResourceMgr_LoadAudioSample(const char* path); -CollisionHeader* ResourceMgr_LoadColByName(const char* path); void Ctx_ReadSaveFile(uintptr_t addr, void* dramAddr, size_t size); void Ctx_WriteSaveFile(uintptr_t addr, void* dramAddr, size_t size); uint64_t GetPerfCounter(); -bool ResourceMgr_IsAltAssetsEnabled(); -struct SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path, SkelAnime* skelAnime); -void ResourceMgr_UnregisterSkeleton(SkelAnime* skelAnime); -void ResourceMgr_ClearSkeletons(); -s32* ResourceMgr_LoadCSByName(const char* path); -int ResourceMgr_OTRSigCheck(char* imgData); uint64_t osGetTime(void); uint32_t osGetCount(void); uint32_t OTRGetCurrentWidth(void); @@ -199,20 +135,17 @@ RandomizerInf Randomizer_GetRandomizerInfFromCheck(RandomizerCheck randomizerChe bool Randomizer_IsCheckShuffled(RandomizerCheck check); GetItemEntry GetItemMystery(); ItemObtainability Randomizer_GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck); -void Randomizer_GenerateSeed(); uint8_t Randomizer_IsSeedGenerated(); void Randomizer_SetSeedGenerated(bool seedGenerated); uint8_t Randomizer_IsSpoilerLoaded(); void Randomizer_SetSpoilerLoaded(bool spoilerLoaded); -uint8_t Randomizer_IsPlandoLoaded(); -void Randomizer_SetPlandoLoaded(bool plandoLoaded); +uint8_t Randomizer_GenerateRandomizer(); +void Randomizer_ShowRandomizerMenu(); int CustomMessage_RetrieveIfExists(PlayState* play); void Overlay_DisplayText(float duration, const char* text); void Overlay_DisplayText_Seconds(int seconds, const char* text); GetItemEntry ItemTable_Retrieve(int16_t getItemID); GetItemEntry ItemTable_RetrieveEntry(s16 modIndex, s16 getItemID); -void Entrance_ClearEntranceTrackingData(void); -void Entrance_InitEntranceTrackingData(void); void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex); void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex); void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement); diff --git a/soh/soh/ResourceManagerHelpers.cpp b/soh/soh/ResourceManagerHelpers.cpp new file mode 100644 index 000000000..2ab345861 --- /dev/null +++ b/soh/soh/ResourceManagerHelpers.cpp @@ -0,0 +1,505 @@ +#include "ResourceManagerHelpers.h" +#include "OTRGlobals.h" +#include "variables.h" +#include "z64.h" +#include "cvar_prefixes.h" +#include "Enhancements/enhancementTypes.h" +#include "Enhancements/randomizer/dungeon.h" +#include +#include +#include "resource/type/SohResourceType.h" +#include "resource/type/Array.h" +#include "resource/type/Skeleton.h" +#include "resource/type/PlayerAnimation.h" +#include +#include + +extern "C" PlayState* gPlayState; + +extern "C" uint32_t ResourceMgr_GetNumGameVersions() { + return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions().size(); +} + +extern "C" uint32_t ResourceMgr_GetGameVersion(int index) { + return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; +} + +extern "C" uint32_t ResourceMgr_GetGamePlatform(int index) { + uint32_t version = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; + + switch (version) { + case OOT_NTSC_US_10: + case OOT_NTSC_US_11: + case OOT_NTSC_US_12: + case OOT_PAL_10: + case OOT_PAL_11: + return GAME_PLATFORM_N64; + case OOT_NTSC_JP_GC: + case OOT_NTSC_US_GC: + case OOT_PAL_GC: + case OOT_NTSC_JP_MQ: + case OOT_NTSC_US_MQ: + case OOT_PAL_MQ: + case OOT_PAL_GC_DBG1: + case OOT_PAL_GC_DBG2: + case OOT_PAL_GC_MQ_DBG: + return GAME_PLATFORM_GC; + } +} + +extern "C" uint32_t ResourceMgr_GetGameRegion(int index) { + uint32_t version = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->GetGameVersions()[index]; + + switch (version) { + case OOT_NTSC_US_10: + case OOT_NTSC_US_11: + case OOT_NTSC_US_12: + case OOT_NTSC_JP_GC: + case OOT_NTSC_US_GC: + case OOT_NTSC_JP_MQ: + case OOT_NTSC_US_MQ: + return GAME_REGION_NTSC; + case OOT_PAL_10: + case OOT_PAL_11: + case OOT_PAL_GC: + case OOT_PAL_MQ: + case OOT_PAL_GC_DBG1: + case OOT_PAL_GC_DBG2: + case OOT_PAL_GC_MQ_DBG: + return GAME_REGION_PAL; + } +} + +u32 IsSceneMasterQuest(s16 sceneNum) { + u8 mqMode = CVarGetInteger(CVAR_GENERAL("BetterDebugWarpScreenMQMode"), WARP_MODE_OVERRIDE_OFF); + if (mqMode == WARP_MODE_OVERRIDE_MQ_AS_VANILLA) { + return true; + } + + if (mqMode == WARP_MODE_OVERRIDE_VANILLA_AS_MQ) { + return false; + } + + if (OTRGlobals::Instance->HasMasterQuest()) { + if (!OTRGlobals::Instance->HasOriginal()) { + return true; + } + + if (IS_MASTER_QUEST) { + return true; + } + + if (IS_RANDO) { + auto dungeon = OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(sceneNum); + if (dungeon != nullptr && dungeon->IsMQ()) { + return true; + } + } + } + + return false; +} + +extern "C" uint32_t ResourceMgr_GameHasMasterQuest() { + return OTRGlobals::Instance->HasMasterQuest(); +} + +extern "C" uint32_t ResourceMgr_GameHasOriginal() { + return OTRGlobals::Instance->HasOriginal(); +} + +extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum) { + return IsSceneMasterQuest(sceneNum); +} + +extern "C" uint32_t ResourceMgr_IsGameMasterQuest() { + return gPlayState != NULL ? IsSceneMasterQuest(gPlayState->sceneNum) : 0; +} + +extern "C" void ResourceMgr_LoadDirectory(const char* resName) { + Ship::Context::GetInstance()->GetResourceManager()->LoadResources(resName); +} + +extern "C" void ResourceMgr_DirtyDirectory(const char* resName) { + Ship::Context::GetInstance()->GetResourceManager()->DirtyResources(resName); +} + +extern "C" void ResourceMgr_UnloadResource(const char* resName) { + std::string path = resName; + if (path.substr(0, 7) == "__OTR__") { + path = path.substr(7); + } + auto res = Ship::Context::GetInstance()->GetResourceManager()->UnloadResource(path); +} + +// OTRTODO: There is probably a more elegant way to go about this... +// Kenix: This is definitely leaking memory when it's called. +extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) { + auto lst = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles(searchMask); + char** result = (char**)malloc(lst->size() * sizeof(char*)); + + for (size_t i = 0; i < lst->size(); i++) { + char* str = (char*)malloc(lst.get()[0][i].size() + 1); + memcpy(str, lst.get()[0][i].data(), lst.get()[0][i].size()); + str[lst.get()[0][i].size()] = '\0'; + result[i] = str; + } + *resultSize = lst->size(); + + return result; +} + +extern "C" uint8_t ResourceMgr_FileExists(const char* filePath) { + std::string path = filePath; + if(path.substr(0, 7) == "__OTR__"){ + path = path.substr(7); + } + + return ExtensionCache.contains(path); +} + +extern "C" uint8_t ResourceMgr_FileAltExists(const char* filePath) { + std::string path = filePath; + if (path.substr(0, 7) == "__OTR__") { + path = path.substr(7); + } + + if (path.substr(0, 4) != "alt/") { + path = "alt/" + path; + } + + return ExtensionCache.contains(path); +} + +extern "C" bool ResourceMgr_IsAltAssetsEnabled() { + return Ship::Context::GetInstance()->GetResourceManager()->IsAltAssetsEnabled(); +} + +// Unloads a resource if an alternate version exists when alt assets are enabled +// The resource is only removed from the internal cache to prevent it from used in the next resource lookup +extern "C" void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName) { + if (ResourceMgr_IsAltAssetsEnabled() && ResourceMgr_FileAltExists((char*)resName)) { + ResourceMgr_UnloadResource((char*) resName); + } +} + +std::shared_ptr ResourceMgr_GetResourceByNameHandlingMQ(const char* path) { + std::string Path = path; + if (ResourceMgr_IsGameMasterQuest()) { + size_t pos = 0; + if ((pos = Path.find("/nonmq/", 0)) != std::string::npos) { + Path.replace(pos, 7, "/mq/"); + } + } + return Ship::Context::GetInstance()->GetResourceManager()->LoadResource(Path.c_str()); +} + +extern "C" char* ResourceMgr_GetResourceDataByNameHandlingMQ(const char* path) { + auto res = ResourceMgr_GetResourceByNameHandlingMQ(path); + + if (res == nullptr) { + return nullptr; + } + + return (char*)res->GetRawPointer(); +} + +extern "C" uint8_t ResourceMgr_TexIsRaw(const char* texPath) { + auto res = std::static_pointer_cast(ResourceMgr_GetResourceByNameHandlingMQ(texPath)); + return res->Flags & TEX_FLAG_LOAD_AS_RAW; +} + +extern "C" uint8_t ResourceMgr_ResourceIsBackground(char* texPath) { + auto res = ResourceMgr_GetResourceByNameHandlingMQ(texPath); + return res->GetInitData()->Type == static_cast(SOH::ResourceType::SOH_Background); +} + +extern "C" char* ResourceMgr_LoadJPEG(char* data, size_t dataSize) { + static char* finalBuffer = 0; + + if (finalBuffer == 0) { + finalBuffer = (char*)malloc(dataSize); + } + + int w; + int h; + int comp; + + unsigned char* pixels = stbi_load_from_memory((const unsigned char*)data, 320 * 240 * 2, &w, &h, &comp, STBI_rgb_alpha); + //unsigned char* pixels = stbi_load_from_memory((const unsigned char*)data, 480 * 240 * 2, &w, &h, &comp, STBI_rgb_alpha); + int idx = 0; + + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + uint16_t* bufferTest = (uint16_t*)finalBuffer; + int pixelIdx = ((y * w) + x) * 4; + + uint8_t r = pixels[pixelIdx + 0] / 8; + uint8_t g = pixels[pixelIdx + 1] / 8; + uint8_t b = pixels[pixelIdx + 2] / 8; + + uint8_t alphaBit = pixels[pixelIdx + 3] != 0; + + uint16_t data = (r << 11) + (g << 6) + (b << 1) + alphaBit; + + finalBuffer[idx++] = (data & 0xFF00) >> 8; + finalBuffer[idx++] = (data & 0x00FF); + } + } + + return (char*)finalBuffer; +} + +extern "C" char* ResourceMgr_LoadTexOrDListByName(const char* filePath) { + auto res = ResourceMgr_GetResourceByNameHandlingMQ(filePath); + + if (res->GetInitData()->Type == static_cast(Fast::ResourceType::DisplayList)) { + return (char*)&((std::static_pointer_cast(res))->Instructions[0]); + } + + if (res->GetInitData()->Type == static_cast(SOH::ResourceType::SOH_Array)) { + return (char*)(std::static_pointer_cast(res))->Vertices.data(); + } + + return (char*)ResourceMgr_GetResourceDataByNameHandlingMQ(filePath); +} + +extern "C" char* ResourceMgr_LoadIfDListByName(const char* filePath) { + auto res = ResourceMgr_GetResourceByNameHandlingMQ(filePath); + + if (res->GetInitData()->Type == static_cast(Fast::ResourceType::DisplayList)) { + return (char*)&((std::static_pointer_cast(res))->Instructions[0]); + } + + return nullptr; +} + +extern "C" char* ResourceMgr_LoadPlayerAnimByName(const char* animPath) { + auto anim = std::static_pointer_cast(ResourceMgr_GetResourceByNameHandlingMQ(animPath)); + + return (char*)&anim->limbRotData[0]; +} + +extern "C" void ResourceMgr_PushCurrentDirectory(char* path) { + gfx_push_current_dir(path); +} + +extern "C" Gfx* ResourceMgr_LoadGfxByName(const char* path) { + // When an alt resource exists for the DL, we need to unload the original asset + // to clear the cache so the alt asset will be loaded instead + // OTRTODO: If Alt loading over original cache is fixed, this line can most likely be removed + ResourceMgr_UnloadOriginalWhenAltExists(path); + + auto res = std::static_pointer_cast(ResourceMgr_GetResourceByNameHandlingMQ(path)); + return (Gfx*)&res->Instructions[0]; +} + +extern "C" uint8_t ResourceMgr_FileIsCustomByName(const char* path) { + auto res = std::static_pointer_cast(ResourceMgr_GetResourceByNameHandlingMQ(path)); + return res->GetInitData()->IsCustom; +} + +typedef struct { + int index; + Gfx instruction; +} GfxPatch; + +std::unordered_map> originalGfx; + +// Attention! This is primarily for cosmetics & bug fixes. For things like mods and model replacement you should be using OTRs +// instead (When that is available). Index can be found using the commented out section below. +extern "C" void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction) { + auto res = std::static_pointer_cast( + Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path)); + + // Leaving this here for people attempting to find the correct Dlist index to patch + /*if (strcmp("__OTR__objects/object_gi_longsword/gGiBiggoronSwordDL", path) == 0) { + for (int i = 0; i < res->instructions.size(); i++) { + Gfx* gfx = (Gfx*)&res->instructions[i]; + // Log all commands + // SPDLOG_INFO("index:{} command:{}", i, gfx->words.w0 >> 24); + // Log only SetPrimColors + if (gfx->words.w0 >> 24 == 250) { + SPDLOG_INFO("index:{} r:{} g:{} b:{} a:{}", i, _SHIFTR(gfx->words.w1, 24, 8), _SHIFTR(gfx->words.w1, 16, 8), _SHIFTR(gfx->words.w1, 8, 8), _SHIFTR(gfx->words.w1, 0, 8)); + } + } + }*/ + + // Index refers to individual gfx words, which are half the size on 32-bit + // if (sizeof(uintptr_t) < 8) { + // index /= 2; + // } + + // Do not patch custom assets as they most likely do not have the same instructions as authentic assets + if (res->GetInitData()->IsCustom) { + return; + } + + Gfx* gfx = (Gfx*)&res->Instructions[index]; + + if (!originalGfx.contains(path) || !originalGfx[path].contains(patchName)) { + originalGfx[path][patchName] = { + index, + *gfx + }; + } + + *gfx = instruction; +} + +extern "C" void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex, int sourceIndex) { + auto res = std::static_pointer_cast( + Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path)); + + // Do not patch custom assets as they most likely do not have the same instructions as authentic assets + if (res->GetInitData()->IsCustom) { + return; + } + + Gfx* destinationGfx = (Gfx*)&res->Instructions[destinationIndex]; + Gfx sourceGfx = *(Gfx*)&res->Instructions[sourceIndex]; + + if (!originalGfx.contains(path) || !originalGfx[path].contains(patchName)) { + originalGfx[path][patchName] = { + destinationIndex, + *destinationGfx + }; + } + + *destinationGfx = sourceGfx; +} + +extern "C" void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName) { + if (originalGfx.contains(path) && originalGfx[path].contains(patchName)) { + auto res = std::static_pointer_cast( + Ship::Context::GetInstance()->GetResourceManager()->LoadResource(path)); + + Gfx* gfx = (Gfx*)&res->Instructions[originalGfx[path][patchName].index]; + *gfx = originalGfx[path][patchName].instruction; + + originalGfx[path].erase(patchName); + } +} + +extern "C" char* ResourceMgr_LoadArrayByName(const char* path) { + auto res = std::static_pointer_cast(ResourceMgr_GetResourceByNameHandlingMQ(path)); + + return (char*)res->Scalars.data(); +} + +// Return of LoadArrayByNameAsVec3s must be freed by the caller +extern "C" char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path) { + auto res = std::static_pointer_cast(ResourceMgr_GetResourceByNameHandlingMQ(path)); + + // if (res->CachedGameAsset != nullptr) + // return (char*)res->CachedGameAsset; + // else + // { + Vec3s* data = (Vec3s*)malloc(sizeof(Vec3s) * res->Scalars.size()); + + for (size_t i = 0; i < res->Scalars.size(); i += 3) { + data[(i / 3)].x = res->Scalars[i + 0].s16; + data[(i / 3)].y = res->Scalars[i + 1].s16; + data[(i / 3)].z = res->Scalars[i + 2].s16; + } + + // res->CachedGameAsset = data; + + return (char*)data; + // } +} + +extern "C" CollisionHeader* ResourceMgr_LoadColByName(const char* path) { + return (CollisionHeader*) ResourceGetDataByName(path); +} + +extern "C" Vtx* ResourceMgr_LoadVtxByName(char* path) { + return (Vtx*) ResourceGetDataByName(path); +} + +extern "C" SequenceData ResourceMgr_LoadSeqByName(const char* path) { + SequenceData* sequence = (SequenceData*) ResourceGetDataByName(path); + return *sequence; +} + +extern "C" SoundFontSample* ResourceMgr_LoadAudioSample(const char* path) { + return (SoundFontSample*) ResourceGetDataByName(path); +} + +extern "C" SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path) { + return (SoundFont*) ResourceGetDataByName(path); +} + +extern "C" int ResourceMgr_OTRSigCheck(char* imgData) { + uintptr_t i = (uintptr_t)(imgData); + +// if (i == 0xD9000000 || i == 0xE7000000 || (i & 1) == 1) + if ((i & 1) == 1) + return 0; + +// if ((i & 0xFF000000) != 0xAB000000 && (i & 0xFF000000) != 0xCD000000 && i != 0) { + if (i != 0) { + if ( + imgData[0] == '_' && + imgData[1] == '_' && + imgData[2] == 'O' && + imgData[3] == 'T' && + imgData[4] == 'R' && + imgData[5] == '_' && + imgData[6] == '_' + ) { + return 1; + } + } + + return 0; +} + +extern "C" AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path) { + return (AnimationHeaderCommon*) ResourceGetDataByName(path); +} + +extern "C" SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path, SkelAnime* skelAnime) { + std::string pathStr = std::string(path); + static const std::string sOtr = "__OTR__"; + + if (pathStr.starts_with(sOtr)) { + pathStr = pathStr.substr(sOtr.length()); + } + + bool isAlt = ResourceMgr_IsAltAssetsEnabled(); + + if (isAlt) { + pathStr = Ship::IResource::gAltAssetPrefix + pathStr; + } + + SkeletonHeader* skelHeader = (SkeletonHeader*) ResourceGetDataByName(pathStr.c_str()); + + // If there isn't an alternate model, load the regular one + if (isAlt && skelHeader == NULL) { + skelHeader = (SkeletonHeader*) ResourceGetDataByName(path); + } + + // This function is only called when a skeleton is initialized. + // Therefore we can take this oppurtunity to take note of the Skeleton that is created... + if (skelAnime != nullptr) { + auto stringPath = std::string(path); + SOH::SkeletonPatcher::RegisterSkeleton(stringPath, skelAnime); + } + + return skelHeader; +} + +extern "C" void ResourceMgr_UnregisterSkeleton(SkelAnime* skelAnime) { + if (skelAnime != nullptr) { + SOH::SkeletonPatcher::UnregisterSkeleton(skelAnime); + } +} + +extern "C" void ResourceMgr_ClearSkeletons() { + SOH::SkeletonPatcher::ClearSkeletons(); +} + +extern "C" s32* ResourceMgr_LoadCSByName(const char* path) { + return (s32*)ResourceMgr_GetResourceDataByNameHandlingMQ(path); +} diff --git a/soh/soh/ResourceManagerHelpers.h b/soh/soh/ResourceManagerHelpers.h new file mode 100644 index 000000000..3b14188b7 --- /dev/null +++ b/soh/soh/ResourceManagerHelpers.h @@ -0,0 +1,66 @@ +#pragma once + +#include "libultraship/libultra/types.h" + +#define GAME_REGION_NTSC 0 +#define GAME_REGION_PAL 1 + +#define GAME_PLATFORM_N64 0 +#define GAME_PLATFORM_GC 1 + +#ifdef __cplusplus +#include +#include + +std::shared_ptr ResourceMgr_GetResourceByNameHandlingMQ(const char* path); + +extern "C" { +#endif // __cplusplus + #include "z64animation.h" + #include "z64audio.h" + #include "z64bgcheck.h" + uint32_t ResourceMgr_IsGameMasterQuest(); + uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum); + uint32_t ResourceMgr_GameHasMasterQuest(); + uint32_t ResourceMgr_GameHasOriginal(); + uint32_t ResourceMgr_GetNumGameVersions(); + uint32_t ResourceMgr_GetGameVersion(int index); + uint32_t ResourceMgr_GetGamePlatform(int index); + uint32_t ResourceMgr_GetGameRegion(int index); + void ResourceMgr_LoadDirectory(const char* resName); + void ResourceMgr_UnloadResource(const char* resName); + char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize); + uint8_t ResourceMgr_FileExists(const char* resName); + uint8_t ResourceMgr_FileAltExists(const char* resName); + void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName); + uint8_t ResourceMgr_TexIsRaw(const char* texPath); + uint8_t ResourceMgr_ResourceIsBackground(char* texPath); + char* ResourceMgr_LoadJPEG(char* data, size_t dataSize); + uint16_t ResourceMgr_LoadTexWidthByName(char* texPath); + uint16_t ResourceMgr_LoadTexHeightByName(char* texPath); + char* ResourceMgr_LoadTexOrDListByName(const char* filePath); + char* ResourceMgr_LoadPlayerAnimByName(const char* animPath); + AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path); + char* ResourceMgr_GetNameByCRC(uint64_t crc, char* alloc); + Gfx* ResourceMgr_LoadGfxByCRC(uint64_t crc); + Gfx* ResourceMgr_LoadGfxByName(const char* path); + uint8_t ResourceMgr_FileIsCustomByName(const char* path); + void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction); + void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName); + char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path); + Vtx* ResourceMgr_LoadVtxByCRC(uint64_t crc); + Vtx* ResourceMgr_LoadVtxByName(char* path); + SoundFont* ResourceMgr_LoadAudioSoundFont(const char* path); + SequenceData ResourceMgr_LoadSeqByName(const char* path); + SoundFontSample* ResourceMgr_LoadAudioSample(const char* path); + CollisionHeader* ResourceMgr_LoadColByName(const char* path); + bool ResourceMgr_IsAltAssetsEnabled(); + SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path, SkelAnime* skelAnime); + void ResourceMgr_UnregisterSkeleton(SkelAnime* skelAnime); + void ResourceMgr_ClearSkeletons(); + s32* ResourceMgr_LoadCSByName(const char* path); + int ResourceMgr_OTRSigCheck(char* imgData); + char* ResourceMgr_GetResourceDataByNameHandlingMQ(const char* path); +#ifdef __cplusplus +} +#endif // __cplusplus \ No newline at end of file diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 47e73d4ac..36de01199 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -10,6 +10,7 @@ #include "Enhancements/randomizer/item.h" #include "z64.h" +#include "cvar_prefixes.h" #include "functions.h" #include "macros.h" #include @@ -179,7 +180,7 @@ void SaveManager::LoadRandomizerVersion1() { int key, value; SaveManager::Instance->LoadData("sk" + std::to_string(i), key); SaveManager::Instance->LoadData("sv" + std::to_string(i), value); - randoContext->GetOption(RandomizerSettingKey(key)).SetSelectedIndex(value); + randoContext->GetOption(RandomizerSettingKey(key)).SetContextIndex(value); } for (int i = 0; i < 50; i++) { @@ -285,7 +286,7 @@ void SaveManager::LoadRandomizerVersion2() { SaveManager::Instance->LoadArray("randoSettings", RSK_MAX, [&](size_t i) { int value = 0; SaveManager::Instance->LoadData("", value); - randoContext->GetOption(RandomizerSettingKey(i)).SetSelectedIndex(value); + randoContext->GetOption(RandomizerSettingKey(i)).SetContextIndex(value); }); SaveManager::Instance->LoadArray("hintLocations", RH_ZR_OPEN_GROTTO_GOSSIP_STONE + 1, [&](size_t i) { @@ -434,7 +435,7 @@ void SaveManager::LoadRandomizerVersion3() { SaveManager::Instance->LoadArray("randoSettings", RSK_MAX, [&](size_t i) { int value = 0; SaveManager::Instance->LoadData("", value); - randoContext->GetOption(RandomizerSettingKey(i)).SetSelectedIndex(value); + randoContext->GetOption(RandomizerSettingKey(i)).SetContextIndex(value); }); SaveManager::Instance->LoadArray("hintLocations", RH_MAX, [&](size_t i) { @@ -463,7 +464,7 @@ void SaveManager::LoadRandomizerVersion3() { }); randoContext->GetTrials()->SkipAll(); - SaveManager::Instance->LoadArray("requiredTrials", randoContext->GetOption(RSK_TRIAL_COUNT).GetSelectedOptionIndex()+1, [&](size_t i) { + SaveManager::Instance->LoadArray("requiredTrials", randoContext->GetOption(RSK_TRIAL_COUNT).GetContextOptionIndex() + 1, [&](size_t i) { size_t trialId; SaveManager::Instance->LoadData("", trialId); randoContext->GetTrial(trialId)->SetAsRequired(); @@ -512,7 +513,7 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f SaveManager::Instance->SaveData("finalSeed", randoContext->GetSettings()->GetSeed()); SaveManager::Instance->SaveArray("randoSettings", RSK_MAX, [&](size_t i) { - SaveManager::Instance->SaveData("", randoContext->GetOption((RandomizerSettingKey(i))).GetSelectedOptionIndex()); + SaveManager::Instance->SaveData("", randoContext->GetOption((RandomizerSettingKey(i))).GetContextOptionIndex()); }); SaveManager::Instance->SaveArray("hintLocations", RH_MAX, [&](size_t i) { @@ -661,6 +662,8 @@ void SaveManager::Init() { OTRGlobals::Instance->gRandoContext->ClearItemLocations(); } } + auto ctx = Rando::Context::GetInstance(); + ctx->GetSettings()->CreateOptions(); } void SaveManager::InitMeta(int fileNum) { @@ -976,7 +979,7 @@ void SaveManager::InitFileDebug() { } } - gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_0; + gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; gSaveContext.magicLevel = 0; gSaveContext.sceneFlags[5].swch = 0x40000000; } @@ -1119,7 +1122,7 @@ void SaveManager::InitFileMaxed() { } } - gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_0; + gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; gSaveContext.sceneFlags[5].swch = 0x40000000; } diff --git a/soh/soh/SaveManager.h b/soh/soh/SaveManager.h index c17f3d125..1eb6ee87a 100644 --- a/soh/soh/SaveManager.h +++ b/soh/soh/SaveManager.h @@ -1,6 +1,7 @@ #pragma once #include +#include "z64save.h" #define SECTION_PARENT_NONE -1 typedef struct { @@ -45,8 +46,6 @@ typedef struct { #define BS_THREAD_POOL_ENABLE_PAUSE #include -#include "z64save.h" - #include class SaveManager { diff --git a/soh/soh/ShipInit.hpp b/soh/soh/ShipInit.hpp new file mode 100644 index 000000000..b7612eb06 --- /dev/null +++ b/soh/soh/ShipInit.hpp @@ -0,0 +1,43 @@ +#ifndef SHIP_INIT_HPP +#define SHIP_INIT_HPP + +#ifdef __cplusplus + +#include +#include +#include +#include + +struct ShipInit { + static std::unordered_map>>& GetAll() { + static std::unordered_map>> shipInitFuncs; + return shipInitFuncs; + } + + static void InitAll() { + ShipInit::Init("*"); + } + + static void Init(const std::string& path) { + auto& shipInitFuncs = ShipInit::GetAll(); + for (const auto& initFunc : shipInitFuncs[path]) { + initFunc(); + } + } +}; + +struct RegisterShipInitFunc { + RegisterShipInitFunc(std::function initFunc, const std::set& updatePaths = {}) { + auto& shipInitFuncs = ShipInit::GetAll(); + + shipInitFuncs["*"].push_back(initFunc); + + for (const auto& path : updatePaths) { + shipInitFuncs[path].push_back(initFunc); + } + } +}; + +#endif // __cplusplus + +#endif // SHIP_INIT_HPP diff --git a/soh/soh/SohGui.cpp b/soh/soh/SohGui.cpp index c70f544b0..42ba25de2 100644 --- a/soh/soh/SohGui.cpp +++ b/soh/soh/SohGui.cpp @@ -38,6 +38,7 @@ #include "Enhancements/resolution-editor/ResolutionEditor.h" #include "Enhancements/debugger/MessageViewer.h" #include "soh/Notification/Notification.h" +#include "soh/Enhancements/TimeDisplay/TimeDisplay.h" bool isBetaQuestEnabled = false; @@ -131,10 +132,12 @@ namespace SohGui { std::shared_ptr mItemTrackerSettingsWindow; std::shared_ptr mItemTrackerWindow; std::shared_ptr mTimeSplitWindow; + std::shared_ptr mPlandomizerWindow; std::shared_ptr mRandomizerSettingsWindow; std::shared_ptr mAdvancedResolutionSettingsWindow; std::shared_ptr mModalWindow; std::shared_ptr mNotificationWindow; + std::shared_ptr mTimeDisplayWindow; void SetupGuiElements() { auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui(); @@ -210,6 +213,8 @@ namespace SohGui { gui->AddGuiWindow(mRandomizerSettingsWindow); mTimeSplitWindow = std::make_shared(CVAR_WINDOW("TimeSplitEnabled"), "Time Splits", ImVec2(450, 660)); gui->AddGuiWindow(mTimeSplitWindow); + mPlandomizerWindow = std::make_shared(CVAR_WINDOW("PlandomizerWindow"), "Plandomizer Editor", ImVec2(850, 760)); + gui->AddGuiWindow(mPlandomizerWindow); mAdvancedResolutionSettingsWindow = std::make_shared(CVAR_WINDOW("AdvancedResolutionEditor"), "Advanced Resolution Settings", ImVec2(497, 599)); gui->AddGuiWindow(mAdvancedResolutionSettingsWindow); mModalWindow = std::make_shared(CVAR_WINDOW("ModalWindow"), "Modal Window"); @@ -218,6 +223,8 @@ namespace SohGui { mNotificationWindow = std::make_shared(CVAR_WINDOW("Notifications"), "Notifications Window"); gui->AddGuiWindow(mNotificationWindow); mNotificationWindow->Show(); + mTimeDisplayWindow = std::make_shared(CVAR_WINDOW("TimeDisplayEnabled"), "Additional Timers"); + gui->AddGuiWindow(mTimeDisplayWindow); } void Destroy() { @@ -252,9 +259,15 @@ namespace SohGui { mInputViewer = nullptr; mInputViewerSettings = nullptr; mTimeSplitWindow = nullptr; + mPlandomizerWindow = nullptr; + mTimeDisplayWindow = nullptr; } void RegisterPopup(std::string title, std::string message, std::string button1, std::string button2, std::function button1callback, std::function button2callback) { mModalWindow->RegisterPopup(title, message, button1, button2, button1callback, button2callback); } + + void ShowRandomizerSettingsMenu() { + mRandomizerSettingsWindow->Show(); + } } diff --git a/soh/soh/SohGui.hpp b/soh/soh/SohGui.hpp index 1c8eecb79..3f9d616db 100644 --- a/soh/soh/SohGui.hpp +++ b/soh/soh/SohGui.hpp @@ -25,6 +25,7 @@ #include "Enhancements/randomizer/randomizer_item_tracker.h" #include "Enhancements/randomizer/randomizer_settings_window.h" #include "Enhancements/timesplits/TimeSplits.h" +#include "Enhancements/randomizer/Plandomizer.h" #include "SohModals.h" #ifdef __cplusplus @@ -42,6 +43,7 @@ namespace SohGui { void Draw(); void Destroy(); void RegisterPopup(std::string title, std::string message, std::string button1 = "OK", std::string button2 = "", std::function button1callback = nullptr, std::function button2callback = nullptr); + void ShowRandomizerSettingsMenu(); } #endif /* SohGui_hpp */ diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 015ec18af..31f71ec8c 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -10,8 +10,12 @@ #include "include/z64audio.h" #include "graphic/Fast3D/gfx_rendering_api.h" #include "OTRGlobals.h" +#include "SaveManager.h" #include "z64.h" +#include "cvar_prefixes.h" #include "macros.h" +#include "functions.h" +#include "variables.h" #include "Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/presets.h" #include "soh/Enhancements/mods.h" @@ -41,6 +45,8 @@ #include "Enhancements/resolution-editor/ResolutionEditor.h" #include "Enhancements/enemyrandomizer.h" #include "Enhancements/timesplits/TimeSplits.h" +#include "Enhancements/randomizer/Plandomizer.h" +#include "Enhancements/TimeDisplay/TimeDisplay.h" // FA icons are kind of wonky, if they worked how I expected them to the "+ 2.0f" wouldn't be needed, but // they don't work how I expect them to so I added that because it looked good when I eyeballed it @@ -80,6 +86,7 @@ static const char* imguiScaleOptions[4] = { "Small", "Normal", "Large", "X-Large static const char* chestStyleMatchesContentsOptions[4] = { "Disabled", "Both", "Texture Only", "Size Only" }; static const char* skipGetItemAnimationOptions[3] = { "Disabled", "Junk Items", "All Items" }; static const char* skipForcedDialogOptions[4] = { "None", "Navi Only", "NPCs Only", "All" }; + static const char* sleepingWaterfallOptions[3] = { "Always", "Once", "Never" }; static const char* bunnyHoodOptions[3] = { "Disabled", "Faster Run & Longer Jump", "Faster Run" }; static const char* mirroredWorldModes[9] = { "Disabled", "Always", "Random", "Random (Seeded)", "Dungeons", @@ -120,7 +127,7 @@ static const char* imguiScaleOptions[4] = { "Small", "Normal", "Large", "X-Large CVAR_ENHANCEMENT("InjectItemCounts.HeartPiece"), CVAR_ENHANCEMENT("InjectItemCounts.HeartContainer"), }; - static const char* itemCountMessageOptions[sizeof(itemCountMessageCVars) / sizeof(const char*)] = { + static const char* itemCountMessageOptions[ARRAY_COUNT(itemCountMessageCVars)] = { "Gold Skulltula Tokens", "Pieces of Heart", "Heart Containers", @@ -228,18 +235,18 @@ void DrawSettingsMenu() { if (ImGui::BeginMenu("Settings")) { if (ImGui::BeginMenu("Audio")) { - UIWidgets::PaddedEnhancementSliderFloat("Master Volume: %.1f %%", "##Master_Vol", CVAR_SETTING("Volume.Master"), 0.0f, 1.0f, "", 1.0f, true, true, false, true); - if (UIWidgets::PaddedEnhancementSliderFloat("Main Music Volume: %.1f %%", "##Main_Music_Vol", CVAR_SETTING("Volume.MainMusic"), 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { - Audio_SetGameVolume(SEQ_PLAYER_BGM_MAIN, CVarGetFloat(CVAR_SETTING("Volume.MainMusic"), 1.0f)); + UIWidgets::PaddedEnhancementSliderInt("Master Volume: %d %%", "##Master_Vol", CVAR_SETTING("Volume.Master"), 0, 100, "", 100, true, false, true); + if (UIWidgets::PaddedEnhancementSliderInt("Main Music Volume: %d %%", "##Main_Music_Vol", CVAR_SETTING("Volume.MainMusic"), 0, 100, "", 100, true, false, true)) { + Audio_SetGameVolume(SEQ_PLAYER_BGM_MAIN, ((float)CVarGetInteger(CVAR_SETTING("Volume.MainMusic"), 100) / 100.0f)); } - if (UIWidgets::PaddedEnhancementSliderFloat("Sub Music Volume: %.1f %%", "##Sub_Music_Vol", CVAR_SETTING("Volume.SubMusic"), 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { - Audio_SetGameVolume(SEQ_PLAYER_BGM_SUB, CVarGetFloat(CVAR_SETTING("Volume.SubMusic"), 1.0f)); + if (UIWidgets::PaddedEnhancementSliderInt("Sub Music Volume: %d %%", "##Sub_Music_Vol", CVAR_SETTING("Volume.SubMusic"), 0, 100, "", 100, true, false, true)) { + Audio_SetGameVolume(SEQ_PLAYER_BGM_SUB, ((float)CVarGetInteger(CVAR_SETTING("Volume.SubMusic"), 100) / 100.0f)); } - if (UIWidgets::PaddedEnhancementSliderFloat("Sound Effects Volume: %.1f %%", "##Sound_Effect_Vol", CVAR_SETTING("Volume.SFX"), 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { - Audio_SetGameVolume(SEQ_PLAYER_SFX, CVarGetFloat(CVAR_SETTING("Volume.SFX"), 1.0f)); + if (UIWidgets::PaddedEnhancementSliderInt("Fanfare Volume: %d %%", "##Fanfare_Vol", CVAR_SETTING("Volume.Fanfare"), 0, 100, "", 100, true, false, true)) { + Audio_SetGameVolume(SEQ_PLAYER_FANFARE, ((float)CVarGetInteger(CVAR_SETTING("Volume.Fanfare"), 100) / 100.0f)); } - if (UIWidgets::PaddedEnhancementSliderFloat("Fanfare Volume: %.1f %%", "##Fanfare_Vol", CVAR_SETTING("Volume.Fanfare"), 0.0f, 1.0f, "", 1.0f, true, true, false, true)) { - Audio_SetGameVolume(SEQ_PLAYER_FANFARE, CVarGetFloat(CVAR_SETTING("Volume.Fanfare"), 1.0f)); + if (UIWidgets::PaddedEnhancementSliderInt("Sound Effects Volume: %d %%", "##Sound_Effect_Vol", CVAR_SETTING("Volume.SFX"), 0, 100, "", 100, true, false, true)) { + Audio_SetGameVolume(SEQ_PLAYER_SFX, ((float)CVarGetInteger(CVAR_SETTING("Volume.SFX"), 100) / 100.0f)); } static std::unordered_map audioBackendNames = { @@ -248,7 +255,7 @@ void DrawSettingsMenu() { }; ImGui::Text("Audio API (Needs reload)"); - auto currentAudioBackend = Ship::Context::GetInstance()->GetAudio()->GetAudioBackend(); + auto currentAudioBackend = Ship::Context::GetInstance()->GetAudio()->GetCurrentAudioBackend(); if (Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) { UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); @@ -257,7 +264,7 @@ void DrawSettingsMenu() { for (uint8_t i = 0; i < Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size(); i++) { auto backend = Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->data()[i]; if (ImGui::Selectable(audioBackendNames[backend], backend == currentAudioBackend)) { - Ship::Context::GetInstance()->GetAudio()->SetAudioBackend(backend); + Ship::Context::GetInstance()->GetAudio()->SetCurrentAudioBackend(backend); } } ImGui::EndCombo(); @@ -429,7 +436,7 @@ void DrawSettingsMenu() { currentFps = 60; } CVarSetInteger(CVAR_SETTING("InterpolationFPS"), currentFps); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); #else bool matchingRefreshRate = CVarGetInteger(CVAR_SETTING("MatchRefreshRate"), 0) && Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() != Ship::WindowBackend::FAST3D_DXGI_DX11; @@ -458,7 +465,7 @@ void DrawSettingsMenu() { int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); if (hz >= 20 && hz <= 360) { CVarSetInteger(CVAR_SETTING("InterpolationFPS"), hz); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } } else { @@ -580,9 +587,9 @@ void DrawSettingsMenu() { ImGui::Text("Position"); UIWidgets::EnhancementCombobox(CVAR_SETTING("Notifications.Position"), notificationPosition, 0); - UIWidgets::EnhancementSliderFloat("Duration: %.0f seconds", "##NotificationDuration", CVAR_SETTING("Notifications.Duration"), 3.0f, 30.0f, "", 10.0f, false, false, false); - UIWidgets::EnhancementSliderFloat("BG Opacity: %.1f %%", "##NotificaitonBgOpacity", CVAR_SETTING("Notifications.BgOpacity"), 0.0f, 1.0f, "", 0.5f, true, false, false); - UIWidgets::EnhancementSliderFloat("Size: %.1f", "##NotificaitonSize", CVAR_SETTING("Notifications.Size"), 1.0f, 5.0f, "", 1.8f, false, false, false); + UIWidgets::EnhancementSliderFloat("Duration: %.1f seconds", "##NotificationDuration", CVAR_SETTING("Notifications.Duration"), 3.0f, 30.0f, "", 10.0f, false, true, false); + UIWidgets::EnhancementSliderFloat("BG Opacity: %.1f %%", "##NotificaitonBgOpacity", CVAR_SETTING("Notifications.BgOpacity"), 0.0f, 1.0f, "", 0.5f, true, true, false); + UIWidgets::EnhancementSliderFloat("Size: %.1f", "##NotificaitonSize", CVAR_SETTING("Notifications.Size"), 1.0f, 20.0f, "", 1.8f, false, true, false); UIWidgets::Spacer(0); @@ -603,6 +610,7 @@ extern std::shared_ptr mAudioEditorWindow; extern std::shared_ptr mCosmeticsEditorWindow; extern std::shared_ptr mGameplayStatsWindow; extern std::shared_ptr mTimeSplitWindow; +extern std::shared_ptr mTimeDisplayWindow; void DrawEnhancementsMenu() { if (ImGui::BeginMenu("Enhancements")) @@ -665,7 +673,7 @@ void DrawEnhancementsMenu() { CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), newValue); CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), newValue); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } g->CurrentItemFlags = backup_item_flags; UIWidgets::PaddedEnhancementCheckbox("Skip Intro", CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); @@ -678,8 +686,8 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedEnhancementCheckbox("Skip Owl Interactions", CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Skip Misc Interactions", CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); UIWidgets::PaddedEnhancementCheckbox("Disable Title Card", CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), false, false, false, "", UIWidgets::CheckboxGraphics::Cross, IS_RANDO); - UIWidgets::PaddedEnhancementCheckbox("Skip Glitch-Aiding Cutscenes", CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), false, false, false, "", UIWidgets::CheckboxGraphics::Cross, 0); - UIWidgets::Tooltip("Skip cutscenes that are associated with useful glitches, currently this is only the Fire Temple Darunia CS and Forest Temple Poe Sisters CS"); + UIWidgets::PaddedEnhancementCheckbox("Exclude Glitch-Aiding Cutscenes", CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), false, false, false, "", UIWidgets::CheckboxGraphics::Cross, 0); + UIWidgets::Tooltip("Don't skip cutscenes that are associated with useful glitches, currently this is only the Fire Temple Darunia CS, Forest Temple Poe Sisters CS and the Box Skip One Point in Jabu"); UIWidgets::PaddedEnhancementCheckbox("Skip Child Stealth", CVAR_ENHANCEMENT("TimeSavers.SkipChildStealth"), false, false, false, "", UIWidgets::CheckboxGraphics::Cross, false); UIWidgets::Tooltip("The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards."); UIWidgets::PaddedEnhancementCheckbox("Skip Tower Escape", CVAR_ENHANCEMENT("TimeSavers.SkipTowerEscape"), false, false, false, "", UIWidgets::CheckboxGraphics::Cross, false); @@ -715,18 +723,11 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("Skip pickup messages for new consumable items and bottle swipes"); UIWidgets::PaddedEnhancementCheckbox("Fast Ocarina Playback", CVAR_ENHANCEMENT("FastOcarinaPlayback"), true, false); UIWidgets::Tooltip("Skip the part where the Ocarina playback is called when you play a song"); - bool forceSkipScarecrow = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_SCARECROWS_SONG); - static const char* forceSkipScarecrowText = "This setting is forcefully enabled because a savefile\nwith \"Skip Scarecrow Song\" is loaded"; - UIWidgets::PaddedEnhancementCheckbox("Skip Scarecrow Song", CVAR_ENHANCEMENT("InstantScarecrow"), true, false, - forceSkipScarecrow, forceSkipScarecrowText, UIWidgets::CheckboxGraphics::Checkmark); - UIWidgets::Tooltip("Pierre appears when Ocarina is pulled out. Requires learning scarecrow song."); UIWidgets::PaddedEnhancementCheckbox("Skip Magic Arrow Equip Animation", CVAR_ENHANCEMENT("SkipArrowAnimation"), true, false); UIWidgets::PaddedEnhancementCheckbox("Skip save confirmation", CVAR_ENHANCEMENT("SkipSaveConfirmation"), true, false); UIWidgets::Tooltip("Skip the \"Game saved.\" confirmation screen"); UIWidgets::PaddedEnhancementCheckbox("Faster Farore's Wind", CVAR_ENHANCEMENT("FastFarores"), true, false); UIWidgets::Tooltip("Greatly decreases cast time of Farore's Wind magic spell."); - UIWidgets::PaddedEnhancementCheckbox("Skip water take breath animation", CVAR_ENHANCEMENT("SkipSwimDeepEndAnim"), true, false); - UIWidgets::Tooltip("Skips Link's taking breath animation after coming up from water. This setting does not interfere with getting items from underwater."); ImGui::TableNextColumn(); UIWidgets::Spacer(0); @@ -793,6 +794,30 @@ void DrawEnhancementsMenu() { "- Not within range of Ocarina playing spots"); UIWidgets::PaddedEnhancementCheckbox("Pause Warp", CVAR_ENHANCEMENT("PauseWarp"), true, false); UIWidgets::Tooltip("Selection of warp song in pause menu initiates warp. Disables song playback."); + UIWidgets::PaddedEnhancementCheckbox("Skip water take breath animation", CVAR_ENHANCEMENT("SkipSwimDeepEndAnim"), true, false); + UIWidgets::Tooltip("Skips Link's taking breath animation after coming up from water. This setting does not interfere with getting items from underwater."); + bool forceSkipScarecrow = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_SCARECROWS_SONG); + static const char* forceSkipScarecrowText = "This setting is forcefully enabled because a savefile\nwith \"Skip Scarecrow Song\" is loaded"; + UIWidgets::PaddedEnhancementCheckbox("Skip Scarecrow Song", CVAR_ENHANCEMENT("InstantScarecrow"), true, false, + forceSkipScarecrow, forceSkipScarecrowText, UIWidgets::CheckboxGraphics::Checkmark); + UIWidgets::Tooltip("Pierre appears when Ocarina is pulled out. Requires learning scarecrow song."); + bool forceSleepingWaterfallEnhancement = + IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SLEEPING_WATERFALL) == RO_WATERFALL_OPEN; + uint8_t forceSleepingWaterfallValue = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SLEEPING_WATERFALL) + 1; + static const char* forceSleepingWaterfallText = + "This setting is forcefully enabled because a randomizer savefile with \"Sleeping Waterfall: Open\" is loaded."; + UIWidgets::PaddedText("Play Zelda's Lullaby to open Sleeping Waterfall", true, false); + UIWidgets::EnhancementCombobox(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), + sleepingWaterfallOptions, 0, forceSleepingWaterfallEnhancement, + forceSleepingWaterfallText, forceSleepingWaterfallValue); + UIWidgets::Tooltip( + "Always: Link must always play Zelda's Lullaby to open " + "the waterfall entrance to Zora's Domain.\n" + "Once: Link only needs to play Zelda's Lullaby once to " + "open the waterfall; after that, it stays open permanently.\n" + "Never: Link never needs to play Zelda's Lullaby to open the " + "waterfall; he only needs to have learned it and have an ocarina." + ); ImGui::EndTable(); ImGui::EndMenu(); @@ -851,6 +876,17 @@ void DrawEnhancementsMenu() { "Toggling while inside the shop will not change prices or restock any SOLD OUTs"); UIWidgets::PaddedEnhancementCheckbox("Aiming reticle for the bow/slingshot", CVAR_ENHANCEMENT("BowReticle"), true, false); UIWidgets::Tooltip("Aiming with a bow or slingshot will display a reticle as with the hookshot when the projectile is ready to fire."); + if (UIWidgets::PaddedEnhancementCheckbox("Aim boomerang in first-person mode", CVAR_ENHANCEMENT("BoomerangFirstPerson"), true, false)) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("BoomerangFirstPerson"), 0)) { + CVarSetInteger(CVAR_ENHANCEMENT("BoomerangReticle"), 0); + } + } + UIWidgets::Tooltip( + "Change aiming for the boomerang from third person to first person to see past Link's head"); + if (CVarGetInteger(CVAR_ENHANCEMENT("BoomerangFirstPerson"), 0)) { + UIWidgets::PaddedEnhancementCheckbox("Aiming reticle for boomerang", CVAR_ENHANCEMENT("BoomerangReticle"), true, false); + UIWidgets::Tooltip("Aiming with the boomerang will display a reticle as with the hookshot"); + } if (UIWidgets::PaddedEnhancementCheckbox("Allow strength equipment to be toggled", CVAR_ENHANCEMENT("ToggleStrength"), true, false)) { if (!CVarGetInteger(CVAR_ENHANCEMENT("ToggleStrength"), 0)) { CVarSetInteger(CVAR_ENHANCEMENT("StrengthDisabled"), 0); @@ -863,7 +899,7 @@ void DrawEnhancementsMenu() { UIWidgets::Spacer(0); if (ImGui::BeginMenu("Item Count Messages")) { - int numOptions = sizeof(itemCountMessageCVars) / sizeof(const char*); + int numOptions = ARRAY_COUNT(itemCountMessageCVars); bool allItemCountsChecked = std::all_of(itemCountMessageCVars, itemCountMessageCVars + numOptions, [](const char* cvar) { return CVarGetInteger(cvar, 0); }); bool someItemCountsChecked = std::any_of(itemCountMessageCVars, itemCountMessageCVars + numOptions, @@ -878,7 +914,7 @@ void DrawEnhancementsMenu() { std::for_each(itemCountMessageCVars, itemCountMessageCVars + numOptions, [newValue](const char* cvar) { CVarSetInteger(cvar, newValue); }); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } g->CurrentItemFlags = backup_item_flags; @@ -1265,6 +1301,9 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedEnhancementCheckbox("Targetable Hookshot Reticle", CVAR_ENHANCEMENT("HookshotableReticle"), true, false); UIWidgets::Tooltip("Use a different color when aiming at hookshotable collision"); + UIWidgets::PaddedEnhancementCheckbox("Faster Rupee Accumulator", CVAR_ENHANCEMENT("TimeSavers.FasterRupeeAccumulator"), true, false); + UIWidgets::Tooltip("Causes your wallet to fill and empty faster when you gain or lose money."); + ImGui::EndMenu(); } @@ -1488,10 +1527,23 @@ void DrawEnhancementsMenu() { "This will lower them, making activating them easier"); UIWidgets::PaddedEnhancementCheckbox("Fix Zora hint dialogue", CVAR_ENHANCEMENT("FixZoraHintDialogue"), true, false); UIWidgets::Tooltip("Fixes one Zora's dialogue giving a hint about bringing Ruto's Letter to King Zora to properly occur before moving King Zora rather than after"); - if (UIWidgets::PaddedEnhancementCheckbox("Fix hand holding Hammer", "gEnhancements.FixHammerHand", true, false)) { + if (UIWidgets::PaddedEnhancementCheckbox("Fix hand holding Hammer", CVAR_ENHANCEMENT("FixHammerHand"), true, false)) { UpdatePatchHand(); } - UIWidgets::Tooltip("Fixes Adult Link have a backwards left hand when holding the Megaton Hammer."); + UIWidgets::Tooltip("Fixes Adult Link having a backwards left hand when holding the Megaton Hammer."); + if (UIWidgets::PaddedEnhancementCheckbox( + "Fix Broken Giant's Knife bug", CVAR_ENHANCEMENT("FixBrokenGiantsKnife"), true, false, IS_RANDO, + "This setting is forcefully enabled when you are playing a randomizer.", + UIWidgets::CheckboxGraphics::Checkmark)) { + bool hasGiantsKnife = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON); + bool hasBrokenKnife = CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE); + bool knifeIsBroken = gSaveContext.swordHealth == 0.0f; + + if (hasGiantsKnife && (hasBrokenKnife != knifeIsBroken)) { + func_800849EC(gPlayState); + } + } + UIWidgets::Tooltip("Fixes the Broken Giant's Knife flag not being reset when Medigoron fixes it"); ImGui::EndMenu(); } @@ -1520,6 +1572,8 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("Restores the original outcomes when performing Reverse Bottle Adventure."); UIWidgets::PaddedEnhancementCheckbox("Early Eyeball Frog", CVAR_ENHANCEMENT("EarlyEyeballFrog"), true, false); UIWidgets::Tooltip("Restores a bug from NTSC 1.0/1.1 that allows you to obtain the eyeball frog from King Zora instead of the Zora Tunic by holding shield."); + UIWidgets::PaddedEnhancementCheckbox("Pulsate boss icon", CVAR_ENHANCEMENT("PulsateBossIcon"), true, false); + UIWidgets::Tooltip("Restores an unfinished feature to pulsate the boss room icon when you are in the boss room."); ImGui::EndMenu(); } @@ -1690,6 +1744,36 @@ void DrawEnhancementsMenu() { mTimeSplitWindow->ToggleVisibility(); } } + + if (mTimeDisplayWindow) { + if (ImGui::Button(GetWindowButtonText("Additional Timers", CVarGetInteger(CVAR_WINDOW("TimeDisplayEnabled"), 0)).c_str(), ImVec2(-1.0f, 0.0f))) { + mTimeDisplayWindow->ToggleVisibility(); + } + } + if (mTimeDisplayWindow->IsVisible()) { + ImGui::SeparatorText("Timer Display Options"); + + if (!gPlayState) { + ImGui::Text("Additional Timer options\n" + "available when a file is\n" + "loaded..."); + } else { + if (UIWidgets::PaddedEnhancementSliderFloat("Font Scale: %.2fx", "##FontScale", CVAR_ENHANCEMENT("TimeDisplay.FontScale"), + 1.0f, 5.0f, "", 1.0f, false, true, false, true)) { + TimeDisplayInitSettings(); + } + if (UIWidgets::PaddedEnhancementCheckbox("Hide Background", CVAR_ENHANCEMENT("TimeDisplay.ShowWindowBG"), + false, false)) { + TimeDisplayInitSettings(); + } + ImGui::Separator(); + for (auto& timer : timeDisplayList) { + if (UIWidgets::PaddedEnhancementCheckbox(timer.timeLabel.c_str(), timer.timeEnable, false, false)) { + TimeDisplayUpdateDisplayOptions(); + } + } + } + } ImGui::PopStyleVar(3); ImGui::PopStyleColor(1); @@ -1744,7 +1828,7 @@ void DrawCheatsMenu() { UIWidgets::EnhancementSliderFloat("Hookshot Reach Multiplier: %.2fx", "##gCheatHookshotReachMultiplier", CVAR_CHEAT("HookshotReachMultiplier"), 1.0f, 5.0f, "", 1.0f, false); UIWidgets::Spacer(2.0f); if (ImGui::Button("Change Age")) { - CVarSetInteger(CVAR_GENERAL("SwitchAge"), 1); + SwitchAge(); } UIWidgets::Tooltip("Switches Link's age and reloads the area."); UIWidgets::Spacer(2.0f); @@ -1783,7 +1867,7 @@ void DrawCheatsMenu() { if (UIWidgets::PaddedEnhancementCheckbox("I promise I have read the warning", CVAR_CHEAT("SaveStatePromise"), true, false)) { CVarSetInteger(CVAR_CHEAT("SaveStatesEnabled"), 0); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (CVarGetInteger(CVAR_CHEAT("SaveStatePromise"), 0) == 1) { UIWidgets::PaddedEnhancementCheckbox("I understand, enable save states", CVAR_CHEAT("SaveStatesEnabled"), true, @@ -1878,7 +1962,7 @@ void DrawCheatsMenu() { CVarSetInteger(CVAR_CHEAT("BetaQuestWorld"), betaQuestWorld); std::reinterpret_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch("reset"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } if (!isBetaQuestEnabled) { @@ -2041,6 +2125,7 @@ void DrawRemoteControlMenu() { #endif extern std::shared_ptr mRandomizerSettingsWindow; +extern std::shared_ptr mPlandomizerWindow; extern std::shared_ptr mItemTrackerWindow; extern std::shared_ptr mItemTrackerSettingsWindow; extern std::shared_ptr mEntranceTrackerWindow; @@ -2051,14 +2136,6 @@ extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); void DrawRandomizerMenu() { if (ImGui::BeginMenu("Randomizer")) { - UIWidgets::EnhancementCheckbox("Plando Mode", CVAR_GENERAL("PlandoMode")); - UIWidgets::Tooltip( - "When dropping a spoiler file on the game window, parse the full spoiler file instead of just the " - "necessary " - "parts to regenerate a seed.\n\nKeep in mind if you do this, all custom text will only be available in the " - "language present in the spoilerfile. You can use this to edit a previously generated spoilerfile that has " - "been edited with custom hint text and item locations. May be useful for debugging."); - UIWidgets::PaddedSeparator(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); @@ -2084,6 +2161,14 @@ void DrawRandomizerMenu() { UIWidgets::Spacer(0); + if (mPlandomizerWindow) { + if (ImGui::Button(GetWindowButtonText("Plandomizer Editor", CVarGetInteger(CVAR_WINDOW("PlandomizerWindow"), 0)).c_str(), buttonSize)) { + mPlandomizerWindow->ToggleVisibility(); + } + } + + UIWidgets::Spacer(0); + if (mItemTrackerWindow) { if (ImGui::Button(GetWindowButtonText("Item Tracker", CVarGetInteger(CVAR_WINDOW("ItemTracker"), 0)).c_str(), buttonWithOptionsSize)) { mItemTrackerWindow->ToggleVisibility(); diff --git a/soh/soh/SohModals.cpp b/soh/soh/SohModals.cpp index b77a5f47f..576df50f7 100644 --- a/soh/soh/SohModals.cpp +++ b/soh/soh/SohModals.cpp @@ -35,7 +35,7 @@ void SohModalWindow::DrawElement() { ImGui::OpenPopup(curModal.title_.c_str()); } if (ImGui::BeginPopupModal(curModal.title_.c_str(), NULL, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings)) { - ImGui::Text(curModal.message_.c_str()); + ImGui::Text("%s", curModal.message_.c_str()); if (ImGui::Button(curModal.button1_.c_str())) { if (curModal.button1callback_ != nullptr) { curModal.button1callback_(); @@ -60,4 +60,4 @@ void SohModalWindow::DrawElement() { void SohModalWindow::RegisterPopup(std::string title, std::string message, std::string button1, std::string button2, std::function button1callback, std::function button2callback) { modals.push_back({ title, message, button1, button2, button1callback, button2callback }); -} \ No newline at end of file +} diff --git a/soh/soh/UIWidgets.cpp b/soh/soh/UIWidgets.cpp index 1d7a56c00..9272cbefc 100644 --- a/soh/soh/UIWidgets.cpp +++ b/soh/soh/UIWidgets.cpp @@ -238,7 +238,8 @@ namespace UIWidgets { bool val = (bool)CVarGetInteger(cvarName, defaultValue); if (CustomCheckbox(text, &val, disabled, disabledGraphic)) { CVarSetInteger(cvarName, val); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ShipInit::Init(cvarName); changed = true; } @@ -257,7 +258,7 @@ namespace UIWidgets { int val = CVarGetInteger(cvarName, defaultValue); if (CustomCheckboxTristate(text, &val, disabled, disabledGraphic)) { CVarSetInteger(cvarName, val); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); changed = true; } @@ -297,7 +298,8 @@ namespace UIWidgets { CVarSetInteger(cvarName, i); selected = i; changed = true; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ShipInit::Init(cvarName); } } } @@ -310,7 +312,7 @@ namespace UIWidgets { if (disabledValue >= 0 && selected != disabledValue) { CVarSetInteger(cvarName, disabledValue); changed = true; - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } @@ -400,7 +402,7 @@ namespace UIWidgets { if (changed && (oldVal != val)) { CVarSetInteger(cvarName, val); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } else { changed = false; } @@ -501,7 +503,7 @@ namespace UIWidgets { ss << std::setprecision(ticks + 1) << std::setiosflags(std::ios_base::fixed) << val; val = std::stof(ss.str()); CVarSetFloat(cvarName, val); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } else { changed = false; } @@ -550,7 +552,7 @@ namespace UIWidgets { int val = CVarGetInteger(cvarName, 0); if (ImGui::RadioButton(make_invisible.c_str(), id == val)) { CVarSetInteger(cvarName, id); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); ret = true; } ImGui::SameLine(); @@ -577,7 +579,7 @@ namespace UIWidgets { CVarSetColor(cvarName, colorsRGBA); CVarSetInteger(Cvar_RBM.c_str(), 0); //On click disable rainbow mode. - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); changed = true; } Tooltip("Revert colors to the game's original colors (GameCube version)\nOverwrites previously chosen color"); @@ -593,7 +595,7 @@ namespace UIWidgets { #if defined(__SWITCH__) || defined(__WIIU__) srand(time(NULL)); #endif - ImVec4 color = GetRandomValue(255); + ImVec4 color = GetRandomValue(); colors->x = color.x; colors->y = color.y; colors->z = color.z; @@ -602,7 +604,7 @@ namespace UIWidgets { NewColors.b = fmin(fmax(colors->z * 255, 0), 255); CVarSetColor(cvarName, NewColors); CVarSetInteger(Cvar_RBM.c_str(), 0); // On click disable rainbow mode. - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); changed = true; } Tooltip("Chooses a random color\nOverwrites previously chosen color"); @@ -663,7 +665,7 @@ namespace UIWidgets { colors.a = 255.0; CVarSetColor(cvarName, colors); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); changed = true; } } @@ -679,7 +681,7 @@ namespace UIWidgets { colors.a = ColorRGBA.w * 255.0; CVarSetColor(cvarName, colors); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); changed = true; } } diff --git a/soh/soh/UIWidgets.hpp b/soh/soh/UIWidgets.hpp index 5903220d2..c0e1b4504 100644 --- a/soh/soh/UIWidgets.hpp +++ b/soh/soh/UIWidgets.hpp @@ -1,10 +1,3 @@ -// -// UIWidgets.hpp -// soh -// -// Created by David Chavez on 25.08.22. -// - #ifndef UIWidgets_hpp #define UIWidgets_hpp @@ -17,6 +10,7 @@ #define IMGUI_DEFINE_MATH_OPERATORS #endif #include +#include "soh/ShipInit.hpp" namespace UIWidgets { diff --git a/soh/soh/config/ConfigMigrators.h b/soh/soh/config/ConfigMigrators.h index 1626e38a8..abfe9a6b1 100644 --- a/soh/soh/config/ConfigMigrators.h +++ b/soh/soh/config/ConfigMigrators.h @@ -61,11 +61,6 @@ namespace SOH { { MigrationAction::Rename, "gGfxDebuggerEnabled", "gOpenWindows.GfxDebugger" }, { MigrationAction::Rename, "gStatsEnabled", "gOpenWindows.Stats" }, { MigrationAction::Rename, "gDisableChangingSettings", "gSettings.DisableChanges" }, - { MigrationAction::Rename, "gGameMasterVolume", "gSettings.Volume.Master" }, - { MigrationAction::Rename, "gMainMusicVolume", "gSettings.Volume.MainMusic" }, - { MigrationAction::Rename, "gSubMusicVolume", "gSettings.Volume.SubMusic" }, - { MigrationAction::Rename, "gSFXMusicVolume", "gSettings.Volume.SFX" }, - { MigrationAction::Rename, "gFanfareVolume", "gSettings.Volume.Fanfare" }, { MigrationAction::Rename, "gExtraLatencyThreshold", "gSettings.ExtraLatencyThreshold" }, { MigrationAction::Rename, "gImGuiScale", "gSettings.ImGuiScale" }, { MigrationAction::Rename, "gTitleScreenTranslation", "gSettings.TitleScreenTranslation" }, @@ -77,11 +72,6 @@ namespace SOH { { MigrationAction::Rename, "gLowResMode", "gSettings.LowResMode" }, { MigrationAction::Rename, "gZFightingMode", "gSettings.ZFightingMode" }, { MigrationAction::Rename, "gDisableChangingSettings", "gSettings.DisableChanges" }, - { MigrationAction::Rename, "gGameMasterVolume", "gSettings.Volume.Master" }, - { MigrationAction::Rename, "gMainMusicVolume", "gSettings.Volume.MainMusic" }, - { MigrationAction::Rename, "gSubMusicVolume", "gSettings.Volume.SubMusic" }, - { MigrationAction::Rename, "gSFXMusicVolume", "gSettings.Volume.SFX" }, - { MigrationAction::Rename, "gFanfareVolume", "gSettings.Volume.Fanfare" }, { MigrationAction::Rename, "gExtraLatencyThreshold", "gSettings.ExtraLatencyThreshold" }, { MigrationAction::Rename, "gImGuiScale", "gSettings.ImGuiScale" }, { MigrationAction::Rename, "gTitleScreenTranslation", "gSettings.TitleScreenTranslation" }, @@ -260,7 +250,6 @@ namespace SOH { { MigrationAction::Rename, "gHurtContainer", "gEnhancements.HurtContainer" }, { MigrationAction::Rename, "gHyperBosses", "gEnhancements.HyperBosses" }, { MigrationAction::Rename, "gHyperEnemies", "gEnhancements.HyperEnemies" }, - { MigrationAction::Rename, "gInjectItemCounts", "gEnhancements.InjectItemCounts" }, { MigrationAction::Rename, "gInstantFishing", "gEnhancements.InstantFishing" }, { MigrationAction::Rename, "gInstantOcarinaGameWin", "gEnhancements.InstantOcarinaGameWin" }, { MigrationAction::Rename, "gInstantPutaway", "gEnhancements.InstantPutaway" }, @@ -1332,12 +1321,12 @@ namespace SOH { { MigrationAction::Rename, "gRandomizeEnableBombchuDrops", "gRandoSettings.EnableBombchuDrops" }, { MigrationAction::Rename, "gRandomizeEnableGlitchCutscenes", "gRandoSettings.EnableGlitchCutscenes" }, { MigrationAction::Rename, "gRandomizeEnabledTricks", "gRandoSettings.EnabledTricks" }, - { MigrationAction::Rename, "gRandomizeForest", "gRandoSettings.Forest" }, + { MigrationAction::Rename, "gRandomizeForest", "gRandoSettings.ClosedForest" }, { MigrationAction::Rename, "gRandomizeFrogsHint", "gRandoSettings.FrogsHint" }, { MigrationAction::Rename, "gRandomizeFullWallets", "gRandoSettings.FullWallets" }, { MigrationAction::Rename, "gRandomizeGanonTrial", "gRandoSettings.GanonTrial" }, { MigrationAction::Rename, "gRandomizeGanonTrialCount", "gRandoSettings.GanonTrialCount" }, - { MigrationAction::Rename, "gRandomizeGerudoFortress", "gRandoSettings.GerudoFortress" }, + { MigrationAction::Rename, "gRandomizeGerudoFortress", "gRandoSettings.FortressCarpenters" }, { MigrationAction::Rename, "gRandomizeGerudoKeys", "gRandoSettings.GerudoKeys" }, { MigrationAction::Rename, "gRandomizeGossipStoneHints", "gRandoSettings.GossipStoneHints" }, { MigrationAction::Rename, "gRandomizeGregHint", "gRandoSettings.GregHint" }, diff --git a/soh/soh/config/ConfigUpdaters.cpp b/soh/soh/config/ConfigUpdaters.cpp index e43e98b76..0f3324be7 100644 --- a/soh/soh/config/ConfigUpdaters.cpp +++ b/soh/soh/config/ConfigUpdaters.cpp @@ -71,17 +71,41 @@ namespace SOH { void ConfigVersion3Updater::Update(Ship::Config* conf) { conf->EraseBlock("Controllers"); + + if (conf->GetNestedJson().contains("CVars") && conf->GetNestedJson()["CVars"].contains("gInjectItemCounts")) { + CVarClear("gInjectItemCounts"); + CVarSetInteger("gEnhancements.InjectItemCounts.GoldSkulltula", 1); + CVarSetInteger("gEnhancements.InjectItemCounts.HeartContainer", 1); + CVarSetInteger("gEnhancements.InjectItemCounts.HeartPiece", 1); + } + + // Migrate all audio settings to ints + if (conf->GetNestedJson().contains("CVars") && conf->GetNestedJson()["CVars"].contains("gGameMasterVolume")) { + CVarSetInteger("gSettings.Volume.Master", (int32_t)(CVarGetFloat("gGameMasterVolume", 1.0f) * 100)); + CVarClear("gGameMasterVolume"); + } + if (conf->GetNestedJson().contains("CVars") && conf->GetNestedJson()["CVars"].contains("gMainMusicVolume")) { + CVarSetInteger("gSettings.Volume.MainMusic", (int32_t)(CVarGetFloat("gMainMusicVolume", 1.0f) * 100)); + CVarClear("gMainMusicVolume"); + } + if (conf->GetNestedJson().contains("CVars") && conf->GetNestedJson()["CVars"].contains("gSubMusicVolume")) { + CVarSetInteger("gSettings.Volume.SubMusic", (int32_t)(CVarGetFloat("gSubMusicVolume", 1.0f) * 100)); + CVarClear("gSubMusicVolume"); + } + if (conf->GetNestedJson().contains("CVars") && conf->GetNestedJson()["CVars"].contains("gSFXMusicVolume")) { + CVarSetInteger("gSettings.Volume.SFX", (int32_t)(CVarGetFloat("gSFXMusicVolume", 1.0f) * 100)); + CVarClear("gSFXMusicVolume"); + } + if (conf->GetNestedJson().contains("CVars") && conf->GetNestedJson()["CVars"].contains("gFanfareVolume")) { + CVarSetInteger("gSettings.Volume.Fanfare", (int32_t)(CVarGetFloat("gFanfareVolume", 1.0f) * 100)); + CVarClear("gFanfareVolume"); + } + for (Migration migration : version3Migrations) { if (migration.action == MigrationAction::Rename) { CVarCopy(migration.from.c_str(), migration.to.value().c_str()); } CVarClear(migration.from.c_str()); } - if (conf->Contains("CVars.gEnhancements.InjectItemCounts")) { - CVarClear("gEnhancements.InjectItemCounts"); - CVarSetInteger("gEnhancements.InjectItemCounts.GoldSkulltula", 1); - CVarSetInteger("gEnhancements.InjectItemCounts.HeartContainer", 1); - CVarSetInteger("gEnhancements.InjectItemCounts.HeartPiece", 1); - } } } diff --git a/soh/soh/cvar_prefixes.h b/soh/soh/cvar_prefixes.h new file mode 100644 index 000000000..6ddde97bd --- /dev/null +++ b/soh/soh/cvar_prefixes.h @@ -0,0 +1,17 @@ +#define CVAR_RANDOMIZER_ENHANCEMENT(var) CVAR_PREFIX_RANDOMIZER_ENHANCEMENT "." var +#define CVAR_RANDOMIZER_SETTING(var) CVAR_PREFIX_RANDOMIZER_SETTING "." var +#define CVAR_COSMETIC(var) CVAR_PREFIX_COSMETIC "." var +#define CVAR_AUDIO(var) CVAR_PREFIX_AUDIO "." var +#define CVAR_CHEAT(var) CVAR_PREFIX_CHEAT "." var +#define CVAR_ENHANCEMENT(var) CVAR_PREFIX_ENHANCEMENT "." var +#define CVAR_SETTING(var) CVAR_PREFIX_SETTING "." var +#define CVAR_WINDOW(var) CVAR_PREFIX_WINDOW "." var +#define CVAR_TRACKER(var) CVAR_PREFIX_TRACKER "." var +#define CVAR_TRACKER_ITEM(var) CVAR_TRACKER(".ItemTracker." var) +#define CVAR_TRACKER_CHECK(var) CVAR_TRACKER(".CheckTracker." var) +#define CVAR_TRACKER_ENTRANCE(var) CVAR_TRACKER(".EntranceTracker." var) +#define CVAR_DEVELOPER_TOOLS(var) CVAR_PREFIX_DEVELOPER_TOOLS "." var +#define CVAR_GENERAL(var) CVAR_PREFIX_GENERAL "." var +#define CVAR_REMOTE(var) CVAR_PREFIX_REMOTE "." var +#define CVAR_REMOTE_CROWD_CONTROL(var) CVAR_REMOTE(".CrowdControl." var) +#define CVAR_REMOTE_SAIL(var) CVAR_REMOTE(".Sail." var) \ No newline at end of file diff --git a/soh/soh/resource/logging/PathLogger.h b/soh/soh/resource/logging/PathLogger.h index a5e42aeaf..91274db76 100644 --- a/soh/soh/resource/logging/PathLogger.h +++ b/soh/soh/resource/logging/PathLogger.h @@ -1,5 +1,6 @@ #include "Resource.h" #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" namespace SOH { void LogPathAsXML(std::shared_ptr resource); diff --git a/soh/soh/resource/logging/SceneCommandLoggers.h b/soh/soh/resource/logging/SceneCommandLoggers.h index f952ac766..d8a7ac2d5 100644 --- a/soh/soh/resource/logging/SceneCommandLoggers.h +++ b/soh/soh/resource/logging/SceneCommandLoggers.h @@ -1,5 +1,6 @@ #include "Resource.h" #include "soh/OTRGlobals.h" +#include "soh/cvar_prefixes.h" namespace SOH { diff --git a/soh/soh/resource/type/Skeleton.cpp b/soh/soh/resource/type/Skeleton.cpp index 057f24b65..883eacd19 100644 --- a/soh/soh/resource/type/Skeleton.cpp +++ b/soh/soh/resource/type/Skeleton.cpp @@ -2,6 +2,13 @@ #include "Skeleton.h" #include "soh/OTRGlobals.h" #include "libultraship/libultraship.h" +#include +#include +#include + +extern "C" SaveContext gSaveContext; +extern "C" u16 gEquipMasks[4]; +extern "C" u8 gEquipShifts[4]; namespace SOH { SkeletonData* Skeleton::GetPointer() { @@ -66,10 +73,10 @@ void SkeletonPatcher::ClearSkeletons() void SkeletonPatcher::UpdateSkeletons() { auto resourceMgr = Ship::Context::GetInstance()->GetResourceManager(); - bool isHD = resourceMgr->IsAltAssetsEnabled(); + bool isAlt = resourceMgr->IsAltAssetsEnabled(); for (auto skel : skeletons) { Skeleton* newSkel = - (Skeleton*)resourceMgr->LoadResource((isHD ? Ship::IResource::gAltAssetPrefix : "") + skel.vanillaSkeletonPath, true).get(); + (Skeleton*)resourceMgr->LoadResource((isAlt ? Ship::IResource::gAltAssetPrefix : "") + skel.vanillaSkeletonPath, true).get(); if (newSkel != nullptr) { skel.skelAnime->skeleton = newSkel->skeletonData.skeletonHeader.segment; @@ -78,4 +85,93 @@ void SkeletonPatcher::UpdateSkeletons() { } } } + +void SkeletonPatcher::UpdateCustomSkeletons() { + for (auto skel : skeletons) { + UpdateTunicSkeletons(skel); + } +} + +void SkeletonPatcher::UpdateTunicSkeletons(SkeletonPatchInfo& skel) { + std::string skeletonPath = ""; + + // Check if this is one of Link's skeletons + if (sOtr + skel.vanillaSkeletonPath == std::string(gLinkAdultSkel)) { + // Check what Link's current tunic is + switch (TUNIC_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC))) { + case PLAYER_TUNIC_KOKIRI: + skeletonPath = std::string(gLinkAdultKokiriTunicSkel).substr(sOtr.length()); + break; + case PLAYER_TUNIC_GORON: + skeletonPath = std::string(gLinkAdultGoronTunicSkel).substr(sOtr.length()); + break; + case PLAYER_TUNIC_ZORA: + skeletonPath = std::string(gLinkAdultZoraTunicSkel).substr(sOtr.length()); + break; + default: + return; + } + + UpdateCustomSkeletonFromPath(skeletonPath, skel); + } else if (sOtr + skel.vanillaSkeletonPath == std::string(gLinkChildSkel)) { + // Check what Link's current tunic is + switch (TUNIC_EQUIP_TO_PLAYER(CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC))) { + case PLAYER_TUNIC_KOKIRI: + skeletonPath = std::string(gLinkChildKokiriTunicSkel).substr(sOtr.length()); + break; + case PLAYER_TUNIC_GORON: + skeletonPath = std::string(gLinkChildGoronTunicSkel).substr(sOtr.length()); + break; + case PLAYER_TUNIC_ZORA: + skeletonPath = std::string(gLinkChildZoraTunicSkel).substr(sOtr.length()); + break; + default: + return; + } + + UpdateCustomSkeletonFromPath(skeletonPath, skel); + } +} + +void SkeletonPatcher::UpdateCustomSkeletonFromPath(const std::string& skeletonPath, SkeletonPatchInfo& skel) { + Skeleton* newSkel = nullptr; + Skeleton* altSkel = nullptr; + auto resourceMgr = Ship::Context::GetInstance()->GetResourceManager(); + bool isAlt = resourceMgr->IsAltAssetsEnabled(); + + // If alt assets are on, look for alt tagged skeletons + if (isAlt) { + altSkel = + (Skeleton*)Ship::Context::GetInstance() + ->GetResourceManager() + ->LoadResource(Ship::IResource::gAltAssetPrefix + skeletonPath, true) + .get(); + + // Override non-alt skeleton if necessary + if (altSkel != nullptr) { + newSkel = altSkel; + } + } + + // Load new skeleton based on the custom model if it exists + if (altSkel == nullptr) { + newSkel = + (Skeleton*)Ship::Context::GetInstance() + ->GetResourceManager() + ->LoadResource(skeletonPath, true) + .get(); + } + + // Change back to the original skeleton if no skeleton's were found + if (newSkel == nullptr && skeletonPath != skel.vanillaSkeletonPath) { + UpdateCustomSkeletonFromPath(skel.vanillaSkeletonPath, skel); + return; + } + + if (newSkel != nullptr) { + skel.skelAnime->skeleton = newSkel->skeletonData.skeletonHeader.segment; + uintptr_t skelPtr = (uintptr_t)newSkel->GetPointer(); + memcpy(&skel.skelAnime->skeletonHeader, &skelPtr, sizeof(uintptr_t)); + } +} } // namespace SOH diff --git a/soh/soh/resource/type/Skeleton.h b/soh/soh/resource/type/Skeleton.h index 72d81c5a5..fce931c79 100644 --- a/soh/soh/resource/type/Skeleton.h +++ b/soh/soh/resource/type/Skeleton.h @@ -86,8 +86,13 @@ class SkeletonPatcher { static void UnregisterSkeleton(SkelAnime* skelAnime); static void ClearSkeletons(); static void UpdateSkeletons(); + static void UpdateCustomSkeletons(); static std::vector skeletons; + private: + inline static const std::string sOtr = "__OTR__"; + static void UpdateTunicSkeletons(SkeletonPatchInfo& skel); + static void UpdateCustomSkeletonFromPath(const std::string& skeletonPath, SkeletonPatchInfo& skel); }; diff --git a/soh/soh/stubs.c b/soh/soh/stubs.c index 63340734e..99105d9f0 100644 --- a/soh/soh/stubs.c +++ b/soh/soh/stubs.c @@ -23,6 +23,10 @@ u16 gAudioSEFlagSwapSource[64]; u16 gAudioSEFlagSwapTarget[64]; u8 gAudioSEFlagSwapMode[64]; +// Zbuffer and Color framebuffer +u16 D_0E000000[SCREEN_WIDTH * SCREEN_HEIGHT]; +u16 D_0F000000[SCREEN_WIDTH * SCREEN_HEIGHT]; + u8 osAppNmiBuffer[2048]; f32 qNaN0x10000 = 0x7F810000; diff --git a/soh/soh/util.cpp b/soh/soh/util.cpp index faa171231..4eeaa16fd 100644 --- a/soh/soh/util.cpp +++ b/soh/soh/util.cpp @@ -336,7 +336,7 @@ std::array rcareaPrefixes = { "Shadow Temple", "Bottom of the Well", "Ice Cavern", - "Gerudo Training Grounds", + "Gerudo Training Ground", "Ganon's Castle", }; diff --git a/soh/soh/z_play_otr.cpp b/soh/soh/z_play_otr.cpp index 47e4279b2..279b4e696 100644 --- a/soh/soh/z_play_otr.cpp +++ b/soh/soh/z_play_otr.cpp @@ -1,4 +1,5 @@ #include "OTRGlobals.h" +#include "ResourceManagerHelpers.h" #include #include "soh/resource/type/Scene.h" #include @@ -19,23 +20,23 @@ Ship::IResource* OTRPlay_LoadFile(PlayState* play, const char* fileName) return res.get(); } -extern "C" void OTRPlay_SpawnScene(PlayState* play, s32 sceneNum, s32 spawn) { - SceneTableEntry* scene = &gSceneTable[sceneNum]; +extern "C" void OTRPlay_SpawnScene(PlayState* play, s32 sceneId, s32 spawn) { + SceneTableEntry* scene = &gSceneTable[sceneId]; scene->unk_13 = 0; play->loadedScene = scene; - play->sceneNum = sceneNum; + play->sceneNum = sceneId; play->sceneConfig = scene->config; //osSyncPrintf("\nSCENE SIZE %fK\n", (scene->sceneFile.vromEnd - scene->sceneFile.vromStart) / 1024.0f); // Scenes considered "dungeon" with a MQ variant - int16_t inNonSharedScene = (sceneNum >= SCENE_DEKU_TREE && sceneNum <= SCENE_ICE_CAVERN) || - sceneNum == SCENE_GERUDO_TRAINING_GROUND || sceneNum == SCENE_INSIDE_GANONS_CASTLE; + int16_t inNonSharedScene = (sceneId >= SCENE_DEKU_TREE && sceneId <= SCENE_ICE_CAVERN) || + sceneId == SCENE_GERUDO_TRAINING_GROUND || sceneId == SCENE_INSIDE_GANONS_CASTLE; std::string sceneVersion = "shared"; if (inNonSharedScene) { - sceneVersion = IsGameMasterQuest() ? "mq" : "nonmq"; + sceneVersion = ResourceMgr_IsGameMasterQuest() ? "mq" : "nonmq"; } std::string scenePath = StringHelper::Sprintf("scenes/%s/%s/%s", sceneVersion.c_str(), scene->sceneFile.fileName, scene->sceneFile.fileName); @@ -58,6 +59,9 @@ extern "C" void OTRPlay_SpawnScene(PlayState* play, s32 sceneNum, s32 spawn) { auto roomSize = func_80096FE8(play, &play->roomCtx); osSyncPrintf("ROOM SIZE=%fK\n", roomSize / 1024.0f); + + GameInteractor::Instance->ExecuteHooks(play->sceneNum); + SPDLOG_INFO("Scene Init - sceneNum: {0:#x}, entranceIndex: {1:#x}", play->sceneNum, gSaveContext.entranceIndex); } void OTRPlay_InitScene(PlayState* play, s32 spawn) { @@ -83,9 +87,6 @@ void OTRPlay_InitScene(PlayState* play, s32 spawn) { .get()); auto data2 = ResourceMgr_LoadVtxByCRC(0x68d4ea06044e228f);*/ - - GameInteractor::Instance->ExecuteHooks(play->sceneNum); - SPDLOG_INFO("Scene Init - sceneNum: {0:#x}, entranceIndex: {1:#x}", play->sceneNum, gSaveContext.entranceIndex); volatile int a = 0; } diff --git a/soh/soh/z_scene_otr.cpp b/soh/soh/z_scene_otr.cpp index 0aa92e0ec..022aeee37 100644 --- a/soh/soh/z_scene_otr.cpp +++ b/soh/soh/z_scene_otr.cpp @@ -1,4 +1,5 @@ #include "OTRGlobals.h" +#include "ResourceManagerHelpers.h" #include #include "soh/resource/type/Scene.h" #include @@ -39,9 +40,6 @@ extern "C" s32 Object_Spawn(ObjectContext* objectCtx, s16 objectId); extern "C" RomFile sNaviMsgFiles[]; s32 OTRScene_ExecuteCommands(PlayState* play, SOH::Scene* scene); -// Forward Declaration of function declared in OTRGlobals.cpp -std::shared_ptr GetResourceByNameHandlingMQ(const char* path); - bool Scene_CommandSpawnList(PlayState* play, SOH::ISceneCommand* cmd) { // SOH::SetStartPositionList* cmdStartPos = std::static_pointer_cast(cmd); SOH::SetStartPositionList* cmdStartPos = (SOH::SetStartPositionList*)cmd; @@ -109,7 +107,7 @@ bool Scene_CommandSpecialFiles(PlayState* play, SOH::ISceneCommand* cmd) { if (specialCmd->specialObjects.elfMessage != 0) { auto res = - (LUS::Blob*)OTRPlay_LoadFile(play, sNaviMsgFiles[specialCmd->specialObjects.elfMessage - 1].fileName); + (Ship::Blob*)OTRPlay_LoadFile(play, sNaviMsgFiles[specialCmd->specialObjects.elfMessage - 1].fileName); play->cUpElfMsgs = (ElfMessage*)res->Data.data(); } @@ -273,7 +271,7 @@ bool Scene_CommandTimeSettings(PlayState* play, SOH::ISceneCommand* cmd) { play->envCtx.sunPos.z = (Math_CosS(((void)0, gSaveContext.dayTime) - 0x8000) * 20.0f) * 25.0f; if (((play->envCtx.timeIncrement == 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) || - (gSaveContext.entranceIndex == ENTR_LAKE_HYLIA_8)) { + (gSaveContext.entranceIndex == ENTR_LAKE_HYLIA_WARP_PAD)) { gSaveContext.skyboxTime = ((void)0, gSaveContext.dayTime); if ((gSaveContext.skyboxTime >= 0x2AAC) && (gSaveContext.skyboxTime < 0x4555)) { gSaveContext.skyboxTime = 0x3556; @@ -512,7 +510,7 @@ extern "C" s32 OTRfunc_8009728C(PlayState* play, RoomContext* roomCtx, s32 roomN //&roomCtx->loadQueue, NULL, __FILE__, __LINE__); auto roomData = - std::static_pointer_cast(GetResourceByNameHandlingMQ(play->roomList[roomNum].fileName)); + std::static_pointer_cast(ResourceMgr_GetResourceByNameHandlingMQ(play->roomList[roomNum].fileName)); roomCtx->status = 1; roomCtx->roomToLoad = roomData.get(); diff --git a/soh/src/code/__osMalloc.c b/soh/src/code/__osMalloc.c index 1604332b7..895de5fd9 100644 --- a/soh/src/code/__osMalloc.c +++ b/soh/src/code/__osMalloc.c @@ -3,61 +3,132 @@ #include -#define FILL_ALLOCBLOCK (1 << 0) -#define FILL_FREEBLOCK (1 << 1) -#define CHECK_FREE_BLOCK (1 << 2) +// SOH [General] This file corresponds to decomp's "__osMalloc_gc.c", there's currently no file corresponding to decomp's "__osMalloc_n64.c" -#define NODE_MAGIC (0x7373) +// #region SOH [General] We currently don't set OOT_DEBUG when building so set it here manually +#define OOT_DEBUG 1 +// #endregion -#define BLOCK_UNINIT_MAGIC (0xAB) -#define BLOCK_UNINIT_MAGIC_32 (0xABABABAB) -#define BLOCK_ALLOC_MAGIC (0xCD) -#define BLOCK_ALLOC_MAGIC_32 (0xCDCDCDCD) -#define BLOCK_FREE_MAGIC (0xEF) -#define BLOCK_FREE_MAGIC_32 (0xEFEFEFEF) +// #region SOH [General] We renamed OoT's memmove to prevent conflicts with the libc version +#define memmove oot_memmove +// #endregion + +#define FILL_ALLOC_BLOCK_FLAG (1 << 0) +#define FILL_FREE_BLOCK_FLAG (1 << 1) +#define CHECK_FREE_BLOCK_FLAG (1 << 2) + +#define NODE_MAGIC 0x7373 + +#define BLOCK_UNINIT_MAGIC 0xAB +#define BLOCK_UNINIT_MAGIC_32 0xABABABAB +#define BLOCK_ALLOC_MAGIC 0xCD +#define BLOCK_ALLOC_MAGIC_32 0xCDCDCDCD +#define BLOCK_FREE_MAGIC 0xEF +#define BLOCK_FREE_MAGIC_32 0xEFEFEFEF + +#define NODE_IS_VALID(node) (((node) != NULL) && ((node)->magic == NODE_MAGIC)) + +#if OOT_DEBUG + +#define NODE_GET_NEXT(node) ArenaImpl_GetNextBlock(node) +#define NODE_GET_PREV(node) ArenaImpl_GetPrevBlock(node) + +#define SET_DEBUG_INFO(node, file, line, arena) ArenaImpl_SetDebugInfo(node, file, line, arena) + +#define FILL_UNINIT_BLOCK(arena, node, size) memset(node, BLOCK_UNINIT_MAGIC, size) + +#define FILL_ALLOC_BLOCK(arena, alloc, size) \ + if ((arena)->flag & FILL_ALLOC_BLOCK_FLAG) \ + memset(alloc, BLOCK_ALLOC_MAGIC, size) + +#define FILL_FREE_BLOCK_HEADER(arena, node) \ + if ((arena)->flag & FILL_FREE_BLOCK_FLAG) \ + memset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode)) + +#define FILL_FREE_BLOCK_CONTENTS(arena, node) \ + if ((arena)->flag & FILL_FREE_BLOCK_FLAG) \ + memset((void*)((uintptr_t)(node) + sizeof(ArenaNode)), BLOCK_FREE_MAGIC, (node)->size) + +#define CHECK_FREE_BLOCK(arena, node) \ + if ((arena)->flag & CHECK_FREE_BLOCK_FLAG) \ + __osMalloc_FreeBlockTest(arena, node) + +#define CHECK_ALLOC_FAILURE(arena, ptr) (void)0 + +#else + +#define NODE_GET_NEXT(node) (NODE_IS_VALID((node)->next) ? (node)->next : NULL) +#define NODE_GET_PREV(node) (NODE_IS_VALID((node)->prev) ? (node)->prev : NULL) + +#define SET_DEBUG_INFO(node, file, line, arena) (void)0 +#define FILL_UNINIT_BLOCK(arena, node, size) (void)0 +#define FILL_ALLOC_BLOCK(arena, alloc, size) (void)0 +#define FILL_FREE_BLOCK_HEADER(arena, node) (void)0 +#define FILL_FREE_BLOCK_CONTENTS(arena, node) (void)0 +#define CHECK_FREE_BLOCK(arena, node) (void)0 + +// Number of allocation failures across all arenas. +u32 gTotalAllocFailures = 0; // "Arena_failcnt" + +#define CHECK_ALLOC_FAILURE(arena, ptr) \ + do { \ + if ((ptr) == NULL) { \ + gTotalAllocFailures++; \ + (arena)->allocFailures++; \ + } \ + } while (0) + +#endif OSMesg sArenaLockMsg; + +void __osMallocAddBlock(Arena* arena, void* start, ptrdiff_t size); + +#if OOT_DEBUG u32 __osMalloc_FreeBlockTest_Enable; u32 ArenaImpl_GetFillAllocBlock(Arena* arena) { - return (arena->flag & FILL_ALLOCBLOCK) != 0; + return (arena->flag & FILL_ALLOC_BLOCK_FLAG) != 0; } u32 ArenaImpl_GetFillFreeBlock(Arena* arena) { - return (arena->flag & FILL_FREEBLOCK) != 0; + return (arena->flag & FILL_FREE_BLOCK_FLAG) != 0; } u32 ArenaImpl_GetCheckFreeBlock(Arena* arena) { - return (arena->flag & CHECK_FREE_BLOCK) != 0; + return (arena->flag & CHECK_FREE_BLOCK_FLAG) != 0; } void ArenaImpl_SetFillAllocBlock(Arena* arena) { - arena->flag |= FILL_ALLOCBLOCK; + arena->flag |= FILL_ALLOC_BLOCK_FLAG; } void ArenaImpl_SetFillFreeBlock(Arena* arena) { - arena->flag |= FILL_FREEBLOCK; + arena->flag |= FILL_FREE_BLOCK_FLAG; } void ArenaImpl_SetCheckFreeBlock(Arena* arena) { - arena->flag |= CHECK_FREE_BLOCK; + arena->flag |= CHECK_FREE_BLOCK_FLAG; } void ArenaImpl_UnsetFillAllocBlock(Arena* arena) { - arena->flag &= ~FILL_ALLOCBLOCK; + arena->flag &= ~FILL_ALLOC_BLOCK_FLAG; } void ArenaImpl_UnsetFillFreeBlock(Arena* arena) { - arena->flag &= ~FILL_FREEBLOCK; + arena->flag &= ~FILL_FREE_BLOCK_FLAG; } void ArenaImpl_UnsetCheckFreeBlock(Arena* arena) { - arena->flag &= ~CHECK_FREE_BLOCK; + arena->flag &= ~CHECK_FREE_BLOCK_FLAG; } -#if 0 -void ArenaImpl_SetDebugInfo(ArenaNode* node, const char* file, s32 line, Arena* arena) { +void ArenaImpl_SetDebugInfo(ArenaNode* node, const char* file, int line, Arena* arena) { + // Upstream TODO: Figure out why uncommenting this crashes + /* node->filename = file; node->line = line; node->threadId = osGetThreadId(NULL); node->arena = arena; node->time = osGetTime(); + */ } #endif + void ArenaImpl_LockInit(Arena* arena) { osCreateMesgQueue(&arena->lock, &sArenaLockMsg, 1); } @@ -70,6 +141,7 @@ void ArenaImpl_Unlock(Arena* arena) { osRecvMesg(&arena->lock, NULL, OS_MESG_BLOCK); } +#if OOT_DEBUG ArenaNode* ArenaImpl_GetNextBlock(ArenaNode* node) { ArenaNode* next = node->next; @@ -91,16 +163,17 @@ ArenaNode* ArenaImpl_GetPrevBlock(ArenaNode* node) { } return prev; } +#endif ArenaNode* ArenaImpl_GetLastBlock(Arena* arena) { ArenaNode* last = NULL; ArenaNode* iter; - if (arena != NULL && arena->head != NULL && arena->head->magic == NODE_MAGIC) { + if (arena != NULL && NODE_IS_VALID(arena->head)) { iter = arena->head; while (iter != NULL) { last = iter; - iter = ArenaImpl_GetNextBlock(iter); + iter = NODE_GET_NEXT(last); } } return last; @@ -125,7 +198,7 @@ void __osMallocAddBlock(Arena* arena, void* start, ptrdiff_t size) { size2 = (size - diff) & ~0xF; if (size2 > (ptrdiff_t)sizeof(ArenaNode)) { - memset(firstNode, BLOCK_UNINIT_MAGIC, size2); // memset + FILL_UNINIT_BLOCK(arena, firstNode, size2); firstNode->next = NULL; firstNode->prev = NULL; firstNode->size = size2 - sizeof(ArenaNode); @@ -145,6 +218,7 @@ void __osMallocAddBlock(Arena* arena, void* start, ptrdiff_t size) { } } +#if OOT_DEBUG void ArenaImpl_RemoveAllBlocks(Arena* arena) { ArenaNode* iter; ArenaNode* next; @@ -153,23 +227,27 @@ void ArenaImpl_RemoveAllBlocks(Arena* arena) { iter = arena->head; while (iter != NULL) { - next = ArenaImpl_GetNextBlock(iter); - memset(iter, BLOCK_UNINIT_MAGIC, iter->size + sizeof(ArenaNode)); // memset + next = NODE_GET_NEXT(iter); + memset(iter, BLOCK_UNINIT_MAGIC, iter->size + sizeof(ArenaNode)); iter = next; } ArenaImpl_Unlock(arena); } +#endif void __osMallocCleanup(Arena* arena) { +#if OOT_DEBUG ArenaImpl_RemoveAllBlocks(arena); +#endif memset(arena, 0, sizeof(*arena)); } -u8 __osMallocIsInitalized(Arena* arena) { +s32 __osMallocIsInitialized(Arena* arena) { return arena->isInit; } +#if OOT_DEBUG void __osMalloc_FreeBlockTest(Arena* arena, ArenaNode* node) { ArenaNode* node2 = node; u32* start; @@ -194,26 +272,24 @@ void __osMalloc_FreeBlockTest(Arena* arena, ArenaNode* node) { } } -void* __osMalloc_NoLockDebug(Arena* arena, size_t size, const char* file, s32 line) { +void* __osMalloc_NoLockDebug(Arena* arena, size_t size, const char* file, int line) { ArenaNode* iter; u32 blockSize; ArenaNode* newNode; void* alloc = NULL; ArenaNode* next; - iter = arena->head; size = ALIGN16(size); blockSize = ALIGN16(size) + sizeof(ArenaNode); + iter = arena->head; while (iter != NULL) { if (iter->isFree && iter->size >= size) { - if (arena->flag & CHECK_FREE_BLOCK) { - __osMalloc_FreeBlockTest(arena, iter); - } + CHECK_FREE_BLOCK(arena, iter); if (blockSize < iter->size) { newNode = (ArenaNode*)((uintptr_t)iter + blockSize); - newNode->next = ArenaImpl_GetNextBlock(iter); + newNode->next = NODE_GET_NEXT(iter); newNode->prev = iter; newNode->size = iter->size - blockSize; newNode->isFree = true; @@ -221,29 +297,27 @@ void* __osMalloc_NoLockDebug(Arena* arena, size_t size, const char* file, s32 li iter->next = newNode; iter->size = size; - next = ArenaImpl_GetNextBlock(newNode); + next = NODE_GET_NEXT(newNode); if (next) { next->prev = newNode; } } iter->isFree = false; - //ArenaImpl_SetDebugInfo(iter, file, line, arena); + SET_DEBUG_INFO(iter, file, line, arena); alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode)); - if (arena->flag & FILL_ALLOCBLOCK) { - memset(alloc, BLOCK_ALLOC_MAGIC, size); - } + FILL_ALLOC_BLOCK(arena, alloc, size); break; } - iter = ArenaImpl_GetNextBlock(iter); + iter = NODE_GET_NEXT(iter); } return alloc; } -void* __osMallocDebug(Arena* arena, size_t size, const char* file, s32 line) { +void* __osMallocDebug(Arena* arena, size_t size, const char* file, int line) { void* alloc; ArenaImpl_Lock(arena); @@ -253,7 +327,7 @@ void* __osMallocDebug(Arena* arena, size_t size, const char* file, s32 line) { return alloc; } -void* __osMallocRDebug(Arena* arena, size_t size, const char* file, s32 line) { +void* __osMallocRDebug(Arena* arena, size_t size, const char* file, int line) { ArenaNode* iter; ArenaNode* newNode; u32 blockSize; @@ -266,21 +340,19 @@ void* __osMallocRDebug(Arena* arena, size_t size, const char* file, s32 line) { while (iter != NULL) { if (iter->isFree && iter->size >= size) { - if (arena->flag & CHECK_FREE_BLOCK) { - __osMalloc_FreeBlockTest(arena, iter); - } + CHECK_FREE_BLOCK(arena, iter); blockSize = ALIGN16(size) + sizeof(ArenaNode); if (blockSize < iter->size) { newNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size)); - newNode->next = ArenaImpl_GetNextBlock(iter); + newNode->next = NODE_GET_NEXT(iter); newNode->prev = iter; newNode->size = size; newNode->magic = NODE_MAGIC; iter->next = newNode; iter->size -= blockSize; - next = ArenaImpl_GetNextBlock(newNode); + next = NODE_GET_NEXT(newNode); if (next) { next->prev = newNode; } @@ -288,21 +360,21 @@ void* __osMallocRDebug(Arena* arena, size_t size, const char* file, s32 line) { } iter->isFree = false; - //ArenaImpl_SetDebugInfo(iter, file, line, arena); + SET_DEBUG_INFO(iter, file, line, arena); allocR = (void*)((uintptr_t)iter + sizeof(ArenaNode)); - if (arena->flag & FILL_ALLOCBLOCK) { - memset(allocR, BLOCK_ALLOC_MAGIC, size); - } + FILL_ALLOC_BLOCK(arena, allocR, size); break; } - iter = ArenaImpl_GetPrevBlock(iter); + iter = NODE_GET_PREV(iter); } + ArenaImpl_Unlock(arena); return allocR; } +#endif void* __osMalloc_NoLock(Arena* arena, size_t size) { ArenaNode* iter; @@ -311,20 +383,17 @@ void* __osMalloc_NoLock(Arena* arena, size_t size) { void* alloc = NULL; ArenaNode* next; - iter = arena->head; size = ALIGN16(size); blockSize = ALIGN16(size) + sizeof(ArenaNode); + iter = arena->head; while (iter != NULL) { - if (iter->isFree && iter->size >= size) { - if (arena->flag & CHECK_FREE_BLOCK) { - __osMalloc_FreeBlockTest(arena, iter); - } + CHECK_FREE_BLOCK(arena, iter); if (blockSize < iter->size) { newNode = (ArenaNode*)((uintptr_t)iter + blockSize); - newNode->next = ArenaImpl_GetNextBlock(iter); + newNode->next = NODE_GET_NEXT(iter); newNode->prev = iter; newNode->size = iter->size - blockSize; newNode->isFree = true; @@ -332,24 +401,25 @@ void* __osMalloc_NoLock(Arena* arena, size_t size) { iter->next = newNode; iter->size = size; - next = ArenaImpl_GetNextBlock(newNode); + next = NODE_GET_NEXT(newNode); if (next) { next->prev = newNode; } } iter->isFree = false; - //ArenaImpl_SetDebugInfo(iter, NULL, 0, arena); + SET_DEBUG_INFO(iter, NULL, 0, arena); alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode)); - if (arena->flag & FILL_ALLOCBLOCK) { - memset(alloc, BLOCK_ALLOC_MAGIC, size); - } + FILL_ALLOC_BLOCK(arena, alloc, size); + break; } - iter = ArenaImpl_GetNextBlock(iter); + iter = NODE_GET_NEXT(iter); } + CHECK_ALLOC_FAILURE(arena, alloc); + return alloc; } @@ -365,32 +435,33 @@ void* __osMalloc(Arena* arena, size_t size) { void* __osMallocR(Arena* arena, size_t size) { ArenaNode* iter; + ArenaNode* allocNode; ArenaNode* newNode; - u32 blockSize; ArenaNode* next; void* alloc = NULL; + u32 blockSize; size = ALIGN16(size); + blockSize = ALIGN16(size) + sizeof(ArenaNode); ArenaImpl_Lock(arena); iter = ArenaImpl_GetLastBlock(arena); while (iter != NULL) { if (iter->isFree && iter->size >= size) { - if (arena->flag & CHECK_FREE_BLOCK) { - __osMalloc_FreeBlockTest(arena, iter); - } + CHECK_FREE_BLOCK(arena, iter); - blockSize = ALIGN16(size) + sizeof(ArenaNode); if (blockSize < iter->size) { - newNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size)); - newNode->next = ArenaImpl_GetNextBlock(iter); + allocNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size)); + allocNode->next = NODE_GET_NEXT(iter); + + newNode = allocNode; newNode->prev = iter; newNode->size = size; newNode->magic = NODE_MAGIC; iter->next = newNode; iter->size -= blockSize; - next = ArenaImpl_GetNextBlock(newNode); + next = NODE_GET_NEXT(newNode); if (next) { next->prev = newNode; } @@ -398,15 +469,16 @@ void* __osMallocR(Arena* arena, size_t size) { } iter->isFree = false; - //ArenaImpl_SetDebugInfo(iter, NULL, 0, arena); + SET_DEBUG_INFO(iter, NULL, 0, arena); alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode)); - if (arena->flag & FILL_ALLOCBLOCK) { - memset(alloc, BLOCK_ALLOC_MAGIC, size); - } + FILL_ALLOC_BLOCK(arena, alloc, size); break; } - iter = ArenaImpl_GetPrevBlock(iter); + iter = NODE_GET_PREV(iter); } + + CHECK_ALLOC_FAILURE(arena, alloc); + ArenaImpl_Unlock(arena); return alloc; @@ -416,14 +488,13 @@ void __osFree_NoLock(Arena* arena, void* ptr) { ArenaNode* node; ArenaNode* next; ArenaNode* prev; - ArenaNode* newNext; if (ptr == NULL) { return; } node = (ArenaNode*)((uintptr_t)ptr - sizeof(ArenaNode)); - if (node == NULL || node->magic != NODE_MAGIC) { + if (!NODE_IS_VALID(node)) { // "__osFree: Unauthorized release (%08x)" osSyncPrintf(VT_COL(RED, WHITE) "__osFree:不正解放(%08x)\n" VT_RST, ptr); return; @@ -432,34 +503,32 @@ void __osFree_NoLock(Arena* arena, void* ptr) { osSyncPrintf(VT_COL(RED, WHITE) "__osFree:二重解放(%08x)\n" VT_RST, ptr); // "__osFree: Double release (%08x)" return; } - #if 0 +#if OOT_DEBUG + /* if (arena != node->arena && arena != NULL) { // "__osFree:Tried to release in a different way than when it was secured (%08x:%08x)" osSyncPrintf(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena, node->arena); return; } + */ #endif - next = ArenaImpl_GetNextBlock(node); - prev = ArenaImpl_GetPrevBlock(node); + + next = NODE_GET_NEXT(node); + prev = NODE_GET_PREV(node); node->isFree = true; - //ArenaImpl_SetDebugInfo(node, NULL, 0, arena); + SET_DEBUG_INFO(node, NULL, 0, arena); - if (arena->flag & FILL_FREEBLOCK) { - memset((uintptr_t)node + sizeof(ArenaNode), BLOCK_FREE_MAGIC, node->size); - } + FILL_FREE_BLOCK_CONTENTS(arena, node); - newNext = next; if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) { - newNext = ArenaImpl_GetNextBlock(next); + ArenaNode* newNext = NODE_GET_NEXT(next); if (newNext != NULL) { newNext->prev = node; } node->size += next->size + sizeof(ArenaNode); - if (arena->flag & FILL_FREEBLOCK) { - memset(next, BLOCK_FREE_MAGIC, sizeof(ArenaNode)); - } + FILL_FREE_BLOCK_HEADER(arena, next); node->next = newNext; next = newNext; } @@ -470,9 +539,7 @@ void __osFree_NoLock(Arena* arena, void* ptr) { } prev->next = next; prev->size += node->size + sizeof(ArenaNode); - if (arena->flag & FILL_FREEBLOCK) { - memset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode)); - } + FILL_FREE_BLOCK_HEADER(arena, node); } } @@ -482,7 +549,8 @@ void __osFree(Arena* arena, void* ptr) { ArenaImpl_Unlock(arena); } -void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) { +#if OOT_DEBUG +void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, int line) { ArenaNode* node; ArenaNode* next; ArenaNode* prev; @@ -493,7 +561,7 @@ void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) { } node = (ArenaNode*)((uintptr_t)ptr - sizeof(ArenaNode)); - if (node == NULL || node->magic != NODE_MAGIC) { + if (!NODE_IS_VALID(node)) { // "__osFree: Unauthorized release (%08x)" osSyncPrintf(VT_COL(RED, WHITE) "__osFree:不正解放(%08x) [%s:%d ]\n" VT_RST, ptr, file, line); return; @@ -503,34 +571,32 @@ void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) { osSyncPrintf(VT_COL(RED, WHITE) "__osFree:二重解放(%08x) [%s:%d ]\n" VT_RST, ptr, file, line); return; } - #if 0 + + /* if (arena != node->arena && arena != NULL) { // "__osFree:Tried to release in a different way than when it was secured (%08x:%08x)" osSyncPrintf(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena, node->arena); return; } - #endif - next = ArenaImpl_GetNextBlock(node); - prev = ArenaImpl_GetPrevBlock(node); - node->isFree = true; - //ArenaImpl_SetDebugInfo(node, file, line, arena); + */ - if (arena->flag & FILL_FREEBLOCK) { - memset((uintptr_t)node + sizeof(ArenaNode), BLOCK_FREE_MAGIC, node->size); - } + next = NODE_GET_NEXT(node); + prev = NODE_GET_PREV(node); + node->isFree = true; + SET_DEBUG_INFO(node, file, line, arena); + + FILL_FREE_BLOCK_CONTENTS(arena, node); newNext = node->next; if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) { - newNext = ArenaImpl_GetNextBlock(next); + newNext = NODE_GET_NEXT(next); if (newNext != NULL) { newNext->prev = node; } node->size += next->size + sizeof(ArenaNode); - if (arena->flag & FILL_FREEBLOCK) { - memset(next, BLOCK_FREE_MAGIC, sizeof(ArenaNode)); - } + FILL_FREE_BLOCK_HEADER(arena, next); node->next = newNext; next = newNext; } @@ -541,21 +607,20 @@ void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) { } prev->next = next; prev->size += node->size + sizeof(ArenaNode); - if (arena->flag & FILL_FREEBLOCK) { - memset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode)); - } + FILL_FREE_BLOCK_HEADER(arena, node); } } -void __osFreeDebug(Arena* arena, void* ptr, const char* file, s32 line) { +void __osFreeDebug(Arena* arena, void* ptr, const char* file, int line) { ArenaImpl_Lock(arena); __osFree_NoLockDebug(arena, ptr, file, line); ArenaImpl_Unlock(arena); } +#endif void* __osRealloc(Arena* arena, void* ptr, size_t newSize) { - void* newAlloc; ArenaNode* node; + void* newAlloc; ArenaNode* next; ArenaNode* newNext; ArenaNode* overNext; @@ -582,20 +647,20 @@ void* __osRealloc(Arena* arena, void* ptr, size_t newSize) { // "Does nothing because the memory block size does not change" osSyncPrintf("メモリブロックサイズが変わらないためなにもしません\n"); } else if (node->size < newSize) { - next = ArenaImpl_GetNextBlock(node); + next = NODE_GET_NEXT(node); sizeDiff = newSize - node->size; if ((uintptr_t)next == ((uintptr_t)node + node->size + sizeof(ArenaNode)) && next->isFree && next->size >= sizeDiff) { // "Merge because there is a free block after the current memory block" osSyncPrintf("現メモリブロックの後ろにフリーブロックがあるので結合します\n"); next->size -= sizeDiff; - overNext = ArenaImpl_GetNextBlock(next); + overNext = NODE_GET_NEXT(next); newNext = (ArenaNode*)((uintptr_t)next + sizeDiff); if (overNext != NULL) { overNext->prev = newNext; } node->next = newNext; node->size = newSize; - func_801068B0(newNext, next, sizeof(ArenaNode)); // memcpy + memmove(node->next, next, sizeof(ArenaNode)); } else { // "Allocate a new memory block and move the contents" osSyncPrintf("新たにメモリブロックを確保して内容を移動します\n"); @@ -607,7 +672,7 @@ void* __osRealloc(Arena* arena, void* ptr, size_t newSize) { ptr = newAlloc; } } else if (newSize < node->size) { - next2 = ArenaImpl_GetNextBlock(node); + next2 = NODE_GET_NEXT(node); if (next2 != NULL && next2->isFree) { blockSize = ALIGN16(newSize) + sizeof(ArenaNode); // "Increased free block behind current memory block" @@ -618,7 +683,7 @@ void* __osRealloc(Arena* arena, void* ptr, size_t newSize) { newNext2->size += node->size - newSize; node->next = newNext2; node->size = newSize; - overNext2 = ArenaImpl_GetNextBlock(newNext2); + overNext2 = NODE_GET_NEXT(newNext2); if (overNext2 != NULL) { overNext2->prev = newNext2; } @@ -627,14 +692,14 @@ void* __osRealloc(Arena* arena, void* ptr, size_t newSize) { // "Generated because there is no free block after the current memory block" osSyncPrintf("現メモリブロックの後ろにフリーブロックがないので生成します\n"); newNext2 = (ArenaNode*)((uintptr_t)node + blockSize); - newNext2->next = ArenaImpl_GetNextBlock(node); + newNext2->next = NODE_GET_NEXT(node); newNext2->prev = node; newNext2->size = node->size - blockSize; newNext2->isFree = true; newNext2->magic = NODE_MAGIC; node->next = newNext2; node->size = newSize; - overNext2 = ArenaImpl_GetNextBlock(newNext2); + overNext2 = NODE_GET_NEXT(newNext2); if (overNext2 != NULL) { overNext2->prev = newNext2; } @@ -644,15 +709,19 @@ void* __osRealloc(Arena* arena, void* ptr, size_t newSize) { ptr = NULL; } } + + CHECK_ALLOC_FAILURE(arena, ptr); } ArenaImpl_Unlock(arena); return ptr; } -void* __osReallocDebug(Arena* arena, void* ptr, size_t newSize, const char* file, s32 line) { +#if OOT_DEBUG +void* __osReallocDebug(Arena* arena, void* ptr, size_t newSize, const char* file, int line) { return __osRealloc(arena, ptr, newSize); } +#endif void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAlloc) { ArenaNode* iter; @@ -674,12 +743,13 @@ void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAll *outAlloc += iter->size; } - iter = ArenaImpl_GetNextBlock(iter); + iter = NODE_GET_NEXT(iter); } ArenaImpl_Unlock(arena); } +#if OOT_DEBUG void __osDisplayArena(Arena* arena) { size_t freeSize; size_t allocatedSize; @@ -687,7 +757,7 @@ void __osDisplayArena(Arena* arena) { ArenaNode* iter; ArenaNode* next; - if (!__osMallocIsInitalized(arena)) { + if (!__osMallocIsInitialized(arena)) { osSyncPrintf("アリーナは初期化されていません\n"); // "Arena is not initalized" return; } @@ -710,12 +780,14 @@ void __osDisplayArena(Arena* arena) { (next == NULL) ? '$' : (iter != next->prev ? '!' : ' '), iter->isFree ? "空き" : "確保", //? "Free" : "Secure" iter->size); - #if 0 + + /* if (!iter->isFree) { osSyncPrintf(" [%016llu:%2d:%s:%d]", OS_CYCLES_TO_NSEC(iter->time), iter->threadId, iter->filename != NULL ? iter->filename : "**NULL**", iter->line); } - #endif + */ + osSyncPrintf("\n"); if (iter->isFree) { @@ -742,6 +814,7 @@ void __osDisplayArena(Arena* arena) { ArenaImpl_Unlock(arena); } +#endif void ArenaImpl_FaultClient(Arena* arena) { size_t freeSize; @@ -751,7 +824,7 @@ void ArenaImpl_FaultClient(Arena* arena) { ArenaNode* next; FaultDrawer_Printf("ARENA INFO (0x%08x)\n", arena); - if (!__osMallocIsInitalized(arena)) { + if (!__osMallocIsInitialized(arena)) { FaultDrawer_Printf("Arena is uninitalized\n", arena); return; } @@ -793,7 +866,7 @@ void ArenaImpl_FaultClient(Arena* arena) { FaultDrawer_Printf("Largest Free Block Size %08x\n", maxFree); } -u32 __osCheckArena(Arena* arena) { +s32 __osCheckArena(Arena* arena) { ArenaNode* iter; u32 error = 0; @@ -802,13 +875,20 @@ u32 __osCheckArena(Arena* arena) { osSyncPrintf("アリーナの内容をチェックしています... (%08x)\n", arena); iter = arena->head; while (iter != NULL) { - if (iter && iter->magic == NODE_MAGIC) { + //! @bug: Probably intended to be `!NODE_IS_VALID(iter)` + if (NODE_IS_VALID(iter)) { +#if OOT_DEBUG // "Oops!! (%08x %08x)" - osSyncPrintf(VT_COL(RED, WHITE) "おおっと!! (%08x %08x)\n" VT_RST, iter, iter->magic); + osSyncPrintf(VT_COL(RED, WHITE) "おおっと!! (%08x %08x)\n" VT_RST, iter, + iter->magic); +#else + // "Oops!! (%08x %08x)" + osSyncPrintf("おおっと!! (%08x %08x)\n", iter, iter->magic); +#endif error = 1; break; } - iter = ArenaImpl_GetNextBlock(iter); + iter = NODE_GET_NEXT(iter); } if (error == 0) { osSyncPrintf("アリーナはまだ、いけそうです\n"); // "The arena is still going well" @@ -818,6 +898,8 @@ u32 __osCheckArena(Arena* arena) { return error; } -u8 func_800FF334(Arena* arena) { +#if OOT_DEBUG +u8 ArenaImpl_GetAllocFailures(Arena* arena) { return arena->unk_20; } +#endif \ No newline at end of file diff --git a/soh/src/code/audioMgr.c b/soh/src/code/audioMgr.c index 2a6752206..54f0b2afe 100644 --- a/soh/src/code/audioMgr.c +++ b/soh/src/code/audioMgr.c @@ -109,10 +109,10 @@ void AudioMgr_Init(AudioMgr* audioMgr, void* stack, OSPri pri, OSId id, SchedCon Audio_InitSound(); osSendMesgPtr(&audioMgr->unk_C8, NULL, OS_MESG_BLOCK); - Audio_SetGameVolume(SEQ_PLAYER_BGM_MAIN, CVarGetFloat(CVAR_SETTING("Volume.MainMusic"), 1.0f)); - Audio_SetGameVolume(SEQ_PLAYER_BGM_SUB, CVarGetFloat(CVAR_SETTING("Volume.SubMusic"), 1.0f)); - Audio_SetGameVolume(SEQ_PLAYER_FANFARE, CVarGetFloat(CVAR_SETTING("Volume.Fanfare"), 1.0f)); - Audio_SetGameVolume(SEQ_PLAYER_SFX, CVarGetFloat(CVAR_SETTING("Volume.SFX"), 1.0f)); + Audio_SetGameVolume(SEQ_PLAYER_BGM_MAIN, ((float)CVarGetInteger(CVAR_SETTING("Volume.MainMusic"), 100) / 100.0f)); + Audio_SetGameVolume(SEQ_PLAYER_BGM_SUB, ((float)CVarGetInteger(CVAR_SETTING("Volume.SubMusic"), 100) / 100.0f)); + Audio_SetGameVolume(SEQ_PLAYER_FANFARE, ((float)CVarGetInteger(CVAR_SETTING("Volume.Fanfare"), 100) / 100.0f)); + Audio_SetGameVolume(SEQ_PLAYER_SFX, ((float)CVarGetInteger(CVAR_SETTING("Volume.SFX"), 100) / 100.0f)); // Removed due to crash //IrqMgr_AddClient(audioMgr->irqMgr, &irqClient, &audioMgr->unk_74); diff --git a/soh/src/code/audio_load.c b/soh/src/code/audio_load.c index cb7ba60bb..3c7224612 100644 --- a/soh/src/code/audio_load.c +++ b/soh/src/code/audio_load.c @@ -7,6 +7,7 @@ #include "soh/OTRGlobals.h" #include "soh/Enhancements/audio/AudioCollection.h" #include "soh/Enhancements/audio/AudioEditor.h" +#include "soh/ResourceManagerHelpers.h" #define MK_ASYNC_MSG(retData, tableType, id, status) (((retData) << 24) | ((tableType) << 16) | ((id) << 8) | (status)) #define ASYNC_TBLTYPE(v) ((u8)(v >> 16)) diff --git a/soh/src/code/audio_playback.c b/soh/src/code/audio_playback.c index 39be0c3a7..430c463f8 100644 --- a/soh/src/code/audio_playback.c +++ b/soh/src/code/audio_playback.c @@ -1,4 +1,5 @@ #include "global.h" +#include "soh/ResourceManagerHelpers.h" #include extern bool gUseLegacySD; @@ -94,7 +95,7 @@ void Audio_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) { vel = 0.0f > vel ? 0.0f : vel; vel = 1.0f < vel ? 1.0f : vel; - float master_vol = CVarGetFloat(CVAR_SETTING("Volume.Master"), 1.0f); + float master_vol = (float)CVarGetInteger(CVAR_SETTING("Volume.Master"), 100) / 100.0f; sub->targetVolLeft = (s32)((vel * volLeft) * (0x1000 - 0.001f)) * master_vol; sub->targetVolRight = (s32)((vel * volRight) * (0x1000 - 0.001f)) * master_vol; diff --git a/soh/src/code/audio_seqplayer.c b/soh/src/code/audio_seqplayer.c index 8d484575d..e194fd28b 100644 --- a/soh/src/code/audio_seqplayer.c +++ b/soh/src/code/audio_seqplayer.c @@ -4,6 +4,7 @@ #include "global.h" #include "soh/Enhancements/audio/AudioEditor.h" +#include "soh/ResourceManagerHelpers.h" extern char** sequenceMap; diff --git a/soh/src/code/code_800430A0.c b/soh/src/code/code_800430A0.c index 379f4a3e6..6047b2fc0 100644 --- a/soh/src/code/code_800430A0.c +++ b/soh/src/code/code_800430A0.c @@ -60,10 +60,10 @@ void func_80043334(CollisionContext* colCtx, Actor* actor, s32 bgId) { if (DynaPoly_IsBgIdBgActor(bgId)) { DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, bgId); if (dynaActor != NULL) { - func_800434A8(dynaActor); + DynaPolyActor_SetActorOnTop(dynaActor); if (CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_CAN_PRESS_SWITCH)) { - func_80043538(dynaActor); + DynaPolyActor_SetSwitchPressed(dynaActor); } } } @@ -91,12 +91,12 @@ s32 func_800433A4(CollisionContext* colCtx, s32 bgId, Actor* actor) { return false; } - if (dynaActor->unk_15C & 1) { + if (dynaActor->transformFlags & 1) { func_800430A0(colCtx, bgId, actor); result = true; } - if (dynaActor->unk_15C & 2) { + if (dynaActor->transformFlags & 2) { func_800432A0(colCtx, bgId, actor); result = true; } diff --git a/soh/src/code/code_800ACE70.c b/soh/src/code/code_800ACE70.c deleted file mode 100644 index e22162777..000000000 --- a/soh/src/code/code_800ACE70.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "global.h" - -// Note : This file is related to z_vismono, the original name was probably z_vis - -Gfx D_8012AC00[] = { - gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | - G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, - G_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2), - gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1), - gsDPPipeSync(), - gsDPSetBlendColor(0, 0, 0, 8), - gsSPEndDisplayList(), -}; - -Gfx D_8012AC28[] = { - gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | - G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, - G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | - GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM) | - GBL_c2(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM)), - gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1), - gsSPEndDisplayList(), -}; - -Gfx D_8012AC40[] = { - gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | - G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, - G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | - GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) | - GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)), - - gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1), - gsSPEndDisplayList(), -}; - -Gfx D_8012AC58[] = { - gsDPSetCombineMode(G_CC_PRIMITIVE, G_CC_PRIMITIVE), - gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_DISABLE | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | - G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, - G_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2), - gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1), - gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | - G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, - G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | - GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) | - GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)), - gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1), - gsSPEndDisplayList(), -}; - -// Init -void func_800ACE70(struct_801664F0* this) { - this->type = 0; - this->setScissor = false; - this->color.r = 255; - this->color.g = 255; - this->color.b = 255; - this->color.a = 255; -} - -// Destroy -void func_800ACE90(struct_801664F0* this) { -} - -// Draw -void func_800ACE98(struct_801664F0* this, Gfx** gfxp) { - Gfx* gfx = *gfxp; - - gDPPipeSync(gfx++); - gDPSetPrimDepth(gfx++, -1, -1); - - if (this->setScissor == true) { - gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - } - - switch (this->type) { - case 1: - gSPDisplayList(gfx++, D_8012AC40); - break; - case 2: - gDPSetColor(gfx++, G_SETPRIMCOLOR, this->color.rgba); - gSPDisplayList(gfx++, D_8012AC58); - break; - case 3: - gDPSetColor(gfx++, G_SETBLENDCOLOR, this->color.rgba); - gSPDisplayList(gfx++, D_8012AC00); - break; - case 4: - gDPSetColor(gfx++, G_SETFOGCOLOR, this->color.rgba); - gSPDisplayList(gfx++, D_8012AC28); - break; - } - - gDPPipeSync(gfx++); - *gfxp = gfx; -} diff --git a/soh/src/code/code_800AD920.c b/soh/src/code/code_800AD920.c deleted file mode 100644 index 2ef7cf0bb..000000000 --- a/soh/src/code/code_800AD920.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "global.h" - -// Note : This file is related to z_vismono, the original name was probably z_vis - -// z-buffer -extern u16 D_0E000000[]; - -// Init -void func_800AD920(struct_80166500* this) { - this->useRgba = false; - this->setScissor = false; - this->primColor.r = 255; - this->primColor.g = 255; - this->primColor.b = 255; - this->primColor.a = 255; - this->envColor.a = 255; - this->envColor.r = 0; - this->envColor.g = 0; - this->envColor.b = 0; -} - -// Destroy -void func_800AD950(struct_80166500* this) { -} - -// Draw -void func_800AD958(struct_80166500* this, Gfx** gfxp) { - Gfx* gfx = *gfxp; - - // OTRTODO -#if 0 - u16* tex = D_0E000000; - s32 fmt = this->useRgba == false ? G_IM_FMT_IA : G_IM_FMT_RGBA; - s32 y; - s32 height = 6; - - gDPPipeSync(gfx++); - if (this->setScissor == true) { - gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - } - - gDPSetOtherMode(gfx++, - G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | - G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, - G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2); - gDPSetCombineLERP(gfx++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, - PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT); - - gDPSetColor(gfx++, G_SETPRIMCOLOR, this->primColor.rgba); - gDPSetColor(gfx++, G_SETENVCOLOR, this->envColor.rgba); - - for (y = 0; y <= SCREEN_HEIGHT - height; y += height) { - gDPLoadTextureBlock(gfx++, tex, fmt, G_IM_SIZ_16b, SCREEN_WIDTH, 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); - - gSPTextureRectangle(gfx++, 0, (y) << 2, (SCREEN_WIDTH << 2), (y + height) << 2, G_TX_RENDERTILE, 0, 0, - (1 << 10), (1 << 10)); - tex += SCREEN_WIDTH * height; - } - - gDPPipeSync(gfx++); - *gfxp = gfx; -#endif -} diff --git a/soh/src/code/code_800EC960.c b/soh/src/code/code_800EC960.c index 7a64a2b54..0af2ed9ca 100644 --- a/soh/src/code/code_800EC960.c +++ b/soh/src/code/code_800EC960.c @@ -1,5 +1,6 @@ #include #include "global.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/audio/AudioEditor.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -25,6 +26,10 @@ #define Audio_SeqCmd8(playerIdx, a, b, c) \ Audio_QueueSeqCmd(0x80000000 | ((u8)playerIdx << 24) | ((u8)a << 16) | ((u8)b << 8) | ((u8)c)) #define Audio_SeqCmdF(playerIdx, a) Audio_QueueSeqCmd(0xF0000000 | ((u8)playerIdx << 24) | ((u8)a)) +#define BTN_CUSTOM_RSTICK_UP ((CONTROLLERBUTTONS_T)0x01000000) +#define BTN_CUSTOM_RSTICK_DOWN ((CONTROLLERBUTTONS_T)0x02000000) +#define BTN_CUSTOM_RSTICK_LEFT ((CONTROLLERBUTTONS_T)0x04000000) +#define BTN_CUSTOM_RSTICK_RIGHT ((CONTROLLERBUTTONS_T)0x08000000) typedef struct { /* 0x0 */ f32 vol; @@ -1260,13 +1265,26 @@ void Audio_OcaUpdateBtnMap(bool customControls) { sOcarinaA4BtnMap = BTN_CUSTOM_OCARINA_NOTE_A4; sOcarinaF4BtnMap = BTN_CUSTOM_OCARINA_NOTE_F4; sOcarinaD4BtnMap = BTN_CUSTOM_OCARINA_NOTE_D4; - } else { + } + else { sOcarinaD5BtnMap = BTN_CUP; sOcarinaB4BtnMap = BTN_CLEFT; sOcarinaA4BtnMap = BTN_CRIGHT; sOcarinaF4BtnMap = BTN_CDOWN; sOcarinaD4BtnMap = BTN_A; } + if (CVarGetInteger(CVAR_SETTING("CustomOcarina.Dpad"), 0)) { + sOcarinaD5BtnMap |= BTN_DUP; + sOcarinaB4BtnMap |= BTN_DLEFT; + sOcarinaA4BtnMap |= BTN_DRIGHT; + sOcarinaF4BtnMap |= BTN_DDOWN; + } + if (CVarGetInteger(CVAR_SETTING("CustomOcarina.RightStick"), 0)) { + sOcarinaD5BtnMap |= BTN_CUSTOM_RSTICK_UP; + sOcarinaB4BtnMap |= BTN_CUSTOM_RSTICK_LEFT; + sOcarinaA4BtnMap |= BTN_CUSTOM_RSTICK_RIGHT; + sOcarinaF4BtnMap |= BTN_CUSTOM_RSTICK_DOWN; + } sOcarinaAllowedBtnMask = ( sOcarinaD5BtnMap | @@ -1288,6 +1306,21 @@ void Audio_GetOcaInput(void) { sPrevOcarinaBtnPress = sp18; sCurOcaStick.x = input->rel.stick_x; sCurOcaStick.y = input->rel.stick_y; + s8 rstick_x = input->cur.right_stick_x; + s8 rstick_y = input->cur.right_stick_y; + const s8 sensitivity = 64; + if (rstick_x > sensitivity) { + sCurOcarinaBtnPress |= BTN_CUSTOM_RSTICK_RIGHT; + } + if (rstick_x < -sensitivity) { + sCurOcarinaBtnPress |= BTN_CUSTOM_RSTICK_LEFT; + } + if (rstick_y > sensitivity) { + sCurOcarinaBtnPress |= BTN_CUSTOM_RSTICK_UP; + } + if (rstick_y < -sensitivity) { + sCurOcarinaBtnPress |= BTN_CUSTOM_RSTICK_DOWN; + } } f32 Audio_OcaAdjStick(s8 inp) { @@ -1648,7 +1681,7 @@ void func_800ED458(s32 arg0) { if ((sCurOcarinaBtnVal != 0xFF) && (sPrevOcarinaNoteVal != sCurOcarinaBtnVal)) { Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | 0xD07, D_80130F10 - 1); Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | 0xD05, sCurOcarinaBtnVal); - Audio_PlaySoundGeneral(NA_SE_OC_OCARINA, &D_801333D4, 4, &D_80130F24, &D_80130F28, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &D_80130F24, &D_80130F28, &gSfxDefaultReverb); } else if ((sPrevOcarinaNoteVal != 0xFF) && (sCurOcarinaBtnVal == 0xFF)) { Audio_StopSfxById(NA_SE_OC_OCARINA); } @@ -1791,8 +1824,8 @@ void Audio_OcaPlayback(void) { sStaffPlaybackPos++; Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | 0xD07, D_80130F10 - 1); Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | 0xD05, sDisplayedNoteValue & 0x3F); - Audio_PlaySoundGeneral(NA_SE_OC_OCARINA, &D_801333D4, 4, &sNormalizedNotePlaybackTone, - &sNormalizedNotePlaybackVolume, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sNormalizedNotePlaybackTone, + &sNormalizedNotePlaybackVolume, &gSfxDefaultReverb); } else { Audio_StopSfxById(NA_SE_OC_OCARINA); } @@ -3044,7 +3077,7 @@ void AudioDebug_ProcessInput_SndCont(void) { case 2: case 3: Audio_PlaySoundGeneral(((sAudioSndContWork[2] << 12) & 0xFFFF) + sAudioSndContWork[3] + SFX_FLAG, - &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); break; case 4: func_800F6700(sAudioSndContWork[sAudioSndContSel]); @@ -3443,7 +3476,7 @@ void AudioDebug_ProcessInput_SfxParamChg(void) { if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) { sfx = (u16)(sAudioSfxParamChgWork[0] << 12) + sAudioSfxParamChgWork[1] + SFX_FLAG; - Audio_PlaySoundGeneral(sfx, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfx, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) { @@ -3974,7 +4007,7 @@ void Audio_PlayFanfare_Rando(GetItemEntry getItem) { if (getItem.modIndex == MOD_NONE) { if (((itemId >= ITEM_RUPEE_GREEN) && (itemId <= ITEM_RUPEE_GOLD)) || (itemId == ITEM_HEART)) { - Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { if (itemId == ITEM_HEART_CONTAINER || ((itemId == ITEM_HEART_PIECE_2) && ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000))) { @@ -4046,7 +4079,7 @@ void func_800F4010(Vec3f* pos, u16 sfxId, f32 arg2) { D_80131C8C = arg2; sp24 = func_800F3F84(arg2); - Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &gSfxDefaultReverb); if ((sfxId & 0xF0) == 0xB0) { phi_f0 = 0.3f; @@ -4064,22 +4097,22 @@ void func_800F4010(Vec3f* pos, u16 sfxId, f32 arg2) { sfxId2 = NA_SE_PL_METALEFFECT_KID; } D_8016B7AC = (sp24 * 0.7) + 0.3; - Audio_PlaySoundGeneral(sfxId2, pos, 4, &D_8016B7B0, &D_8016B7AC, &D_801333E8); + Audio_PlaySoundGeneral(sfxId2, pos, 4, &D_8016B7B0, &D_8016B7AC, &gSfxDefaultReverb); } } void func_800F4138(Vec3f* pos, u16 sfxId, f32 arg2) { func_800F3F84(arg2); - Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &gSfxDefaultReverb); } void func_800F4190(Vec3f* pos, u16 sfxId) { - Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801305B0, &D_801333E0, &D_801305B4); + Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801305B0, &gSfxDefaultFreqAndVolScale, &D_801305B4); } void Audio_PlaySoundRandom(Vec3f* pos, u16 baseSfxId, u8 randLim) { u8 offset = Audio_NextRandom() % randLim; - Audio_PlaySoundGeneral(baseSfxId + offset, pos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(baseSfxId + offset, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } void func_800F4254(Vec3f* pos, u8 level) { @@ -4088,10 +4121,10 @@ void func_800F4254(Vec3f* pos, u8 level) { D_801305F4 = D_801305E4[level]; switch (level) { case 1: - Audio_PlaySoundGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); break; case 2: - Audio_PlaySoundGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); break; } @@ -4099,7 +4132,7 @@ void func_800F4254(Vec3f* pos, u8 level) { } if (level != 0) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_CHARGE - SFX_FLAG, pos, 4, &D_801305F4, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_CHARGE - SFX_FLAG, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -4111,14 +4144,14 @@ void func_800F436C(Vec3f* pos, u16 sfxId, f32 arg2) { } if (D_8016B7D8 > 0.5f) { - Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7D8, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7D8, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } void func_800F4414(Vec3f* pos, u16 sfxId, f32 arg2) { D_801305B8--; if (D_801305B8 == 0) { - Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7D8, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7D8, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (arg2 > 2.0f) { arg2 = 2.0f; @@ -4135,17 +4168,17 @@ void func_800F44EC(s8 arg0, s8 arg1) { void func_800F4524(Vec3f* pos, u16 sfxId, s8 arg2) { D_8016B7DC = arg2; - Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801333E0, &D_801333E0, &D_8016B7DC); + Audio_PlaySoundGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &D_8016B7DC); } void func_800F4578(Vec3f* pos, u16 sfxId, f32 arg2) { D_8016B7E0 = arg2; - Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801333E0, &D_8016B7E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &D_8016B7E0, &gSfxDefaultReverb); } void func_800F45D0(f32 arg0) { - func_800F4414(&D_801333D4, NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG, arg0); - func_800F436C(&D_801333D4, 0, (0.15f * arg0) + 1.4f); + func_800F4414(&gSfxDefaultPos, NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG, arg0); + func_800F436C(&gSfxDefaultPos, 0, (0.15f * arg0) + 1.4f); } void Audio_PlaySoundRiver(Vec3f* pos, f32 freqScale) { @@ -4156,8 +4189,8 @@ void Audio_PlaySoundRiver(Vec3f* pos, f32 freqScale) { sRiverFreqScaleLerp.remainingFrames = 40; sRiverFreqScaleLerp.step = (sRiverFreqScaleLerp.target - sRiverFreqScaleLerp.value) / 40; } - Audio_PlaySoundGeneral(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } void Audio_PlaySoundWaterfall(Vec3f* pos, f32 freqScale) { @@ -4169,7 +4202,7 @@ void Audio_PlaySoundWaterfall(Vec3f* pos, f32 freqScale) { sWaterfallFreqScaleLerp.step = (sWaterfallFreqScaleLerp.target - sWaterfallFreqScaleLerp.value) / 40; } Audio_PlaySoundGeneral(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value, - &sWaterfallFreqScaleLerp.value, &D_801333E8); + &sWaterfallFreqScaleLerp.value, &gSfxDefaultReverb); } void Audio_StepFreqLerp(FreqLerp* lerp) { @@ -4285,8 +4318,8 @@ void func_800F4A70(void) { } void Audio_PlaySoundIncreasinglyTransposed(Vec3f* pos, s16 sfxId, u8* semitones) { - Audio_PlaySoundGeneral(sfxId, pos, 4, &gNoteFrequencies[semitones[sAudioIncreasingTranspose] + 39], &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(sfxId, pos, 4, &gNoteFrequencies[semitones[sAudioIncreasingTranspose] + 39], &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (sAudioIncreasingTranspose < 15) { sAudioIncreasingTranspose++; @@ -4298,7 +4331,7 @@ void Audio_ResetIncreasingTranspose(void) { } void Audio_PlaySoundTransposed(Vec3f* pos, u16 sfxId, s8 semitone) { - Audio_PlaySoundGeneral(sfxId, pos, 4, &gNoteFrequencies[semitone + 39], &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, pos, 4, &gNoteFrequencies[semitone + 39], &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } void func_800F4C58(Vec3f* pos, u16 sfxId, u8 arg2) { @@ -4319,7 +4352,7 @@ void func_800F4C58(Vec3f* pos, u16 sfxId, u8 arg2) { } phi_s1++; } - Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } void func_800F4E30(Vec3f* pos, f32 arg1) { @@ -4880,10 +4913,10 @@ void func_800F6268(f32 dist, u16 arg1) { void func_800F64E0(u8 arg0) { D_80130608 = arg0; if (arg0 != 0) { - Audio_PlaySoundGeneral(NA_SE_SY_WIN_OPEN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WIN_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Audio_QueueCmdS32(0xF1000000, 0); } else { - Audio_PlaySoundGeneral(NA_SE_SY_WIN_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WIN_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Audio_QueueCmdS32(0xF2000000, 0); } } @@ -4961,7 +4994,7 @@ void Audio_SetBaseFilter(u8 filter) { if (filter == 0) { Audio_StopSfxById(NA_SE_PL_IN_BUBBLE); } else if (sAudioBaseFilter == 0) { - Audio_PlaySoundGeneral(NA_SE_PL_IN_BUBBLE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_PL_IN_BUBBLE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } sAudioBaseFilter = filter; @@ -4994,7 +5027,7 @@ void Audio_PlaySoundGeneralIfNotInCutscene(u16 sfxId, Vec3f* pos, u8 arg2, f32* } void Audio_PlaySoundIfNotInCutscene(u16 sfxId) { - Audio_PlaySoundGeneralIfNotInCutscene(sfxId, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneralIfNotInCutscene(sfxId, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } void func_800F6964(u16 arg0) { diff --git a/soh/src/code/code_800F7260.c b/soh/src/code/code_800F7260.c index e62291c0d..a22679957 100644 --- a/soh/src/code/code_800F7260.c +++ b/soh/src/code/code_800F7260.c @@ -81,13 +81,13 @@ u8 gSfxChannelLayout = 0; u16 D_801333D0 = 0; -Vec3f D_801333D4 = { 0.0f, 0.0f, 0.0f }; // default pos +Vec3f gSfxDefaultPos = { 0.0f, 0.0f, 0.0f }; // default pos -f32 D_801333E0 = 1.0f; // default freqScale +f32 gSfxDefaultFreqAndVolScale = 1.0f; // default freqScale s32 D_801333E4 = 0; // unused -s8 D_801333E8 = 0; // default reverbAdd +s8 gSfxDefaultReverb = 0; // default reverbAdd s32 D_801333EC = 0; // unused @@ -381,7 +381,7 @@ void Audio_ChooseActiveSounds(u8 bankId) } else if (gSoundBanks[bankId][entryIndex].state != SFX_STATE_EMPTY) { entry = &gSoundBanks[bankId][entryIndex]; - if (&D_801333D4.x == entry[0].posX) { + if (&gSfxDefaultPos.x == entry[0].posX) { entry->dist = 0.0f; } else { tempf1 = *entry->posY * 1; diff --git a/soh/src/code/code_801068B0.c b/soh/src/code/code_801068B0.c index d673cc5e0..87434a274 100644 --- a/soh/src/code/code_801068B0.c +++ b/soh/src/code/code_801068B0.c @@ -1,24 +1,33 @@ #include "global.h" -// memmove used in __osMalloc.c -void* func_801068B0(void* dst, void* src, size_t size) { - u8* spC = dst; - u8* sp8 = src; - register s32 a3; +/** + * memmove: copies `len` bytes from memory starting at `src` to memory starting at `dest`. + * + * Unlike memcpy(), the regions of memory may overlap. + * + * @param dest address of start of buffer to write to + * @param src address of start of buffer to read from + * @param len number of bytes to copy. + * + * @return dest + */ +void* oot_memmove(void* dest, const void* src, size_t len) { + char* d = dest; + const char* s = src; - if (spC == sp8) { - return dst; + if (d == s) { + return dest; } - if (spC < sp8) { - for (a3 = size--; a3 != 0; a3 = size--) { - *spC++ = *sp8++; + if (d < s) { + while (len--) { + *d++ = *s++; } } else { - spC += size - 1; - sp8 += size - 1; - for (a3 = size--; a3 != 0; a3 = size--) { - *spC-- = *sp8--; + d += len - 1; + s += len - 1; + while (len--) { + *d-- = *s--; } } - return dst; + return dest; } diff --git a/soh/src/code/db_camera.c b/soh/src/code/db_camera.c index 628b9d406..b3e26be7d 100644 --- a/soh/src/code/db_camera.c +++ b/soh/src/code/db_camera.c @@ -294,7 +294,7 @@ void func_800B44E0(DbCamera* dbCamera, Camera* cam) { if (dbCamera->sub.nPoints < 6) { if (sDbCamAnim.unk_0A != 0) { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sDbCamAnim.unk_0A = 0; } func_8006376C(0x0D, 0x17, 3, cameraStrings[0]); @@ -308,7 +308,7 @@ void func_800B44E0(DbCamera* dbCamera, Camera* cam) { !func_800BB2B4(&sDbCamAnim.lookAtPos, &sDbCamAnim.roll, &sDbCamAnim.fov, dbCamera->sub.lookAt, &sDbCamAnim.keyframe, &sDbCamAnim.curFrame) && sDbCamAnim.unk_0A == 1) { - Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sDbCamAnim.unk_04++; if (dbCamera->sub.nFrames > 0 && dbCamera->sub.nFrames < sDbCamAnim.unk_04) { @@ -536,7 +536,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_40 = -1; dbCamera->sub.demoCtrlActionIdx = 0; sDbCamAnim.unk_0A = 0; - Audio_PlaySoundGeneral(NA_SE_SY_LOCK_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_LOCK_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (dbCamera->unk_38 == -1) { dbCamera->unk_38 = 1; } else { @@ -856,22 +856,22 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_1C.z = 0.0f; dbCamera->unk_1C.y = 1.0f; } else if (dbCamera->sub.unk_08 == 2) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.unk_08 = 0; func_800B41DC(dbCamera, dbCamera->sub.unkIdx, cam); } else { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_R) && CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L)) { - Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.nPoints = dbCamera->sub.unkIdx + 1; func_800B4088(dbCamera, cam); } else if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_R)) { if (dbCamera->sub.unkIdx == 0x80) { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_PUTAWAY, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_PUTAWAY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); func_800B42C0(dbCamera, cam); if (dbCamera->sub.unkIdx == (dbCamera->sub.nPoints - 1)) { dbCamera->sub.unkIdx++; @@ -923,7 +923,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } else { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CRIGHT) && CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L)) { - Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); osSyncPrintf("@@@\n@@@\n@@@/* *** spline point data ** start here *** */\n@@@\n"); DbCamera_PrintPoints("Lookat", dbCamera->sub.nPoints, dbCamera->sub.lookAt); DbCamera_PrintPoints("Position", dbCamera->sub.nPoints, dbCamera->sub.position); @@ -932,13 +932,13 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { osSyncPrintf("@@@static short Mode = %d;\n@@@\n", dbCamera->sub.mode); osSyncPrintf("@@@\n@@@\n@@@/* *** spline point data ** finish! *** */\n@@@\n"); } else if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CLEFT)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.unk_08 = (dbCamera->sub.unk_08 + 1) % 3; } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CUP) && CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L)) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (dbCamera->sub.unkIdx > 0) { dbCamera->sub.unkIdx--; } else { @@ -946,8 +946,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } } else { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CUP)) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (dbCamera->sub.unkIdx > 0) { dbCamera->sub.unkIdx--; } else { @@ -968,7 +968,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } if (CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L) && CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CDOWN)) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (dbCamera->sub.unkIdx < (dbCamera->sub.nPoints - 1)) { dbCamera->sub.unkIdx++; } else { @@ -976,8 +976,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } } else { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CDOWN)) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (dbCamera->sub.unkIdx < (dbCamera->sub.nPoints - 1)) { dbCamera->sub.unkIdx++; } else { @@ -1046,8 +1046,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { case 1: dbCamera->unk_3C = true; if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DUP)) { - Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (dbCamera->sub.unk_0A == 0) { dbCamera->sub.unk_0A = 5; } else { @@ -1055,8 +1055,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DDOWN)) { - Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (dbCamera->sub.unk_0A == 5) { dbCamera->sub.unk_0A = 0; } else { @@ -1064,8 +1064,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DLEFT)) { - Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); switch (dbCamera->sub.unk_0A) { case 1: if (CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L)) { @@ -1114,8 +1114,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { if (CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_DLEFT)) { if ((D_8012D10C++ % 5) == 0) { - Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } switch (dbCamera->sub.unk_0A) { @@ -1152,8 +1152,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DRIGHT)) { - Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); switch (dbCamera->sub.unk_0A) { case 1: @@ -1201,8 +1201,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } if (CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_DRIGHT)) { if ((D_8012D10C++ % 5) == 0) { - Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } switch (dbCamera->sub.unk_0A) { @@ -1353,7 +1353,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->fov = 60.0f; dbCamera->rollDegrees = dbCamera->roll * 1.40625f; if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CLEFT)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->unk_78 = (dbCamera->unk_78 + 1) % 3; dbCamera->unk_38 = -1; } @@ -1634,7 +1634,7 @@ void DbCamera_DrawSlotLetters(char* str, s16 y, s16 x, s32 colorId) { void DbCamera_PrintAllCuts(Camera* cam) { s32 i; - Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); osSyncPrintf("@@@\n@@@\n@@@/* ****** spline point data ** start here ***** */\n@@@\n"); for (i = 0; i < ARRAY_COUNT(sDbCameraCuts) - 1; i++) { @@ -1777,8 +1777,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { if ((1 << sCurFileIdx) & sMempakFiles) { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DLEFT) || CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DRIGHT)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); dbCamera->sub.demoCtrlToggleSwitch ^= 1; } cameraStrings[41][9] = sCurFileIdx + 'A'; @@ -1791,12 +1791,12 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_A)) { if (dbCamera->sub.demoCtrlToggleSwitch == 0) { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); dbCamera->sub.demoCtrlMenu++; } else { - Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); dbCamera->sub.demoCtrlMenu = 0; } } @@ -1812,7 +1812,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_B)) { - Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlMenu = 0; return 1; } @@ -1848,7 +1848,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_A) || CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_B)) { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (dbCamera->sub.demoCtrlMenu == DEMO_CTRL_MENU(ACTION_LOAD, MENU_SUCCESS)) { dbCamera->sub.demoCtrlActionIdx = ACTION_E; } @@ -1870,7 +1870,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_A) || CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_B)) { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlMenu -= 9; } block_2: @@ -1904,8 +1904,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { sp74[i * 2 + 1] = '\0'; if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DRIGHT)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (sCurFileIdx >= 4) { sCurFileIdx = 0; } else { @@ -1921,8 +1921,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DLEFT)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (sCurFileIdx <= 0) { sCurFileIdx = 4; } else { @@ -1964,25 +1964,25 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { func_8006376C(0x14, 0x1A, 5, cameraStrings[36]); if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DUP)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx - 1) % 4u; } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DDOWN)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx + 1) % 4u; } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_A)) { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); dbCamera->sub.demoCtrlToggleSwitch = 0; dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(dbCamera->sub.demoCtrlActionIdx, MENU_INFO); } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_B)) { - Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); dbCamera->sub.demoCtrlActionIdx = ACTION_E; return 1; } @@ -1994,8 +1994,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DUP) || CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DDOWN)) { - Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); dbCamera->sub.demoCtrlActionIdx = ACTION_E; } return 2; @@ -2007,13 +2007,13 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { default: { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DUP)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(ACTION_E, MENU_INFO); dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx - 1) % 4u; sCurFileIdx = 0; } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DDOWN)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(ACTION_E, MENU_INFO); dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx + 1) % 4u; sCurFileIdx = 0; @@ -2052,7 +2052,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { if (func_800B91B0(cam, dbCamera) == 0) { Interface_ChangeAlpha(2); ShrinkWindow_SetVal(0); - Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } OLib_Vec3fDiffToVecSphGeo(&sp5C, &dbCamera->eye, &dbCamera->at); DbCamera_CalcUpFromPitchYawRoll(&dbCamera->unk_1C, sp5C.pitch, sp5C.yaw, @@ -2070,7 +2070,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { sDbCamAnim.unk_0A = 1; sDbCamAnim.unk_0C = 0; D_8016110C = 0; - Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_L)) { @@ -2085,15 +2085,15 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { if (sLastFileIdx != -1) { switch (sp74[sCurFileIdx]) { case '?': - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); sDbCameraCuts[idx1] = sDbCameraCuts[idx2]; sp74[sCurFileIdx] = '?'; // useless DbCamera_ResetCut(idx2, false); break; case '-': - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); sp64 = sDbCameraCuts[idx2]; if (sLastFileIdx < sCurFileIdx) { @@ -2115,8 +2115,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } break; default: - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); break; } } @@ -2125,7 +2125,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_A)) { if (sp74[sCurFileIdx] == '?') { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sp74[sCurFileIdx] = DbCamera_InitCut(idx1, &dbCamera->sub); if (sp74[sCurFileIdx] == '?') { func_8006376C(0xF, 0x18, 7, cameraStrings[26]); @@ -2135,7 +2135,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_B)) { if (sp74[sCurFileIdx] != '?' && sp74[sCurFileIdx] != '-') { - Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sp74[sCurFileIdx] = '?'; DbCamera_ResetCut(idx1, true); } @@ -2143,7 +2143,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_R)) { if (sp74[sCurFileIdx] != '?' && sp74[sCurFileIdx] != '-') { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); for (i = 0; i < sDbCameraCuts[idx1].nPoints; i++) { dbCamera->sub.lookAt[i] = sDbCameraCuts[idx1].lookAt[i]; @@ -2165,7 +2165,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DRIGHT)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (sCurFileIdx == 0x1E) { sCurFileIdx = 0; } else { @@ -2173,7 +2173,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } } if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DLEFT)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sCurFileIdx = (sCurFileIdx == 0) ? 0x1E : sCurFileIdx - 1; } @@ -2187,7 +2187,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { DbCamera_PrintAllCuts(cam); } else if (CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L) && CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CLEFT)) { - Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); for (i = 0; i < ARRAY_COUNT(sDbCameraCuts) - 1; i++) { if (sDbCameraCuts[i].nPoints != 0) { osSyncPrintf("\n@@@ /* CUT [%d]\t*/", i); @@ -2203,7 +2203,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { Interface_ChangeAlpha(50); ShrinkWindow_SetVal(0x20); D_8016110C = 0; - Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } func_8006376C(4, 7, 5, cameraStrings[28]); diff --git a/soh/src/code/debug_malloc.c b/soh/src/code/debug_malloc.c index c1c4f99d0..396e4086d 100644 --- a/soh/src/code/debug_malloc.c +++ b/soh/src/code/debug_malloc.c @@ -109,5 +109,5 @@ void DebugArena_Cleanup(void) { } u8 DebugArena_IsInitalized(void) { - return __osMallocIsInitalized(&sDebugArena); + return __osMallocIsInitialized(&sDebugArena); } diff --git a/soh/src/code/game.c b/soh/src/code/game.c index e1974ed98..a14266719 100644 --- a/soh/src/code/game.c +++ b/soh/src/code/game.c @@ -4,11 +4,12 @@ #include "libultraship/bridge.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" SpeedMeter D_801664D0; -struct_801664F0 D_801664F0; -struct_80166500 D_80166500; -VisMono sMonoColors; +VisCvg sVisCvg; +VisZBuf sVisZBuf; +VisMono sVisMono; ViMode sViMode; FaultClient sGameFaultClient; u16 sLastButtonPressed; @@ -31,41 +32,43 @@ void GameState_FaultPrint(void) { } } -void GameState_SetFBFilter(Gfx** gfx) { - Gfx* gfxP; - gfxP = *gfx; +void GameState_SetFBFilter(Gfx** gfxP) { + Gfx* gfx = *gfxP; - if ((R_FB_FILTER_TYPE > 0) && (R_FB_FILTER_TYPE < 5)) { - D_801664F0.type = R_FB_FILTER_TYPE; - D_801664F0.color.r = R_FB_FILTER_PRIM_COLOR(0); - D_801664F0.color.g = R_FB_FILTER_PRIM_COLOR(1); - D_801664F0.color.b = R_FB_FILTER_PRIM_COLOR(2); - D_801664F0.color.a = R_FB_FILTER_A; - func_800ACE98(&D_801664F0, &gfxP); - } else if ((R_FB_FILTER_TYPE == 5) || (R_FB_FILTER_TYPE == 6)) { - D_80166500.useRgba = (R_FB_FILTER_TYPE == 6); - D_80166500.primColor.r = R_FB_FILTER_PRIM_COLOR(0); - D_80166500.primColor.g = R_FB_FILTER_PRIM_COLOR(1); - D_80166500.primColor.b = R_FB_FILTER_PRIM_COLOR(2); - D_80166500.primColor.a = R_FB_FILTER_A; - D_80166500.envColor.r = R_FB_FILTER_ENV_COLOR(0); - D_80166500.envColor.g = R_FB_FILTER_ENV_COLOR(1); - D_80166500.envColor.b = R_FB_FILTER_ENV_COLOR(2); - D_80166500.envColor.a = R_FB_FILTER_A; - func_800AD958(&D_80166500, &gfxP); - } else if (R_FB_FILTER_TYPE == 7) { - sMonoColors.unk_00 = 0; - sMonoColors.primColor.r = R_FB_FILTER_PRIM_COLOR(0); - sMonoColors.primColor.g = R_FB_FILTER_PRIM_COLOR(1); - sMonoColors.primColor.b = R_FB_FILTER_PRIM_COLOR(2); - sMonoColors.primColor.a = R_FB_FILTER_A; - sMonoColors.envColor.r = R_FB_FILTER_ENV_COLOR(0); - sMonoColors.envColor.g = R_FB_FILTER_ENV_COLOR(1); - sMonoColors.envColor.b = R_FB_FILTER_ENV_COLOR(2); - sMonoColors.envColor.a = R_FB_FILTER_A; - VisMono_Draw(&sMonoColors, &gfxP); + if ((R_FB_FILTER_TYPE >= FB_FILTER_CVG_RGB) && (R_FB_FILTER_TYPE <= FB_FILTER_CVG_RGB_FOG)) { + // Visualize coverage + sVisCvg.vis.type = FB_FILTER_TO_CVG_TYPE(R_FB_FILTER_TYPE); + sVisCvg.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0); + sVisCvg.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1); + sVisCvg.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2); + sVisCvg.vis.primColor.a = R_FB_FILTER_A; + VisCvg_Draw(&sVisCvg, &gfx); + } else if ((R_FB_FILTER_TYPE == FB_FILTER_ZBUF_IA) || (R_FB_FILTER_TYPE == FB_FILTER_ZBUF_RGBA)) { + // Visualize z-buffer + sVisZBuf.vis.type = (R_FB_FILTER_TYPE == FB_FILTER_ZBUF_RGBA); + sVisZBuf.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0); + sVisZBuf.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1); + sVisZBuf.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2); + sVisZBuf.vis.primColor.a = R_FB_FILTER_A; + sVisZBuf.vis.envColor.r = R_FB_FILTER_ENV_COLOR(0); + sVisZBuf.vis.envColor.g = R_FB_FILTER_ENV_COLOR(1); + sVisZBuf.vis.envColor.b = R_FB_FILTER_ENV_COLOR(2); + sVisZBuf.vis.envColor.a = R_FB_FILTER_A; + VisZBuf_Draw(&sVisZBuf, &gfx); + } else if (R_FB_FILTER_TYPE == FB_FILTER_MONO) { + // Monochrome filter + sVisMono.vis.type = 0; + sVisMono.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0); + sVisMono.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1); + sVisMono.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2); + sVisMono.vis.primColor.a = R_FB_FILTER_A; + sVisMono.vis.envColor.r = R_FB_FILTER_ENV_COLOR(0); + sVisMono.vis.envColor.g = R_FB_FILTER_ENV_COLOR(1); + sVisMono.vis.envColor.b = R_FB_FILTER_ENV_COLOR(2); + sVisMono.vis.envColor.a = R_FB_FILTER_A; + VisMono_Draw(&sVisMono, &gfx); } - *gfx = gfxP; + *gfxP = gfx; } void func_800C4344(GameState* gameState) { @@ -420,9 +423,9 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g startTime = endTime; LOG_CHECK_NULL_POINTER("this->cleanup", gameState->destroy); - func_800ACE70(&D_801664F0); - func_800AD920(&D_80166500); - VisMono_Init(&sMonoColors); + VisCvg_Init(&sVisCvg); + VisZBuf_Init(&sVisZBuf); + VisMono_Init(&sVisMono); if (SREG(48) == 0) { ViMode_Init(&sViMode); } @@ -450,9 +453,9 @@ void GameState_Destroy(GameState* gameState) { } func_800AA0F0(); SpeedMeter_Destroy(&D_801664D0); - func_800ACE90(&D_801664F0); - func_800AD950(&D_80166500); - VisMono_Destroy(&sMonoColors); + VisCvg_Destroy(&sVisCvg); + VisZBuf_Destroy(&sVisZBuf); + VisMono_Destroy(&sVisMono); if (SREG(48) == 0) { ViMode_Destroy(&sViMode); } diff --git a/soh/src/code/gfxprint.c b/soh/src/code/gfxprint.c index 6d8686074..8c77e828b 100644 --- a/soh/src/code/gfxprint.c +++ b/soh/src/code/gfxprint.c @@ -1,5 +1,28 @@ #include "global.h" + #include "align_asset_macro.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" + +// #region SOH [HD Textures] +#define drGfxPrintFontData "__OTR__textures/font/sGfxPrintFontData" +static const ALIGN_ASSET(2) char rGfxPrintFontData[] = drGfxPrintFontData; + +#define drGfxPrintFontDataAlt "__OTR__alt/textures/font/sGfxPrintFontData" +static const ALIGN_ASSET(2) char rGfxPrintFontDataAlt[] = drGfxPrintFontDataAlt; + +bool sHasArchiveTexture = false; + +// OTRTODO: this isn't as clean as it could be if we implemented +// the GfxPrint texture extraction to `.otr` as described in +// https://github.com/HarbourMasters/Shipwright/issues/2762 + +// Checks if we have a gfx font as a resource in an archive, which needs to be rendered differently +bool GfxPrint_HasArchiveTexture() { + return ResourceMgr_FileExists(rGfxPrintFontData) || + (ResourceMgr_IsAltAssetsEnabled() && ResourceMgr_FileExists(rGfxPrintFontDataAlt)); +} +// #endregion u16 sGfxPrintFontTLUT[64] = { 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, 0xFFFF, 0x0000, @@ -130,29 +153,6 @@ u8 sGfxPrintFontData[(16 * 256) / 2] = { // Can be used to set GFXP_FLAG_ENLARGE by default static u8 sDefaultSpecialFlags; -#define drGfxPrintFontData "__OTR__textures/font/sGfxPrintFontData"; -static const ALIGN_ASSET(2) char rGfxPrintFontData[] = drGfxPrintFontData; - -#define drGfxPrintFontDataAlt "__OTR__alt/textures/font/sGfxPrintFontData"; -static const ALIGN_ASSET(2) char rGfxPrintFontDataAlt[] = drGfxPrintFontDataAlt; - -// OTRTODO: this isn't as clean as it could be if we implemented -// the GfxPrint texture extraction to `.otr` as described in -// https://github.com/HarbourMasters/Shipwright/issues/2762 -typedef enum {hardcoded, otrDefault, otrAlt} font_texture_t; -font_texture_t GfxPrint_TextureToUse() { - if (ResourceMgr_IsAltAssetsEnabled() && ResourceMgr_FileExists(rGfxPrintFontDataAlt)) { - // If we have alt assets enabled, and we have alt prefixed font texture, use that - return otrAlt; - } else if (ResourceMgr_FileExists(rGfxPrintFontData)) { - // if we have a non alt prefixed font texture, use that - return otrDefault; - } - - // default to hardcoded font - return hardcoded; -} - void GfxPrint_Setup(GfxPrint* this) { s32 width = 16; s32 height = 256; @@ -164,35 +164,31 @@ void GfxPrint_Setup(GfxPrint* this) { G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, G_AC_NONE | G_ZS_PRIM | G_RM_XLU_SURF | G_RM_XLU_SURF2); gDPSetCombineMode(this->dList++, G_CC_DECALRGBA, G_CC_DECALRGBA); - - - if (GfxPrint_TextureToUse() == hardcoded) { - gDPLoadTextureBlock_4b(this->dList++, sGfxPrintFontData, G_IM_FMT_CI, width, height, 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); + // SOH [HD Textures] Font data from an archive has 4 times the width as the letter columns are side by side + if (sHasArchiveTexture) { + gDPLoadTextureBlock_4b(this->dList++, rGfxPrintFontData, G_IM_FMT_CI, width * 4, height, 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); } else { - gDPLoadTextureBlock_4b(this->dList++, - GfxPrint_TextureToUse() == otrAlt ? rGfxPrintFontDataAlt : rGfxPrintFontData, - G_IM_FMT_CI, width * 4, height, 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); + gDPLoadTextureBlock_4b(this->dList++, sGfxPrintFontData, G_IM_FMT_CI, width, height, 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); } - + gDPLoadTLUT(this->dList++, 64, 256, sGfxPrintFontTLUT); for (i = 1; i < 4; i++) { - if (GfxPrint_TextureToUse() != hardcoded) { - gDPSetTile(this->dList++, G_IM_FMT_RGBA, G_IM_SIZ_4b, 1, 0, i * 2, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, - G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); - } else { - gDPSetTile(this->dList++, G_IM_FMT_CI, G_IM_SIZ_4b, 1, 0, i * 2, i, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, - G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); - } + gDPSetTile(this->dList++, G_IM_FMT_CI, G_IM_SIZ_4b, 1, 0, i * 2, i, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOLOD); gDPSetTileSize(this->dList++, i * 2, 0, 0, 60, 1020); } gDPSetColor(this->dList++, G_SETPRIMCOLOR, this->color.rgba); - /*gDPLoadMultiTile_4b(this->dList++, sGfxPrintRainbowData, 0, 1, G_IM_FMT_CI, 2, 8, 0, 0, 1, 7, 4, + // SOH [Port] Rainbow disabled until LUS supports multiple palettes and tiles + /* + gDPLoadMultiTile_4b(this->dList++, sGfxPrintRainbowData, 0, 1, G_IM_FMT_CI, 2, 8, 0, 0, 1, 7, 4, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 1, 3, G_TX_NOLOD, G_TX_NOLOD); gDPLoadTLUT(this->dList++, 16, 320, sGfxPrintRainbowTLUT); @@ -201,7 +197,8 @@ void GfxPrint_Setup(GfxPrint* this) { gDPSetTile(this->dList++, G_IM_FMT_CI, G_IM_SIZ_4b, 1, 0, i * 2 + 1, 4, G_TX_NOMIRROR | G_TX_WRAP, 3, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 1, G_TX_NOLOD); gDPSetTileSize(this->dList++, i * 2 + 1, 0, 0, 4, 28); - }*/ + } + */ } void GfxPrint_SetColor(GfxPrint* this, u32 r, u32 g, u32 b, u32 a) { @@ -248,6 +245,16 @@ void GfxPrint_PrintCharImpl(GfxPrint* this, u8 c) { } } + // SOH [HD Textures] The font data is normally 4 sets of 2 columns overlayed on top of each other with + // different CI palette values. Custom font data from archives instead are all 4 sets laid out side by side. + // This means we have to compute an additional offset value that represents which of the 4 sets a letter is from. + u16 assetOffsetX = 0; + if (sHasArchiveTexture) { + // Multiplied by the offset of 2 columns before added with the original value below + assetOffsetX = (c & 0x3) * (256 * 2); + tile = 0; + } + if (this->flags & GFXP_FLAG_SHADOW) { gDPSetColor(this->dList++, G_SETPRIMCOLOR, 0); @@ -257,7 +264,7 @@ void GfxPrint_PrintCharImpl(GfxPrint* this, u8 c) { 1 << 9); } else { gSPTextureRectangle(this->dList++, this->posX + 4, this->posY + 4, this->posX + 4 + 32, this->posY + 4 + 32, - tile, (u16)(c & 4) * 64, (u16)(c >> 3) * 256, 1 << 10, 1 << 10); + tile, assetOffsetX + (u16)(c & 4) * 64, (u16)(c >> 3) * 256, 1 << 10, 1 << 10); } gDPSetColor(this->dList++, G_SETPRIMCOLOR, this->color.rgba); @@ -267,20 +274,31 @@ void GfxPrint_PrintCharImpl(GfxPrint* this, u8 c) { gSPTextureRectangle(this->dList++, (this->posX) << 1, (this->posY) << 1, (this->posX + 32) << 1, (this->posY + 32) << 1, tile, (u16)(c & 4) * 64, (u16)(c >> 3) * 256, 1 << 9, 1 << 9); } else { - gSPTextureRectangle(this->dList++, this->posX, this->posY, this->posX + 32, this->posY + 32, - GfxPrint_TextureToUse() != hardcoded ? 0 : tile, (GfxPrint_TextureToUse() != hardcoded ? ((128 * 4) * offset) : 0) + (u16)((c & 4) * 64), - (u16)(c >> 3) * 256, 1 << 10, 1 << 10); + gSPTextureRectangle(this->dList++, this->posX, this->posY, this->posX + 32, this->posY + 32, tile, + assetOffsetX + (u16)((c & 4) * 64), (u16)(c >> 3) * 256, 1 << 10, 1 << 10); } this->posX += CVarGetInteger(CVAR_DEVELOPER_TOOLS("GfxPrintChar.Spacing"), 32); } void GfxPrint_PrintStringWithSize(GfxPrint* this, const void* buffer, u32 charSize, u32 charCount) { - OTRGfxPrint((const char*)buffer, this, GfxPrint_PrintCharImpl); + const char* str = (const char*)buffer; + u32 count = charSize * charCount; + + // SOH [Port] Process the string with our wrapper that converts Japanese UTF8 characters for the print system + OTRGfxPrint(str, this, GfxPrint_PrintCharImpl); + // while (count != 0) { + // GfxPrint_PrintChar(this, *(str++)); + // count--; + // } } void GfxPrint_PrintString(GfxPrint* this, const char* str) { + // SOH [Port] Process the string with our wrapper that converts Japanese UTF8 characters for the print system OTRGfxPrint(str, this, GfxPrint_PrintCharImpl); + // while (*str != '\0') { + // GfxPrint_PrintChar(this, *(str++)); + // } } void* GfxPrint_Callback(void* arg, const char* str, size_t size) { @@ -312,6 +330,8 @@ void GfxPrint_Init(GfxPrint* this) { } else { this->flags &= ~GFXP_FLAG_ENLARGE; } + + sHasArchiveTexture = GfxPrint_HasArchiveTexture(); } void GfxPrint_Destroy(GfxPrint* this) { diff --git a/soh/src/code/graph.c b/soh/src/code/graph.c index 6a49117dd..f691c2619 100644 --- a/soh/src/code/graph.c +++ b/soh/src/code/graph.c @@ -300,7 +300,6 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) { GameState_ReqPadData(gameState); GameState_Update(gameState); - DrawColViewer(); OPEN_DISPS(gfxCtx); diff --git a/soh/src/code/padmgr.c b/soh/src/code/padmgr.c index 57dd2c6f7..8665fb448 100644 --- a/soh/src/code/padmgr.c +++ b/soh/src/code/padmgr.c @@ -3,6 +3,8 @@ #include #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" s32 D_8012D280 = 1; diff --git a/soh/src/code/system_malloc.c b/soh/src/code/system_malloc.c index e8bfefed3..7995209ee 100644 --- a/soh/src/code/system_malloc.c +++ b/soh/src/code/system_malloc.c @@ -107,5 +107,5 @@ void SystemArena_Cleanup(void) { } u8 SystemArena_IsInitalized(void) { - return __osMallocIsInitalized(&gSystemArena); + return __osMallocIsInitialized(&gSystemArena); } diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index dccb4d9bf..70c7a3233 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -2,6 +2,7 @@ #include "vt.h" #include "overlays/actors/ovl_Arms_Hook/z_arms_hook.h" +#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" #include "overlays/actors/ovl_En_Part/z_en_part.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" @@ -13,6 +14,7 @@ #include "soh/Enhancements/nametag.h" #include "soh/ActorDB.h" +#include "soh/OTRGlobals.h" #include #include @@ -624,7 +626,7 @@ void func_8002C7BC(TargetContext* targetCtx, Player* player, Actor* actorArg, Pl lockOnSfxId = CHECK_FLAG_ALL(actorArg->flags, ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) ? NA_SE_SY_LOCK_ON : NA_SE_SY_LOCK_ON_HUMAN; - func_80078884(lockOnSfxId); + Sfx_PlaySfxCentered(lockOnSfxId); } targetCtx->targetCenterPos.x = actorArg->world.pos.x; @@ -1080,14 +1082,11 @@ void TitleCard_InitPlaceName(PlayState* play, TitleCardContext* titleCtx, void* } void TitleCard_Update(PlayState* play, TitleCardContext* titleCtx) { - const Color_RGB8 TitleCard_Colors_ori = {255,255,255}; - Color_RGB8 TitleCard_Colors = {255,255,255}; - if (titleCtx->isBossCard && CVarGetInteger(CVAR_COSMETIC("HUD.TitleCard.Boss.Changed"), 1) == 2) { - TitleCard_Colors = CVarGetColor24(CVAR_COSMETIC("HUD.TitleCard.Boss.Value"), TitleCard_Colors_ori); - } else if (!titleCtx->isBossCard && CVarGetInteger(CVAR_COSMETIC("HUD.TitleCard.Map.Changed"), 1) == 2) { - TitleCard_Colors = CVarGetColor24(CVAR_COSMETIC("HUD.TitleCard.Map.Value"), TitleCard_Colors_ori); - } else { - TitleCard_Colors = TitleCard_Colors_ori; + Color_RGB8 TitleCard_Colors = { 255, 255, 255 }; + if (titleCtx->isBossCard && CVarGetInteger(CVAR_COSMETIC("HUD.TitleCard.Boss.Changed"), 0) == 1) { + TitleCard_Colors = CVarGetColor24(CVAR_COSMETIC("HUD.TitleCard.Boss.Value"), TitleCard_Colors); + } else if (!titleCtx->isBossCard && CVarGetInteger(CVAR_COSMETIC("HUD.TitleCard.Map.Changed"), 0) == 1) { + TitleCard_Colors = CVarGetColor24(CVAR_COSMETIC("HUD.TitleCard.Map.Value"), TitleCard_Colors); } if (DECR(titleCtx->delayTimer) == 0) { @@ -1256,7 +1255,7 @@ void Actor_Destroy(Actor* actor, PlayState* play) { NameTag_RemoveAllForActor(actor); } -void func_8002D7EC(Actor* actor) { +void Actor_UpdatePos(Actor* actor) { f32 speedRate = R_UPDATE_RATE * 0.5f; actor->world.pos.x += (actor->velocity.x * speedRate) + actor->colChkInfo.displacement.x; @@ -1264,7 +1263,7 @@ void func_8002D7EC(Actor* actor) { actor->world.pos.z += (actor->velocity.z * speedRate) + actor->colChkInfo.displacement.z; } -void func_8002D868(Actor* actor) { +void Actor_UpdateVelocityXZGravity(Actor* actor) { actor->velocity.x = Math_SinS(actor->world.rot.y) * actor->speedXZ; actor->velocity.z = Math_CosS(actor->world.rot.y) * actor->speedXZ; @@ -1274,12 +1273,12 @@ void func_8002D868(Actor* actor) { } } -void Actor_MoveForward(Actor* actor) { - func_8002D868(actor); - func_8002D7EC(actor); +void Actor_MoveXZGravity(Actor* actor) { + Actor_UpdateVelocityXZGravity(actor); + Actor_UpdatePos(actor); } -void func_8002D908(Actor* actor) { +void Actor_UpdateVelocityXYZ(Actor* actor) { f32 sp24 = Math_CosS(actor->world.rot.x) * actor->speedXZ; actor->velocity.x = Math_SinS(actor->world.rot.y) * sp24; @@ -1287,17 +1286,17 @@ void func_8002D908(Actor* actor) { actor->velocity.z = Math_CosS(actor->world.rot.y) * sp24; } -void func_8002D97C(Actor* actor) { - func_8002D908(actor); - func_8002D7EC(actor); +void Actor_MoveXYZ(Actor* actor) { + Actor_UpdateVelocityXYZ(actor); + Actor_UpdatePos(actor); } -void func_8002D9A4(Actor* actor, f32 arg1) { +void Actor_SetProjectileSpeed(Actor* actor, f32 arg1) { actor->speedXZ = Math_CosS(actor->world.rot.x) * arg1; actor->velocity.y = -Math_SinS(actor->world.rot.x) * arg1; } -void func_8002D9F8(Actor* actor, SkelAnime* skelAnime) { +void Actor_UpdatePosByAnimation(Actor* actor, SkelAnime* skelAnime) { Vec3f sp1C; SkelAnime_UpdateTranslation(skelAnime, &sp1C, actor->shape.rot.y); @@ -1346,20 +1345,20 @@ f32 Actor_WorldDistXZToPoint(Actor* actor, Vec3f* refPoint) { return Math_Vec3f_DistXZ(&actor->world.pos, refPoint); } -void func_8002DBD0(Actor* actor, Vec3f* result, Vec3f* arg2) { - f32 cosRot2Y; - f32 sinRot2Y; +void Actor_WorldToActorCoords(Actor* actor, Vec3f* dest, Vec3f* pos) { + f32 cosY; + f32 sinY; f32 deltaX; f32 deltaZ; - cosRot2Y = Math_CosS(actor->shape.rot.y); - sinRot2Y = Math_SinS(actor->shape.rot.y); - deltaX = arg2->x - actor->world.pos.x; - deltaZ = arg2->z - actor->world.pos.z; + cosY = Math_CosS(actor->shape.rot.y); + sinY = Math_SinS(actor->shape.rot.y); + deltaX = pos->x - actor->world.pos.x; + deltaZ = pos->z - actor->world.pos.z; - result->x = (deltaX * cosRot2Y) - (deltaZ * sinRot2Y); - result->z = (deltaX * sinRot2Y) + (deltaZ * cosRot2Y); - result->y = arg2->y - actor->world.pos.y; + dest->x = (deltaX * cosY) - (deltaZ * sinY); + dest->z = (deltaX * sinY) + (deltaZ * cosY); + dest->y = pos->y - actor->world.pos.y; } f32 Actor_HeightDiff(Actor* actorA, Actor* actorB) { @@ -2103,14 +2102,13 @@ s32 Actor_OfferGetItem(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange return false; } -// TODO: Rename to GiveItemIdFromActorWithFixedRange or similar // If you're doing something for randomizer, you're probably looking for GiveItemEntryFromActorWithFixedRange -void func_8002F554(Actor* actor, PlayState* play, s32 getItemId) { +void Actor_OfferGetItemNearby(Actor* actor, PlayState* play, s32 getItemId) { Actor_OfferGetItem(actor, play, getItemId, 50.0f, 10.0f); } -void func_8002F580(Actor* actor, PlayState* play) { - func_8002F554(actor, play, GI_NONE); +void Actor_OfferCarry(Actor* actor, PlayState* play) { + Actor_OfferGetItemNearby(actor, play, GI_NONE); } u32 Actor_HasNoParent(Actor* actor, PlayState* play) { @@ -2202,7 +2200,7 @@ void func_8002F7A0(PlayState* play, Actor* actor, f32 arg2, s16 arg3, f32 arg4) void Player_PlaySfx(Actor* actor, u16 sfxId) { if (actor->id != ACTOR_PLAYER || sfxId < NA_SE_VO_LI_SWORD_N || sfxId > NA_SE_VO_LI_ELECTRIC_SHOCK_LV_KID) { - Audio_PlaySoundGeneral(sfxId, &actor->projectedPos, 4, &D_801333E0 , &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, &actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale , &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { freqMultiplier = CVarGetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0); if (freqMultiplier <= 0) { @@ -2210,12 +2208,12 @@ void Player_PlaySfx(Actor* actor, u16 sfxId) { } // Authentic behavior uses D_801333E0 for both freqScale and a4 // Audio_PlaySoundGeneral(sfxId, &actor->projectedPos, 4, &D_801333E0 , &D_801333E0, &D_801333E8); - Audio_PlaySoundGeneral(sfxId, &actor->projectedPos, 4, &freqMultiplier, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, &actor->projectedPos, 4, &freqMultiplier, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } void Audio_PlayActorSound2(Actor* actor, u16 sfxId) { - func_80078914(&actor->projectedPos, sfxId); + Sfx_PlaySfxAtPos(&actor->projectedPos, sfxId); } void func_8002F850(PlayState* play, Actor* actor) { @@ -2231,8 +2229,8 @@ void func_8002F850(PlayState* play, Actor* actor) { sfxId = SurfaceType_GetSfx(&play->colCtx, actor->floorPoly, actor->floorBgId); } - func_80078914(&actor->projectedPos, NA_SE_EV_BOMB_BOUND); - func_80078914(&actor->projectedPos, sfxId + SFX_FLAG); + Sfx_PlaySfxAtPos(&actor->projectedPos, NA_SE_EV_BOMB_BOUND); + Sfx_PlaySfxAtPos(&actor->projectedPos, sfxId + SFX_FLAG); } void func_8002F8F0(Actor* actor, u16 sfxId) { @@ -2344,8 +2342,14 @@ void Actor_DrawFaroresWindPointer(PlayState* play) { } else if (D_8015BC18 > 0.0f) { static Vec3f effectVel = { 0.0f, -0.05f, 0.0f }; static Vec3f effectAccel = { 0.0f, -0.025f, 0.0f }; - static Color_RGBA8 effectPrimCol = { 255, 255, 255, 0 }; - static Color_RGBA8 effectEnvCol = { 100, 200, 0, 0 }; + Color_RGBA8 effectPrimCol = { 255, 255, 255, 0 }; + Color_RGBA8 effectEnvCol = { 100, 200, 0, 0 }; + if (CVarGetInteger(CVAR_COSMETIC("Magic.FaroresSecondary.Changed"), 0)) { + effectEnvCol = CVarGetColor(CVAR_COSMETIC("Magic.FaroresSecondary.Value"), effectEnvCol); + } + if (CVarGetInteger(CVAR_COSMETIC("Magic.FaroresPrimary.Changed"), 0)) { + effectPrimCol = CVarGetColor(CVAR_COSMETIC("Magic.FaroresPrimary.Value"), effectPrimCol); + } Vec3f* curPos = &gSaveContext.respawn[RESPAWN_MODE_TOP].pos; Vec3f* nextPos = &gSaveContext.respawn[RESPAWN_MODE_DOWN].pos; f32 prevNum = D_8015BC18; @@ -2440,8 +2444,16 @@ void Actor_DrawFaroresWindPointer(PlayState* play) { Matrix_Push(); gDPPipeSync(POLY_XLU_DISP++); - gDPSetPrimColor(POLY_XLU_DISP++, 128, 128, 255, 255, 200, alpha); - gDPSetEnvColor(POLY_XLU_DISP++, 100, 200, 0, 255); + Color_RGB8 Spell_env = { 100, 200, 0 }; + Color_RGB8 Spell_col = { 255, 255, 200 }; + if (CVarGetInteger(CVAR_COSMETIC("Magic.FaroresSecondary.Changed"), 0)) { + Spell_env = CVarGetColor24(CVAR_COSMETIC("Magic.FaroresSecondary.Value"), Spell_env); + } + if (CVarGetInteger(CVAR_COSMETIC("Magic.FaroresPrimary.Changed"), 0)) { + Spell_col = CVarGetColor24(CVAR_COSMETIC("Magic.FaroresPrimary.Value"), Spell_col); + } + gDPSetPrimColor(POLY_XLU_DISP++, 128, 128, Spell_col.r, Spell_col.g, Spell_col.b, alpha); + gDPSetEnvColor(POLY_XLU_DISP++, Spell_env.r, Spell_env.g, Spell_env.b, 255); Matrix_RotateZ(((play->gameplayFrames * 1500) & 0xFFFF) * M_PI / 32768.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), @@ -2654,7 +2666,7 @@ void Actor_UpdateAll(PlayState* play, ActorContext* actorCtx) { actor = NULL; if (actorCtx->targetCtx.unk_4B != 0) { actorCtx->targetCtx.unk_4B = 0; - func_80078884(NA_SE_SY_LOCK_OFF); + Sfx_PlaySfxCentered(NA_SE_SY_LOCK_OFF); } } @@ -2755,15 +2767,15 @@ void Actor_Draw(PlayState* play, Actor* actor) { void func_80030ED8(Actor* actor) { if (actor->flags & ACTOR_FLAG_SFX_AT_POS) { - Audio_PlaySoundGeneral(actor->sfx, &actor->projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(actor->sfx, &actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (actor->flags & ACTOR_FLAG_SFX_AT_CENTER) { - func_80078884(actor->sfx); + Sfx_PlaySfxCentered(actor->sfx); } else if (actor->flags & ACTOR_FLAG_SFX_AT_CENTER2) { - func_800788CC(actor->sfx); + Sfx_PlaySfxCentered2(actor->sfx); } else if (actor->flags & ACTOR_FLAG_SFX_AS_TIMER) { - func_800F4C58(&D_801333D4, NA_SE_SY_TIMER - SFX_FLAG, (s8)(actor->sfx - 1)); + func_800F4C58(&gSfxDefaultPos, NA_SE_SY_TIMER - SFX_FLAG, (s8)(actor->sfx - 1)); } else { - func_80078914(&actor->projectedPos, actor->sfx); + Sfx_PlaySfxAtPos(&actor->projectedPos, actor->sfx); } } @@ -3842,8 +3854,14 @@ Actor* Actor_GetProjectileActor(PlayState* play, Actor* refActor, f32 radius) { // it can also be an arrow. // Luckily, the field at the same offset in the arrow actor is the x component of a vector // which will rarely ever be 0. So it's very unlikely for this bug to cause an issue. + // + // SoH [Port] We're making a change here, it doesn't technically fix the bug but makes it behave + // more like hardware. Because of pointer size differences in SoH this was accessing a different + // place in memory and causing issues with Dark link behavior, and probably other places too if ((Math_Vec3f_DistXYZ(&refActor->world.pos, &actor->world.pos) > radius) || - (((ArmsHook*)actor)->timer == 0)) { + (actor->id == ACTOR_ARMS_HOOK && ((ArmsHook*)actor)->timer == 0) || + (actor->id == ACTOR_EN_ARROW && ((EnArrow*)actor)->unk_210.x == 0) + ) { actor = actor->next; } else { deltaX = Math_SinS(actor->world.rot.y) * (actor->speedXZ * 10.0f); @@ -4528,25 +4546,25 @@ void func_80034CC4(PlayState* play, SkelAnime* skelAnime, OverrideLimbDraw overr CLOSE_DISPS(play->state.gfxCtx); } -s16 func_80034DD4(Actor* actor, PlayState* play, s16 arg2, f32 arg3) { +s16 Actor_UpdateAlphaByDistance(Actor* actor, PlayState* play, s16 alpha, f32 radius) { Player* player = GET_PLAYER(play); - f32 var; + f32 distance; if ((play->csCtx.state != CS_STATE_IDLE) || (gDbgCamEnabled)) { - var = Math_Vec3f_DistXYZ(&actor->world.pos, &play->view.eye) * 0.25f; + distance = Math_Vec3f_DistXYZ(&actor->world.pos, &play->view.eye) * 0.25f; } else { - var = Math_Vec3f_DistXYZ(&actor->world.pos, &player->actor.world.pos); + distance = Math_Vec3f_DistXYZ(&actor->world.pos, &player->actor.world.pos); } - if (arg3 < var) { + if (radius < distance) { actor->flags &= ~ACTOR_FLAG_TARGETABLE; - Math_SmoothStepToS(&arg2, 0, 6, 0x14, 1); + Math_SmoothStepToS(&alpha, 0, 6, 0x14, 1); } else { actor->flags |= ACTOR_FLAG_TARGETABLE; - Math_SmoothStepToS(&arg2, 0xFF, 6, 0x14, 1); + Math_SmoothStepToS(&alpha, 0xFF, 6, 0x14, 1); } - return arg2; + return alpha; } void Animation_ChangeByInfo(SkelAnime* skelAnime, AnimationInfo* animationInfo, s32 index) { @@ -4585,13 +4603,13 @@ s32 func_80035124(Actor* actor, PlayState* play) { if (Actor_HasParent(actor, play)) { actor->params = 1; } else if (!(actor->bgCheckFlags & 1)) { - Actor_MoveForward(actor); + Actor_MoveXZGravity(actor); Math_SmoothStepToF(&actor->speedXZ, 0.0f, 1.0f, 0.1f, 0.0f); } else if ((actor->bgCheckFlags & 2) && (actor->velocity.y < -4.0f)) { ret = 1; } else { actor->shape.rot.x = actor->shape.rot.z = 0; - func_8002F580(actor, play); + Actor_OfferCarry(actor, play); } break; case 1: @@ -5737,8 +5755,8 @@ void func_80036E50(u16 textId, s16 arg1) { Flags_SetInfTable(INFTABLE_0C); return; case 0x1033: - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD); Flags_SetInfTable(INFTABLE_0E); return; @@ -6201,7 +6219,7 @@ s32 func_80037CB8(PlayState* play, Actor* actor, s16 arg2) { case TEXT_STATE_CHOICE: case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play) && func_80037C94(play, actor, arg2)) { - Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); msgCtx->msgMode = MSGMODE_TEXT_CLOSING; ret = true; } diff --git a/soh/src/code/code_80043480.c b/soh/src/code/z_bg_item.c similarity index 57% rename from soh/src/code/code_80043480.c rename to soh/src/code/z_bg_item.c index 3ba733e26..d36374b59 100644 --- a/soh/src/code/code_80043480.c +++ b/soh/src/code/z_bg_item.c @@ -2,74 +2,74 @@ void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 flags) { dynaActor->bgId = -1; - dynaActor->unk_15C = flags; - dynaActor->unk_160 = 0; + dynaActor->transformFlags = flags; + dynaActor->interactFlags = 0; dynaActor->unk_150 = 0.0f; dynaActor->unk_154 = 0.0f; } -void func_800434A0(DynaPolyActor* dynaActor) { - dynaActor->unk_160 = 0; +void DynaPolyActor_UnsetAllInteractFlags(DynaPolyActor* dynaActor) { + dynaActor->interactFlags = 0; } -void func_800434A8(DynaPolyActor* dynaActor) { - dynaActor->unk_160 |= 1; +void DynaPolyActor_SetActorOnTop(DynaPolyActor* dynaActor) { + dynaActor->interactFlags |= DYNA_INTERACT_ACTOR_ON_TOP; } -void func_800434B8(DynaPolyActor* dynaActor) { - dynaActor->unk_160 |= 2; +void DynaPolyActor_SetPlayerOnTop(DynaPolyActor* dynaActor) { + dynaActor->interactFlags |= DYNA_INTERACT_PLAYER_ON_TOP; } -void func_800434C8(CollisionContext* colCtx, s32 floorBgId) { +void DynaPoly_SetPlayerOnTop(CollisionContext* colCtx, s32 floorBgId) { DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, floorBgId); if (dynaActor != NULL) { - func_800434B8(dynaActor); + DynaPolyActor_SetPlayerOnTop(dynaActor); } } -void func_800434F8(DynaPolyActor* dynaActor) { - dynaActor->unk_160 |= 4; +void DynaPolyActor_SetPlayerAbove(DynaPolyActor* dynaActor) { + dynaActor->interactFlags |= DYNA_INTERACT_PLAYER_ABOVE; } -void func_80043508(CollisionContext* colCtx, s32 floorBgId) { +void DynaPoly_SetPlayerAbove(CollisionContext* colCtx, s32 floorBgId) { DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, floorBgId); if (dynaActor != NULL) { - func_800434F8(dynaActor); + DynaPolyActor_SetPlayerAbove(dynaActor); } } -void func_80043538(DynaPolyActor* dynaActor) { - dynaActor->unk_160 |= 8; +void DynaPolyActor_SetSwitchPressed(DynaPolyActor* dynaActor) { + dynaActor->interactFlags |= DYNA_INTERACT_ACTOR_SWITCH_PRESSED; } -s32 func_80043548(DynaPolyActor* dynaActor) { - if (dynaActor->unk_160 & 1) { +s32 DynaPolyActor_IsActorOnTop(DynaPolyActor* dynaActor) { + if (dynaActor->interactFlags & DYNA_INTERACT_ACTOR_ON_TOP) { return true; } else { return false; } } -s32 func_8004356C(DynaPolyActor* dynaActor) { - if (dynaActor->unk_160 & 2) { +s32 DynaPolyActor_IsPlayerOnTop(DynaPolyActor* dynaActor) { + if (dynaActor->interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) { return true; } else { return false; } } -s32 func_80043590(DynaPolyActor* dynaActor) { - if (dynaActor->unk_160 & 4) { +s32 DynaPolyActor_IsPlayerAbove(DynaPolyActor* dynaActor) { + if (dynaActor->interactFlags & DYNA_INTERACT_PLAYER_ABOVE) { return true; } else { return false; } } -s32 func_800435B4(DynaPolyActor* dynaActor) { - if (dynaActor->unk_160 & 8) { +s32 DynaPolyActor_IsSwitchPressed(DynaPolyActor* dynaActor) { + if (dynaActor->interactFlags & DYNA_INTERACT_ACTOR_SWITCH_PRESSED) { return true; } else { return false; diff --git a/soh/src/code/z_bgcheck.c b/soh/src/code/z_bgcheck.c index 2a385f966..20deee679 100644 --- a/soh/src/code/z_bgcheck.c +++ b/soh/src/code/z_bgcheck.c @@ -1,7 +1,8 @@ #include "global.h" #include "vt.h" -#include +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include #define SS_NULL 0xFFFF @@ -2953,7 +2954,7 @@ void func_8003F8EC(PlayState* play, DynaCollisionContext* dyna, Actor* actor) { if ((dyna->bgActorFlags[i] & 1)) { dynaActor = DynaPoly_GetActor(&play->colCtx, i); if (dynaActor != NULL && &dynaActor->actor == actor) { - func_800434A0((DynaPolyActor*)actor); + DynaPolyActor_UnsetAllInteractFlags((DynaPolyActor*)actor); return; } } diff --git a/soh/src/code/z_camera.c b/soh/src/code/z_camera.c index 986606045..6551d6347 100644 --- a/soh/src/code/z_camera.c +++ b/soh/src/code/z_camera.c @@ -6168,7 +6168,7 @@ s32 Camera_Demo5(Camera* camera) { pad = sDemo5PrevSfxFrame - camera->play->state.frames; if ((pad >= 0x33) || (pad < -0x32)) { - func_80078884(camera->data1); + Sfx_PlaySfxCentered(camera->data1); } sDemo5PrevSfxFrame = camera->play->state.frames; @@ -7362,11 +7362,11 @@ s32 Camera_DbgChangeMode(Camera* camera) { if (!gDbgCamEnabled && camera->play->activeCamera == MAIN_CAM) { if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CUP)) { osSyncPrintf("attention sound URGENCY\n"); - func_80078884(NA_SE_SY_ATTENTION_URGENCY); + Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_URGENCY); } if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CDOWN)) { osSyncPrintf("attention sound NORMAL\n"); - func_80078884(NA_SE_SY_ATTENTION_ON); + Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_ON); } if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CRIGHT)) { @@ -7783,7 +7783,7 @@ s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags) { if (!((sCameraSettings[camera->setting].unk_00 & 0x3FFFFFFF) & (1 << mode))) { if (mode == CAM_MODE_FIRSTPERSON) { osSyncPrintf("camera: error sound\n"); - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } if (camera->mode != CAM_MODE_NORMAL) { @@ -7871,20 +7871,20 @@ s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags) { if (camera->status == CAM_STAT_ACTIVE) { switch (modeChangeFlags) { case 1: - func_80078884(0); + Sfx_PlaySfxCentered(0); break; case 2: if (camera->play->roomCtx.curRoom.behaviorType1 == ROOM_BEHAVIOR_TYPE1_1) { - func_80078884(NA_SE_SY_ATTENTION_URGENCY); + Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_URGENCY); } else { - func_80078884(NA_SE_SY_ATTENTION_ON); + Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_ON); } break; case 4: - func_80078884(NA_SE_SY_ATTENTION_URGENCY); + Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_URGENCY); break; case 8: - func_80078884(NA_SE_SY_ATTENTION_ON); + Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_ON); break; } } diff --git a/soh/src/code/z_cheap_proc.c b/soh/src/code/z_cheap_proc.c index cf52db2d3..4af2867e5 100644 --- a/soh/src/code/z_cheap_proc.c +++ b/soh/src/code/z_cheap_proc.c @@ -1,4 +1,5 @@ #include "global.h" +#include "soh/ResourceManagerHelpers.h" void Gfx_DrawDListOpa(PlayState* play, Gfx* dlist) { OPEN_DISPS(play->state.gfxCtx); diff --git a/soh/src/code/z_collision_check.c b/soh/src/code/z_collision_check.c index 5376ae41c..312675f7f 100644 --- a/soh/src/code/z_collision_check.c +++ b/soh/src/code/z_collision_check.c @@ -1607,10 +1607,10 @@ void CollisionCheck_HitSolid(PlayState* play, ColliderInfo* info, Collider* coll if (flags == TOUCH_SFX_NORMAL && collider->colType != COLTYPE_METAL) { EffectSsHitMark_SpawnFixedScale(play, EFFECT_HITMARK_WHITE, hitPos); if (collider->actor == NULL) { - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } else if (flags == TOUCH_SFX_NORMAL) { // collider->colType == COLTYPE_METAL EffectSsHitMark_SpawnFixedScale(play, EFFECT_HITMARK_METAL, hitPos); @@ -1622,18 +1622,18 @@ void CollisionCheck_HitSolid(PlayState* play, ColliderInfo* info, Collider* coll } else if (flags == TOUCH_SFX_HARD) { EffectSsHitMark_SpawnFixedScale(play, EFFECT_HITMARK_WHITE, hitPos); if (collider->actor == NULL) { - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } else if (flags == TOUCH_SFX_WOOD) { EffectSsHitMark_SpawnFixedScale(play, EFFECT_HITMARK_DUST, hitPos); if (collider->actor == NULL) { - Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &collider->actor->projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &collider->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } } @@ -1644,17 +1644,17 @@ void CollisionCheck_HitSolid(PlayState* play, ColliderInfo* info, Collider* coll s32 CollisionCheck_SwordHitAudio(Collider* at, ColliderInfo* acInfo) { if (at->actor != NULL && at->actor->category == ACTORCAT_PLAYER) { if (acInfo->elemType == ELEMTYPE_UNK0) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE, &at->actor->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE, &at->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (acInfo->elemType == ELEMTYPE_UNK1) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE_HARD, &at->actor->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE_HARD, &at->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (acInfo->elemType == ELEMTYPE_UNK2) { - Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &at->actor->projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &at->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (acInfo->elemType == ELEMTYPE_UNK3) { - Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &at->actor->projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &at->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } return 1; @@ -1691,7 +1691,7 @@ void CollisionCheck_HitEffects(PlayState* play, Collider* at, ColliderInfo* atIn } else if (sHitInfo[ac->colType].effect == HIT_WOOD) { if (at->actor == NULL) { CollisionCheck_SpawnShieldParticles(play, hitPos); - Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { CollisionCheck_SpawnShieldParticlesWood(play, hitPos, &at->actor->projectedPos); } @@ -1704,10 +1704,10 @@ void CollisionCheck_HitEffects(PlayState* play, Collider* at, ColliderInfo* atIn } else { EffectSsHitMark_SpawnFixedScale(play, EFFECT_HITMARK_WHITE, hitPos); if (ac->actor == NULL) { - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &ac->actor->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &ac->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } } @@ -3460,7 +3460,7 @@ void CollisionCheck_SpawnShieldParticles(PlayState* play, Vec3f* v) { */ void CollisionCheck_SpawnShieldParticlesMetal(PlayState* play, Vec3f* v) { CollisionCheck_SpawnShieldParticles(play, v); - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } /** @@ -3468,7 +3468,7 @@ void CollisionCheck_SpawnShieldParticlesMetal(PlayState* play, Vec3f* v) { */ void CollisionCheck_SpawnShieldParticlesMetalSound(PlayState* play, Vec3f* v, Vec3f* pos) { CollisionCheck_SpawnShieldParticles(play, v); - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, pos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } /** @@ -3508,7 +3508,7 @@ void CollisionCheck_SpawnShieldParticlesWood(PlayState* play, Vec3f* v, Vec3f* a initWood.lightPoint.z = initWood.position.z; Effect_Add(play, &effectIndex, EFFECT_SHIELD_PARTICLE, 0, 1, &initWood); - Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, actorPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, actorPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } /** diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c index 499e16898..9247be6aa 100644 --- a/soh/src/code/z_demo.c +++ b/soh/src/code/z_demo.c @@ -32,6 +32,8 @@ #include "scenes/misc/hakaana_ouke/hakaana_ouke_scene.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" u16 D_8011E1C0 = 0; @@ -57,29 +59,29 @@ CutsceneStateHandler sCsStateHandlers2[] = { u8 sTitleCsState = 0; EntranceCutscene sEntranceCutsceneTable[] = { - { ENTR_HYRULE_FIELD_3, 2, 0xA0, gHyruleFieldIntroCs }, - { ENTR_DEATH_MOUNTAIN_TRAIL_0, 2, 0xA1, gDMTIntroCs }, - { ENTR_KAKARIKO_VILLAGE_0, 2, 0xA3, gKakarikoVillageIntroCs }, - { ENTR_ZORAS_DOMAIN_0, 2, 0xA4, gZorasDomainIntroCs }, - { ENTR_HYRULE_CASTLE_0, 1, 0xA5, gHyruleCastleIntroCs }, - { ENTR_GORON_CITY_0, 2, 0xA6, gGoronCityIntroCs }, - { ENTR_TEMPLE_OF_TIME_0, 2, 0xA7, gTempleOfTimeIntroCs }, - { ENTR_DEKU_TREE_0, 2, 0xA8, gDekuTreeIntroCs }, + { ENTR_HYRULE_FIELD_WOODED_EXIT, 2, 0xA0, gHyruleFieldIntroCs }, + { ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT, 2, 0xA1, gDMTIntroCs }, + { ENTR_KAKARIKO_VILLAGE_FRONT_GATE, 2, 0xA3, gKakarikoVillageIntroCs }, + { ENTR_ZORAS_DOMAIN_ENTRANCE, 2, 0xA4, gZorasDomainIntroCs }, + { ENTR_CASTLE_GROUNDS_SOUTH_EXIT, 1, 0xA5, gHyruleCastleIntroCs }, + { ENTR_GORON_CITY_UPPER_EXIT, 2, 0xA6, gGoronCityIntroCs }, + { ENTR_TEMPLE_OF_TIME_ENTRANCE, 2, 0xA7, gTempleOfTimeIntroCs }, + { ENTR_DEKU_TREE_ENTRANCE, 2, 0xA8, gDekuTreeIntroCs }, { ENTR_HYRULE_FIELD_11, 0, 0x18, gHyruleFieldSouthEponaJumpCs }, { ENTR_HYRULE_FIELD_13, 0, 0x18, gHyruleFieldEastEponaJumpCs }, { ENTR_HYRULE_FIELD_12, 0, 0x18, gHyruleFieldWestEponaJumpCs }, { ENTR_HYRULE_FIELD_15, 0, 0x18, gHyruleFieldGateEponaJumpCs }, { ENTR_HYRULE_FIELD_16, 1, 0xA9, gHyruleFieldGetOoTCs }, - { ENTR_LAKE_HYLIA_0, 2, 0xB1, gLakeHyliaIntroCs }, - { ENTR_GERUDO_VALLEY_0, 2, 0xB2, gGerudoValleyIntroCs }, - { ENTR_GERUDOS_FORTRESS_0, 2, 0xB3, gGerudoFortressIntroCs }, - { ENTR_LON_LON_RANCH_0, 2, 0xB4, gLonLonRanchIntroCs }, - { ENTR_JABU_JABU_0, 2, 0xB5, gJabuJabuIntroCs }, - { ENTR_GRAVEYARD_0, 2, 0xB6, gGraveyardIntroCs }, - { ENTR_ZORAS_FOUNTAIN_2, 2, 0xB7, gZorasFountainIntroCs }, - { ENTR_DESERT_COLOSSUS_0, 2, 0xB8, gDesertColossusIntroCs }, - { ENTR_DEATH_MOUNTAIN_CRATER_0, 2, 0xB9, gDeathMountainCraterIntroCs }, - { ENTR_HYRULE_CASTLE_0, 0, 0xBA, gGanonsCastleIntroCs }, + { ENTR_LAKE_HYLIA_NORTH_EXIT, 2, 0xB1, gLakeHyliaIntroCs }, + { ENTR_GERUDO_VALLEY_EAST_EXIT, 2, 0xB2, gGerudoValleyIntroCs }, + { ENTR_GERUDOS_FORTRESS_EAST_EXIT, 2, 0xB3, gGerudoFortressIntroCs }, + { ENTR_LON_LON_RANCH_ENTRANCE, 2, 0xB4, gLonLonRanchIntroCs }, + { ENTR_JABU_JABU_ENTRANCE, 2, 0xB5, gJabuJabuIntroCs }, + { ENTR_GRAVEYARD_ENTRANCE, 2, 0xB6, gGraveyardIntroCs }, + { ENTR_ZORAS_FOUNTAIN_TUNNEL_EXIT, 2, 0xB7, gZorasFountainIntroCs }, + { ENTR_DESERT_COLOSSUS_EAST_EXIT, 2, 0xB8, gDesertColossusIntroCs }, + { ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT, 2, 0xB9, gDeathMountainCraterIntroCs }, + { ENTR_CASTLE_GROUNDS_SOUTH_EXIT, 0, 0xBA, gGanonsCastleIntroCs }, { ENTR_ROYAL_FAMILYS_TOMB_1, 2, 0x5A, gSunSongGraveSunSongTeachPart2Cs }, { ENTR_INSIDE_GANONS_CASTLE_2, 2, 0xBB, gForestBarrierCs }, { ENTR_INSIDE_GANONS_CASTLE_3, 2, 0xBC, gWaterBarrierCs }, @@ -87,9 +89,9 @@ EntranceCutscene sEntranceCutsceneTable[] = { { ENTR_INSIDE_GANONS_CASTLE_5, 2, 0xBE, gFireBarrierCs }, { ENTR_INSIDE_GANONS_CASTLE_6, 2, 0xBF, gLightBarrierCs }, { ENTR_INSIDE_GANONS_CASTLE_7, 2, 0xAD, gSpiritBarrierCs }, - { ENTR_SPIRIT_TEMPLE_BOSS_0, 0, 0xC0, gSpiritBossNabooruKnuckleIntroCs }, + { ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE, 0, 0xC0, gSpiritBossNabooruKnuckleIntroCs }, { ENTR_GERUDOS_FORTRESS_17, 0, 0xC7, gGerudoFortressFirstCaptureCs }, - { ENTR_DEATH_MOUNTAIN_CRATER_1, 2, 0xB9, gDeathMountainCraterIntroCs }, + { ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT, 2, 0xB9, gDeathMountainCraterIntroCs }, { ENTR_KOKIRI_FOREST_12, 2, 0xC6, gKokiriForestDekuSproutCs }, }; @@ -247,7 +249,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { case 3: if (sp3F != 0) { Flags_SetEnv(play, 0); - if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_0 || (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_7)) { + if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_ENTRANCE || (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_WARP_PAD)) { Flags_SetEnv(play, 2); } } @@ -285,7 +287,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { play->roomCtx.unk_74[0] += 0x14; } if (csCtx->frames == 0x30F) { - func_80078884(NA_SE_EV_DEKU_DEATH); + Sfx_PlaySfxCentered(NA_SE_EV_DEKU_DEATH); } else if (csCtx->frames == 0x2CD) { play->roomCtx.unk_74[0] = 0; } @@ -299,7 +301,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { break; case 13: if (play->roomCtx.unk_74[1] == 0) { - func_80078884(NA_SE_EV_TRIFORCE_FLASH); + Sfx_PlaySfxCentered(NA_SE_EV_TRIFORCE_FLASH); } if (play->roomCtx.unk_74[1] < 0xFF) { play->roomCtx.unk_74[1] += 5; @@ -307,7 +309,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { break; case 14: if (sp3F != 0) { - func_800BC490(play, 1); + Play_SetViewpoint(play, 1); } break; case 15: @@ -350,16 +352,16 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); break; case 22: - D_801614B0.r = 255; - D_801614B0.g = 255; - D_801614B0.b = 255; - D_801614B0.a = 255; + gVisMonoColor.r = 255; + gVisMonoColor.g = 255; + gVisMonoColor.b = 255; + gVisMonoColor.a = 255; break; case 23: - D_801614B0.r = 255; - D_801614B0.g = 180; - D_801614B0.b = 100; - D_801614B0.a = 255.0f * temp; + gVisMonoColor.r = 255; + gVisMonoColor.g = 180; + gVisMonoColor.b = 100; + gVisMonoColor.a = 255.0f * temp; break; case 24: play->roomCtx.curRoom.segment = NULL; @@ -412,7 +414,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) { if (sp3F != 0) { play->envCtx.sandstormState = SANDSTORM_FILL; } - func_800788CC(NA_SE_EV_SAND_STORM - SFX_FLAG); + Sfx_PlaySfxCentered2(NA_SE_EV_SAND_STORM - SFX_FLAG); break; case 33: gSaveContext.sunsSongState = SUNSSONG_START; @@ -514,7 +516,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB CHECK_BTN_ALL(play->state.input[0].press.button, BTN_B) || CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START)) && (gSaveContext.fileNum != 0xFEDC) && (play->transitionTrigger == TRANS_TRIGGER_OFF)) { - Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); temp = 1; } @@ -593,13 +595,13 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FILL_WHITE; break; case 3: - play->nextEntranceIndex = ENTR_GERUDO_VALLEY_0; + play->nextEntranceIndex = ENTR_GERUDO_VALLEY_EAST_EXIT; gSaveContext.cutsceneIndex = 0xFFF1; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FILL_WHITE; break; case 4: - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT; gSaveContext.cutsceneIndex = 0xFFF0; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FILL_WHITE; @@ -652,13 +654,13 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB } break; case 9: - play->nextEntranceIndex = ENTR_GERUDO_VALLEY_0; + play->nextEntranceIndex = ENTR_GERUDO_VALLEY_EAST_EXIT; gSaveContext.cutsceneIndex = 0xFFF0; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FILL_BROWN; break; case 10: - play->nextEntranceIndex = ENTR_LINKS_HOUSE_0; + play->nextEntranceIndex = ENTR_LINKS_HOUSE_CHILD_SPAWN; gSaveContext.cutsceneIndex = 0xFFF0; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; @@ -670,35 +672,35 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 12: - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 13: - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; + play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK; break; case 14: - play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11; + play->nextEntranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 15: - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF4; play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 16: - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF5; play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 17: - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF6; play->transitionType = TRANS_TYPE_FADE_WHITE; @@ -711,13 +713,13 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK; break; case 19: - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; gSaveContext.cutsceneIndex = 0x8000; break; case 21: - play->nextEntranceIndex = ENTR_LAKE_HYLIA_0; + play->nextEntranceIndex = ENTR_LAKE_HYLIA_NORTH_EXIT; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF0; play->transitionType = TRANS_TYPE_FADE_WHITE; @@ -726,7 +728,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB if (GameInteractor_Should(VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true)) { Item_Give(play, ITEM_SONG_REQUIEM); } - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0; + play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_EAST_EXIT; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF0; play->transitionType = TRANS_TYPE_FADE_WHITE; @@ -738,7 +740,11 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 24: - play->nextEntranceIndex = ENTR_JABU_JABU_0; + if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { + play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_JABU_JABU_ENTRANCE); + } else { + play->nextEntranceIndex = ENTR_JABU_JABU_ENTRANCE; + } play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; @@ -750,19 +756,19 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 26: - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF4; play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 27: - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF5; play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 28: - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF6; play->transitionType = TRANS_TYPE_FADE_WHITE; @@ -790,13 +796,13 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB break; case 32: play->linkAgeOnLoad = 1; - play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF2; play->transitionType = TRANS_TYPE_INSTANT; break; case 33: - play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; break; @@ -807,7 +813,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 35: - play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF0; play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; @@ -819,14 +825,14 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; break; case 39: - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF9; play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; break; case 40: play->linkAgeOnLoad = 0; - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFFA; play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; @@ -837,7 +843,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 42: - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; + play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_FRONT_GATE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF2; play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; @@ -863,7 +869,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB Item_Give(play, ITEM_SONG_NOCTURNE); } Flags_SetEventChkInf(EVENTCHKINF_LEARNED_NOCTURNE_OF_SHADOW); - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; + play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_FRONT_GATE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF1; play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; @@ -885,13 +891,13 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE_INSTANT; break; case 51: - play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; gSaveContext.cutsceneIndex = 0xFFF8; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_CIRCLE(TCA_NORMAL, TCC_WHITE, TCS_SLOW); break; case 52: - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; gSaveContext.cutsceneIndex = 0xFFF7; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_INSTANT; @@ -905,49 +911,49 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB gSaveContext.gameMode = 3; Audio_SetSoundBanksMute(0x6F); play->linkAgeOnLoad = 1; - play->nextEntranceIndex = ENTR_GERUDO_VALLEY_0; + play->nextEntranceIndex = ENTR_GERUDO_VALLEY_EAST_EXIT; gSaveContext.cutsceneIndex = 0xFFF2; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 55: - play->nextEntranceIndex = ENTR_GERUDOS_FORTRESS_0; + play->nextEntranceIndex = ENTR_GERUDOS_FORTRESS_EAST_EXIT; gSaveContext.cutsceneIndex = 0xFFF1; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 56: - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; + play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_FRONT_GATE; gSaveContext.cutsceneIndex = 0xFFF4; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 57: - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT; gSaveContext.cutsceneIndex = 0xFFF3; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 58: - play->nextEntranceIndex = ENTR_GORON_CITY_0; + play->nextEntranceIndex = ENTR_GORON_CITY_UPPER_EXIT; gSaveContext.cutsceneIndex = 0xFFF1; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 59: - play->nextEntranceIndex = ENTR_LAKE_HYLIA_0; + play->nextEntranceIndex = ENTR_LAKE_HYLIA_NORTH_EXIT; gSaveContext.cutsceneIndex = 0xFFF1; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 60: - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; + play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP; gSaveContext.cutsceneIndex = 0xFFF2; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 61: - play->nextEntranceIndex = ENTR_ZORAS_DOMAIN_0; + play->nextEntranceIndex = ENTR_ZORAS_DOMAIN_ENTRANCE; gSaveContext.cutsceneIndex = 0xFFF0; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; @@ -966,25 +972,25 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 64: - play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; gSaveContext.cutsceneIndex = 0xFFF5; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 65: play->linkAgeOnLoad = 1; - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; gSaveContext.cutsceneIndex = 0xFFF2; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 66: - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_14; + play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_OWL_DROP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 67: - play->nextEntranceIndex = ENTR_HYRULE_FIELD_9; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_OWL_DROP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; @@ -1000,7 +1006,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 70: - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF4; play->transitionType = TRANS_TYPE_FADE_BLACK; @@ -1012,7 +1018,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB gSaveContext.equips.equipment |= EQUIP_VALUE_BOOTS_KOKIRI << (EQUIP_TYPE_BOOTS * 4); Player_SetEquipmentData(play, player); play->linkAgeOnLoad = 1; - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF1; play->transitionType = TRANS_TYPE_FADE_BLACK; @@ -1026,13 +1032,13 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB break; case 73: play->linkAgeOnLoad = 1; - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF2; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 74: - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF3; play->transitionType = TRANS_TYPE_FADE_WHITE; @@ -1040,27 +1046,27 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB break; case 75: play->linkAgeOnLoad = 1; - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF4; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 76: play->linkAgeOnLoad = 0; - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF5; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 77: play->linkAgeOnLoad = 1; - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF6; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 78: - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF7; play->transitionType = TRANS_TYPE_FADE_BLACK; @@ -1080,7 +1086,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB case 91: case 92: case 93: - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; @@ -1092,24 +1098,24 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB case 95: if ((Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) && (Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) && (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP))) { - play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_0; + play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF3; play->transitionType = TRANS_TYPE_FADE_BLACK; } else { switch (gSaveContext.sceneSetupIndex) { case 8: - play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_0; + play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 9: - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_0; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 10: - play->nextEntranceIndex = ENTR_LAKE_HYLIA_0; + play->nextEntranceIndex = ENTR_LAKE_HYLIA_NORTH_EXIT; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF0; play->transitionType = TRANS_TYPE_FADE_WHITE; @@ -1125,7 +1131,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE_FAST; } else { Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_SPIRIT_MEDALLION); - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_8; + play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; @@ -1138,20 +1144,20 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB gSaveContext.cutsceneIndex = 0xFFF1; play->transitionType = TRANS_TYPE_FADE_WHITE_FAST; } else { - play->nextEntranceIndex = ENTR_GRAVEYARD_8; + play->nextEntranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; } break; case 98: - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; break; case 99: - play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_3; + play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK; @@ -1174,7 +1180,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_BLACK; break; case 103: - play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF3; play->transitionType = TRANS_TYPE_FADE_BLACK; @@ -1182,14 +1188,14 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB case 104: switch (sTitleCsState) { case 0: - play->nextEntranceIndex = ENTR_SPIRIT_TEMPLE_BOSS_0; + play->nextEntranceIndex = ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF2; play->transitionType = TRANS_TYPE_FADE_BLACK; sTitleCsState++; break; case 1: - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_0; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF1; play->transitionType = TRANS_TYPE_FADE_BLACK; @@ -1205,7 +1211,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB } break; case 105: - play->nextEntranceIndex = ENTR_GRAVEYARD_0; + play->nextEntranceIndex = ENTR_GRAVEYARD_ENTRANCE; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF1; play->transitionType = TRANS_TYPE_FADE_BLACK; @@ -1259,7 +1265,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB } break; case 114: - play->nextEntranceIndex = ENTR_HYRULE_FIELD_3; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_WOODED_EXIT; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; break; @@ -1271,11 +1277,11 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB break; case 116: if (Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_SPIRIT_MEDALLION)) { - play->nextEntranceIndex = ENTR_GRAVEYARD_8; + play->nextEntranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; } else { - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_8; + play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; } @@ -1285,7 +1291,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB gSaveContext.gameMode = 3; Audio_SetSoundBanksMute(0x6F); play->linkAgeOnLoad = 0; - play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; gSaveContext.cutsceneIndex = 0xFFF7; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; @@ -1304,10 +1310,6 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE; break; } - - if (shouldSkipCommand && IS_RANDO) { - Entrance_OverrideCutsceneEntrance(cmd->base); - } } } @@ -1328,15 +1330,15 @@ void Cutscene_Command_TransitionFX(PlayState* play, CutsceneContext* csCtx, CsCm if (cmd->base == 1) { play->envCtx.screenFillColor[3] = 255.0f * temp; if ((temp == 0.0f) && (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0)) { - Audio_PlaySoundGeneral(NA_SE_SY_WHITE_OUT_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WHITE_OUT_S, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if ((temp == 0.0f) && - ((gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_0) || (gSaveContext.entranceIndex == ENTR_HYRULE_CASTLE_0) || - (gSaveContext.entranceIndex == ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0))) { - Audio_PlaySoundGeneral(NA_SE_EV_WHITE_OUT, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + ((gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_ENTRANCE) || (gSaveContext.entranceIndex == ENTR_CASTLE_GROUNDS_SOUTH_EXIT) || + (gSaveContext.entranceIndex == ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF))) { + Audio_PlaySoundGeneral(NA_SE_EV_WHITE_OUT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if ((temp == 0.0f) && (play->sceneNum == SCENE_INSIDE_GANONS_CASTLE)) { - func_800788CC(NA_SE_EV_WHITE_OUT); + Sfx_PlaySfxCentered2(NA_SE_EV_WHITE_OUT); } } else { play->envCtx.screenFillColor[3] = (1.0f - temp) * 255.0f; @@ -1602,7 +1604,7 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BONGO_BONGO, RG_SHADOW_MEDALLION); break; case 0x40: - getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GIFT_FROM_SAGES, RG_LIGHT_MEDALLION); + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GIFT_FROM_RAURU, RG_LIGHT_MEDALLION); break; case 0x72: getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS); @@ -2052,7 +2054,7 @@ void func_80068C3C(PlayState* play, CutsceneContext* csCtx) { csCtx->frames++; if (dREG(95) != 0) { - Cutscene_ProcessCommands(play, csCtx, D_8012D1F0); + Cutscene_ProcessCommands(play, csCtx, gDebugCutsceneScript); } else { Cutscene_ProcessCommands(play, csCtx, play->csCtx.segment); } @@ -2202,12 +2204,12 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) { } if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { - if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { + if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); - gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_0; + gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_EAST_EXIT; gSaveContext.cutsceneIndex = 0xFFF0; } else if (GameInteractor_Should(VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, ( - (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0) && + (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE) && LINK_IS_ADULT && Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) && Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) && @@ -2216,12 +2218,12 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) { ))) { Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); gSaveContext.cutsceneIndex = 0xFFF0; - } else if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { + } else if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_BRIDGE_EAST_EXIT) && !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(play, ITEM_OCARINA_FAIRY); } - gSaveContext.entranceIndex = ENTR_LOST_WOODS_0; + gSaveContext.entranceIndex = ENTR_LOST_WOODS_SOUTH_EXIT; gSaveContext.cutsceneIndex = 0xFFF0; } else if (GameInteractor_Should(VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, ( CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && @@ -2231,7 +2233,7 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) { (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) ))) { Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); - gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_0; + gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_ENTRANCE; gSaveContext.cutsceneIndex = 0xFFF8; } else if (!Flags_GetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO) && (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANON_BOSS)) { diff --git a/soh/src/code/z_elf_message.c b/soh/src/code/z_elf_message.c index e586c1bcc..91f00105f 100644 --- a/soh/src/code/z_elf_message.c +++ b/soh/src/code/z_elf_message.c @@ -1,6 +1,7 @@ #include "global.h" #include "z64elf_message.h" #include +#include "soh/OTRGlobals.h" ElfMessage sChildSariaMsgs[] = { ELF_MSG_STRENGTH_UPG(SKIP, 3, false, 0), diff --git a/soh/src/code/z_en_a_keep.c b/soh/src/code/z_en_a_keep.c index c0eded587..9b29b666e 100644 --- a/soh/src/code/z_en_a_keep.c +++ b/soh/src/code/z_en_a_keep.c @@ -122,8 +122,8 @@ void EnAObj_Init(Actor* thisx, PlayState* play) { thisx->focus.pos = thisx->world.pos; this->dyna.bgId = BGACTOR_NEG_ONE; - this->dyna.unk_160 = 0; - this->dyna.unk_15C = DPM_UNK; + this->dyna.interactFlags = 0; + this->dyna.transformFlags = DPM_UNK; thisx->uncullZoneDownward = 1200.0f; thisx->uncullZoneScale = 200.0f; @@ -234,7 +234,7 @@ void EnAObj_SetupBlockRot(EnAObj* this, s16 type) { void EnAObj_BlockRot(EnAObj* this, PlayState* play) { if (this->rotateState == 0) { - if (this->dyna.unk_160 != 0) { + if (this->dyna.interactFlags != 0) { this->rotateState++; this->rotateForTimer = 20; @@ -322,7 +322,7 @@ void EnAObj_Update(Actor* thisx, PlayState* play) { EnAObj* this = (EnAObj*)thisx; this->actionFunc(this, play); - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); if (this->dyna.actor.gravity != 0.0f) { if (this->dyna.actor.params != A_OBJ_BOULDER_FRAGMENT) { diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 90b535966..05e5785b9 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -4,6 +4,7 @@ #include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h" #include "textures/icon_item_static/icon_item_static.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -349,7 +350,6 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { f32 yOffset = 980.0f; f32 shadowScale = 6.0f; s32 getItemId = GI_NONE; - this->randoGiEntry = (GetItemEntry)GET_ITEM_NONE; this->randoCheck = (RandomizerCheck)RC_UNKNOWN_CHECK; this->itemEntry = (GetItemEntry)GET_ITEM_NONE; s16 spawnParam8000 = this->actor.params & 0x8000; @@ -492,13 +492,6 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->actor.shape.shadowAlpha = 180; this->actor.focus.pos = this->actor.world.pos; this->getItemId = GI_NONE; - this->randoCheck = Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams); - this->randoInf = RAND_INF_MAX; - - if (IS_RANDO && this->randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, getItemId); - this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; - } if (!spawnParam8000) { EnItem00_SetupAction(this, func_8001DFC8); @@ -587,7 +580,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { } if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) { - func_8002F554(&this->actor, play, getItemId); + Actor_OfferGetItemNearby(&this->actor, play, getItemId); } EnItem00_SetupAction(this, func_8001E5C8); @@ -830,7 +823,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { } else { sp3A = 1; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } if (sp3A || D_80157D94[0]) { @@ -955,7 +948,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { params = &this->actor.params; if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) { - func_8002F554(&this->actor, play, getItemId); + Actor_OfferGetItemNearby(&this->actor, play, getItemId); } switch (*params) { @@ -974,7 +967,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { } if ((*params <= ITEM00_RUPEE_RED) || (*params == ITEM00_RUPEE_ORANGE)) { - Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (getItemId != GI_NONE) { if (Actor_HasParent(&this->actor, play)) { Flags_SetCollectible(play, this->collectibleFlag); @@ -982,7 +975,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { } return; } else { - Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } Flags_SetCollectible(play, this->collectibleFlag); @@ -1182,36 +1175,58 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) { } } + +typedef enum { + PARTICLE_BRIGHT_GREEN, + PARTICLE_RED, + PARTICLE_CYAN, + PARTICLE_ORANGE, + PARTICLE_VIOLET, + PARTICLE_YELLOW, + PARTICLE_GREEN, + PARTICLE_GOLD, + PARTICLE_WHITE, + PARTICLE_DARK_BLUE, + PARTICLE_PINK, + PARTICLE_BRIGHT_RED, + PARTICLE_BLUE, +} Item00ParticleColors; + void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry giEntry) { - s16 color_slot; + s16 colorIndex; switch (giEntry.drawModIndex) { case MOD_NONE: switch (giEntry.drawItemId) { case ITEM_SONG_MINUET: - color_slot = 0; + colorIndex = PARTICLE_BRIGHT_GREEN; break; case ITEM_SONG_BOLERO: - color_slot = 1; + colorIndex = PARTICLE_RED; break; case ITEM_SONG_SERENADE: - color_slot = 2; + colorIndex = PARTICLE_CYAN; break; case ITEM_SONG_REQUIEM: - color_slot = 3; + colorIndex = PARTICLE_ORANGE; break; case ITEM_SONG_NOCTURNE: - color_slot = 4; + colorIndex = PARTICLE_VIOLET; break; case ITEM_SONG_PRELUDE: - color_slot = 5; + colorIndex = PARTICLE_YELLOW; break; case ITEM_STICK_UPGRADE_20: case ITEM_STICK_UPGRADE_30: - color_slot = 6; + colorIndex = PARTICLE_GREEN; break; case ITEM_NUT_UPGRADE_30: case ITEM_NUT_UPGRADE_40: - color_slot = 7; + colorIndex = PARTICLE_GOLD; + break; + case ITEM_BOTTLE: + case ITEM_MILK_BOTTLE: + case ITEM_LETTER_RUTO: + colorIndex = PARTICLE_WHITE; break; default: return; @@ -1222,13 +1237,41 @@ void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry case RG_MAGIC_SINGLE: case RG_MAGIC_DOUBLE: case RG_MAGIC_BEAN_PACK: - color_slot = 0; + case RG_BOTTLE_WITH_GREEN_POTION: + case RG_BOTTLE_WITH_BUGS: + case RG_GREG_RUPEE: + colorIndex = PARTICLE_BRIGHT_GREEN; + break; + case RG_BOTTLE_WITH_FISH: + colorIndex = PARTICLE_CYAN; + break; + case RG_BOTTLE_WITH_POE: + colorIndex = PARTICLE_VIOLET; + break; + case RG_BOTTLE_WITH_BIG_POE: + colorIndex = PARTICLE_YELLOW; + break; + case RG_DEKU_STICK_BAG: + colorIndex = PARTICLE_GREEN; + break; + case RG_DEKU_NUT_BAG: + colorIndex = PARTICLE_GOLD; break; case RG_DOUBLE_DEFENSE: - color_slot = 8; + colorIndex = PARTICLE_WHITE; break; case RG_PROGRESSIVE_BOMBCHUS: - color_slot = 9; + colorIndex = PARTICLE_DARK_BLUE; + break; + case RG_BOTTLE_WITH_FAIRY: + colorIndex = PARTICLE_PINK; + break; + case RG_BOTTLE_WITH_RED_POTION: + colorIndex = PARTICLE_BRIGHT_RED; + break; + case RG_BOTTLE_WITH_BLUE_FIRE: + case RG_BOTTLE_WITH_BLUE_POTION: + colorIndex = PARTICLE_BLUE; break; default: return; @@ -1239,39 +1282,45 @@ void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry } // Color of the circle for the particles - static Color_RGBA8 mainColors[10][3] = { - { 34, 255, 76 }, // Minuet, Bean Pack, and Magic Upgrades + static Color_RGBA8 mainColors[13][3] = { + { 34, 255, 76 }, // Minuet, Bean Pack, Magic Upgrades, Bottle with Green Potion, Bottle with Bugs, and Greg { 177, 35, 35 }, // Bolero - { 115, 251, 253 }, // Serenade + { 115, 251, 253 }, // Serenade and Bottle with Fish { 177, 122, 35 }, // Requiem - { 177, 28, 212 }, // Nocturne - { 255, 255, 92 }, // Prelude + { 177, 28, 212 }, // Nocturne and Bottle with Poe + { 255, 255, 92 }, // Prelude and Bottle with Big Poe { 31, 152, 49 }, // Stick Upgrade { 222, 182, 20 }, // Nut Upgrade - { 255, 255, 255 }, // Double Defense - { 19, 120, 182 } // Progressive Bombchu + { 255, 255, 255 }, // Double Defense, Empty Bottle, Bottle with Milk, and Bottle with Ruto's Letter + { 19, 120, 182 }, // Progressive Bombchu + { 255, 205, 255 }, // Bottle with Fairy + { 255, 118, 118 }, // Bottle with Red Potion + { 154, 204, 255 } // Bottle with Blue Fire and Bottle with Blue Potion }; // Color of the faded flares stretching off the particles - static Color_RGBA8 flareColors[10][3] = { - { 30, 110, 30 }, // Minuet, Bean Pack, and Magic Upgrades + static Color_RGBA8 flareColors[13][3] = { + { 30, 110, 30 }, // Minuet, Bean Pack, Magic Upgrades, Bottle with Green Potion, Bottle with Bugs, and Greg { 90, 10, 10 }, // Bolero - { 35, 35, 177 }, // Serenade + { 35, 35, 177 }, // Serenade and Bottle with Fish { 70, 20, 10 }, // Requiem - { 100, 20, 140 }, // Nocturne - { 100, 100, 10 }, // Prelude + { 100, 20, 140 }, // Nocturne and Bottle with Poe + { 100, 100, 10 }, // Prelude and Bottle with Big Poe { 5, 50, 10 }, // Stick Upgrade { 150, 100, 5 }, // Nut Upgrade - { 154, 154, 154 }, // Double Defense - { 204, 102, 0 } // Progressive Bombchu + { 154, 154, 154 }, // Double Defense, Empty Bottle, Bottle with Milk, and Bottle with Ruto's Letter + { 204, 102, 0 }, // Progressive Bombchu + { 216, 70, 216 }, // Bottle with Fairy + { 90, 10, 10 }, // Bottle with Red Potion + { 35, 35, 177 } // Bottle with Blue Fire }; static Vec3f velocity = { 0.0f, 0.0f, 0.0f }; static Vec3f accel = { 0.0f, 0.0f, 0.0f }; Color_RGBA8 primColor; Color_RGBA8 envColor; - Color_RGBA8_Copy(&primColor, &mainColors[color_slot]); - Color_RGBA8_Copy(&envColor, &flareColors[color_slot]); + Color_RGBA8_Copy(&primColor, &mainColors[colorIndex]); + Color_RGBA8_Copy(&envColor, &flareColors[colorIndex]); Vec3f pos; // Make particles more compact for shop items and use a different height offset for them. diff --git a/soh/src/code/z_fbdemo_circle.c b/soh/src/code/z_fbdemo_circle.c index 98183023a..9a85dcf05 100644 --- a/soh/src/code/z_fbdemo_circle.c +++ b/soh/src/code/z_fbdemo_circle.c @@ -1,5 +1,7 @@ #include "global.h" #include +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" // unused Gfx sCircleNullDList[] = { @@ -9,31 +11,35 @@ Gfx sCircleNullDList[] = { //#include "code/fbdemo_circle/z_fbdemo_circle.c" #include "code/fbdemo_circle/z_fbdemo_circle.h" -Gfx __sCircleDList[] = { - gsDPPipeSync(), // 0 - gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | // 1 +Gfx sTransCircleDL[] = { + gsDPPipeSync(), + gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH), - gsSPSetGeometryMode(G_SHADE | G_SHADING_SMOOTH), // 2 - gsDPSetOtherMode(G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | // 3 + gsSPSetGeometryMode(G_SHADE | G_SHADING_SMOOTH), + gsDPSetOtherMode(G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE | G_PM_NPRIMITIVE, - G_AC_NONE | G_ZS_PIXEL | G_RM_XLU_SURF | G_RM_XLU_SURF2), // 4 - gsDPSetCombineMode(G_CC_BLENDPEDECALA, G_CC_BLENDPEDECALA), // 5 - gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON), // 6 - gsDPLoadTextureBlock(SEG_ADDR(8, 0), G_IM_FMT_I, G_IM_SIZ_8b, 16, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, // 7 + G_AC_NONE | G_ZS_PIXEL | G_RM_XLU_SURF | G_RM_XLU_SURF2), + gsDPSetCombineMode(G_CC_BLENDPEDECALA, G_CC_BLENDPEDECALA), + gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON), + gsDPLoadTextureBlock(SEG_ADDR(8, 0), G_IM_FMT_I, G_IM_SIZ_8b, 16, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_CLAMP, 4, 6, G_TX_NOLOD, G_TX_NOLOD), - gsSPDisplayList(SEG_ADDR(9, 0)), // 8 - gsSPVertex(sTransCircleVtx, 32, 0), // 9 - gsSP2Triangles(0, 1, 2, 0, 1, 3, 4, 0), // 10 - gsSP2Triangles(3, 5, 6, 0, 5, 7, 8, 0), // 11 - gsSP2Triangles(7, 9, 10, 0, 9, 11, 12, 0), // 12 - gsSP2Triangles(11, 13, 14, 0, 13, 15, 16, 0), // 13 - gsSP2Triangles(15, 17, 18, 0, 17, 19, 20, 0), // 14 - gsSP2Triangles(19, 21, 22, 0, 21, 23, 24, 0), // 15 - gsSP2Triangles(23, 25, 26, 0, 25, 27, 28, 0), // 16 - gsSP1Triangle(27, 29, 30, 0), // 17 - gsSPVertex(&sTransCircleVtx[31], 3, 0), // 18 - gsSP1Triangle(0, 1, 2, 0), // 19 - gsSPEndDisplayList(), // 20 + gsSPDisplayList(SEG_ADDR(9, 0)), + // OTRTODO: Add proper gsSPVertexOTRFilepath macro + { G_VTX_OTR_FILEPATH << 24, (uintptr_t)sTransCircleVtx }, + { 32, 0 << 16 | 0 }, + gsSP2Triangles(0, 1, 2, 0, 1, 3, 4, 0), + gsSP2Triangles(3, 5, 6, 0, 5, 7, 8, 0), + gsSP2Triangles(7, 9, 10, 0, 9, 11, 12, 0), + gsSP2Triangles(11, 13, 14, 0, 13, 15, 16, 0), + gsSP2Triangles(15, 17, 18, 0, 17, 19, 20, 0), + gsSP2Triangles(19, 21, 22, 0, 21, 23, 24, 0), + gsSP2Triangles(23, 25, 26, 0, 25, 27, 28, 0), + gsSP1Triangle(27, 29, 30, 0), + // OTRTODO: Add proper gsSPVertexOTRFilepath macro + { G_VTX_OTR_FILEPATH << 24, (uintptr_t)sTransCircleVtx }, + { 3, 0 << 16 | 31 }, + gsSP1Triangle(0, 1, 2, 0), + gsSPEndDisplayList(), }; void TransitionCircle_Start(void* thisx) { @@ -84,7 +90,7 @@ void TransitionCircle_Start(void* thisx) { } else { this->texY = 0x1F4; if (this->appearanceType == TCA_RIPPLE) { - Audio_PlaySoundGeneral(NA_SE_OC_SECRET_WARP_OUT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_OC_SECRET_WARP_OUT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } guPerspective(&this->projection, &this->normal, 60.0f, (4.0f / 3.0f), 10.0f, 12800.0f, 1.0f); @@ -109,7 +115,7 @@ void TransitionCircle_Update(void* thisx, s32 updateRate) { if (this->direction != 0) { if (this->texY == 0) { if (this->appearanceType == TCA_RIPPLE) { - Audio_PlaySoundGeneral(NA_SE_OC_SECRET_WARP_IN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_OC_SECRET_WARP_IN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } this->texY += this->speed * 3 / updateRate; @@ -147,7 +153,7 @@ void TransitionCircle_Draw(void* thisx, Gfx** gfxP) { this->frame ^= 1; gDPPipeSync(gfx++); - texScroll = Gfx_BranchTexScroll(&gfx, this->texX, this->texY, 0x10, 0x40); + texScroll = Gfx_BranchTexScroll(&gfx, this->texX, this->texY, 16, 64); gSPSegment(gfx++, 9, texScroll); gSPSegment(gfx++, 8, this->texture); gDPSetColor(gfx++, G_SETPRIMCOLOR, this->color.rgba); @@ -172,15 +178,7 @@ void TransitionCircle_Draw(void* thisx, Gfx** gfxP) { guTranslate(&modelView[2], tPos, tPos, 0.0f); gSPMatrix(gfx++, &modelView[2], G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); } - - // OTRTODO: This is an ugly hack but it will do for now... - Vtx* vtx = ResourceMgr_LoadVtxByName(sTransCircleVtx); - Gfx var1 = gsSPVertex(vtx, 32, 0); - Gfx var2 = gsSPVertex(&vtx[31], 3, 0); - __sCircleDList[0xe] = var1; - __sCircleDList[0x17] = var2; - - gSPDisplayList(gfx++, __sCircleDList); + gSPDisplayList(gfx++, sTransCircleDL); gDPPipeSync(gfx++); *gfxP = gfx; } diff --git a/soh/src/code/z_fbdemo_wipe1.c b/soh/src/code/z_fbdemo_wipe1.c index 6bc3fb039..1ffefabb1 100644 --- a/soh/src/code/z_fbdemo_wipe1.c +++ b/soh/src/code/z_fbdemo_wipe1.c @@ -3,25 +3,30 @@ #include "code/fbdemo_wipe1/z_fbdemo_wipe1.h" -Gfx sWipeDList[] = { +Gfx sTransWipeDL[] = { gsDPPipeSync(), gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH), - gsSPSetGeometryMode(G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH), + // SOH [Port] Removed G_ZBUFFER as gsDPSetPrimDepth is unimplemented in LUS. + // This should have the same effect of ignoring previous depth values + // LUSTODO: Add back once gsDPSetPrimDepth is implemented + gsSPSetGeometryMode(/* G_ZBUFFER | */ G_SHADE | G_SHADING_SMOOTH), gsDPSetOtherMode(G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_PERSP | G_CYC_2CYCLE | G_PM_1PRIMITIVE, G_AC_NONE | G_ZS_PRIM | G_RM_PASS | G_RM_AA_ZB_TEX_EDGE2), gsDPSetCombineLERP(TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, COMBINED, 0, PRIMITIVE, 0, COMBINED, 0, PRIMITIVE, 0), gsDPSetPrimDepth(0, 0), - gsDPLoadTextureBlock_4b(sTransWipeTex, G_IM_FMT_I, 64, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, 6, 6, - 11, G_TX_NOLOD), + gsDPLoadTextureBlock_4b(sTransWipeTex, G_IM_FMT_I, 64, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, 6, + 6, 11, G_TX_NOLOD), gsDPLoadMultiBlock_4b(sTransWipeTex, 0x0100, 1, G_IM_FMT_I, 64, 64, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, 6, 6, 11, 1), gsDPSetTextureLUT(G_TT_NONE), gsSPTexture(0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON), gsSPDisplayList(SEG_ADDR(8, 0)), - gsSPVertex(sTransWipeVtx, 25, 0), + // OTRTODO: Add proper gsSPVertexOTRFilepath macro + { G_VTX_OTR_FILEPATH << 24, (uintptr_t)sTransWipeVtx }, + { 25, 0 << 16 | 0 }, gsSP2Triangles(0, 1, 2, 0, 1, 3, 4, 0), gsSP2Triangles(5, 6, 7, 0, 6, 8, 9, 0), gsSP2Triangles(8, 10, 11, 0, 10, 12, 13, 0), @@ -32,7 +37,7 @@ Gfx sWipeDList[] = { }; // unused. -Gfx sWipeSyncDList[] = { +Gfx sTransWipeSyncDL[] = { gsDPPipeSync(), gsSPEndDisplayList(), }; @@ -88,18 +93,17 @@ void TransitionWipe_Draw(void* thisx, Gfx** gfxP) { Mtx* modelView; TransitionWipe* this = (TransitionWipe*)thisx; s32 pad[4]; - Gfx* tex; - Gfx* wipeDl = sWipeDList; + Gfx* texScroll; modelView = this->modelView[this->frame]; - this->frame ^= 1; + guScale(&modelView[0], 0.56f, 0.56f, 1.0f); guRotate(&modelView[1], 0.0f, 0.0f, 0.0f, 1.0f); guTranslate(&modelView[2], 0.0f, 0.0f, 0.0f); gDPPipeSync(gfx++); - tex = Gfx_BranchTexScroll(&gfx, this->texX, this->texY, 0, 0); - gSPSegment(gfx++, 8, tex); + texScroll = Gfx_BranchTexScroll(&gfx, this->texX, this->texY, 0, 0); + gSPSegment(gfx++, 8, texScroll); gDPSetPrimColor(gfx++, 0, 0x80, this->color.r, this->color.g, this->color.b, 255); gSPMatrix(gfx++, &this->projection, G_MTX_LOAD | G_MTX_PROJECTION); gSPPerspNormalize(gfx++, this->normal); @@ -107,7 +111,7 @@ void TransitionWipe_Draw(void* thisx, Gfx** gfxP) { gSPMatrix(gfx++, &modelView[0], G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPMatrix(gfx++, &modelView[1], G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); gSPMatrix(gfx++, &modelView[2], G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); - gSPDisplayList(gfx++, sWipeDList); + gSPDisplayList(gfx++, sTransWipeDL); gDPPipeSync(gfx++); *gfxP = gfx; } diff --git a/soh/src/code/z_fcurve_data_skelanime.c b/soh/src/code/z_fcurve_data_skelanime.c index c75450be2..3daa6528a 100644 --- a/soh/src/code/z_fcurve_data_skelanime.c +++ b/soh/src/code/z_fcurve_data_skelanime.c @@ -1,5 +1,6 @@ #include "global.h" #include +#include "soh/ResourceManagerHelpers.h" void SkelCurve_Clear(SkelAnimeCurve* skelCurve) { skelCurve->limbCount = 0; diff --git a/soh/src/code/z_game_over.c b/soh/src/code/z_game_over.c index 2d46a1899..1850133aa 100644 --- a/soh/src/code/z_game_over.c +++ b/soh/src/code/z_game_over.c @@ -1,4 +1,7 @@ #include "global.h" +#include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" void GameOver_Init(PlayState* play) { play->gameOverCtx.state = GAMEOVER_INACTIVE; @@ -33,7 +36,7 @@ void GameOver_Update(PlayState* play) { gSaveContext.eventInf[1] &= ~1; // search inventory for spoiling items and revert if necessary - if (!(IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE))) { + if (GameInteractor_Should(VB_REVERT_SPOILING_ITEMS, true)) { for (i = 0; i < ARRAY_COUNT(gSpoilingItems); i++) { if (INV_CONTENT(ITEM_POCKET_EGG) == gSpoilingItems[i]) { INV_CONTENT(gSpoilingItemReverts[i]) = gSpoilingItemReverts[i]; diff --git a/soh/src/code/code_80097A00.c b/soh/src/code/z_inventory.c similarity index 100% rename from soh/src/code/code_80097A00.c rename to soh/src/code/z_inventory.c diff --git a/soh/src/code/z_kaleido_scope_call.c b/soh/src/code/z_kaleido_scope_call.c index d95819187..196e20041 100644 --- a/soh/src/code/z_kaleido_scope_call.c +++ b/soh/src/code/z_kaleido_scope_call.c @@ -4,7 +4,7 @@ void (*sKaleidoScopeUpdateFunc)(PlayState* play); void (*sKaleidoScopeDrawFunc)(PlayState* play); -f32 gBossMarkScale; +f32 gBossMarkScale = 1.0f; u32 D_8016139C; PauseMapMarksData* gLoadedPauseMarkDataTable; diff --git a/soh/src/code/z_kankyo.c b/soh/src/code/z_kankyo.c index 90ac9135f..6e3736b77 100644 --- a/soh/src/code/z_kankyo.c +++ b/soh/src/code/z_kankyo.c @@ -4,6 +4,8 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh/frame_interpolation.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" typedef enum { /* 0 */ LENS_FLARE_CIRCLE0, @@ -914,10 +916,10 @@ void Environment_Update(PlayState* play, EnvironmentContext* envCtx, LightContex osSyncPrintf("\nnext_zelda_time=[%x]", ((void)0, gSaveContext.nextDayTime)); if (((void)0, gSaveContext.nextDayTime) == 0xFF0E) { - func_80078884(NA_SE_EV_CHICKEN_CRY_M); + Sfx_PlaySfxCentered(NA_SE_EV_CHICKEN_CRY_M); gSaveContext.nextDayTime = 0xFFFF; } else if (((void)0, gSaveContext.nextDayTime) == 0xFF0D) { - func_800788CC(NA_SE_EV_DOG_CRY_EVENING); + Sfx_PlaySfxCentered2(NA_SE_EV_DOG_CRY_EVENING); gSaveContext.nextDayTime = 0xFFFF; } } @@ -1322,7 +1324,7 @@ void Environment_DrawSunAndMoon(PlayState* play) { play->envCtx.sunPos.z = +(Math_CosS(((void)0, gSaveContext.dayTime) - 0x8000) * 20.0f) * 25.0f; } - if (gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_0 || ((void)0, gSaveContext.sceneSetupIndex) != 5) { + if (gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN || ((void)0, gSaveContext.sceneSetupIndex) != 5) { Matrix_Translate(play->view.eye.x + play->envCtx.sunPos.x, play->view.eye.y + play->envCtx.sunPos.y, play->view.eye.z + play->envCtx.sunPos.z, MTXMODE_NEW); @@ -2004,7 +2006,7 @@ void Environment_PlaySceneSequence(PlayState* play) { play->envCtx.unk_E0 = 0xFF; // both lost woods exits on the bridge from kokiri to hyrule field - if (((void)0, gSaveContext.entranceIndex) == ENTR_LOST_WOODS_8 || ((void)0, gSaveContext.entranceIndex) == ENTR_LOST_WOODS_9) { + if (((void)0, gSaveContext.entranceIndex) == ENTR_LOST_WOODS_BRIDGE_WEST_EXIT || ((void)0, gSaveContext.entranceIndex) == ENTR_LOST_WOODS_BRIDGE_EAST_EXIT) { Audio_PlayNatureAmbienceSequence(NATURE_ID_KOKIRI_REGION); } else if (((void)0, gSaveContext.forcedSeqId) != NA_BGM_GENERAL_SFX) { if (!Environment_IsForcedSequenceDisabled()) { @@ -2076,7 +2078,7 @@ void func_80075B44(PlayState* play) { break; case 2: if (gSaveContext.dayTime > 0xC000) { - func_800788CC(NA_SE_EV_DOG_CRY_EVENING); + Sfx_PlaySfxCentered2(NA_SE_EV_DOG_CRY_EVENING); play->envCtx.unk_E0++; } break; @@ -2105,7 +2107,7 @@ void func_80075B44(PlayState* play) { gSaveContext.totalDays++; gSaveContext.bgsDayCount++; gSaveContext.dogIsLost = true; - func_80078884(NA_SE_EV_CHICKEN_CRY_M); + Sfx_PlaySfxCentered(NA_SE_EV_CHICKEN_CRY_M); if ((Inventory_ReplaceItem(play, ITEM_WEIRD_EGG, ITEM_CHICKEN) || Inventory_HatchPocketCucco(play)) && play->csCtx.state == 0 && !Player_InCsMode(play)) { @@ -2546,22 +2548,22 @@ void Environment_WarpSongLeave(PlayState* play) { gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; switch (play->nextEntranceIndex) { - case ENTR_DEATH_MOUNTAIN_CRATER_0: + case ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT: Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DEATH_MOUNTAIN_CRATER); break; - case ENTR_LAKE_HYLIA_0: + case ENTR_LAKE_HYLIA_NORTH_EXIT: Flags_SetEventChkInf(EVENTCHKINF_ENTERED_LAKE_HYLIA); break; - case ENTR_DESERT_COLOSSUS_0: + case ENTR_DESERT_COLOSSUS_EAST_EXIT: Flags_SetEventChkInf(EVENTCHKINF_ENTERED_DESERT_COLOSSUS); break; - case ENTR_GRAVEYARD_0: + case ENTR_GRAVEYARD_ENTRANCE: Flags_SetEventChkInf(EVENTCHKINF_ENTERED_GRAVEYARD); break; - case ENTR_TEMPLE_OF_TIME_0: + case ENTR_TEMPLE_OF_TIME_ENTRANCE: Flags_SetEventChkInf(EVENTCHKINF_ENTERED_TEMPLE_OF_TIME); break; - case ENTR_SACRED_FOREST_MEADOW_0: + case ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT: break; } } diff --git a/soh/src/code/z_lib.c b/soh/src/code/z_lib.c index 57f1312dd..6b691df44 100644 --- a/soh/src/code/z_lib.c +++ b/soh/src/code/z_lib.c @@ -572,14 +572,17 @@ void Color_RGBA8_Copy(Color_RGBA8* dst, Color_RGBA8* src) { dst->a = src->a; } -void func_80078884(u16 sfxId) { - Audio_PlaySoundGeneral(sfxId, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); +void Sfx_PlaySfxCentered(u16 sfxId) { + Audio_PlaySoundGeneral(sfxId, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } -void func_800788CC(u16 sfxId) { - Audio_PlaySoundGeneral(sfxId, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); +void Sfx_PlaySfxCentered2(u16 sfxId) { + Audio_PlaySoundGeneral(sfxId, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } -void func_80078914(Vec3f* arg0, u16 sfxId) { - Audio_PlaySoundGeneral(sfxId, arg0, 4, &D_801333E0, &D_801333E0, &D_801333E8); +void Sfx_PlaySfxAtPos(Vec3f* arg0, u16 sfxId) { + Audio_PlaySoundGeneral(sfxId, arg0, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } diff --git a/soh/src/code/z_lifemeter.c b/soh/src/code/z_lifemeter.c index 3cb9d4715..52742bc62 100644 --- a/soh/src/code/z_lifemeter.c +++ b/soh/src/code/z_lifemeter.c @@ -1,6 +1,7 @@ #include "global.h" #include "textures/parameter_static/parameter_static.h" #include "soh/frame_interpolation.h" +#include "soh/OTRGlobals.h" s16 Top_LM_Margin = 0; s16 Left_LM_Margin = 0; @@ -648,7 +649,7 @@ void HealthMeter_HandleCriticalAlarm(PlayState* play) { interfaceCtx->unk_22C = 0; if (CVarGetInteger(CVAR_ENHANCEMENT("LowHpAlarm"), 0) == 0 && !Player_InCsMode(play) && (play->pauseCtx.state == 0) && (play->pauseCtx.debugState == 0) && HealthMeter_IsCritical() && !Play_InCsMode(play)) { - func_80078884(NA_SE_SY_HITPOINT_ALARM); + Sfx_PlaySfxCentered(NA_SE_SY_HITPOINT_ALARM); } } } else { diff --git a/soh/src/code/z_lights.c b/soh/src/code/z_lights.c index aed55eda0..d45d10cc9 100644 --- a/soh/src/code/z_lights.c +++ b/soh/src/code/z_lights.c @@ -5,6 +5,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "soh/frame_interpolation.h" +#include "soh/OTRGlobals.h" #define LIGHTS_BUFFER_SIZE 32 //#define LIGHTS_BUFFER_SIZE 1024 // Kill me diff --git a/soh/src/code/z_malloc.c b/soh/src/code/z_malloc.c index acd4429c0..a44c1e47d 100644 --- a/soh/src/code/z_malloc.c +++ b/soh/src/code/z_malloc.c @@ -106,5 +106,5 @@ void ZeldaArena_Cleanup() { } u8 ZeldaArena_IsInitalized() { - return __osMallocIsInitalized(&sZeldaArena); + return __osMallocIsInitialized(&sZeldaArena); } diff --git a/soh/src/code/z_map_exp.c b/soh/src/code/z_map_exp.c index e05c2a6b2..be358f075 100644 --- a/soh/src/code/z_map_exp.c +++ b/soh/src/code/z_map_exp.c @@ -5,6 +5,7 @@ #include "textures/map_i_static/map_i_static.h" #include "textures/map_grand_static/map_grand_static.h" #include +#include "soh/OTRGlobals.h" MapData* gMapData; @@ -810,10 +811,10 @@ void Minimap_Draw(PlayState* play) { if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_L) && !Play_InCsMode(play) && enableMapToggle) { osSyncPrintf("Game_play_demo_mode_check=%d\n", Play_InCsMode(play)); // clang-format off - if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &D_801333D4, 4, - &D_801333E0, &D_801333E0, &D_801333E8); } - else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &D_801333D4, 4, - &D_801333E0, &D_801333E0, &D_801333E8); } + if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } + else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } // clang-format on R_MINIMAP_DISABLED ^= 1; } @@ -965,10 +966,10 @@ void Minimap_Draw(PlayState* play) { if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_L) && !Play_InCsMode(play) && enableMapToggle) { // clang-format off - if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &D_801333D4, 4, - &D_801333E0, &D_801333E0, &D_801333E8); } - else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &D_801333D4, 4, - &D_801333E0, &D_801333E0, &D_801333E8); } + if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } + else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } // clang-format on R_MINIMAP_DISABLED ^= 1; } diff --git a/soh/src/code/z_map_mark.c b/soh/src/code/z_map_mark.c index df8ef4464..1831b8fdd 100644 --- a/soh/src/code/z_map_mark.c +++ b/soh/src/code/z_map_mark.c @@ -1,6 +1,8 @@ #include "global.h" #include "vt.h" #include "textures/parameter_static/parameter_static.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" typedef struct { /* 0x00 */ void* texture; diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 53b2bb943..e6b944a73 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -7,6 +7,7 @@ #include "textures/parameter_static/parameter_static.h" #include "textures/message_static/message_static.h" #include "textures/message_texture_static/message_texture_static.h" +#include "soh/Enhancements/cosmetics/CosmeticsEditor.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -154,7 +155,7 @@ u8 Message_ShouldAdvance(PlayState* play) { : CHECK_BTN_ALL(input->press.button, BTN_B); if (CHECK_BTN_ALL(input->press.button, BTN_A) || isB_Held || CHECK_BTN_ALL(input->press.button, BTN_CUP)) { - Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_PASS, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_PASS, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } return CHECK_BTN_ALL(input->press.button, BTN_A) || isB_Held || CHECK_BTN_ALL(input->press.button, BTN_CUP); } @@ -179,7 +180,7 @@ void Message_CloseTextbox(PlayState* play) { msgCtx->stateTimer = 2; msgCtx->msgMode = MSGMODE_TEXT_CLOSING; msgCtx->textboxEndType = TEXTBOX_ENDTYPE_DEFAULT; - Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -195,7 +196,7 @@ void Message_HandleChoiceSelection(PlayState* play, u8 numChoices) { if (msgCtx->choiceIndex > 128) { msgCtx->choiceIndex = 0; } else { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else if ((input->rel.stick_y <= -30 && !sAnalogStickHeld) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) { sAnalogStickHeld = true; @@ -203,7 +204,7 @@ void Message_HandleChoiceSelection(PlayState* play, u8 numChoices) { if (msgCtx->choiceIndex > numChoices) { msgCtx->choiceIndex = numChoices; } else { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else if (ABS(input->rel.stick_y) < 30) { sAnalogStickHeld = false; @@ -367,6 +368,80 @@ void Message_FindCreditsMessage(PlayState* play, u16 textId) { } } +#pragma region [SoH] Cosmetics + +#define MESSAGE_COSMETICS_HANDLE_COLOR(id) \ + if (CVarGetInteger(CVAR_COSMETIC("Message." id ".Changed"), 0)) { \ + Color_RGBA8 color = CVarGetColor(CVAR_COSMETIC("Message." id ".Value"), CosmeticsEditor_GetDefaultValue("Message." id)); \ + msgCtx->textColorR = color.r; \ + msgCtx->textColorG = color.g; \ + msgCtx->textColorB = color.b; \ + } + +void Cosmetics_MaybeSetTextColor(MessageContext* msgCtx, u16 colorParameter) { + switch (colorParameter) { + case MSGCOL_RED: + if (msgCtx->textBoxType == TEXTBOX_TYPE_WOODEN) { + MESSAGE_COSMETICS_HANDLE_COLOR("Red.Wooden") + } else { + MESSAGE_COSMETICS_HANDLE_COLOR("Red.Normal") + } + break; + case MSGCOL_ADJUSTABLE: + if (msgCtx->textBoxType == TEXTBOX_TYPE_WOODEN) { + MESSAGE_COSMETICS_HANDLE_COLOR("Adjustable.Wooden") + } else { + MESSAGE_COSMETICS_HANDLE_COLOR("Adjustable.Normal") + } + break; + case MSGCOL_BLUE: + if (msgCtx->textBoxType == TEXTBOX_TYPE_WOODEN) { + MESSAGE_COSMETICS_HANDLE_COLOR("Blue.Wooden") + } else { + MESSAGE_COSMETICS_HANDLE_COLOR("Blue.Normal") + } + break; + case MSGCOL_LIGHTBLUE: + if (msgCtx->textBoxType == TEXTBOX_TYPE_WOODEN) { + MESSAGE_COSMETICS_HANDLE_COLOR("LightBlue.Wooden") + } else if (msgCtx->textBoxType == TEXTBOX_TYPE_NONE_NO_SHADOW) { + MESSAGE_COSMETICS_HANDLE_COLOR("LightBlue.NoneNoShadow") + } else { + MESSAGE_COSMETICS_HANDLE_COLOR("LightBlue.Normal") + } + break; + case MSGCOL_PURPLE: + if (msgCtx->textBoxType == TEXTBOX_TYPE_WOODEN) { + MESSAGE_COSMETICS_HANDLE_COLOR("Purple.Wooden") + } else { + MESSAGE_COSMETICS_HANDLE_COLOR("Purple.Normal") + } + break; + case MSGCOL_YELLOW: + if (msgCtx->textBoxType == TEXTBOX_TYPE_WOODEN) { + MESSAGE_COSMETICS_HANDLE_COLOR("Yellow.Wooden") + } else { + MESSAGE_COSMETICS_HANDLE_COLOR("Yellow.Normal") + } + break; + case MSGCOL_BLACK: + MESSAGE_COSMETICS_HANDLE_COLOR("Black") + break; + case MSGCOL_DEFAULT: + default: + if (msgCtx->textBoxType == TEXTBOX_TYPE_NONE_NO_SHADOW) { + MESSAGE_COSMETICS_HANDLE_COLOR("Default.NoneNoShadow") + } else { + MESSAGE_COSMETICS_HANDLE_COLOR("Default.Normal") + } + break; + } +} + +#undef MESSAGE_COSMETICS_HANDLE_COLOR + +#pragma endregion + void Message_SetTextColor(MessageContext* msgCtx, u16 colorParameter) { switch (colorParameter) { case MSGCOL_RED: @@ -451,6 +526,7 @@ void Message_SetTextColor(MessageContext* msgCtx, u16 colorParameter) { } break; } + Cosmetics_MaybeSetTextColor(msgCtx, colorParameter); } void Message_DrawTextboxIcon(PlayState* play, Gfx** p, s16 x, s16 y) { @@ -724,7 +800,7 @@ u16 Message_DrawItemIcon(PlayState* play, u16 itemId, Gfx** p, u16 i) { MessageContext* msgCtx = &play->msgCtx; // clang-format off - if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } + if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } // clang-format on gDPPipeSync(gfx++); @@ -853,6 +929,8 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) { msgCtx->textColorR = msgCtx->textColorG = msgCtx->textColorB = 255; } + Cosmetics_MaybeSetTextColor(msgCtx, MSGCOL_DEFAULT); + msgCtx->unk_E3D0 = 0; charTexIdx = 0; @@ -882,7 +960,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) { case MESSAGE_BOX_BREAK: if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { if (!sTextboxSkipped) { - Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); msgCtx->msgMode = MSGMODE_TEXT_AWAIT_NEXT; Font_LoadMessageBoxIcon(font, TEXTBOX_ICON_TRIANGLE); } else { @@ -899,7 +977,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) { case MESSAGE_TEXTID: msgCtx->textboxEndType = TEXTBOX_ENDTYPE_HAS_NEXT; if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { - Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); msgCtx->msgMode = MSGMODE_TEXT_DONE; Font_LoadMessageBoxIcon(font, TEXTBOX_ICON_TRIANGLE); } @@ -970,8 +1048,8 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) { // "Sound (SE)" osSyncPrintf("サウンド(SE)\n"); sfxHi = msgCtx->msgBufDecoded[i + 1] << 8; - Audio_PlaySoundGeneral(sfxHi | msgCtx->msgBufDecoded[i + 2], &D_801333D4, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxHi | msgCtx->msgBufDecoded[i + 2], &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } i += 2; break; @@ -980,7 +1058,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) { break; case MESSAGE_BACKGROUND: // clang-format off - if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } + if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } // clang-format on gDPPipeSync(gfx++); gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); @@ -1062,8 +1140,8 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) { if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { msgCtx->msgMode = MSGMODE_TEXT_DONE; if (msgCtx->textboxEndType == TEXTBOX_ENDTYPE_DEFAULT) { - Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_END, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_END, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); Font_LoadMessageBoxIcon(font, TEXTBOX_ICON_SQUARE); if (play->csCtx.state == 0) { Interface_SetDoAction(play, DO_ACTION_RETURN); @@ -1094,7 +1172,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) { return; case MESSAGE_PERSISTENT: if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { - Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); msgCtx->msgMode = MSGMODE_TEXT_DONE; msgCtx->textboxEndType = TEXTBOX_ENDTYPE_PERSISTENT; } @@ -1105,14 +1183,14 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) { msgCtx->msgMode = MSGMODE_TEXT_DONE; msgCtx->textboxEndType = TEXTBOX_ENDTYPE_EVENT; Font_LoadMessageBoxIcon(font, TEXTBOX_ICON_TRIANGLE); - Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_END, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_END, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } *gfxP = gfx; return; default: if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING && i + 1 == msgCtx->textDrawPos && msgCtx->textDelayTimer == msgCtx->textDelay) { - Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } Message_DrawTextChar(play, &font->charTexBuf[charTexIdx], &gfx); charTexIdx += FONT_CHAR_TEX_SIZE; @@ -1812,7 +1890,7 @@ void Message_StartOcarina(PlayState* play, u16 ocarinaActionId) { osSyncPrintf("ocarina_set 000000000000000000 = %d\n", ocarinaActionId); msgCtx->ocarinaAction = ocarinaActionId; if (ocarinaActionId >= OCARINA_ACTION_CHECK_SARIA && ocarinaActionId <= OCARINA_ACTION_CHECK_STORMS) { - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } if (ocarinaActionId == OCARINA_ACTION_SCARECROW_PLAYBACK) { Message_OpenText(play, 0x86F); // Ocarina @@ -2259,8 +2337,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) { if (msgCtx->ocarinaStaff->state < OCARINA_SONG_SARIAS || msgCtx->ocarinaStaff->state == OCARINA_SONG_SCARECROW) { Audio_OcaSetInstrument(0); - Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); msgCtx->msgMode = MSGMODE_OCARINA_STARTING; } else { // "Ocarina_Flog Correct Example Performance" @@ -2269,15 +2347,15 @@ void Message_DrawMain(PlayState* play, Gfx** p) { msgCtx->msgMode = MSGMODE_SONG_PLAYED; msgCtx->textBoxType = TEXTBOX_TYPE_OCARINA; msgCtx->stateTimer = 10; - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Interface_ChangeAlpha(1); } } else if (msgCtx->ocarinaAction == OCARINA_ACTION_CHECK_SCARECROW) { if (msgCtx->ocarinaStaff->state < OCARINA_SONG_SCARECROW) { Audio_OcaSetInstrument(0); - Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); msgCtx->stateTimer = 10; msgCtx->msgMode = MSGMODE_OCARINA_FAIL; } else { @@ -2287,8 +2365,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) { msgCtx->msgMode = MSGMODE_SONG_PLAYED; msgCtx->textBoxType = TEXTBOX_TYPE_OCARINA; msgCtx->stateTimer = 10; - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Interface_ChangeAlpha(1); } } else if (msgCtx->ocarinaAction == OCARINA_ACTION_FREE_PLAY) { @@ -2298,23 +2376,23 @@ void Message_DrawMain(PlayState* play, Gfx** p) { msgCtx->msgMode = MSGMODE_SONG_PLAYED; msgCtx->textBoxType = TEXTBOX_TYPE_OCARINA; msgCtx->stateTimer = 10; - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } Interface_ChangeAlpha(1); } else { Audio_OcaSetInstrument(0); - Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); msgCtx->msgMode = MSGMODE_OCARINA_STARTING; } } else if (msgCtx->ocarinaStaff->state == 0xFF) { Audio_OcaSetInstrument(0); - Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); msgCtx->stateTimer = 10; msgCtx->msgMode = MSGMODE_OCARINA_FAIL; } else if (isB_Held) { @@ -2641,11 +2719,11 @@ void Message_DrawMain(PlayState* play, Gfx** p) { osSyncPrintf("z_message.c 取得メロディ=%d\n", ITEM_SONG_MINUET + msgCtx->ocarinaStaff->state); osSyncPrintf(VT_RST); msgCtx->stateTimer = 20; - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (msgCtx->ocarinaStaff->state == 0xFF) { - Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); msgCtx->stateTimer = 10; msgCtx->msgMode = MSGMODE_SONG_PLAYBACK_FAIL; } @@ -2696,8 +2774,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) { msgCtx->ocarinaStaff->state); gSaveContext.scarecrowLongSongSet = true; } - Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); osSyncPrintf("aaaaaaaaaaaaaa\n"); Audio_OcaSetRecordingState(0); msgCtx->stateTimer = 10; @@ -2766,8 +2844,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) { msgCtx->stateTimer = 20; gSaveContext.scarecrowSpawnSongSet = true; msgCtx->msgMode = MSGMODE_SCARECROW_RECORDING_DONE; - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); osSyncPrintf(VT_FGCOL(YELLOW)); osSyncPrintf("\n====================================================================\n"); memcpy(gSaveContext.scarecrowSpawnSong, gScarecrowSpawnSongPtr, @@ -2781,8 +2859,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) { // "Played an existing song!!!" osSyncPrintf("すでに存在する曲吹いた!!! \n"); Audio_OcaSetRecordingState(0); - Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); Message_CloseTextbox(play); msgCtx->msgMode = MSGMODE_SCARECROW_RECORDING_FAILED; } @@ -2807,8 +2885,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) { break; case MSGMODE_MEMORY_GAME_LEFT_SKULLKID_PLAYING: case MSGMODE_MEMORY_GAME_RIGHT_SKULLKID_PLAYING: - Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_LV - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_LV - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); msgCtx->ocarinaStaff = Audio_OcaGetDisplayingStaff(); if (msgCtx->ocarinaStaff->pos && sOcarinaNoteBufPos == msgCtx->ocarinaStaff->pos - 1) { sOcarinaNoteBuf[msgCtx->ocarinaStaff->pos - 1] = msgCtx->ocarinaStaff->noteIdx; @@ -2818,11 +2896,11 @@ void Message_DrawMain(PlayState* play, Gfx** p) { if (msgCtx->stateTimer == 0) { if (msgCtx->ocarinaStaff->state == 0) { if (msgCtx->msgMode == MSGMODE_MEMORY_GAME_LEFT_SKULLKID_PLAYING) { - Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_2, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_2, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } msgCtx->msgMode++; } @@ -2840,8 +2918,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) { } break; case MSGMODE_MEMORY_GAME_PLAYER_PLAYING: - Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_LV - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_LV - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); msgCtx->ocarinaStaff = Audio_OcaGetPlayingStaff(); if (msgCtx->ocarinaStaff->pos && sOcarinaNoteBufPos == msgCtx->ocarinaStaff->pos - 1) { sOcarinaNoteBuf[msgCtx->ocarinaStaff->pos - 1] = msgCtx->ocarinaStaff->noteIdx; @@ -2852,14 +2930,14 @@ void Message_DrawMain(PlayState* play, Gfx** p) { // "Musical round failed!!!!!!!!!" osSyncPrintf("輪唱失敗!!!!!!!!!\n"); Audio_OcaSetInstrument(0); - Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); msgCtx->stateTimer = 10; play->msgCtx.ocarinaMode = OCARINA_MODE_03; } else if (msgCtx->ocarinaStaff->state == 0xD) { // "Musical round succeeded!!!!!!!!!" osSyncPrintf("輪唱成功!!!!!!!!!\n"); - Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); msgCtx->msgMode = MSGMODE_MEMORY_GAME_ROUND_SUCCESS; msgCtx->stateTimer = 30; } @@ -2875,8 +2953,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) { msgCtx->stateTimer--; if (msgCtx->stateTimer == 0) { if (Audio_OcaMemoryGameGenNote() != 1) { - Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); msgCtx->ocarinaStaff = Audio_OcaGetPlayingStaff(); msgCtx->ocarinaStaff->pos = sOcarinaNoteBufPos = 0; Message_ResetOcarinaNoteState(); @@ -3337,11 +3415,11 @@ void Message_Update(PlayState* play) { } else if (Message_ShouldAdvanceSilent(play)) { osSyncPrintf("select=%d\n", msgCtx->textboxEndType); if (msgCtx->textboxEndType == TEXTBOX_ENDTYPE_HAS_NEXT) { - Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_PASS, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_PASS, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); Message_ContinueTextbox(play, sNextTextId); } else { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Message_CloseTextbox(play); } } diff --git a/soh/src/code/z_onepointdemo.c b/soh/src/code/z_onepointdemo.c index 0bc6728f5..6440acbee 100644 --- a/soh/src/code/z_onepointdemo.c +++ b/soh/src/code/z_onepointdemo.c @@ -471,7 +471,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3); Player_SetCsActionWithHaltedActors(play, &player->actor, 5); OnePointCutscene_SetCsCamPoints(csCam, D_80120304 | 0x2000, D_80120300, D_8012013C, D_8012021C); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); OnePointCutscene_Vec3sToVec3f(&mainCam->at, &D_8012013C[D_801202FC - 2].pos); OnePointCutscene_Vec3sToVec3f(&mainCam->eye, &D_8012021C[D_801202FC - 2].pos); D_8012013C[D_801202FC - 3].pos.x += diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 3135eb210..396188b48 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -21,6 +21,9 @@ #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/randomizer/randomizer_grotto.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/gameplaystats.h" #define DO_ACTION_TEX_WIDTH() 48 #define DO_ACTION_TEX_HEIGHT() 16 @@ -1607,10 +1610,8 @@ void Inventory_SwapAgeEquipment(void) { s16 i; u16 shieldEquipValue; - // Mod Enhancments can utilise the rando flow path - if (IS_RANDO || CVarGetInteger(CVAR_GENERAL("SwitchAge"), 0) || CVarGetInteger(CVAR_GENERAL("SwitchTimeline"), 0)) { + if (IS_RANDO) { Rando_Inventory_SwapAgeEquipment(); - CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 0); return; } @@ -1847,45 +1848,7 @@ void GameplayStats_SetTimestamp(PlayState* play, u8 item) { GameInteractor_ExecuteOnTimestamp(item); } -// Gameplay stat tracking: Update time the item was acquired -// (special cases for rando items) -void Randomizer_GameplayStats_SetTimestamp(uint16_t item) { - - u32 time = GAMEPLAYSTAT_TOTAL_TIME; - - // Have items in Link's pocket shown as being obtained at 0.1 seconds - if (time == 0) { - time = 1; - } - - // Use ITEM_KEY_BOSS to timestamp Ganon's boss key - if (item == RG_GANONS_CASTLE_BOSS_KEY) { - gSaveContext.sohStats.itemTimestamp[ITEM_KEY_BOSS] = time; - } - - // Count any bottled item as a bottle - if (item >= RG_EMPTY_BOTTLE && item <= RG_BOTTLE_WITH_BIG_POE) { - if (gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] == 0) { - gSaveContext.sohStats.itemTimestamp[ITEM_BOTTLE] = time; - } - return; - } - // Count any bombchu pack as bombchus - if ((item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS) { - if (gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = 0) { - gSaveContext.sohStats.itemTimestamp[ITEM_BOMBCHU] = time; - } - return; - } - if (item == RG_MAGIC_SINGLE) { - gSaveContext.sohStats.itemTimestamp[ITEM_SINGLE_MAGIC] = time; - } - if (item == RG_DOUBLE_DEFENSE) { - gSaveContext.sohStats.itemTimestamp[ITEM_DOUBLE_DEFENSE] = time; - } -} - -u8 Return_Item_Entry(GetItemEntry itemEntry, ItemID returnItem ) { +u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem) { GameInteractor_ExecuteOnItemReceiveHooks(itemEntry); return returnItem; } @@ -1912,6 +1875,7 @@ u8 Return_Item(u8 itemID, ModIndex modId, ItemID returnItem) { // All randomizer items should go through Randomizer_Item_Give, so this should never be reached // but leaving this here just in case, as it was in the original behavior + assert(false); return Return_Item_Entry(ItemTable_RetrieveEntry(MOD_RANDOMIZER, itemID), returnItem); } @@ -2023,13 +1987,9 @@ u8 Item_Give(PlayState* play, u8 item) { if (item == ITEM_SWORD_BGS) { gSaveContext.swordHealth = 8; - // In rando, when buying Giant's Knife, also check - // without the Koriri Sword in case we don't have it if (ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD) == ((1 << EQUIP_INV_SWORD_KOKIRI) | (1 << EQUIP_INV_SWORD_MASTER) | (1 << EQUIP_INV_SWORD_BIGGORON) | - (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE)) || - (IS_RANDO && ALL_EQUIP_VALUE(EQUIP_TYPE_SWORD) == - ((1 << EQUIP_INV_SWORD_MASTER) | (1 << EQUIP_INV_SWORD_BIGGORON) | (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE)))) { + (1 << EQUIP_INV_SWORD_BROKENGIANTKNIFE))) { gSaveContext.inventory.equipment ^= OWNED_EQUIP_FLAG_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE); @@ -2517,354 +2477,6 @@ u8 Item_Give(PlayState* play, u8 item) { return Return_Item(item, MOD_NONE, returnItem); } -u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { - uint16_t item = giEntry.getItemId; - uint16_t temp; - uint16_t i; - uint16_t slot; - - // Gameplay stats: Update the time the item was obtained - Randomizer_GameplayStats_SetTimestamp(item); - - slot = SLOT(item); - if (item == RG_MAGIC_SINGLE) { - gSaveContext.isMagicAcquired = true; - gSaveContext.magicFillTarget = MAGIC_NORMAL_METER; - Magic_Fill(play); - return Return_Item_Entry(giEntry, RG_NONE); - } else if (item == RG_MAGIC_DOUBLE) { - if (!gSaveContext.isMagicAcquired) { - gSaveContext.isMagicAcquired = true; - } - gSaveContext.isDoubleMagicAcquired = true; - gSaveContext.magicFillTarget = MAGIC_DOUBLE_METER; - gSaveContext.magicLevel = 0; - Magic_Fill(play); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_MAGIC_BEAN_PACK) { - if (INV_CONTENT(ITEM_BEAN) == ITEM_NONE) { - INV_CONTENT(ITEM_BEAN) = ITEM_BEAN; - AMMO(ITEM_BEAN) = 10; - } - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_DOUBLE_DEFENSE) { - gSaveContext.isDoubleDefenseAcquired = true; - gSaveContext.inventory.defenseHearts = 20; - gSaveContext.healthAccumulator = 0x140; - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item >= RG_BOTTLE_WITH_RED_POTION && item <= RG_BOTTLE_WITH_BIG_POE) { - temp = SLOT(ITEM_BOTTLE); - for (i = 0; i < 4; i++) { - if (gSaveContext.inventory.items[temp + i] == ITEM_NONE) { - switch (item) { - case RG_BOTTLE_WITH_RED_POTION: - item = ITEM_POTION_RED; - break; - case RG_BOTTLE_WITH_GREEN_POTION: - item = ITEM_POTION_GREEN; - break; - case RG_BOTTLE_WITH_BLUE_POTION: - item = ITEM_POTION_BLUE; - break; - case RG_BOTTLE_WITH_FAIRY: - item = ITEM_FAIRY; - break; - case RG_BOTTLE_WITH_FISH: - item = ITEM_FISH; - break; - case RG_BOTTLE_WITH_BLUE_FIRE: - item = ITEM_BLUE_FIRE; - break; - case RG_BOTTLE_WITH_BUGS: - item = ITEM_BUG; - break; - case RG_BOTTLE_WITH_POE: - item = ITEM_POE; - break; - case RG_BOTTLE_WITH_BIG_POE: - item = ITEM_BIG_POE; - break; - } - - gSaveContext.inventory.items[temp + i] = item; - return Return_Item_Entry(giEntry, RG_NONE); - } - } - } else if ((item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_GANONS_CASTLE_SMALL_KEY) || - (item >= RG_FOREST_TEMPLE_KEY_RING && item <= RG_GANONS_CASTLE_KEY_RING) || - (item >= RG_FOREST_TEMPLE_BOSS_KEY && item <= RG_GANONS_CASTLE_BOSS_KEY) || - (item >= RG_DEKU_TREE_MAP && item <= RG_ICE_CAVERN_MAP) || - (item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS)) { - int mapIndex = gSaveContext.mapIndex; - int numOfKeysOnKeyring = 0; - switch (item) { - case RG_DEKU_TREE_MAP: - case RG_DEKU_TREE_COMPASS: - mapIndex = SCENE_DEKU_TREE; - break; - case RG_DODONGOS_CAVERN_MAP: - case RG_DODONGOS_CAVERN_COMPASS: - mapIndex = SCENE_DODONGOS_CAVERN; - break; - case RG_JABU_JABUS_BELLY_MAP: - case RG_JABU_JABUS_BELLY_COMPASS: - mapIndex = SCENE_JABU_JABU; - break; - case RG_FOREST_TEMPLE_MAP: - case RG_FOREST_TEMPLE_COMPASS: - case RG_FOREST_TEMPLE_SMALL_KEY: - case RG_FOREST_TEMPLE_KEY_RING: - case RG_FOREST_TEMPLE_BOSS_KEY: - mapIndex = SCENE_FOREST_TEMPLE; - numOfKeysOnKeyring = FOREST_TEMPLE_SMALL_KEY_MAX; - break; - case RG_FIRE_TEMPLE_MAP: - case RG_FIRE_TEMPLE_COMPASS: - case RG_FIRE_TEMPLE_SMALL_KEY: - case RG_FIRE_TEMPLE_KEY_RING: - case RG_FIRE_TEMPLE_BOSS_KEY: - mapIndex = SCENE_FIRE_TEMPLE; - numOfKeysOnKeyring = FIRE_TEMPLE_SMALL_KEY_MAX; - break; - case RG_WATER_TEMPLE_MAP: - case RG_WATER_TEMPLE_COMPASS: - case RG_WATER_TEMPLE_SMALL_KEY: - case RG_WATER_TEMPLE_KEY_RING: - case RG_WATER_TEMPLE_BOSS_KEY: - mapIndex = SCENE_WATER_TEMPLE; - numOfKeysOnKeyring = WATER_TEMPLE_SMALL_KEY_MAX; - break; - case RG_SPIRIT_TEMPLE_MAP: - case RG_SPIRIT_TEMPLE_COMPASS: - case RG_SPIRIT_TEMPLE_SMALL_KEY: - case RG_SPIRIT_TEMPLE_KEY_RING: - case RG_SPIRIT_TEMPLE_BOSS_KEY: - mapIndex = SCENE_SPIRIT_TEMPLE; - numOfKeysOnKeyring = SPIRIT_TEMPLE_SMALL_KEY_MAX; - break; - case RG_SHADOW_TEMPLE_MAP: - case RG_SHADOW_TEMPLE_COMPASS: - case RG_SHADOW_TEMPLE_SMALL_KEY: - case RG_SHADOW_TEMPLE_KEY_RING: - case RG_SHADOW_TEMPLE_BOSS_KEY: - mapIndex = SCENE_SHADOW_TEMPLE; - numOfKeysOnKeyring = SHADOW_TEMPLE_SMALL_KEY_MAX; - break; - case RG_BOTTOM_OF_THE_WELL_MAP: - case RG_BOTTOM_OF_THE_WELL_COMPASS: - case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: - case RG_BOTTOM_OF_THE_WELL_KEY_RING: - mapIndex = SCENE_BOTTOM_OF_THE_WELL; - numOfKeysOnKeyring = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; - break; - case RG_ICE_CAVERN_MAP: - case RG_ICE_CAVERN_COMPASS: - mapIndex = SCENE_ICE_CAVERN; - break; - case RG_GANONS_CASTLE_BOSS_KEY: - mapIndex = SCENE_GANONS_TOWER; - break; - case RG_GERUDO_TRAINING_GROUNDS_SMALL_KEY: - case RG_GERUDO_TRAINING_GROUNDS_KEY_RING: - mapIndex = SCENE_GERUDO_TRAINING_GROUND; - numOfKeysOnKeyring = GERUDO_TRAINING_GROUNDS_SMALL_KEY_MAX; - break; - case RG_GERUDO_FORTRESS_SMALL_KEY: - case RG_GERUDO_FORTRESS_KEY_RING: - mapIndex = SCENE_THIEVES_HIDEOUT; - numOfKeysOnKeyring = GERUDO_FORTRESS_SMALL_KEY_MAX; - break; - case RG_GANONS_CASTLE_SMALL_KEY: - case RG_GANONS_CASTLE_KEY_RING: - mapIndex = SCENE_INSIDE_GANONS_CASTLE; - numOfKeysOnKeyring = GANONS_CASTLE_SMALL_KEY_MAX; - break; - } - - if ((item >= RG_FOREST_TEMPLE_SMALL_KEY) && (item <= RG_GANONS_CASTLE_SMALL_KEY)) { - gSaveContext.sohStats.dungeonKeys[mapIndex]++; - if (gSaveContext.inventory.dungeonKeys[mapIndex] < 0) { - gSaveContext.inventory.dungeonKeys[mapIndex] = 1; - } else { - gSaveContext.inventory.dungeonKeys[mapIndex]++; - } - return Return_Item_Entry(giEntry, RG_NONE); - } else if ((item >= RG_FOREST_TEMPLE_KEY_RING) && (item <= RG_GANONS_CASTLE_KEY_RING)) { - gSaveContext.sohStats.dungeonKeys[mapIndex] = numOfKeysOnKeyring; - gSaveContext.inventory.dungeonKeys[mapIndex] = numOfKeysOnKeyring; - return Return_Item_Entry(giEntry, RG_NONE); - } else { - int bitmask; - if ((item >= RG_DEKU_TREE_MAP) && (item <= RG_ICE_CAVERN_MAP)) { - bitmask = gBitFlags[2]; - } else if ((item >= RG_DEKU_TREE_COMPASS) && (item <= RG_ICE_CAVERN_COMPASS)) { - bitmask = gBitFlags[1]; - } else { - bitmask = gBitFlags[0]; - } - - gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; - return Return_Item_Entry(giEntry, RG_NONE); - } - } - - if (item == RG_TYCOON_WALLET) { - Inventory_ChangeUpgrade(UPG_WALLET, 3); - if (IS_RANDO && Randomizer_GetSettingValue(RSK_FULL_WALLETS)) { - Rupees_ChangeBy(999); - } - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_CHILD_WALLET) { - Flags_SetRandomizerInf(RAND_INF_HAS_WALLET); - if (IS_RANDO && Randomizer_GetSettingValue(RSK_FULL_WALLETS)) { - Rupees_ChangeBy(99); - } - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_GREG_RUPEE) { - Rupees_ChangeBy(1); - Flags_SetRandomizerInf(RAND_INF_GREG_FOUND); - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_FOUND_GREG] = GAMEPLAYSTAT_TOTAL_TIME; - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_TRIFORCE_PIECE) { - gSaveContext.triforcePiecesCollected++; - GameInteractor_SetTriforceHuntPieceGiven(true); - - // Teleport to credits when goal is reached. - if (gSaveContext.triforcePiecesCollected == (Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1)) { - gSaveContext.sohStats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = GAMEPLAYSTAT_TOTAL_TIME; - gSaveContext.sohStats.gameComplete = 1; - Flags_SetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY); - Play_PerformSave(play); - GameInteractor_SetTriforceHuntCreditsWarpActive(true); - } - - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item >= RG_GOHMA_SOUL && item <= RG_GANON_SOUL) { - u8 index = item - RG_GOHMA_SOUL; - Flags_SetRandomizerInf(RAND_INF_GOHMA_SOUL + index); - - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_FISHING_POLE) { - Flags_SetRandomizerInf(RAND_INF_FISHING_POLE_FOUND); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_PROGRESSIVE_BOMBCHUS) { - if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_NONE) { - INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU; - AMMO(ITEM_BOMBCHU) = 20; - } else if (Randomizer_GetSettingValue(RSK_INFINITE_UPGRADES)) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS); - } else { - AMMO(ITEM_BOMBCHU) += AMMO(ITEM_BOMBCHU) < 5 ? 10 : 5; - if (AMMO(ITEM_BOMBCHU) > 50) { - AMMO(ITEM_BOMBCHU) = 50; - } - } - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_MASTER_SWORD) { - if (!CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { - gSaveContext.inventory.equipment |= gBitFlags[1] << gEquipShifts[EQUIP_TYPE_SWORD]; - } - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item >= RG_OCARINA_A_BUTTON && item <= RG_OCARINA_C_RIGHT_BUTTON) { - u8 index = item - RG_OCARINA_A_BUTTON; - Flags_SetRandomizerInf(RAND_INF_HAS_OCARINA_A + index); - - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_BRONZE_SCALE) { - Flags_SetRandomizerInf(RAND_INF_CAN_SWIM); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_QUIVER_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_BOMB_BAG_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_BOMB_BAG); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_BULLET_BAG_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_STICK_UPGRADE_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_NUT_UPGRADE_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_MAGIC_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_MAGIC_METER); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_BOMBCHU_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_WALLET_INF) { - Flags_SetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_SKELETON_KEY) { - Flags_SetRandomizerInf(RAND_INF_HAS_SKELETON_KEY); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_DEKU_STICK_BAG) { - Inventory_ChangeUpgrade(UPG_STICKS, 1); - INV_CONTENT(ITEM_STICK) = ITEM_STICK; - AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS); - return Return_Item_Entry(giEntry, RG_NONE); - } - - if (item == RG_DEKU_NUT_BAG) { - Inventory_ChangeUpgrade(UPG_NUTS, 1); - INV_CONTENT(ITEM_NUT) = ITEM_NUT; - AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS); - return Return_Item_Entry(giEntry, RG_NONE); - } - - temp = gSaveContext.inventory.items[slot]; - osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, temp); - INV_CONTENT(item) = item; - - return temp; -} - u8 Item_CheckObtainability(u8 item) { s16 i; s16 slot = SLOT(item); @@ -3214,12 +2826,12 @@ void Interface_SetNaviCall(PlayState* play, u16 naviCallState) { (play->csCtx.state == CS_STATE_IDLE)) { if (!CVarGetInteger(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 0)) { // clang-format off - if (naviCallState == 0x1E) { Audio_PlaySoundGeneral(NA_SE_VO_NAVY_CALL, &D_801333D4, 4, - &D_801333E0, &D_801333E0, &D_801333E8); } + if (naviCallState == 0x1E) { Audio_PlaySoundGeneral(NA_SE_VO_NAVY_CALL, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } // clang-format on if (naviCallState == 0x1D) { - func_800F4524(&D_801333D4, NA_SE_VO_NA_HELLO_2, 32); + func_800F4524(&gSfxDefaultPos, NA_SE_VO_NA_HELLO_2, 32); } } @@ -3283,8 +2895,8 @@ s32 Health_ChangeBy(PlayState* play, s16 healthChange) { } // clang-format off - if (healthChange > 0) { Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &D_801333D4, 4, - &D_801333E0, &D_801333E0, &D_801333E8); + if (healthChange > 0) { Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if ((gSaveContext.isDoubleDefenseAcquired != 0) && (healthChange < 0)) { healthChange >>= 1; osSyncPrintf("ハート減少半分!!=%d\n", healthChange); // "Heart decrease halved!!=%d" @@ -3464,7 +3076,7 @@ s32 Magic_RequestChange(PlayState* play, s16 amount, s16 type) { if ((type != 5) && (gSaveContext.magic - amount) < 0) { if (gSaveContext.magicCapacity != 0) { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } return false; } @@ -3480,7 +3092,7 @@ s32 Magic_RequestChange(PlayState* play, s16 amount, s16 type) { gSaveContext.magicState = MAGIC_STATE_CONSUME_SETUP; return 1; } else { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); return false; } case MAGIC_CONSUME_WAIT_NO_PREVIEW: @@ -3492,7 +3104,7 @@ s32 Magic_RequestChange(PlayState* play, s16 amount, s16 type) { gSaveContext.magicState = MAGIC_STATE_METER_FLASH_3; return true; } else { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); return false; } case MAGIC_CONSUME_LENS: @@ -3520,7 +3132,7 @@ s32 Magic_RequestChange(PlayState* play, s16 amount, s16 type) { gSaveContext.magicState = MAGIC_STATE_METER_FLASH_2; return true; } else { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); return false; } case MAGIC_ADD: @@ -3604,8 +3216,8 @@ void Interface_UpdateMagicBar(PlayState* play) { gSaveContext.magic += 4; if (gSaveContext.gameMode == 0 && gSaveContext.sceneSetupIndex < 4) { - Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } // "Storage MAGIC_NOW=%d (%d)" @@ -3706,8 +3318,8 @@ void Interface_UpdateMagicBar(PlayState* play) { !hasLens || !play->actorCtx.lensActive) { play->actorCtx.lensActive = false; - Audio_PlaySoundGeneral(NA_SE_SY_GLASSMODE_OFF, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GLASSMODE_OFF, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); gSaveContext.magicState = MAGIC_STATE_IDLE; if (CVarGetInteger(CVAR_COSMETIC("Consumable.MagicBorder.Changed"), 0)) { sMagicBorder = CVarGetColor24(CVAR_COSMETIC("Consumable.MagicBorder.Value"), sMagicBorder_ori); @@ -3762,7 +3374,7 @@ void Interface_UpdateMagicBar(PlayState* play) { case MAGIC_STATE_ADD: gSaveContext.magic += 4; - Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (gSaveContext.magic >= gSaveContext.magicTarget) { gSaveContext.magic = gSaveContext.magicTarget; gSaveContext.magicState = gSaveContext.prevMagicState; @@ -3772,6 +3384,11 @@ void Interface_UpdateMagicBar(PlayState* play) { default: gSaveContext.magicState = MAGIC_STATE_IDLE; + if (CVarGetInteger(CVAR_COSMETIC("Consumable.MagicBorder.Changed"), 0)) { + sMagicBorder = CVarGetColor24(CVAR_COSMETIC("Consumable.MagicBorder.Value"), sMagicBorder_ori); + } else { + sMagicBorder = sMagicBorder_ori; + } break; } } @@ -4001,8 +3618,8 @@ void Interface_DrawEnemyHealthBar(TargetContext* targetCtx, PlayState* play) { s32 healthbar_offsetY = CVarGetInteger(CVAR_COSMETIC("HUD.EnemyHealthBar.PosY"), 0); s8 anchorType = CVarGetInteger(CVAR_COSMETIC("HUD.EnemyHealthBar.PosType"), ENEMYHEALTH_ANCHOR_ACTOR); - if (CVarGetInteger(CVAR_COSMETIC("HUD.EnemyHealthBar..Changed"), 0)) { - healthbar_red = CVarGetColor(CVAR_COSMETIC("HUD.EnemyHealthBar..Value"), healthbar_red); + if (CVarGetInteger(CVAR_COSMETIC("HUD.EnemyHealthBar.Changed"), 0)) { + healthbar_red = CVarGetColor(CVAR_COSMETIC("HUD.EnemyHealthBar.Value"), healthbar_red); } if (CVarGetInteger(CVAR_COSMETIC("HUD.EnemyHealthBorder.Changed"), 0)) { healthbar_border = CVarGetColor(CVAR_COSMETIC("HUD.EnemyHealthBorder.Value"), healthbar_border); @@ -6066,17 +5683,19 @@ void Interface_Draw(PlayState* play) { } // Revert any spoiling trade quest items - for (svar1 = 0; svar1 < ARRAY_COUNT(gSpoilingItems); svar1++) { - if (INV_CONTENT(ITEM_TRADE_ADULT) == gSpoilingItems[svar1]) { - gSaveContext.eventInf[0] &= 0x7F80; - osSyncPrintf("EVENT_INF=%x\n", gSaveContext.eventInf[0]); - play->nextEntranceIndex = spoilingItemEntrances[svar1]; - INV_CONTENT(gSpoilingItemReverts[svar1]) = gSpoilingItemReverts[svar1]; + if (GameInteractor_Should(VB_REVERT_SPOILING_ITEMS, true)) { + for (svar1 = 0; svar1 < ARRAY_COUNT(gSpoilingItems); svar1++) { + if (INV_CONTENT(ITEM_TRADE_ADULT) == gSpoilingItems[svar1]) { + gSaveContext.eventInf[0] &= 0x7F80; + osSyncPrintf("EVENT_INF=%x\n", gSaveContext.eventInf[0]); + play->nextEntranceIndex = spoilingItemEntrances[svar1]; + INV_CONTENT(gSpoilingItemReverts[svar1]) = gSpoilingItemReverts[svar1]; - for (svar2 = 1; svar2 < ARRAY_COUNT(gSaveContext.equips.buttonItems); svar2++) { - if (gSaveContext.equips.buttonItems[svar2] == gSpoilingItems[svar1]) { - gSaveContext.equips.buttonItems[svar2] = gSpoilingItemReverts[svar1]; - Interface_LoadItemIcon1(play, svar2); + for (svar2 = 1; svar2 < ARRAY_COUNT(gSaveContext.equips.buttonItems); svar2++) { + if (gSaveContext.equips.buttonItems[svar2] == gSpoilingItems[svar1]) { + gSaveContext.equips.buttonItems[svar2] = gSpoilingItemReverts[svar1]; + Interface_LoadItemIcon1(play, svar2); + } } } } @@ -6183,17 +5802,17 @@ void Interface_Draw(PlayState* play) { D_80125A5C = 0; } else if (gSaveContext.timer1Value > 60) { if (timerDigits[4] == 1) { - Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &D_801333D4, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else if (gSaveContext.timer1Value >= 11) { if (timerDigits[4] & 1) { - Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &D_801333D4, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else { - Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_E, &D_801333D4, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_E, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } } @@ -6240,8 +5859,8 @@ void Interface_Draw(PlayState* play) { D_8015FFE2 = 40; gSaveContext.timer1State = 15; } else { - Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &D_801333D4, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } } @@ -6358,17 +5977,17 @@ void Interface_Draw(PlayState* play) { } } else if (gSaveContext.timer2Value > 60) { if (timerDigits[4] == 1) { - Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &D_801333D4, 4, - &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else if (gSaveContext.timer2Value > 10) { if ((timerDigits[4] & 1)) { - Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &D_801333D4, 4, - &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else { - Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_E, &D_801333D4, 4, - &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_E, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else { gSaveContext.timer2Value++; @@ -6382,8 +6001,8 @@ void Interface_Draw(PlayState* play) { } if ((gSaveContext.timer2Value % 60) == 0) { - Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &D_801333D4, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } } @@ -6447,7 +6066,7 @@ void Interface_Draw(PlayState* play) { svar5 = CVarGetInteger(CVAR_COSMETIC("HUD.Timers.PosX"), 0)+204+X_Margins_Timer; } else if (CVarGetInteger(CVAR_COSMETIC("HUD.Timers.PosType"), 0) == 4) {//Hidden svar5 = -9999; - } + } } OVERLAY_DISP = @@ -6748,7 +6367,7 @@ void Interface_Update(PlayState* play) { gSaveContext.health += 4; if ((gSaveContext.health & 0xF) < 4) { - Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } osSyncPrintf("now_life=%d max_life=%d\n", gSaveContext.health, gSaveContext.healthCapacity); @@ -6785,7 +6404,7 @@ void Interface_Update(PlayState* play) { if (gSaveContext.rupees < CUR_CAPACITY(UPG_WALLET)) { gSaveContext.rupeeAccumulator--; gSaveContext.rupees++; - Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { // "Rupee Amount MAX = %d" osSyncPrintf("ルピー数MAX = %d\n", CUR_CAPACITY(UPG_WALLET)); @@ -6801,11 +6420,11 @@ void Interface_Update(PlayState* play) { gSaveContext.rupees = 0; } - Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { gSaveContext.rupeeAccumulator++; gSaveContext.rupees--; - Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else { gSaveContext.rupeeAccumulator = 0; diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index d85ff6063..df1314e71 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -7,11 +7,13 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/debugconsole.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" -#include "soh/Enhancements/randomizer/randomizer_entrance.h" #include #include #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/SaveManager.h" #include "soh/framebuffer_effects.h" #include @@ -19,53 +21,70 @@ #include #include -void* D_8012D1F0 = NULL; -//UNK_TYPE D_8012D1F4 = 0; // unused -Input* D_8012D1F8 = NULL; - TransitionUnk sTrnsnUnk; s32 gTrnsnUnkState; -VisMono D_80161498; -Color_RGBA8_u32 D_801614B0; +VisMono gPlayVisMono; +Color_RGBA8_u32 gVisMonoColor; + FaultClient D_801614B8; -s16 D_801614C8; -#if 0 -u64 D_801614D0[0xA00]; -#endif + +s16 sTransitionFillTimer; + +void* gDebugCutsceneScript = NULL; +UNK_TYPE D_8012D1F4 = 0; // unused + +Input* D_8012D1F8 = NULL; PlayState* gPlayState; s16 firstInit = 0; - s16 gEnPartnerId; -void OTRPlay_SpawnScene(PlayState* play, s32 sceneNum, s32 spawn); +void Play_SpawnScene(PlayState* play, s32 sceneId, s32 spawn); + +// This macro prints the number "1" with a file and line number if R_ENABLE_PLAY_LOGS is enabled. +// For example, it can be used to trace the play state execution at a high level. +// SOHTODO: Revert log statements everywhere back to authentic, and deal with dynamic line/file names via macro +#define PLAY_LOG(line) \ + do { \ + if (1 & HREG(63)) { \ + LOG_NUM("1", 1 /*, "../z_play.c", line */); \ + } \ + } while (0) void enableBetaQuest(); void disableBetaQuest(); -void func_800BC450(PlayState* play) { +void OTRPlay_SpawnScene(PlayState* play, s32 sceneId, s32 spawn); + +void Play_RequestViewpointBgCam(PlayState* play) { Camera_ChangeDataIdx(GET_ACTIVE_CAM(play), play->unk_1242B - 1); } -void func_800BC490(PlayState* play, s16 point) { - assert(point == 1 || point == 2); +void Play_SetViewpoint(PlayState* play, s16 viewpoint) { + assert(viewpoint == 1 || viewpoint == 2); - play->unk_1242B = point; + play->unk_1242B = viewpoint; if ((YREG(15) != 0x10) && (gSaveContext.cutsceneIndex < 0xFFF0)) { - Audio_PlaySoundGeneral((point == 1) ? NA_SE_SY_CAMERA_ZOOM_DOWN : NA_SE_SY_CAMERA_ZOOM_UP, &D_801333D4, 4, - &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral((viewpoint == 1) ? NA_SE_SY_CAMERA_ZOOM_DOWN : NA_SE_SY_CAMERA_ZOOM_UP, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } - func_800BC450(play); + Play_RequestViewpointBgCam(play); } -s32 func_800BC56C(PlayState* play, s16 arg1) { - return (arg1 == play->unk_1242B); +/** + * @return true if the currently set viewpoint is the same as the one provided in the argument + */ +s32 Play_CheckViewpoint(PlayState* play, s16 viewpoint) { + return (viewpoint == play->unk_1242B); } -// original name: "Game_play_shop_pr_vr_switch_set" -void func_800BC590(PlayState* play) { +/** + * If the scene is a shop, set the viewpoint that will set the bgCamIndex + * to toggle the camera into a "browsing item selection" setting. + */ +void Play_SetShopBrowsingViewpoint(PlayState* play) { osSyncPrintf("Game_play_shop_pr_vr_switch_set()\n"); if (YREG(15) == 0x10) { @@ -76,7 +95,7 @@ void func_800BC590(PlayState* play) { void Gameplay_SetupTransition(PlayState* play, s32 transitionType) { TransitionContext* transitionCtx = &play->transitionCtx; - memset(transitionCtx,0, sizeof(TransitionContext)); + memset(transitionCtx, 0, sizeof(TransitionContext)); transitionCtx->transitionType = transitionType; @@ -104,6 +123,7 @@ void Gameplay_SetupTransition(PlayState* play, s32 transitionType) { transitionCtx->setColor = TransitionTriforce_SetColor; transitionCtx->setEnvColor = NULL; break; + case TRANS_TYPE_WIPE: case TRANS_TYPE_WIPE_FAST: transitionCtx->init = TransitionWipe_Init; @@ -116,6 +136,7 @@ void Gameplay_SetupTransition(PlayState* play, s32 transitionType) { transitionCtx->setColor = TransitionWipe_SetColor; transitionCtx->setEnvColor = NULL; break; + case TRANS_TYPE_FADE_BLACK: case TRANS_TYPE_FADE_WHITE: case TRANS_TYPE_FADE_BLACK_FAST: @@ -136,25 +157,32 @@ void Gameplay_SetupTransition(PlayState* play, s32 transitionType) { transitionCtx->setColor = TransitionFade_SetColor; transitionCtx->setEnvColor = NULL; break; + case TRANS_TYPE_FILL_WHITE2: case TRANS_TYPE_FILL_WHITE: play->transitionMode = TRANS_MODE_FILL_WHITE_INIT; break; + case TRANS_TYPE_INSTANT: play->transitionMode = TRANS_MODE_INSTANT; break; + case TRANS_TYPE_FILL_BROWN: play->transitionMode = TRANS_MODE_FILL_BROWN_INIT; break; + case TRANS_TYPE_SANDSTORM_PERSIST: play->transitionMode = TRANS_MODE_SANDSTORM_INIT; break; + case TRANS_TYPE_SANDSTORM_END: play->transitionMode = TRANS_MODE_SANDSTORM_END_INIT; break; + case TRANS_TYPE_CS_BLACK_FILL: play->transitionMode = TRANS_MODE_CS_BLACK_FILL_INIT; break; + default: Fault_AddHungupAndCrash(__FILE__, __LINE__); break; @@ -167,8 +195,8 @@ void func_800BC88C(PlayState* play) { } Gfx* Play_SetFog(PlayState* play, Gfx* gfx) { - return Gfx_SetFog2(gfx, play->lightCtx.fogColor[0], play->lightCtx.fogColor[1], - play->lightCtx.fogColor[2], 0, play->lightCtx.fogNear, 1000); + return Gfx_SetFog2(gfx, play->lightCtx.fogColor[0], play->lightCtx.fogColor[1], play->lightCtx.fogColor[2], 0, + play->lightCtx.fogNear, 1000); } void Play_Destroy(GameState* thisx) { @@ -182,13 +210,9 @@ void Play_Destroy(GameState* thisx) { play->gameplayFrames = 0; } - // In ER, remove link from epona when entering somewhere that doesn't support epona - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) { - Entrance_HandleEponaState(); - } - play->state.gfxCtx->callback = NULL; play->state.gfxCtx->callbackParam = 0; + SREG(91) = 0; R_PAUSE_MENU_MODE = 0; @@ -210,7 +234,7 @@ void Play_Destroy(GameState* thisx) { ShrinkWindow_Destroy(); TransitionFade_Destroy(&play->transitionFade); - VisMono_Destroy(&D_80161498); + VisMono_Destroy(&gPlayVisMono); if (gSaveContext.linkAge != play->linkAgeOnLoad) { Inventory_SwapAgeEquipment(); @@ -222,8 +246,11 @@ void Play_Destroy(GameState* thisx) { KaleidoScopeCall_Destroy(play); KaleidoManager_Destroy(); ZeldaArena_Cleanup(); + Fault_RemoveClient(&D_801614B8); + disableBetaQuest(); + gPlayState = NULL; } @@ -352,18 +379,17 @@ u8 CheckLACSRewardCount() { void Play_Init(GameState* thisx) { PlayState* play = (PlayState*)thisx; GraphicsContext* gfxCtx = play->state.gfxCtx; - enableBetaQuest(); - gPlayState = play; - //play->state.gfxCtx = NULL; uintptr_t zAlloc; uintptr_t zAllocAligned; size_t zAllocSize; Player* player; - s32 playerStartCamId; + s32 playerStartBgCamIndex; s32 i; - u8 tempSetupIndex; + u8 baseSceneLayer; s32 pad[2]; + enableBetaQuest(); + // Properly initialize the frame counter so it doesn't use garbage data if (!firstInit) { play->gameplayFrames = 0; @@ -379,7 +405,10 @@ void Play_Init(GameState* thisx) { return; } + gPlayState = play; + SystemArena_Display(); + // OTRTODO allocate double the normal amount of memory // This is to avoid some parts of the game, like loading actors, causing OoM // This is potionally unavoidable due to struct size differences, but is x2 the right amount? @@ -405,6 +434,7 @@ void Play_Init(GameState* thisx) { play->cameraPtrs[MAIN_CAM]->uid = 0; play->activeCamera = MAIN_CAM; func_8005AC48(&play->mainCamera, 0xFF); + // Sram_Init(this, &this->sramCtx); Regs_InitData(play); Message_Init(play); GameOver_Init(play); @@ -437,41 +467,53 @@ void Play_Init(GameState* thisx) { Cutscene_HandleConditionalTriggers(play); - if (gSaveContext.gameMode != 0 || gSaveContext.cutsceneIndex >= 0xFFF0) { + if (gSaveContext.gameMode != GAMEMODE_NORMAL || gSaveContext.cutsceneIndex >= 0xFFF0) { gSaveContext.nayrusLoveTimer = 0; Magic_Reset(play); - gSaveContext.sceneSetupIndex = (gSaveContext.cutsceneIndex & 0xF) + 4; + gSaveContext.sceneSetupIndex = SCENE_LAYER_CUTSCENE_FIRST + (gSaveContext.cutsceneIndex & 0xF); } else if (!LINK_IS_ADULT && IS_DAY) { - gSaveContext.sceneSetupIndex = 0; + gSaveContext.sceneSetupIndex = SCENE_LAYER_CHILD_DAY; } else if (!LINK_IS_ADULT && !IS_DAY) { - gSaveContext.sceneSetupIndex = 1; + gSaveContext.sceneSetupIndex = SCENE_LAYER_CHILD_NIGHT; } else if (LINK_IS_ADULT && IS_DAY) { - gSaveContext.sceneSetupIndex = 2; + gSaveContext.sceneSetupIndex = SCENE_LAYER_ADULT_DAY; } else { - gSaveContext.sceneSetupIndex = 3; + gSaveContext.sceneSetupIndex = SCENE_LAYER_ADULT_NIGHT; } - tempSetupIndex = gSaveContext.sceneSetupIndex; + // save the base scene layer (before accounting for the special cases below) to use later for the transition type + baseSceneLayer = gSaveContext.sceneSetupIndex; + if ((gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_HYRULE_FIELD) && !LINK_IS_ADULT && - gSaveContext.sceneSetupIndex < 4) { + !IS_CUTSCENE_LAYER) { if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE)) { gSaveContext.sceneSetupIndex = 1; } else { gSaveContext.sceneSetupIndex = 0; } - } else if ((gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KOKIRI_FOREST) && LINK_IS_ADULT && - gSaveContext.sceneSetupIndex < 4) { + } else if ((gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KOKIRI_FOREST) && + LINK_IS_ADULT && !IS_CUTSCENE_LAYER) { gSaveContext.sceneSetupIndex = (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) ? 3 : 2; } Play_SpawnScene( - play, - gEntranceTable[((void)0, gSaveContext.entranceIndex) + ((void)0, gSaveContext.sceneSetupIndex)].scene, + play, gEntranceTable[((void)0, gSaveContext.entranceIndex) + ((void)0, gSaveContext.sceneSetupIndex)].scene, gEntranceTable[((void)0, gSaveContext.sceneSetupIndex) + ((void)0, gSaveContext.entranceIndex)].spawn); osSyncPrintf("\nSCENE_NO=%d COUNTER=%d\n", ((void)0, gSaveContext.entranceIndex), gSaveContext.sceneSetupIndex); +#if 0 + // When entering Gerudo Valley in the credits, trigger the GC emulator to play the ending movie. + // The emulator constantly checks whether PC is 0x81000000, so this works even though it's not a valid address. + if ((gEntranceTable[((void)0, gSaveContext.save.entranceIndex)].sceneId == SCENE_GERUDO_VALLEY) && + gSaveContext.sceneLayer == 6) { + PRINTF("エンディングはじまるよー\n"); // "The ending starts" + ((void (*)(void))0x81000000)(); + PRINTF("出戻り?\n"); // "Return?" + } +#endif + Cutscene_HandleEntranceTriggers(play); KaleidoScopeCall_Init(play); func_801109B0(play); @@ -481,10 +523,12 @@ void Play_Init(GameState* thisx) { gSaveContext.totalDays++; gSaveContext.bgsDayCount++; gSaveContext.dogIsLost = true; + if (Inventory_ReplaceItem(play, ITEM_WEIRD_EGG, ITEM_CHICKEN) || Inventory_HatchPocketCucco(play)) { Message_StartTextbox(play, 0x3066, NULL); } + gSaveContext.nextDayTime = 0xFFFE; } else { gSaveContext.nextDayTime = 0xFFFD; @@ -494,11 +538,10 @@ void Play_Init(GameState* thisx) { SREG(91) = -1; R_PAUSE_MENU_MODE = 0; PreRender_Init(&play->pauseBgPreRender); - PreRender_SetValuesSave(&play->pauseBgPreRender, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0); - PreRender_SetValues(&play->pauseBgPreRender, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); + PreRender_SetValuesSave(&play->pauseBgPreRender, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, NULL); + PreRender_SetValues(&play->pauseBgPreRender, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL); gTrnsnUnkState = 0; play->transitionMode = TRANS_MODE_OFF; - FrameAdvance_Init(&play->frameAdvCtx); Rand_Seed((u32)osGetTime()); Matrix_Init(&play->state); @@ -507,12 +550,12 @@ void Play_Init(GameState* thisx) { play->transitionTrigger = TRANS_TRIGGER_END; play->unk_11E16 = 0xFF; play->unk_11E18 = 0; - play->unk_11DE9 = 0; + play->unk_11DE9 = false; - if (gSaveContext.gameMode != 1) { + if (gSaveContext.gameMode != GAMEMODE_TITLE_SCREEN) { if (gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT) { play->transitionType = ENTRANCE_INFO_END_TRANS_TYPE( - gEntranceTable[((void)0, gSaveContext.entranceIndex) + tempSetupIndex].field); // Fade In + gEntranceTable[((void)0, gSaveContext.entranceIndex) + baseSceneLayer].field); // Fade In } else { play->transitionType = gSaveContext.nextTransitionType; gSaveContext.nextTransitionType = TRANS_NEXT_TYPE_DEFAULT; @@ -526,20 +569,21 @@ void Play_Init(GameState* thisx) { TransitionFade_SetType(&play->transitionFade, 3); TransitionFade_SetColor(&play->transitionFade, RGBA8(160, 160, 160, 255)); TransitionFade_Start(&play->transitionFade); - VisMono_Init(&D_80161498); - D_801614B0.a = 0; + VisMono_Init(&gPlayVisMono); + gVisMonoColor.a = 0; Flags_UnsetAllEnv(play); osSyncPrintf("ZELDA ALLOC SIZE=%x\n", THA_GetSize(&play->state.tha)); zAllocSize = THA_GetSize(&play->state.tha); - zAlloc = GAMESTATE_ALLOC_MC(&play->state, zAllocSize); + zAlloc = (uintptr_t)GAMESTATE_ALLOC_MC(&play->state, zAllocSize); zAllocAligned = (zAlloc + 8) & ~0xF; - ZeldaArena_Init(zAllocAligned, zAllocSize - zAllocAligned + zAlloc); + ZeldaArena_Init((void*)zAllocAligned, zAllocSize - (zAllocAligned - zAlloc)); // "Zelda Heap" osSyncPrintf("ゼルダヒープ %08x-%08x\n", zAllocAligned, - (s32)(zAllocAligned + zAllocSize) - (s32)(zAllocAligned - zAlloc)); + (u8*)zAllocAligned + zAllocSize - (s32)(zAllocAligned - zAlloc)); Fault_AddClient(&D_801614B8, ZeldaArena_Display, NULL, NULL); + // In order to keep masks equipped on first load, we need to pre-set the age reqs for the item and slot if (CVarGetInteger(CVAR_ENHANCEMENT("AdultMasks"), 0) || CVarGetInteger(CVAR_CHEAT("TimelessEquipment"), 0)) { for (int i = ITEM_MASK_KEATON; i <= ITEM_MASK_TRUTH; i += 1) { @@ -554,6 +598,7 @@ void Play_Init(GameState* thisx) { } gSlotAgeReqs[SLOT_TRADE_CHILD] = AGE_REQ_CHILD; } + func_800304DC(play, &play->actorCtx, play->linkActorEntry); while (!func_800973FC(play, &play->roomCtx)) { @@ -571,16 +616,17 @@ void Play_Init(GameState* thisx) { { CollisionHeader* colHeader = BgCheck_GetCollisionHeader(&play->colCtx, BGCHECK_SCENE); + u8 camId = player->actor.params & 0xFF; // If the player's start cam is out of bounds, set it to 0xFF so it isn't used. - if (colHeader != NULL && ((player->actor.params & 0xFF) >= colHeader->cameraDataListLen)) { + if (colHeader != NULL && (camId != 0xFF) && (camId >= colHeader->cameraDataListLen)) { player->actor.params |= 0xFF; } } - playerStartCamId = player->actor.params & 0xFF; - if (playerStartCamId != 0xFF) { - osSyncPrintf("player has start camera ID (" VT_FGCOL(BLUE) "%d" VT_RST ")\n", playerStartCamId); - Camera_ChangeDataIdx(&play->mainCamera, playerStartCamId); + playerStartBgCamIndex = player->actor.params & 0xFF; + if (playerStartBgCamIndex != 0xFF) { + osSyncPrintf("player has start camera ID (" VT_FGCOL(BLUE) "%d" VT_RST ")\n", playerStartBgCamIndex); + Camera_ChangeDataIdx(&play->mainCamera, playerStartBgCamIndex); } if (YREG(15) == 32) { @@ -597,7 +643,9 @@ void Play_Init(GameState* thisx) { gSaveContext.natureAmbienceId = play->sequenceCtx.natureAmbienceId; func_8002DF18(play, GET_PLAYER(play)); AnimationContext_Update(play, &play->animationCtx); + gSaveContext.respawnFlag = 0; + // #region SOH [Stats] if (gSaveContext.sohStats.sceneNum != gPlayState->sceneNum) { u16 idx = gSaveContext.sohStats.tsIdx; gSaveContext.sohStats.sceneTimestamps[idx].sceneTime = gSaveContext.sohStats.sceneTimer / 2; @@ -624,14 +672,20 @@ void Play_Init(GameState* thisx) { gSaveContext.sohStats.sceneNum = gPlayState->sceneNum; gSaveContext.sohStats.roomNum = gPlayState->roomCtx.curRoom.num; - gSaveContext.respawnFlag = 0; - #if 0 - if (dREG(95) != 0) { - D_8012D1F0 = D_801614D0; - osSyncPrintf("\nkawauso_data=[%x]", D_8012D1F0); - DmaMgr_DmaRomToRam(0x03FEB000, D_8012D1F0, sizeof(D_801614D0)); + // #endregion + +#if 0 + if (R_USE_DEBUG_CUTSCENE) { + static u64 sDebugCutsceneScriptBuf[0xA00]; + + gDebugCutsceneScript = sDebugCutsceneScriptBuf; + PRINTF("\nkawauso_data=[%x]", gDebugCutsceneScript); + + // This hardcoded ROM address extends past the end of the ROM file. + // Presumably the ROM was larger at a previous point in development when this debug feature was used. + DmaMgr_DmaRomToRam(0x03FEB000, gDebugCutsceneScript, sizeof(sDebugCutsceneScriptBuf)); } - #endif +#endif if (CVarGetInteger(CVAR_ENHANCEMENT("IvanCoopModeEnabled"), 0)) { Actor_Spawn(&play->actorCtx, play, gEnPartnerId, GET_PLAYER(play)->actor.world.pos.x, @@ -641,13 +695,9 @@ void Play_Init(GameState* thisx) { } void Play_Update(PlayState* play) { + Input* input = play->state.input; + s32 isPaused; s32 pad1; - s32 sp80; - Input* input; - u32 i; - s32 pad2; - - input = play->state.input; if ((SREG(1) < 0) || (DREG(0) != 0)) { SREG(1) = 0; @@ -655,20 +705,26 @@ void Play_Update(PlayState* play) { } if ((HREG(80) == 18) && (HREG(81) < 0)) { + u32 i; + s32 pad2; + HREG(81) = 0; osSyncPrintf("object_exchange_rom_address %u\n", gObjectTableSize); osSyncPrintf("RomStart RomEnd Size\n"); + for (i = 0; i < gObjectTableSize; i++) { ptrdiff_t size = gObjectTable[i].vromEnd - gObjectTable[i].vromStart; osSyncPrintf("%08x-%08x %08x(%8.3fKB)\n", gObjectTable[i].vromStart, gObjectTable[i].vromEnd, size, size / 1024.0f); } + osSyncPrintf("\n"); } if ((HREG(81) == 18) && (HREG(82) < 0)) { HREG(82) = 0; + // ActorOverlayTable_LogPrint(); } if (CVarGetInteger(CVAR_SETTING("FreeLook.Enabled"), 0) && Player_InCsMode(play)) { @@ -684,7 +740,7 @@ void Play_Update(PlayState* play) { play->transitionMode = TRANS_MODE_SETUP; } - // Gameplay stats: Count button presses + // #region SOH [Stats] Gameplay stats: Count button presses if (!gSaveContext.sohStats.gameComplete) { if (CHECK_BTN_ALL(input[0].press.button, BTN_A)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_A]++;} if (CHECK_BTN_ALL(input[0].press.button, BTN_B)) {gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_B]++;} @@ -709,6 +765,7 @@ void Play_Update(PlayState* play) { gSaveContext.sohStats.fileCreatedAt = GetUnixTimestamp(); } } + // #endregion if (gTrnsnUnkState != 0) { switch (gTrnsnUnkState) { @@ -728,18 +785,20 @@ void Play_Update(PlayState* play) { } } - if (play->transitionMode) { + if ((u32)play->transitionMode != TRANS_MODE_OFF) { switch (play->transitionMode) { case TRANS_MODE_SETUP: if (play->transitionTrigger != TRANS_TRIGGER_END) { - s16 sp6E = 0; + s16 sceneLayer = 0; Interface_ChangeAlpha(1); if (gSaveContext.cutsceneIndex >= 0xFFF0) { - sp6E = (gSaveContext.cutsceneIndex & 0xF) + 4; + sceneLayer = SCENE_LAYER_CUTSCENE_FIRST + (gSaveContext.cutsceneIndex & 0xF); } - if (!(gEntranceTable[play->nextEntranceIndex + sp6E].field & ENTRANCE_INFO_CONTINUE_BGM_FLAG)) { // Continue BGM Off + // fade out bgm if "continue bgm" flag is not set + if (!(gEntranceTable[play->nextEntranceIndex + sceneLayer].field & + ENTRANCE_INFO_CONTINUE_BGM_FLAG)) { // "Sound initalized. 111" osSyncPrintf("\n\n\nサウンドイニシャル来ました。111"); if ((play->transitionType < TRANS_TYPE_MAX) && !Environment_IsForcedSequenceDisabled()) { @@ -759,25 +818,30 @@ void Play_Update(PlayState* play) { } if (play->transitionMode >= TRANS_MODE_FILL_WHITE_INIT) { + // non-instance modes break out of this switch break; } - + FALLTHROUGH; case TRANS_MODE_INSTANCE_INIT: play->transitionCtx.init(&play->transitionCtx.data); // Circle Transition Types if ((play->transitionCtx.transitionType >> 5) == 1) { play->transitionCtx.setType(&play->transitionCtx.data, - play->transitionCtx.transitionType | TC_SET_PARAMS); + play->transitionCtx.transitionType | TC_SET_PARAMS); } gSaveContext.transWipeSpeed = 14; + if ((play->transitionCtx.transitionType == TRANS_TYPE_WIPE_FAST) || (play->transitionCtx.transitionType == TRANS_TYPE_FILL_WHITE2)) { + //! @bug TRANS_TYPE_FILL_WHITE2 will never reach this code. + //! It is a non-instance type transition which doesn't run this case. gSaveContext.transWipeSpeed = 28; } gSaveContext.transFadeDuration = 60; + if ((play->transitionCtx.transitionType == TRANS_TYPE_FADE_BLACK_FAST) || (play->transitionCtx.transitionType == TRANS_TYPE_FADE_WHITE_FAST)) { gSaveContext.transFadeDuration = 20; @@ -794,24 +858,28 @@ void Play_Update(PlayState* play) { (play->transitionCtx.transitionType == TRANS_TYPE_FADE_WHITE_CS_DELAYED) || (play->transitionCtx.transitionType == TRANS_TYPE_FADE_WHITE_INSTANT)) { play->transitionCtx.setColor(&play->transitionCtx.data, RGBA8(160, 160, 160, 255)); + if (play->transitionCtx.setEnvColor != NULL) { play->transitionCtx.setEnvColor(&play->transitionCtx.data, - RGBA8(160, 160, 160, 255)); + RGBA8(160, 160, 160, 255)); } } else if (play->transitionCtx.transitionType == TRANS_TYPE_FADE_GREEN) { play->transitionCtx.setColor(&play->transitionCtx.data, RGBA8(140, 140, 100, 255)); + if (play->transitionCtx.setEnvColor != NULL) { play->transitionCtx.setEnvColor(&play->transitionCtx.data, - RGBA8(140, 140, 100, 255)); + RGBA8(140, 140, 100, 255)); } } else if (play->transitionCtx.transitionType == TRANS_TYPE_FADE_BLUE) { play->transitionCtx.setColor(&play->transitionCtx.data, RGBA8(70, 100, 110, 255)); + if (play->transitionCtx.setEnvColor != NULL) { play->transitionCtx.setEnvColor(&play->transitionCtx.data, - RGBA8(70, 100, 110, 255)); + RGBA8(70, 100, 110, 255)); } } else { play->transitionCtx.setColor(&play->transitionCtx.data, RGBA8(0, 0, 0, 0)); + if (play->transitionCtx.setEnvColor != NULL) { play->transitionCtx.setEnvColor(&play->transitionCtx.data, RGBA8(0, 0, 0, 0)); } @@ -833,18 +901,20 @@ void Play_Update(PlayState* play) { break; case TRANS_MODE_INSTANCE_RUNNING: - if (play->transitionCtx.isDone(&play->transitionCtx) != 0) { + if (play->transitionCtx.isDone(&play->transitionCtx.data)) { if (play->transitionCtx.transitionType >= TRANS_TYPE_MAX) { if (play->transitionTrigger == TRANS_TRIGGER_END) { - play->transitionCtx.destroy(&play->transitionCtx); + play->transitionCtx.destroy(&play->transitionCtx.data); func_800BC88C(play); play->transitionMode = TRANS_MODE_OFF; } } else if (play->transitionTrigger != TRANS_TRIGGER_END) { - play->state.running = 0; - if (gSaveContext.gameMode != 2) { + play->state.running = false; + + if (gSaveContext.gameMode != GAMEMODE_FILE_SELECT) { SET_NEXT_GAMESTATE(&play->state, Play_Init, PlayState); gSaveContext.entranceIndex = play->nextEntranceIndex; + if (gSaveContext.minigameState == 1) { gSaveContext.minigameState = 3; } @@ -852,18 +922,20 @@ void Play_Update(PlayState* play) { SET_NEXT_GAMESTATE(&play->state, FileChoose_Init, FileChooseContext); } } else { - play->transitionCtx.destroy(&play->transitionCtx); + play->transitionCtx.destroy(&play->transitionCtx.data); func_800BC88C(play); play->transitionMode = TRANS_MODE_OFF; + if (gTrnsnUnkState == 3) { TransitionUnk_Destroy(&sTrnsnUnk); gTrnsnUnkState = 0; R_UPDATE_RATE = 3; } - + // Transition end for standard transitions GameInteractor_ExecuteOnTransitionEndHooks(play->sceneNum); } + play->transitionTrigger = TRANS_TRIGGER_OFF; } else { play->transitionCtx.update(&play->transitionCtx.data, R_UPDATE_RATE); @@ -871,13 +943,15 @@ void Play_Update(PlayState* play) { break; } + // update non-instance transitions switch (play->transitionMode) { case TRANS_MODE_FILL_WHITE_INIT: - D_801614C8 = 0; + sTransitionFillTimer = 0; play->envCtx.fillScreen = true; play->envCtx.screenFillColor[0] = 160; play->envCtx.screenFillColor[1] = 160; play->envCtx.screenFillColor[2] = 160; + if (play->transitionTrigger != TRANS_TRIGGER_END) { play->envCtx.screenFillColor[3] = 0; play->transitionMode = TRANS_MODE_FILL_IN; @@ -888,37 +962,40 @@ void Play_Update(PlayState* play) { break; case TRANS_MODE_FILL_IN: - play->envCtx.screenFillColor[3] = (D_801614C8 / 20.0f) * 255.0f; - if (D_801614C8 >= 20 && 1) { - play->state.running = 0; + play->envCtx.screenFillColor[3] = (sTransitionFillTimer / 20.0f) * 255.0f; + + if (sTransitionFillTimer >= 20) { + play->state.running = false; SET_NEXT_GAMESTATE(&play->state, Play_Init, PlayState); gSaveContext.entranceIndex = play->nextEntranceIndex; play->transitionTrigger = TRANS_TRIGGER_OFF; play->transitionMode = TRANS_MODE_OFF; } else { - D_801614C8++; + sTransitionFillTimer++; } break; case TRANS_MODE_FILL_OUT: - play->envCtx.screenFillColor[3] = (1 - D_801614C8 / 20.0f) * 255.0f; - if (D_801614C8 >= 20 && 1) { + play->envCtx.screenFillColor[3] = (1 - sTransitionFillTimer / 20.0f) * 255.0f; + + if (sTransitionFillTimer >= 20) { gTrnsnUnkState = 0; R_UPDATE_RATE = 3; play->transitionTrigger = TRANS_TRIGGER_OFF; play->transitionMode = TRANS_MODE_OFF; play->envCtx.fillScreen = false; } else { - D_801614C8++; + sTransitionFillTimer++; } break; case TRANS_MODE_FILL_BROWN_INIT: - D_801614C8 = 0; + sTransitionFillTimer = 0; play->envCtx.fillScreen = true; play->envCtx.screenFillColor[0] = 170; play->envCtx.screenFillColor[1] = 160; play->envCtx.screenFillColor[2] = 150; + if (play->transitionTrigger != TRANS_TRIGGER_END) { play->envCtx.screenFillColor[3] = 0; play->transitionMode = TRANS_MODE_FILL_IN; @@ -962,8 +1039,9 @@ void Play_Update(PlayState* play) { break; case TRANS_MODE_SANDSTORM: - Audio_PlaySoundGeneral(NA_SE_EV_SAND_STORM - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_SAND_STORM - SFX_FLAG, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + if (play->transitionTrigger == TRANS_TRIGGER_END) { if (play->envCtx.sandstormPrimA < 110) { gTrnsnUnkState = 0; @@ -976,7 +1054,7 @@ void Play_Update(PlayState* play) { } } else { if (play->envCtx.sandstormEnvA == 255) { - play->state.running = 0; + play->state.running = false; SET_NEXT_GAMESTATE(&play->state, Play_Init, PlayState); gSaveContext.entranceIndex = play->nextEntranceIndex; play->transitionTrigger = TRANS_TRIGGER_OFF; @@ -999,8 +1077,9 @@ void Play_Update(PlayState* play) { break; case TRANS_MODE_SANDSTORM_END: - Audio_PlaySoundGeneral(NA_SE_EV_SAND_STORM - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_SAND_STORM - SFX_FLAG, &gSfxDefaultPos, 4, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + if (play->transitionTrigger == TRANS_TRIGGER_END) { if (play->envCtx.sandstormPrimA <= 0) { gTrnsnUnkState = 0; @@ -1015,7 +1094,7 @@ void Play_Update(PlayState* play) { break; case TRANS_MODE_CS_BLACK_FILL_INIT: - D_801614C8 = 0; + sTransitionFillTimer = 0; play->envCtx.fillScreen = true; play->envCtx.screenFillColor[0] = 0; play->envCtx.screenFillColor[1] = 0; @@ -1027,7 +1106,8 @@ void Play_Update(PlayState* play) { case TRANS_MODE_CS_BLACK_FILL: if (gSaveContext.cutsceneTransitionControl != 0) { play->envCtx.screenFillColor[3] = gSaveContext.cutsceneTransitionControl; - if (gSaveContext.cutsceneTransitionControl < 0x65) { + + if (gSaveContext.cutsceneTransitionControl <= 100) { gTrnsnUnkState = 0; R_UPDATE_RATE = 3; play->transitionTrigger = TRANS_TRIGGER_OFF; @@ -1038,48 +1118,33 @@ void Play_Update(PlayState* play) { } } - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3533); if (1 && (gTrnsnUnkState != 3)) { - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3542); - if ((gSaveContext.gameMode == 0) && (play->msgCtx.msgMode == MSGMODE_NONE) && + if ((gSaveContext.gameMode == GAMEMODE_NORMAL) && (play->msgCtx.msgMode == MSGMODE_NONE) && (play->gameOverCtx.state == GAMEOVER_INACTIVE)) { KaleidoSetup_Update(play); } - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - - sp80 = (play->pauseCtx.state != 0) || (play->pauseCtx.debugState != 0); - - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3551); + isPaused = (play->pauseCtx.state != 0) || (play->pauseCtx.debugState != 0); + PLAY_LOG(3555); AnimationContext_Reset(&play->animationCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3561); Object_UpdateBank(&play->objectCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3577); - if ((sp80 == 0) && (IREG(72) == 0)) { - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + if (!isPaused && (IREG(72) == 0)) { + PLAY_LOG(3580); play->gameplayFrames++; + func_800AA178(true); + // Gameplay stat tracking if (!gSaveContext.sohStats.gameComplete && (!IS_BOSS_RUSH || !gSaveContext.isBossRushPaused)) { @@ -1092,12 +1157,10 @@ void Play_Update(PlayState* play) { } } - func_800AA178(1); - if (play->actorCtx.freezeFlashTimer && (play->actorCtx.freezeFlashTimer-- < 5)) { osSyncPrintf("FINISH=%d\n", play->actorCtx.freezeFlashTimer); - if ((play->actorCtx.freezeFlashTimer > 0) && - ((play->actorCtx.freezeFlashTimer % 2) != 0)) { + + if ((play->actorCtx.freezeFlashTimer > 0) && ((play->actorCtx.freezeFlashTimer % 2) != 0)) { play->envCtx.fillScreen = true; play->envCtx.screenFillColor[0] = play->envCtx.screenFillColor[1] = play->envCtx.screenFillColor[2] = 150; @@ -1106,91 +1169,52 @@ void Play_Update(PlayState* play) { play->envCtx.fillScreen = false; } } else { - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3606); func_800973FC(play, &play->roomCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3612); CollisionCheck_AT(play, &play->colChkCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3618); CollisionCheck_OC(play, &play->colChkCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3624); CollisionCheck_Damage(play, &play->colChkCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3631); CollisionCheck_ClearContext(play, &play->colChkCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3637); - if (play->unk_11DE9 == 0) { + if (!play->unk_11DE9) { Actor_UpdateAll(play, &play->actorCtx); } - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3643); func_80064558(play, &play->csCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3648); func_800645A0(play, &play->csCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3651); Effect_UpdateAll(play); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3657); EffectSs_UpdateAll(play); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3662); } } else { - func_800AA178(0); - } - - if (1 && HREG(63)) { - LOG_NUM("1", 1); + func_800AA178(false); } + PLAY_LOG(3672); func_80095AA0(play, &play->roomCtx.curRoom, &input[1], 0); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3675); func_80095AA0(play, &play->roomCtx.prevRoom, &input[1], 1); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3677); if (play->unk_1242B != 0) { if (CHECK_BTN_ALL(input[0].press.button, BTN_CUP)) { @@ -1201,124 +1225,82 @@ void Play_Update(PlayState* play) { // "Changing viewpoint is prohibited during the cutscene" osSyncPrintf(VT_FGCOL(CYAN) "デモ中につき視点変更を禁止しております\n" VT_RST); } else if (YREG(15) == 0x10) { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - func_800BC490(play, play->unk_1242B ^ 3); + // C-Up toggle for houses, move between pivot camera and fixed camera + // Toggle viewpoint between VIEWPOINT_LOCKED and VIEWPOINT_PIVOT + Play_SetViewpoint(play, play->unk_1242B ^ 3); } } - func_800BC450(play); - } - - if (1 && HREG(63)) { - LOG_NUM("1", 1); + + Play_RequestViewpointBgCam(play); } + PLAY_LOG(3708); SkyboxDraw_Update(&play->skyboxCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3716); if ((play->pauseCtx.state != 0) || (play->pauseCtx.debugState != 0)) { - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3721); KaleidoScopeCall_Update(play); } else if (play->gameOverCtx.state != GAMEOVER_INACTIVE) { - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3727); GameOver_Update(play); } else { - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3733); Message_Update(play); } - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3737); + PLAY_LOG(3742); Interface_Update(play); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3765); AnimationContext_Update(play, &play->animationCtx); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3771); SoundSource_UpdateAll(play); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3777); ShrinkWindow_Update(R_UPDATE_RATE); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3783); TransitionFade_Update(&play->transitionFade, R_UPDATE_RATE); } else { goto skip; } } - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3799); skip: - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3801); - if ((sp80 == 0) || (gDbgCamEnabled)) { - s32 pad3[5]; + if (!isPaused || gDbgCamEnabled) { s32 i; play->nextCamera = play->activeCamera; - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3806); for (i = 0; i < NUM_CAMS; i++) { if ((i != play->nextCamera) && (play->cameraPtrs[i] != NULL)) { - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(3809); Camera_Update(play->cameraPtrs[i]); } } Camera_Update(play->cameraPtrs[play->nextCamera]); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(3814); } - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - - Environment_Update(play, &play->envCtx, &play->lightCtx, &play->pauseCtx, &play->msgCtx, - &play->gameOverCtx, play->state.gfxCtx); + PLAY_LOG(3816); + Environment_Update(play, &play->envCtx, &play->lightCtx, &play->pauseCtx, &play->msgCtx, &play->gameOverCtx, + play->state.gfxCtx); } void Play_DrawOverlayElements(PlayState* play) { @@ -1326,7 +1308,7 @@ void Play_DrawOverlayElements(PlayState* play) { KaleidoScopeCall_Draw(play); } - if (gSaveContext.gameMode == 0) { + if (gSaveContext.gameMode == GAMEMODE_NORMAL) { Interface_Draw(play); } @@ -1346,15 +1328,16 @@ void Play_Draw(PlayState* play) { // Track render size when paused and that a copy was performed static u32 lastPauseWidth; static u32 lastPauseHeight; - static u8 hasCapturedPauseBuffer; - u8 recapturePauseBuffer = false; + static bool lastAltAssets; + static bool hasCapturedPauseBuffer; + bool recapturePauseBuffer = false; - // If the size has changed or dropped frames leading to the buffer not being copied, + // If the size has changed, alt assets toggled, or dropped frames leading to the buffer not being copied, // set the prerender state back to setup to copy a new frame. - // This requires not rendering kaleido during this copy to avoid kaleido being copied + // This requires not rendering kaleido during this copy to avoid kaleido itself being copied too. if ((R_PAUSE_MENU_MODE == 2 || R_PAUSE_MENU_MODE == 3) && (lastPauseWidth != OTRGetGameRenderWidth() || lastPauseHeight != OTRGetGameRenderHeight() || - !hasCapturedPauseBuffer)) { + lastAltAssets != ResourceMgr_IsAltAssetsEnabled() || !hasCapturedPauseBuffer)) { R_PAUSE_MENU_MODE = 1; recapturePauseBuffer = true; } @@ -1411,12 +1394,11 @@ void Play_Draw(PlayState* play) { Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY); Matrix_Get(&play->viewProjectionMtxF); play->billboardMtxF.mf[0][3] = play->billboardMtxF.mf[1][3] = play->billboardMtxF.mf[2][3] = - play->billboardMtxF.mf[3][0] = play->billboardMtxF.mf[3][1] = play->billboardMtxF.mf[3][2] = - 0.0f; + play->billboardMtxF.mf[3][0] = play->billboardMtxF.mf[3][1] = play->billboardMtxF.mf[3][2] = 0.0f; // This transpose is where the viewing matrix is properly converted into a billboard matrix Matrix_Transpose(&play->billboardMtxF); play->billboardMtx = Matrix_MtxFToMtx(MATRIX_CHECKFLOATS(&play->billboardMtxF), - Graph_Alloc(gfxCtx, sizeof(Mtx))); + Graph_Alloc(gfxCtx, sizeof(Mtx))); gSPSegment(POLY_OPA_DISP++, 0x01, play->billboardMtx); @@ -1428,7 +1410,8 @@ void Play_Draw(PlayState* play) { gSPDisplayList(OVERLAY_DISP++, gfxP); gSPGrayscale(gfxP++, false); - if ((play->transitionMode == TRANS_MODE_INSTANCE_RUNNING) || (play->transitionMode == TRANS_MODE_INSTANCE_WAIT) || + if ((play->transitionMode == TRANS_MODE_INSTANCE_RUNNING) || + (play->transitionMode == TRANS_MODE_INSTANCE_WAIT) || (play->transitionCtx.transitionType >= TRANS_TYPE_MAX)) { View view; @@ -1443,9 +1426,9 @@ void Play_Draw(PlayState* play) { TransitionFade_Draw(&play->transitionFade, &gfxP); - if (D_801614B0.a > 0) { - gDPSetGrayscaleColor(gfxP++, D_801614B0.r, D_801614B0.g, D_801614B0.b, D_801614B0.a); - gSPGrayscale(gfxP++, true); + if (gVisMonoColor.a > 0) { + gPlayVisMono.vis.primColor.rgba = gVisMonoColor.rgba; + VisMono_Draw(&gPlayVisMono, &gfxP); } gSPEndDisplayList(gfxP++); @@ -1459,189 +1442,192 @@ void Play_Draw(PlayState* play) { TransitionUnk_Draw(&sTrnsnUnk, &sp88); POLY_OPA_DISP = sp88; goto Play_Draw_DrawOverlayElements; - } else { - PreRender_SetValues(&play->pauseBgPreRender, SCREEN_WIDTH, SCREEN_HEIGHT, gfxCtx->curFrameBuffer, - gZBuffer); + } - if (R_PAUSE_MENU_MODE == 2) { - MsgEvent_SendNullTask(); - PreRender_Calc(&play->pauseBgPreRender); - R_PAUSE_MENU_MODE = 3; - } else if (R_PAUSE_MENU_MODE >= 4) { - R_PAUSE_MENU_MODE = 0; - } + PreRender_SetValues(&play->pauseBgPreRender, SCREEN_WIDTH, SCREEN_HEIGHT, gfxCtx->curFrameBuffer, gZBuffer); - if (R_PAUSE_MENU_MODE == 3) { - Gfx* sp84 = POLY_OPA_DISP; + if (R_PAUSE_MENU_MODE == 2) { + // Wait for the previous frame's display list to be processed, + // so that `pauseBgPreRender.fbufSave` and `pauseBgPreRender.cvgSave` are filled with the appropriate + // content and can be used by `PreRender_ApplyFilters` below. + MsgEvent_SendNullTask(); - // SOH [Port] Draw game framebuffer using our custom handling - //func_800C24BC(&play->pauseBgPreRender, &sp84); - FB_DrawFromFramebuffer(&sp84, gPauseFrameBuffer, 255); - POLY_OPA_DISP = sp84; + PreRender_Calc(&play->pauseBgPreRender); - goto Play_Draw_DrawOverlayElements; - } else { - s32 sp80; + R_PAUSE_MENU_MODE = 3; + } else if (R_PAUSE_MENU_MODE >= 4) { + R_PAUSE_MENU_MODE = 0; + } - if ((HREG(80) != 10) || (HREG(83) != 0)) { - if (play->skyboxId && (play->skyboxId != SKYBOX_UNSET_1D) && - !play->envCtx.skyboxDisabled) { - if ((play->skyboxId == SKYBOX_NORMAL_SKY) || - (play->skyboxId == SKYBOX_CUTSCENE_MAP)) { - Environment_UpdateSkybox(play, play->skyboxId, &play->envCtx, &play->skyboxCtx); + if (R_PAUSE_MENU_MODE == 3) { + Gfx* gfxP = POLY_OPA_DISP; - SkyboxDraw_Draw(&play->skyboxCtx, gfxCtx, play->skyboxId, - play->envCtx.skyboxBlend, play->view.eye.x, play->view.eye.y, - play->view.eye.z); - } else if (play->skyboxCtx.unk_140 == 0) { - SkyboxDraw_Draw(&play->skyboxCtx, gfxCtx, play->skyboxId, 0, - play->view.eye.x, play->view.eye.y, play->view.eye.z); - } - } - } + // SOH [Port] Draw game framebuffer using our custom handling + //func_800C24BC(&play->pauseBgPreRender, &gfxP); + FB_DrawFromFramebuffer(&gfxP, gPauseFrameBuffer, 255); + POLY_OPA_DISP = gfxP; - if ((HREG(80) != 10) || (HREG(90) & 2)) { - if (!play->envCtx.sunMoonDisabled) { - Environment_DrawSunAndMoon(play); - } - } + goto Play_Draw_DrawOverlayElements; + } - if ((HREG(80) != 10) || (HREG(90) & 1)) { - Environment_DrawSkyboxFilters(play); - } - - if ((HREG(80) != 10) || (HREG(90) & 4)) { - Environment_UpdateLightningStrike(play); - Environment_DrawLightning(play, 0); - } - - if ((HREG(80) != 10) || (HREG(90) & 8)) { - sp228 = LightContext_NewLights(&play->lightCtx, gfxCtx); - Lights_BindAll(sp228, play->lightCtx.listHead, NULL); - Lights_Draw(sp228, gfxCtx); - } - - if ((HREG(80) != 10) || (HREG(84) != 0)) { - if (VREG(94) == 0) { - if (HREG(80) != 10) { - sp80 = 3; - } else { - sp80 = HREG(84); - } - Scene_Draw(play); - Room_Draw(play, &play->roomCtx.curRoom, sp80 & 3); - Room_Draw(play, &play->roomCtx.prevRoom, sp80 & 3); - } - } - - if ((HREG(80) != 10) || (HREG(83) != 0)) { - if ((play->skyboxCtx.unk_140 != 0) && - (GET_ACTIVE_CAM(play)->setting != CAM_SET_PREREND_FIXED)) { - Vec3f sp74; - - Camera_GetSkyboxOffset(&sp74, GET_ACTIVE_CAM(play)); - SkyboxDraw_Draw(&play->skyboxCtx, gfxCtx, play->skyboxId, 0, - play->view.eye.x + sp74.x, play->view.eye.y + sp74.y, - play->view.eye.z + sp74.z); - } - } - - if (play->envCtx.unk_EE[1] != 0) { - Environment_DrawRain(play, &play->view, gfxCtx); - } - - if ((HREG(80) != 10) || (HREG(84) != 0)) { - Environment_FillScreen(gfxCtx, 0, 0, 0, play->unk_11E18, FILL_SCREEN_OPA); - } - - if ((HREG(80) != 10) || (HREG(85) != 0)) { - func_800315AC(play, &play->actorCtx); - } - - if ((HREG(80) != 10) || (HREG(86) != 0)) { - if (!play->envCtx.sunMoonDisabled) { - sp21C.x = play->view.eye.x + play->envCtx.sunPos.x; - sp21C.y = play->view.eye.y + play->envCtx.sunPos.y; - sp21C.z = play->view.eye.z + play->envCtx.sunPos.z; - Environment_DrawSunLensFlare(play, &play->envCtx, &play->view, gfxCtx, sp21C, 0); - } - Environment_DrawCustomLensFlare(play); - } - - if ((HREG(80) != 10) || (HREG(87) != 0)) { - if (MREG(64) != 0) { - Environment_FillScreen(gfxCtx, MREG(65), MREG(66), MREG(67), MREG(68), - FILL_SCREEN_OPA | FILL_SCREEN_XLU); - } - - switch (play->envCtx.fillScreen) { - case 1: - Environment_FillScreen( - gfxCtx, play->envCtx.screenFillColor[0], play->envCtx.screenFillColor[1], - play->envCtx.screenFillColor[2], play->envCtx.screenFillColor[3], - FILL_SCREEN_OPA | FILL_SCREEN_XLU); - break; - default: - break; - } - } - - if ((HREG(80) != 10) || (HREG(88) != 0)) { - if (play->envCtx.sandstormState != SANDSTORM_OFF) { - Environment_DrawSandstorm(play, play->envCtx.sandstormState); - } - } - - if ((HREG(80) != 10) || (HREG(93) != 0)) { - DebugDisplay_DrawObjects(play); - } - - if ((R_PAUSE_MENU_MODE == 1) || (gTrnsnUnkState == 1)) { - Gfx* sp70 = OVERLAY_DISP; - - play->pauseBgPreRender.fbuf = gfxCtx->curFrameBuffer; - play->pauseBgPreRender.fbufSave = (u16*)gZBuffer; - // SOH [Port] Use our custom copy method instead of the prerender system - // func_800C1F20(&play->pauseBgPreRender, &sp70); - if (R_PAUSE_MENU_MODE == 1) { - play->pauseBgPreRender.cvgSave = (u8*)gfxCtx->curFrameBuffer; - // func_800C20B4(&play->pauseBgPreRender, &sp70); - R_PAUSE_MENU_MODE = 2; - - // #region SOH [Port] Custom handling for pause prerender background capture - lastPauseWidth = OTRGetGameRenderWidth(); - lastPauseHeight = OTRGetGameRenderHeight(); - hasCapturedPauseBuffer = false; - - FB_CopyToFramebuffer(&sp70, 0, gPauseFrameBuffer, false, &hasCapturedPauseBuffer); - - // Set the state back to ready after the recapture is done - if (recapturePauseBuffer) { - R_PAUSE_MENU_MODE = 3; - } - // #endregion - } else { - gTrnsnUnkState = 2; - } - OVERLAY_DISP = sp70; - play->unk_121C7 = 2; - SREG(33) |= 1; - - // 2S2H [Port] Continue to render the post world for pausing to avoid flashing the HUD - if (!(gTrnsnUnkState == 1)) { - goto Play_Draw_DrawOverlayElements; - } - } else if (R_PAUSE_MENU_MODE != 3) { - Play_Draw_DrawOverlayElements: - if ((HREG(80) != 10) || (HREG(89) != 0)) { - Play_DrawOverlayElements(play); - } + if ((HREG(80) != 10) || (HREG(83) != 0)) { + if (play->skyboxId && (play->skyboxId != SKYBOX_UNSET_1D) && !play->envCtx.skyboxDisabled) { + if ((play->skyboxId == SKYBOX_NORMAL_SKY) || (play->skyboxId == SKYBOX_CUTSCENE_MAP)) { + Environment_UpdateSkybox(play, play->skyboxId, &play->envCtx, &play->skyboxCtx); + SkyboxDraw_Draw(&play->skyboxCtx, gfxCtx, play->skyboxId, play->envCtx.skyboxBlend, + play->view.eye.x, play->view.eye.y, play->view.eye.z); + } else if (play->skyboxCtx.unk_140 == 0) { + SkyboxDraw_Draw(&play->skyboxCtx, gfxCtx, play->skyboxId, 0, play->view.eye.x, play->view.eye.y, + play->view.eye.z); } } } + if ((HREG(80) != 10) || (HREG(90) & 2)) { + if (!play->envCtx.sunMoonDisabled) { + Environment_DrawSunAndMoon(play); + } + } + + if ((HREG(80) != 10) || (HREG(90) & 1)) { + Environment_DrawSkyboxFilters(play); + } + + if ((HREG(80) != 10) || (HREG(90) & 4)) { + Environment_UpdateLightningStrike(play); + Environment_DrawLightning(play, 0); + } + + if ((HREG(80) != 10) || (HREG(90) & 8)) { + sp228 = LightContext_NewLights(&play->lightCtx, gfxCtx); + Lights_BindAll(sp228, play->lightCtx.listHead, NULL); + Lights_Draw(sp228, gfxCtx); + } + + if ((HREG(80) != 10) || (HREG(84) != 0)) { + if (VREG(94) == 0) { + s32 roomDrawFlags; + + if (HREG(80) != 10) { + roomDrawFlags = 3; + } else { + roomDrawFlags = HREG(84); + } + Scene_Draw(play); + Room_Draw(play, &play->roomCtx.curRoom, roomDrawFlags & 3); + Room_Draw(play, &play->roomCtx.prevRoom, roomDrawFlags & 3); + } + } + + if ((HREG(80) != 10) || (HREG(83) != 0)) { + if ((play->skyboxCtx.unk_140 != 0) && + (GET_ACTIVE_CAM(play)->setting != CAM_SET_PREREND_FIXED)) { + Vec3f quakeOffset; + + Camera_GetSkyboxOffset(&quakeOffset, GET_ACTIVE_CAM(play)); + SkyboxDraw_Draw(&play->skyboxCtx, gfxCtx, play->skyboxId, 0, play->view.eye.x + quakeOffset.x, + play->view.eye.y + quakeOffset.y, play->view.eye.z + quakeOffset.z); + } + } + + if (play->envCtx.unk_EE[1] != 0) { + Environment_DrawRain(play, &play->view, gfxCtx); + } + + if ((HREG(80) != 10) || (HREG(84) != 0)) { + Environment_FillScreen(gfxCtx, 0, 0, 0, play->unk_11E18, FILL_SCREEN_OPA); + } + + if ((HREG(80) != 10) || (HREG(85) != 0)) { + func_800315AC(play, &play->actorCtx); + } + + if ((HREG(80) != 10) || (HREG(86) != 0)) { + if (!play->envCtx.sunMoonDisabled) { + sp21C.x = play->view.eye.x + play->envCtx.sunPos.x; + sp21C.y = play->view.eye.y + play->envCtx.sunPos.y; + sp21C.z = play->view.eye.z + play->envCtx.sunPos.z; + Environment_DrawSunLensFlare(play, &play->envCtx, &play->view, gfxCtx, sp21C, 0); + } + Environment_DrawCustomLensFlare(play); + } + + if ((HREG(80) != 10) || (HREG(87) != 0)) { + if (MREG(64) != 0) { + Environment_FillScreen(gfxCtx, MREG(65), MREG(66), MREG(67), MREG(68), + FILL_SCREEN_OPA | FILL_SCREEN_XLU); + } + + switch (play->envCtx.fillScreen) { + case 1: + Environment_FillScreen(gfxCtx, play->envCtx.screenFillColor[0], play->envCtx.screenFillColor[1], + play->envCtx.screenFillColor[2], play->envCtx.screenFillColor[3], + FILL_SCREEN_OPA | FILL_SCREEN_XLU); + break; + default: + break; + } + } + + if ((HREG(80) != 10) || (HREG(88) != 0)) { + if (play->envCtx.sandstormState != SANDSTORM_OFF) { + Environment_DrawSandstorm(play, play->envCtx.sandstormState); + } + } + + if ((HREG(80) != 10) || (HREG(93) != 0)) { + DebugDisplay_DrawObjects(play); + } + + if ((R_PAUSE_MENU_MODE == 1) || (gTrnsnUnkState == 1)) { + Gfx* gfxP = OVERLAY_DISP; + + // Copy the frame buffer contents at this point in the display list to the zbuffer + // The zbuffer must then stay untouched until unpausing + play->pauseBgPreRender.fbuf = gfxCtx->curFrameBuffer; + play->pauseBgPreRender.fbufSave = (u16*)gZBuffer; + // SOH [Port] Use our custom copy method instead of the prerender system + // func_800C1F20(&play->pauseBgPreRender, &gfxP); + if (R_PAUSE_MENU_MODE == 1) { + play->pauseBgPreRender.cvgSave = (u8*)gfxCtx->curFrameBuffer; + // func_800C20B4(&play->pauseBgPreRender, &gfxP); + R_PAUSE_MENU_MODE = 2; + + // #region SOH [Port] Custom handling for pause prerender background capture + lastPauseWidth = OTRGetGameRenderWidth(); + lastPauseHeight = OTRGetGameRenderHeight(); + lastAltAssets = ResourceMgr_IsAltAssetsEnabled(); + hasCapturedPauseBuffer = false; + + FB_CopyToFramebuffer(&gfxP, 0, gPauseFrameBuffer, false, &hasCapturedPauseBuffer); + + // Set the state back to ready after the recapture is done + if (recapturePauseBuffer) { + R_PAUSE_MENU_MODE = 3; + } + // #endregion + } else { + gTrnsnUnkState = 2; + } + OVERLAY_DISP = gfxP; + play->unk_121C7 = 2; + SREG(33) |= 1; + + // SOH [Port] Continue to render the post world for pausing to avoid flashing the HUD + if (gTrnsnUnkState == 2) { + goto Play_Draw_skip; + } + } + + // Draw Enhancements that need to be placed in the world. This happens before the PostWorldDraw + // so that they aren't drawn when the pause menu is up (e.g. collision viewer, actor name tags) GameInteractor_ExecuteOnPlayDrawEnd(); + Play_Draw_DrawOverlayElements: + if ((HREG(80) != 10) || (HREG(89) != 0)) { + Play_DrawOverlayElements(play); + } + // Reset the inverted culling if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) { gSPClearExtraGeometryMode(POLY_OPA_DISP++, G_EX_INVERT_CULLING); @@ -1649,13 +1635,14 @@ void Play_Draw(PlayState* play) { } } +Play_Draw_skip: + if (play->view.unk_124 != 0) { Camera_Update(GET_ACTIVE_CAM(play)); func_800AB944(&play->view); play->view.unk_124 = 0; if (play->skyboxId && (play->skyboxId != SKYBOX_UNSET_1D) && !play->envCtx.skyboxDisabled) { - SkyboxDraw_UpdateMatrix(&play->skyboxCtx, play->view.eye.x, play->view.eye.y, - play->view.eye.z); + SkyboxDraw_UpdateMatrix(&play->skyboxCtx, play->view.eye.x, play->view.eye.y, play->view.eye.z); } } @@ -1695,9 +1682,7 @@ void Play_Main(GameState* thisx) { DebugDisplay_Init(); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(4556); if ((HREG(80) == 10) && (HREG(94) != 10)) { HREG(81) = 1; @@ -1720,18 +1705,14 @@ void Play_Main(GameState* thisx) { Play_Update(play); } - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } + PLAY_LOG(4583); FrameInterpolation_StartRecord(); Play_Draw(play); FrameInterpolation_StopRecord(); - if (1 && HREG(63)) { - LOG_NUM("1", 1); - } - + PLAY_LOG(4587); + if (CVarGetInteger(CVAR_CHEAT("TimeSync"), 0)) { const int maxRealDaySeconds = 86400; const int maxInGameDayTicks = 65536; @@ -1756,23 +1737,18 @@ s32 Play_InCsMode(PlayState* play) { return (play->csCtx.state != CS_STATE_IDLE) || Player_InCsMode(play); } -f32 func_800BFCB8(PlayState* play, MtxF* mf, Vec3f* vec) { +f32 func_800BFCB8(PlayState* play, MtxF* mf, Vec3f* pos) { CollisionPoly poly; f32 temp1; f32 temp2; f32 temp3; - f32 floorY; - f32 nx; - f32 ny; - f32 nz; - s32 pad[5]; - - floorY = BgCheck_AnyRaycastFloor1(&play->colCtx, &poly, vec); + f32 floorY = BgCheck_AnyRaycastFloor1(&play->colCtx, &poly, pos); if (floorY > BGCHECK_Y_MIN) { - nx = COLPOLY_GET_NORMAL(poly.normal.x); - ny = COLPOLY_GET_NORMAL(poly.normal.y); - nz = COLPOLY_GET_NORMAL(poly.normal.z); + f32 nx = COLPOLY_GET_NORMAL(poly.normal.x); + f32 ny = COLPOLY_GET_NORMAL(poly.normal.y); + f32 nz = COLPOLY_GET_NORMAL(poly.normal.z); + s32 pad[5]; temp1 = sqrtf(1.0f - SQ(nx)); @@ -1796,9 +1772,9 @@ f32 func_800BFCB8(PlayState* play, MtxF* mf, Vec3f* vec) { mf->wy = 0.0f; mf->xz = 0.0f; mf->wz = 0.0f; - mf->xw = vec->x; + mf->xw = pos->x; mf->yw = floorY; - mf->zw = vec->z; + mf->zw = pos->z; mf->ww = 1.0f; } else { mf->xy = 0.0f; @@ -1813,9 +1789,9 @@ f32 func_800BFCB8(PlayState* play, MtxF* mf, Vec3f* vec) { mf->yz = 0.0f; mf->zy = 0.0f; mf->yy = 1.0f; - mf->xw = vec->x; - mf->yw = vec->y; - mf->zw = vec->z; + mf->xw = pos->x; + mf->yw = pos->y; + mf->zw = pos->z; mf->ww = 1.0f; } @@ -1838,16 +1814,18 @@ void Play_InitEnvironment(PlayState* play, s16 skyboxId) { Environment_Init(play, &play->envCtx, 0); } -void Play_InitScene(PlayState* play, s32 spawn) -{ +void Play_InitScene(PlayState* play, s32 spawn) { play->curSpawn = spawn; + play->linkActorEntry = NULL; play->unk_11DFC = NULL; play->setupEntranceList = NULL; play->setupExitList = NULL; play->cUpElfMsgs = NULL; play->setupPathList = NULL; + play->numSetupActors = 0; + Object_InitBank(play, &play->objectCtx); LightContext_Init(play, &play->lightCtx); TransitionActor_InitContext(&play->state, &play->transiActorCtx); @@ -1858,33 +1836,28 @@ void Play_InitScene(PlayState* play, s32 spawn) Play_InitEnvironment(play, play->skyboxId); } -void Play_SpawnScene(PlayState* play, s32 sceneNum, s32 spawn) { +void Play_SpawnScene(PlayState* play, s32 sceneId, s32 spawn) { uint8_t mqMode = CVarGetInteger(CVAR_GENERAL("BetterDebugWarpScreenMQMode"), WARP_MODE_OVERRIDE_OFF); int16_t mqModeScene = CVarGetInteger(CVAR_GENERAL("BetterDebugWarpScreenMQModeScene"), -1); - if (mqMode != WARP_MODE_OVERRIDE_OFF && sceneNum != mqModeScene) { + if (mqMode != WARP_MODE_OVERRIDE_OFF && sceneId != mqModeScene) { CVarClear(CVAR_GENERAL("BetterDebugWarpScreenMQMode")); CVarClear(CVAR_GENERAL("BetterDebugWarpScreenMQModeScene")); } - OTRPlay_SpawnScene(play, sceneNum, spawn); - - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { - Entrance_OverrideSpawnScene(sceneNum, spawn); - } + OTRPlay_SpawnScene(play, sceneId, spawn); } void func_800C016C(PlayState* play, Vec3f* src, Vec3f* dest) { - f32 temp; + f32 w; Matrix_Mult(&play->viewProjectionMtxF, MTXMODE_NEW); Matrix_MultVec3f(src, dest); - temp = play->viewProjectionMtxF.ww + - (play->viewProjectionMtxF.wx * src->x + play->viewProjectionMtxF.wy * src->y + - play->viewProjectionMtxF.wz * src->z); + w = play->viewProjectionMtxF.ww + (play->viewProjectionMtxF.wx * src->x + play->viewProjectionMtxF.wy * src->y + + play->viewProjectionMtxF.wz * src->z); - dest->x = 160.0f + ((dest->x / temp) * 160.0f); - dest->y = 120.0f + ((dest->y / temp) * 120.0f); + dest->x = (SCREEN_WIDTH / 2) + ((dest->x / w) * (SCREEN_WIDTH / 2)); + dest->y = (SCREEN_HEIGHT / 2) - ((dest->y / w) * (SCREEN_HEIGHT / 2)); } s16 Play_CreateSubCamera(PlayState* play) { @@ -2107,8 +2080,8 @@ void Play_SaveSceneFlags(PlayState* play) { savedSceneFlags->collect = play->actorCtx.flags.collect; } -void Play_SetRespawnData(PlayState* play, s32 respawnMode, s16 entranceIndex, s32 roomIndex, - s32 playerParams, Vec3f* pos, s16 yaw) { +void Play_SetRespawnData(PlayState* play, s32 respawnMode, s16 entranceIndex, s32 roomIndex, s32 playerParams, + Vec3f* pos, s16 yaw) { RespawnData* respawnData = &gSaveContext.respawn[respawnMode]; respawnData->entranceIndex = entranceIndex; @@ -2128,8 +2101,8 @@ void Play_SetupRespawnPoint(PlayState* play, s32 respawnMode, s32 playerParams) if ((play->sceneNum != SCENE_FAIRYS_FOUNTAIN) && (play->sceneNum != SCENE_GROTTOS)) { roomIndex = play->roomCtx.curRoom.num; entranceIndex = gSaveContext.entranceIndex; - Play_SetRespawnData(play, respawnMode, entranceIndex, roomIndex, playerParams, - &player->actor.world.pos, player->actor.shape.rot.y); + Play_SetRespawnData(play, respawnMode, entranceIndex, roomIndex, playerParams, &player->actor.world.pos, + player->actor.shape.rot.y); } } @@ -2146,13 +2119,16 @@ void Play_LoadToLastEntrance(PlayState* play) { gSaveContext.respawnFlag = -1; play->transitionTrigger = TRANS_TRIGGER_START; - if ((play->sceneNum == SCENE_GANONS_TOWER_COLLAPSE_INTERIOR) || (play->sceneNum == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) || + if ((play->sceneNum == SCENE_GANONS_TOWER_COLLAPSE_INTERIOR) || + (play->sceneNum == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) || (play->sceneNum == SCENE_INSIDE_GANONS_CASTLE_COLLAPSE) || (play->sceneNum == SCENE_GANON_BOSS)) { play->nextEntranceIndex = ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0; Item_Give(play, ITEM_SWORD_MASTER); - } else if ((gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_11) || (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_12) || - (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_13) || (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_15)) { - play->nextEntranceIndex = ENTR_HYRULE_FIELD_6; + } else if ((gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_11) || + (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_12) || + (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_13) || + (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_15)) { + play->nextEntranceIndex = ENTR_HYRULE_FIELD_CENTER_EXIT; } else { play->nextEntranceIndex = gSaveContext.entranceIndex; } diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index 94a8aa66d..620b5f474 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -9,6 +9,7 @@ #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/randomizer/draw.h" +#include "soh/ResourceManagerHelpers.h" #include @@ -887,6 +888,16 @@ s32 Player_HoldsSlingshot(Player* this) { return this->heldItemAction == PLAYER_IA_SLINGSHOT; } +// #region SOH [Enhancement] +s32 Player_HoldsBoomerang(Player* this) { + return this->heldItemAction == PLAYER_IA_BOOMERANG; +} + +s32 Player_AimsBoomerang(Player* this) { + return Player_HoldsBoomerang(this) && (this->unk_834 != 0); +} +// #endregion + s32 func_8008F128(Player* this) { return Player_HoldsHookshot(this) && (this->heldActor == NULL); } @@ -1762,7 +1773,7 @@ Vec3f sLeftHandArrowVec3 = { 398.0f, 1419.0f, 244.0f }; BowStringData sBowStringData[] = { { gLinkAdultBowStringDL, { 0.0f, -360.4f, 0.0f } }, // bow - { gLinkChildSlinghotStringDL, { 606.0f, 236.0f, 0.0f } }, // slingshot + { gLinkChildSlingshotStringDL, { 606.0f, 236.0f, 0.0f } }, // slingshot }; Vec3f sRightHandLimbModelShieldQuadVertices[] = { @@ -1798,6 +1809,9 @@ Vec3f sLeftRightFootLimbModelFootPos[] = { void Player_PostLimbDrawGameplay(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) { Player* this = (Player*)thisx; + const Vec3s BoomerangViewAdult = { -31200, -9200, 17000 }; + const Vec3s BoomerangViewChild = { -31200, -8700, 17000 }; + if (*dList != NULL) { Matrix_MultVec3f(&sZeroVec, D_80160000); } @@ -1959,6 +1973,8 @@ void Player_PostLimbDrawGameplay(PlayState* play, s32 limbIndex, Gfx** dList, Ve play, this, ((this->heldItemAction == PLAYER_IA_HOOKSHOT) ? 38600.0f : 77600.0f) * CVarGetFloat(CVAR_CHEAT("HookshotReachMultiplier"), 1.0f)); } } + + // #region SOH [Enhancement] } else if (CVarGetInteger(CVAR_ENHANCEMENT("BowReticle"), 0) && ( (this->heldItemAction == PLAYER_IA_BOW_FIRE) || (this->heldItemAction == PLAYER_IA_BOW_ICE) || @@ -1977,6 +1993,21 @@ void Player_PostLimbDrawGameplay(PlayState* play, s32 limbIndex, Gfx** dList, Ve Player_DrawHookshotReticle(play, this, RETICLE_MAX); } } + } else if (CVarGetInteger(CVAR_ENHANCEMENT("BoomerangReticle"), 0) && (this->heldItemAction == PLAYER_IA_BOOMERANG)) { + if (Player_HoldsBoomerang(this)) { + if (LINK_IS_ADULT) { + Matrix_RotateZYX(BoomerangViewAdult.x, BoomerangViewAdult.y, BoomerangViewAdult.z, + MTXMODE_APPLY); + } else { + Matrix_RotateZYX(BoomerangViewChild.x, BoomerangViewChild.y, BoomerangViewChild.z, MTXMODE_APPLY); + } + + if (Player_AimsBoomerang(this)) { + Matrix_Translate(500.0f, 300.0f, 0.0f, MTXMODE_APPLY); + Player_DrawHookshotReticle(play, this, RETICLE_MAX); + } + } + // #endregion } if ((this->unk_862 != 0) || ((func_8002DD6C(this) == 0) && (heldActor != NULL))) { diff --git a/soh/src/code/z_rcp.c b/soh/src/code/z_rcp.c index 978c04d3c..767772949 100644 --- a/soh/src/code/z_rcp.c +++ b/soh/src/code/z_rcp.c @@ -1,5 +1,6 @@ #include "global.h" #include +#include "soh/OTRGlobals.h" Gfx sSetupDL[SETUPDL_MAX][6] = { { diff --git a/soh/src/code/z_room.c b/soh/src/code/z_room.c index 2db187375..2e8cdc655 100644 --- a/soh/src/code/z_room.c +++ b/soh/src/code/z_room.c @@ -4,12 +4,13 @@ #include "global.h" #include "vt.h" -#include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include #include #include "public/bridge/gfxbridge.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" void func_80095AB4(PlayState* play, Room* room, u32 flags); void func_80095D04(PlayState* play, Room* room, u32 flags); @@ -578,13 +579,6 @@ u32 func_80096FE8(PlayState* play, RoomContext* roomCtx) { frontRoom = gSaveContext.respawnFlag > 0 ? ((void)0, gSaveContext.respawn[gSaveContext.respawnFlag - 1].roomIndex) : play->setupEntranceList[play->curSpawn].room; - - // In ER, override roomNum to load based on scene and spawn during scene init - if (IS_RANDO && gSaveContext.respawnFlag <= 0 && - Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { - frontRoom = Entrance_OverrideSpawnSceneRoom(play->sceneNum, play->curSpawn, frontRoom); - } - func_8009728C(play, roomCtx, frontRoom); return maxRoomSize; diff --git a/soh/src/code/z_scene.c b/soh/src/code/z_scene.c index eeff423d7..2ce88cc04 100644 --- a/soh/src/code/z_scene.c +++ b/soh/src/code/z_scene.c @@ -33,6 +33,10 @@ s32 Object_Spawn(ObjectContext* objectCtx, s16 objectId) { return objectCtx->num - 1; } + +// SOH [Port] Track when objects are first loaded for a scene +static u8 sObjectFirstUpdateSkippedForScene = false; + void Object_InitBank(PlayState* play, ObjectContext* objectCtx) { PlayState* play2 = play; // Needs to be a new variable to match (possibly a sub struct?) size_t spaceSize; @@ -75,6 +79,8 @@ void Object_InitBank(PlayState* play, ObjectContext* objectCtx) { objectCtx->mainKeepIndex = Object_Spawn(objectCtx, OBJECT_GAMEPLAY_KEEP); gSegments[4] = VIRTUAL_TO_PHYSICAL(objectCtx->status[objectCtx->mainKeepIndex].segment); + + sObjectFirstUpdateSkippedForScene = false; } void Object_UpdateBank(ObjectContext* objectCtx) { @@ -83,6 +89,12 @@ void Object_UpdateBank(ObjectContext* objectCtx) { RomFile* objectFile; size_t size; + // SOH [Port] Skip the first object load after scene init so that actors have their init delayed by one frame + // This seems to mostly if not nearly resolve actors that depend on console DMA requests ending later + if (!sObjectFirstUpdateSkippedForScene) { + sObjectFirstUpdateSkippedForScene = true; + return; + } for (i = 0; i < objectCtx->num; i++) { if (status->id < 0) { @@ -363,7 +375,7 @@ void Scene_CommandTimeSettings(PlayState* play, SceneCmd* cmd) { play->envCtx.sunPos.z = (Math_CosS(((void)0, gSaveContext.dayTime) - 0x8000) * 20.0f) * 25.0f; if (((play->envCtx.timeIncrement == 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) || - (gSaveContext.entranceIndex == ENTR_LAKE_HYLIA_8)) { + (gSaveContext.entranceIndex == ENTR_LAKE_HYLIA_WARP_PAD)) { gSaveContext.skyboxTime = ((void)0, gSaveContext.dayTime); if ((gSaveContext.skyboxTime >= 0x2AAC) && (gSaveContext.skyboxTime < 0x4555)) { gSaveContext.skyboxTime = 0x3556; diff --git a/soh/src/code/z_scene_table.c b/soh/src/code/z_scene_table.c index 9cb9a31d7..c7d76db01 100644 --- a/soh/src/code/z_scene_table.c +++ b/soh/src/code/z_scene_table.c @@ -25,6 +25,8 @@ #include "soh/mq_asset_hacks.h" #include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" // Entrance Table definition #define DEFINE_ENTRANCE(_0, sceneId, spawn, continueBgm, displayTitleCard, endTransType, startTransType) \ diff --git a/soh/src/code/z_skelanime.c b/soh/src/code/z_skelanime.c index 0bcf39236..e91de847b 100644 --- a/soh/src/code/z_skelanime.c +++ b/soh/src/code/z_skelanime.c @@ -3,6 +3,8 @@ #include #include #include +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define ANIM_INTERP 1 diff --git a/soh/src/code/z_skin_awb.c b/soh/src/code/z_skin_awb.c index d0ebe75b4..3627797b4 100644 --- a/soh/src/code/z_skin_awb.c +++ b/soh/src/code/z_skin_awb.c @@ -1,6 +1,7 @@ #include "global.h" #include "overlays/actors/ovl_En_fHG/z_en_fhg.h" #include +#include "soh/ResourceManagerHelpers.h" /** * Initialises the Vtx buffers used for limb at index `limbIndex` diff --git a/soh/src/code/z_sound_source.c b/soh/src/code/z_sound_source.c index 16e3fee5b..055afec39 100644 --- a/soh/src/code/z_sound_source.c +++ b/soh/src/code/z_sound_source.c @@ -58,5 +58,5 @@ void SoundSource_PlaySfxAtFixedWorldPos(PlayState* play, Vec3f* worldPos, s32 du source->countdown = duration; SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &source->worldPos, &source->projectedPos); - Audio_PlaySoundGeneral(sfxId, &source->projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, &source->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 944751e8c..adea0cbbf 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -4,8 +4,9 @@ #include #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -#include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/randomizer/savefile.h" +#include "soh/OTRGlobals.h" +#include "soh/SaveManager.h" #define NUM_DUNGEONS 8 #define NUM_COWS 10 @@ -41,20 +42,20 @@ void Sram_InitBossRushSave(void) { } static s16 sDungeonEntrances[] = { - ENTR_DEKU_TREE_0, // SCENE_DEKU_TREE - ENTR_DODONGOS_CAVERN_0, // SCENE_DODONGOS_CAVERN - ENTR_JABU_JABU_0, // SCENE_JABU_JABU - ENTR_FOREST_TEMPLE_0, // SCENE_FOREST_TEMPLE - ENTR_FIRE_TEMPLE_0, // SCENE_FIRE_TEMPLE - ENTR_WATER_TEMPLE_0, // SCENE_WATER_TEMPLE - ENTR_SPIRIT_TEMPLE_0, // SCENE_SPIRIT_TEMPLE - ENTR_SHADOW_TEMPLE_0, // SCENE_SHADOW_TEMPLE - ENTR_BOTTOM_OF_THE_WELL_0, // SCENE_BOTTOM_OF_THE_WELL - ENTR_ICE_CAVERN_0, // SCENE_ICE_CAVERN + ENTR_DEKU_TREE_ENTRANCE, // SCENE_DEKU_TREE + ENTR_DODONGOS_CAVERN_ENTRANCE, // SCENE_DODONGOS_CAVERN + ENTR_JABU_JABU_ENTRANCE, // SCENE_JABU_JABU + ENTR_FOREST_TEMPLE_ENTRANCE, // SCENE_FOREST_TEMPLE + ENTR_FIRE_TEMPLE_ENTRANCE, // SCENE_FIRE_TEMPLE + ENTR_WATER_TEMPLE_ENTRANCE, // SCENE_WATER_TEMPLE + ENTR_SPIRIT_TEMPLE_ENTRANCE, // SCENE_SPIRIT_TEMPLE + ENTR_SHADOW_TEMPLE_ENTRANCE, // SCENE_SHADOW_TEMPLE + ENTR_BOTTOM_OF_THE_WELL_ENTRANCE, // SCENE_BOTTOM_OF_THE_WELL + ENTR_ICE_CAVERN_ENTRANCE, // SCENE_ICE_CAVERN ENTR_GANONS_TOWER_0, // SCENE_GANONS_TOWER - ENTR_GERUDO_TRAINING_GROUND_0, // SCENE_GERUDO_TRAINING_GROUND + ENTR_GERUDO_TRAINING_GROUND_ENTRANCE, // SCENE_GERUDO_TRAINING_GROUND ENTR_THIEVES_HIDEOUT_0, // SCENE_THIEVES_HIDEOUT - ENTR_INSIDE_GANONS_CASTLE_0, // SCENE_INSIDE_GANONS_CASTLE + ENTR_INSIDE_GANONS_CASTLE_ENTRANCE, // SCENE_INSIDE_GANONS_CASTLE ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_0, // SCENE_GANONS_TOWER_COLLAPSE_INTERIOR ENTR_INSIDE_GANONS_CASTLE_COLLAPSE_0, // SCENE_INSIDE_GANONS_CASTLE_COLLAPSE }; @@ -94,28 +95,28 @@ void Sram_OpenSave() { gSaveContext.entranceIndex = sDungeonEntrances[gSaveContext.savedSceneNum]; break; case SCENE_DEKU_TREE_BOSS: - gSaveContext.entranceIndex = ENTR_DEKU_TREE_0; + gSaveContext.entranceIndex = ENTR_DEKU_TREE_ENTRANCE; break; case SCENE_DODONGOS_CAVERN_BOSS: - gSaveContext.entranceIndex = ENTR_DODONGOS_CAVERN_0; + gSaveContext.entranceIndex = ENTR_DODONGOS_CAVERN_ENTRANCE; break; case SCENE_JABU_JABU_BOSS: - gSaveContext.entranceIndex = ENTR_JABU_JABU_0; + gSaveContext.entranceIndex = ENTR_JABU_JABU_ENTRANCE; break; case SCENE_FOREST_TEMPLE_BOSS: - gSaveContext.entranceIndex = ENTR_FOREST_TEMPLE_0; + gSaveContext.entranceIndex = ENTR_FOREST_TEMPLE_ENTRANCE; break; case SCENE_FIRE_TEMPLE_BOSS: - gSaveContext.entranceIndex = ENTR_FIRE_TEMPLE_0; + gSaveContext.entranceIndex = ENTR_FIRE_TEMPLE_ENTRANCE; break; case SCENE_WATER_TEMPLE_BOSS: - gSaveContext.entranceIndex = ENTR_WATER_TEMPLE_0; + gSaveContext.entranceIndex = ENTR_WATER_TEMPLE_ENTRANCE; break; case SCENE_SPIRIT_TEMPLE_BOSS: - gSaveContext.entranceIndex = ENTR_SPIRIT_TEMPLE_0; + gSaveContext.entranceIndex = ENTR_SPIRIT_TEMPLE_ENTRANCE; break; case SCENE_SHADOW_TEMPLE_BOSS: - gSaveContext.entranceIndex = ENTR_SHADOW_TEMPLE_0; + gSaveContext.entranceIndex = ENTR_SHADOW_TEMPLE_ENTRANCE; break; case SCENE_GANONS_TOWER_COLLAPSE_INTERIOR: case SCENE_INSIDE_GANONS_CASTLE_COLLAPSE: @@ -133,9 +134,9 @@ void Sram_OpenSave() { } if (gSaveContext.savedSceneNum != SCENE_LINKS_HOUSE) { - gSaveContext.entranceIndex = (LINK_AGE_IN_YEARS == YEARS_CHILD) ? ENTR_LINKS_HOUSE_0 : ENTR_TEMPLE_OF_TIME_7; + gSaveContext.entranceIndex = (LINK_AGE_IN_YEARS == YEARS_CHILD) ? ENTR_LINKS_HOUSE_CHILD_SPAWN : ENTR_TEMPLE_OF_TIME_WARP_PAD; } else { - gSaveContext.entranceIndex = ENTR_LINKS_HOUSE_0; + gSaveContext.entranceIndex = ENTR_LINKS_HOUSE_CHILD_SPAWN; } break; } @@ -233,7 +234,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { Sram_InitDebugSave(); } - gSaveContext.entranceIndex = ENTR_LINKS_HOUSE_0; + gSaveContext.entranceIndex = ENTR_LINKS_HOUSE_CHILD_SPAWN; gSaveContext.linkAge = 1; gSaveContext.dayTime = 0x6AAB; gSaveContext.cutsceneIndex = 0xFFF1; @@ -250,7 +251,7 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { u8 currentQuest = fileChooseCtx->questType[fileChooseCtx->buttonIndex]; - if (currentQuest == QUEST_RANDOMIZER && (Randomizer_IsSeedGenerated() || Randomizer_IsPlandoLoaded())) { + if (currentQuest == QUEST_RANDOMIZER && (Randomizer_IsSeedGenerated() || Randomizer_IsSpoilerLoaded())) { gSaveContext.questId = QUEST_RANDOMIZER; Randomizer_InitSaveFile(); @@ -266,8 +267,4 @@ void Sram_InitSram(GameState* gameState) { Save_Init(); func_800F6700(gSaveContext.audioSetting); - - // When going from a rando save to a vanilla save within the same game instance - // we need to reset the entrance table back to its vanilla state - Entrance_ResetEntranceTable(); } diff --git a/soh/src/code/z_ss_sram.c b/soh/src/code/z_ss_sram.c index 51f28a068..8cea4b5d4 100644 --- a/soh/src/code/z_ss_sram.c +++ b/soh/src/code/z_ss_sram.c @@ -1,5 +1,6 @@ #include #include "global.h" +#include "soh/OTRGlobals.h" #include #include diff --git a/soh/src/code/z_viscvg.c b/soh/src/code/z_viscvg.c new file mode 100644 index 000000000..9caf39a3f --- /dev/null +++ b/soh/src/code/z_viscvg.c @@ -0,0 +1,145 @@ +/** + * @file z_viscvg.c + * + * This file implements full-screen frame buffer effects involving the visualization of Coverage in various ways. + * + * Coverage is roughly how much of a pixel is covered by a primitive; the final coverage for a frame is stored in the + * color image alpha component where it is used for antialiasing, see PreRender.c and §15 of the programming manual for + * details. + * + * To understand this file, it is helpful to remember that A_MEM is essentially synonymous with coverage, and that + * `GBL_c1/2(p, a, m, b)` usually represents the RDP blender calculation `(p * a + m * b)`. + * Note the division step that is often included in the blender calculation is omitted; the division is skipped if + * force blending (FORCE_BL) is set, which is the case for all render modes used in this file. + * + * Coverage is full when not on an edge, while on an edge it is usually lower. Since coverage is treated as an alpha + * value, edges of primitives where coverage is lower will show up darker than primitive interiors in all of the + * available modes. + * + * Coverage is abbreviated to "cvg"; "FB RGB" ("framebuffer red/green/blue") is the color the pixel originally had + * before the filter is applied. + */ + +#include "global.h" + +/** + * Draws only coverage: does not retain any of the original pixel RGB, primColor is used as background color. + */ +Gfx sCoverageOnlyDL[] = { + gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2), + // (blendColor RGB) * (cvg) + gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1), + gsDPPipeSync(), + gsDPSetBlendColor(0, 0, 0, 8), + gsSPEndDisplayList(), +}; + +/** + * Draws fog + coverage * RGB of pixels + * + * @bug This easily overflows the blender because the fog value is added to the coverage value. + */ +Gfx sCoverageRGBFogDL[] = { + gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | + GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM) | + GBL_c2(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM)), + // (fog RGB) * (fog alpha) + (FB RGB) * (cvg) + gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1), + gsSPEndDisplayList(), +}; + +/** + * Draws coverage and RGB of pixels + */ +Gfx sCoverageRGBDL[] = { + gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | + GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) | + GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)), + // (FB RGB) * (cvg) + gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1), + gsSPEndDisplayList(), +}; + +/** + * Two stage filtering: + * + * 1. Apply a uniform color filter by transparently blending primColor with original frame. The "cloud surface" + * RenderMode is used to preserve the coverage for the second stage. + * 2. Second half is the same as `sCoverageRGBDL`'s, i.e. (RGB from stage 1) * cvg + */ +Gfx sCoverageRGBUniformDL[] = { + gsDPSetCombineMode(G_CC_PRIMITIVE, G_CC_PRIMITIVE), + gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_DISABLE | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2), + // stage 1 color = (primColor RGB) * (primColor Alpha) + (FB RGB) * (1 - primColor Alpha) + gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1), + + gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL | + GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) | + GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)), + // final color = (stage 1 RGB) * (cvg) + gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1), + gsSPEndDisplayList(), +}; + +void VisCvg_Init(VisCvg* this) { + this->vis.type = FB_FILTER_NONE; + this->vis.scissorType = VIS_NO_SETSCISSOR; + this->vis.primColor.r = 255; + this->vis.primColor.g = 255; + this->vis.primColor.b = 255; + this->vis.primColor.a = 255; +} + +void VisCvg_Destroy(VisCvg* this) { +} + +void VisCvg_Draw(VisCvg* this, Gfx** gfxP) { + Gfx* gfx = *gfxP; + + gDPPipeSync(gfx++); + gDPSetPrimDepth(gfx++, 0xFFFF, 0xFFFF); + + if (this->vis.scissorType == VIS_SETSCISSOR) { + gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + } + + switch (this->vis.type) { + case FB_FILTER_CVG_RGB: + gSPDisplayList(gfx++, sCoverageRGBDL); + break; + + case FB_FILTER_CVG_RGB_UNIFORM: + // Set primitive color for uniform color filter in custom RenderMode + gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba); + gSPDisplayList(gfx++, sCoverageRGBUniformDL); + break; + + case FB_FILTER_CVG_ONLY: + // Set background color for G_RM_VISCVG + gDPSetColor(gfx++, G_SETBLENDCOLOR, this->vis.primColor.rgba); + gSPDisplayList(gfx++, sCoverageOnlyDL); + break; + + case FB_FILTER_CVG_RGB_FOG: + // Set fog color for custom RenderMode, needs to be close to 0 to not overflow + gDPSetColor(gfx++, G_SETFOGCOLOR, this->vis.primColor.rgba); + gSPDisplayList(gfx++, sCoverageRGBFogDL); + break; + + default: + break; + } + + gDPPipeSync(gfx++); + *gfxP = gfx; +} diff --git a/soh/src/code/z_vismono.c b/soh/src/code/z_vismono.c index c277eb971..a4e77d70d 100644 --- a/soh/src/code/z_vismono.c +++ b/soh/src/code/z_vismono.c @@ -1,137 +1,218 @@ +/** + * @file z_vismono.c + * + * This file implements a full-screen framebuffer effect for desaturating the contents of the framebuffer image. + * + * Broadly, this effect is achieved by reinterpreting the contents of the RGBA16 color image as indices into an IA16 + * color palette that converts each color into the desaturated equivalent. More precise details can be found in inline + * comments. + */ + #include "global.h" -#include + +#include // memset #include +#include "soh/framebuffer_effects.h" -// (Note: 80 = SCREEN_HEIGHT/3, see VisMono_DrawTexture) -// This may not have been kept up-to-date with the code, 1+1+1+80*(7+2+2+3)+1+1 makes more sense -#define DLSIZE (1 + 3 + 1 + 1 + 80 * (7 + 2 + 2 + 3) + 1) +// Upstream TODO: Replace these ones they are served from other headers +#define ASSERT(cond, msg, file, line) assert(cond) +#define GPACK_IA16(i, a) (((i) << 8) | (a)) -// framebuffer +// Height of the fragments the color frame buffer (CFB) is split into. +// It is the maximum amount of lines such that all rgba16 SCREEN_WIDTH-long lines fit into +// the half of TMEM dedicated to color-indexed data. +#define VISMONO_CFBFRAG_HEIGHT ((TMEM_SIZE / 2) / (SCREEN_WIDTH * G_IM_SIZ_16b_BYTES)) + +// Maximum size of the dlist written by `VisMono_DesaturateDList`. +// `VisMono_DesaturateDList` consistently uses `VISMONO_DLSIZE - 2` double words, so this can be 2 less. +#define VISMONO_DLSIZE (3 + SCREEN_HEIGHT / VISMONO_CFBFRAG_HEIGHT * (7 + 2 + 2 + 3) + 2 + 2) + +// How much each color component contributes to the desaturated result. +// These coefficients are close to what the YUV color space defines Y (luminance) as: +// https://en.wikipedia.org/wiki/YUV#Conversion_to/from_RGB +#define VISMONO_FAC_RED 2 +#define VISMONO_FAC_GREEN 4 +#define VISMONO_FAC_BLUE 1 +#define VISMONO_FAC_NORM (0x1F * VISMONO_FAC_RED + 0x1F * VISMONO_FAC_GREEN + 0x1F * VISMONO_FAC_BLUE) + +// color framebuffer extern u16 D_0F000000[]; void VisMono_Init(VisMono* this) { memset(this, 0, sizeof(VisMono)); - this->unk_00 = 0; - this->setScissor = false; - this->primColor.r = 255; - this->primColor.g = 255; - this->primColor.b = 255; - this->primColor.a = 255; - this->envColor.r = 0; - this->envColor.g = 0; - this->envColor.b = 0; - this->envColor.a = 0; + this->vis.type = 0; + this->vis.scissorType = VIS_NO_SETSCISSOR; + this->vis.primColor.r = 255; + this->vis.primColor.g = 255; + this->vis.primColor.b = 255; + this->vis.primColor.a = 255; + this->vis.envColor.r = 0; + this->vis.envColor.g = 0; + this->vis.envColor.b = 0; + this->vis.envColor.a = 0; } void VisMono_Destroy(VisMono* this) { - SYSTEM_ARENA_FREE_DEBUG(this->monoDl); + SYSTEM_ARENA_FREE(this->dList, "../z_vismono.c", 137); } -void VisMono_UpdateTexture(VisMono* this, u16* tex) { +void VisMono_DesaturateTLUT(VisMono* this, u16* tlut) { s32 i; for (i = 0; i < 256; i++) { - tex[i] = ((((i >> 3 & 0x1F) * 2 + (i << 2 & 0x1F) * 4) * 0xFF / 0xD9) << 8) | - (((i >> 6 & 0x1F) * 4 + (i >> 1 & 0x1F)) * 0xFF / 0xD9); + // `tlut[i]` is a IA16 color + // `i` corresponds to either byte of a RGBA16 color RRRR_RGGG GGBB_BBBA from the color frame buffer + + // The high byte I (intensity) corresponds to `i` being interpreted as the high byte RRRR_RGGG + // I = (RRRRR * FAC_RED + GGG00 * FAC_GREEN) * (255 / FAC_NORM) + + // The low byte A (alpha) corresponds to `i` being interpreted as the low byte GGBB_BBBA + // A = (000GG * FAC_GREEN + BBBBB * FAC_BLUE) * (255 / FAC_NORM) + + // Note: I + A = (RRRRR * FAC_RED + GGGGG * FAC_GREEN + BBBBB * FAC_BLUE) * (255 / FAC_NORM) + + tlut[i] = GPACK_IA16( + ((i >> 3 & 0x1F) * VISMONO_FAC_RED + (i << 2 & 0x1F) * VISMONO_FAC_GREEN) * 255 / VISMONO_FAC_NORM, + ((i >> 6 & 0x1F) * VISMONO_FAC_GREEN + (i >> 1 & 0x1F) * VISMONO_FAC_BLUE) * 255 / VISMONO_FAC_NORM); } } -Gfx* VisMono_DrawTexture(VisMono* this, Gfx* gfx) -{ -// OTRTODO -#if 1 +Gfx* VisMono_DesaturateDList(VisMono* this, Gfx* gfx) { s32 y; - s32 height = 3; - //u16* tex = D_0F000000; - u16* tex = SEG_ADDR(0xF, 0); + s32 height = VISMONO_CFBFRAG_HEIGHT; + u16* cfbFrag = D_0F000000; gDPPipeSync(gfx++); + // `G_TT_IA16`: use color-indexed images, and IA16 palettes gDPSetOtherMode(gfx++, G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_IA16 | G_TL_TILE | G_TD_CLAMP | G_TP_NONE | G_CYC_2CYCLE | G_PM_1PRIMITIVE, - G_AC_NONE | G_ZS_PRIM | GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) | G_RM_CLD_SURF2); + G_AC_NONE | G_ZS_PRIM | G_RM_PASS | G_RM_CLD_SURF2); + // First color cycle sums texel 1 alpha and texel 0 color + // By using IA16 palettes, this means summing A (from the IA16 color texel 1 maps to) + // with I (from the IA16 color texel 0 maps to) gDPSetCombineLERP(gfx++, 1, 0, TEXEL1_ALPHA, TEXEL0, 0, 0, 0, 1, PRIMITIVE, ENVIRONMENT, COMBINED, ENVIRONMENT, 0, 0, 0, PRIMITIVE); for (y = 0; y <= SCREEN_HEIGHT - height; y += height) { - gDPLoadTextureBlock(gfx++, tex, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2, height, 0, + // Load a few lines of the color frame buffer + gDPLoadTextureBlock(gfx++, cfbFrag, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2, 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); - gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, 80, 0x0, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0, - G_TX_NOMIRROR | G_TX_CLAMP, 0, 0); - gDPSetTileSize(gfx++, G_TX_RENDERTILE, (2 << 2), 0, ((SCREEN_WIDTH * 2 + 1) << 2), (2 << 2)); + // Set texel 0 to be a CI8 image with width `SCREEN_WIDTH * 2` and height `VISMONO_CFBFRAG_HEIGHT` + // Its position in texture image space is shifted along +S by 2 + gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2 * G_IM_SIZ_8b_LINE_BYTES / 8, 0x0, G_TX_RENDERTILE, + 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0); + gDPSetTileSize(gfx++, G_TX_RENDERTILE, 2 << 2, 0, (SCREEN_WIDTH * 2 + 1) << 2, + (VISMONO_CFBFRAG_HEIGHT - 1) << 2); - gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, 80, 0x0, 1, 1, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0, - G_TX_NOMIRROR | G_TX_CLAMP, 0, 0); - gDPSetTileSize(gfx++, 1, (1 << 2), 0, ((SCREEN_WIDTH * 2) << 2), (2 << 2)); + // Set texel 1 to be a CI8 image with width `SCREEN_WIDTH * 2` and height `VISMONO_CFBFRAG_HEIGHT` + // Its position in texture image space is shifted along +S by 1 + // Note the palette index for this tile has also been incremented from 0 to 1, however the palette index is + // ignored for CI8 texture sampling. + gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2 * G_IM_SIZ_8b_LINE_BYTES / 8, 0x0, 1, 1, + G_TX_NOMIRROR | G_TX_CLAMP, 0, 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0); + gDPSetTileSize(gfx++, 1, 1 << 2, 0, (SCREEN_WIDTH * 2) << 2, (VISMONO_CFBFRAG_HEIGHT - 1) << 2); - gSPTextureRectangle(gfx++, 0, y << 2, (SCREEN_WIDTH << 2), (y + height) << 2, G_TX_RENDERTILE, 2 << 5, 0, - 2 << 10, 1 << 10); - tex += SCREEN_WIDTH * height; + // Draw a `SCREEN_WIDTH` wide, `height` high rectangle. + // Texture coordinate T (vertical) starts at 0 and changes by one each line (dtdy = 1) + // Texture coordinate S (horizontal) starts at 2 and changes by two each column (dsdx = 2) + + // Because texel 0 is shifted by 2 and texel 1 only by 1 along +S, + // a pixel at S coordinates s = 2+2*n will look at the 2*n-th byte of texel 0 and the 2*n+1-th byte of texel 1. + // (in "s = 2+2*n" the first "2" is the starting S coordinate and the second "2" is the dsdx value) + + // The 2*n-th byte of texel 0 is the high byte of the n-th RGBA16 color of the color frame buffer. + // The 2*n+1-th byte of texel 1 is the low byte of the n-th RGBA16 color of the color frame buffer. + + // With the TLUT computed by `VisMono_DesaturateTLUT`: + // The 2*n-th byte of texel 0 maps to a IA16 color where the high byte I (intensity) corresponds to + // the high byte of the n-th RGBA16 color of the color frame buffer. + // The 2*n+1-th byte of texel 1 maps to a IA16 color where the low byte A (alpha) corresponds to + // the low byte of the n-th RGBA16 color of the color frame buffer. + + // Since the combiner is in part set up to sum texel 0 color (I, intensity) with texel 1 alpha (A, alpha), + // the resulting color in the drawn rectangle is a desaturated color as defined by the `VISMONO_FAC_*` values. + + gSPTextureRectangle(gfx++, 0, y << 2, SCREEN_WIDTH << 2, (y + height) << 2, G_TX_RENDERTILE, 2 << 5, 0, 2 << 10, + 1 << 10); + cfbFrag += SCREEN_WIDTH * height; } gDPPipeSync(gfx++); gSPEndDisplayList(gfx++); -#endif return gfx; } -void VisMono_Draw(VisMono* this, Gfx** gfxp) { - Gfx* gfx = *gfxp; +void VisMono_Draw(VisMono* this, Gfx** gfxP) { + Gfx* gfx = *gfxP; u16* tlut; - Gfx* monoDL; - Gfx* glistpEnd; + Gfx* dList; + Gfx* dListEnd; + // SOH [Port] Implement VisMono by performing a framebuffer copy and redraw with an active + // grayscale command to set the mono color + FB_CopyToFramebuffer(&gfx, 0, gReusableFrameBuffer, false, NULL); + gDPSetGrayscaleColor(gfx++, this->vis.primColor.r, this->vis.primColor.g, this->vis.primColor.b, + this->vis.primColor.a); + gSPGrayscale(gfx++, true); + FB_DrawFromFramebuffer(&gfx, gReusableFrameBuffer, 255); + gSPGrayscale(gfx++, false); + +#if 0 if (this->tlut) { tlut = this->tlut; } else { - tlut = Graph_DlistAlloc(&gfx, 256 * sizeof(u16)); - VisMono_UpdateTexture(this, tlut); + tlut = Graph_DlistAlloc(&gfx, 256 * G_IM_SIZ_16b_BYTES); + VisMono_DesaturateTLUT(this, tlut); } - if (this->monoDl) { - monoDL = this->monoDl; + if (this->dList) { + dList = this->dList; } else { - monoDL = Graph_DlistAlloc(&gfx, DLSIZE * sizeof(Gfx)); - glistpEnd = VisMono_DrawTexture(this, monoDL); + dList = Graph_DlistAlloc(&gfx, VISMONO_DLSIZE * sizeof(Gfx)); + dListEnd = VisMono_DesaturateDList(this, dList); - if (!(glistpEnd <= monoDL + DLSIZE)) { - LOG_ADDRESS("glistp_end", glistpEnd); - LOG_ADDRESS("mono_dl", monoDL); - LOG_ADDRESS("mono_dl + (1+3+1+1+80*(7+2+2+3)+1)", monoDL + DLSIZE); - LOG_ADDRESS("(1+3+1+1+80*(7+2+2+3)+1)", DLSIZE); + if (!(dListEnd <= dList + VISMONO_DLSIZE)) { + LOG_ADDRESS("glistp_end", dListEnd); + LOG_ADDRESS("mono_dl", dList); + LOG_ADDRESS("mono_dl + (1+3+1+1+80*(7+2+2+3)+1)", dList + VISMONO_DLSIZE); + LOG_ADDRESS("(1+3+1+1+80*(7+2+2+3)+1)", VISMONO_DLSIZE); } - assert(glistpEnd <= monoDL + DLSIZE); + ASSERT(dListEnd <= dList + VISMONO_DLSIZE, "glistp_end <= mono_dl + DLSIZE", "../z_vismono.c", 262); } gDPPipeSync(gfx++); - if (this->setScissor == true) { + + if (this->vis.scissorType == VIS_SETSCISSOR) { gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); } - gDPSetColor(gfx++, G_SETPRIMCOLOR, this->primColor.rgba); - gDPSetColor(gfx++, G_SETENVCOLOR, this->envColor.rgba); + gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba); + gDPSetColor(gfx++, G_SETENVCOLOR, this->vis.envColor.rgba); gDPLoadTLUT_pal256(gfx++, tlut); - gSPDisplayList(gfx++, monoDL); - gDPPipeSync(gfx++); + gSPDisplayList(gfx++, dList); - *gfxp = gfx; + gDPPipeSync(gfx++); +#endif + + *gfxP = gfx; } void VisMono_DrawOld(VisMono* this) { - Gfx* glistpEnd; + Gfx* dListEnd; - if (!this->tlut) { - this->tlut = SYSTEM_ARENA_MALLOC_DEBUG(256 * sizeof(u16)); - VisMono_UpdateTexture(this, this->tlut); + if (this->tlut == NULL) { + this->tlut = SYSTEM_ARENA_MALLOC(256 * G_IM_SIZ_16b_BYTES, "../z_vismono.c", 283); + VisMono_DesaturateTLUT(this, this->tlut); } - if (!this->monoDl) { - this->monoDl = SYSTEM_ARENA_MALLOC_DEBUG(DLSIZE * sizeof(Gfx)); - glistpEnd = VisMono_DrawTexture(this, this->monoDl); - assert(glistpEnd <= this->monoDl + DLSIZE); + if (this->dList == NULL) { + this->dList = SYSTEM_ARENA_MALLOC(VISMONO_DLSIZE * sizeof(Gfx), "../z_vismono.c", 289); + dListEnd = VisMono_DesaturateDList(this, this->dList); + ASSERT(dListEnd <= this->dList + VISMONO_DLSIZE, "glistp_end <= this->mono_dl + DLSIZE", "../z_vismono.c", 292); } } diff --git a/soh/src/code/z_viszbuf.c b/soh/src/code/z_viszbuf.c new file mode 100644 index 000000000..5a542bc12 --- /dev/null +++ b/soh/src/code/z_viszbuf.c @@ -0,0 +1,116 @@ +/** + * @file z_viszbuf.c + * + * This file implements a full-screen framebuffer effect for visualizing the z-buffer (AKA depth buffer), using either + * cycling RGBA or a single fading color. + * + * This is done by reading the z-buffer as if it were a color image, the format of which is specified by the selected + * vis type: + * - VIS_ZBUF_TYPE_IA : Produces a monotonic fade from primColor to envColor as depth increases. + * - VIS_ZBUF_TYPE_RGBA : Produces vibrant almost-periodic-looking bands. + * + * In both cases this occurs because of the format the depth information takes: it is 18-bit, and is a nonnegative + * floating-point number with + * bbb mmmmmmmmmmm dd|dd + * exponent mantissa dz value (only first 16 bits visible to CPU, the least significant 2 bits of dz are ignored) + * + * Reading z-buffer as IA16: + * bbbmmmmm mmmmmmdd + * iiiiiiii aaaaaaaa + * + * Since floating-point numbers of this format have the same ordering as their binary/hex representation, increasing + * the depth also increases the intensity in the IA16 representation and hence the interpolation parameter used to + * combine primColor and envColor. The alpha is ignored by the RenderMode. + * + * Reading z-buffer as RGBA16: + * bbbmm mmmmm mmmmd d + * rrrrr ggggg bbbbb a + * + * The red increases monotonically with the depth. The significant visible oscillation is the green component, because + * it rolls over every time the second-most-significant bit of the mantissa increments. The blue component oscillates + * too rapidly to be particularly visible (it rolls over when the 7th-most-significant bit increments). The alpha is + * again ignored by the RenderMode. + */ + +#include "global.h" + +// Height of the fragments the z-buffer is split into. +// It is the maximum amount of lines such that all rgba16 SCREEN_WIDTH-long lines fit into TMEM. +#define VISZBUF_ZBUFFRAG_HEIGHT (TMEM_SIZE / (SCREEN_WIDTH * G_IM_SIZ_16b_BYTES)) + +// z-buffer +extern u16 D_0E000000[]; + +/** + * Initialise to IA type with white and black as default colors. + */ +void VisZBuf_Init(VisZBuf* this) { + this->vis.type = VIS_ZBUF_TYPE_IA; + this->vis.scissorType = VIS_NO_SETSCISSOR; + + this->vis.primColor.r = 255; + this->vis.primColor.g = 255; + this->vis.primColor.b = 255; + this->vis.primColor.a = 255; + + // clang-format off + this->vis.envColor.r = 0; \ + this->vis.envColor.g = 0; \ + this->vis.envColor.b = 0; \ + this->vis.envColor.a = 255; + // clang-format on +} + +void VisZBuf_Destroy(VisZBuf* this) { +} + +void VisZBuf_Draw(VisZBuf* this, Gfx** gfxP) { + Gfx* gfx = *gfxP; + s32 pad; + u16* zbufFrag = D_0E000000; + s32 fmt; + s32 y; + s32 height; + + if (this->vis.type == VIS_ZBUF_TYPE_IA) { + fmt = G_IM_FMT_IA; + } else { // VIS_ZBUF_TYPE_RGBA + fmt = G_IM_FMT_RGBA; + } + + height = VISZBUF_ZBUFFRAG_HEIGHT; + + gDPPipeSync(gfx++); + // Scissoring is only required if the scissor has not been set prior. + if (this->vis.scissorType == VIS_SETSCISSOR) { + gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); + } + + // No palette so can use all of TMEM. + // G_RM_OPA_SURF discards all information previously in the pixel, and the current alpha, leaving only the color + // from this filter. + gDPSetOtherMode(gfx++, + G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2); + + // LERP between primColor and envColor in 1-cycle mode using the z-buffer value. + gDPSetCombineLERP(gfx++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, + PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT); + gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba); + gDPSetColor(gfx++, G_SETENVCOLOR, this->vis.envColor.rgba); + + for (y = 0; y <= SCREEN_HEIGHT - height; y += height) { + // Load a few lines of the z-buffer, as many as can fit in TMEM at once. + gDPLoadTextureBlock(gfx++, zbufFrag, fmt, G_IM_SIZ_16b, SCREEN_WIDTH, 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); + + // Overwrite them with the calculated colors. + gSPTextureRectangle(gfx++, 0, y << 2, SCREEN_WIDTH << 2, (y + height) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, + 1 << 10); + zbufFrag += SCREEN_WIDTH * height; + } + + gDPPipeSync(gfx++); + *gfxP = gfx; +} diff --git a/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c b/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c index 5c0b8bcb9..ea1b6f0d6 100644 --- a/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c +++ b/soh/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c @@ -88,7 +88,7 @@ void ArmsHook_Wait(ArmsHook* this, PlayState* play) { s32 length = ((player->heldItemAction == PLAYER_IA_HOOKSHOT) ? 13 : 26) * CVarGetFloat(CVAR_CHEAT("HookshotReachMultiplier"), 1.0f); ArmsHook_SetupAction(this, ArmsHook_Shoot); - func_8002D9A4(&this->actor, 20.0f); + Actor_SetProjectileSpeed(&this->actor, 20.0f); this->actor.parent = &GET_PLAYER(play)->actor; this->timer = length; } @@ -181,8 +181,8 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) { } } this->timer = 0; - Audio_PlaySoundGeneral(NA_SE_IT_ARROW_STICK_CRE, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_ARROW_STICK_CRE, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (DECR(this->timer) == 0) { grabbed = this->grabbed; if (grabbed != NULL) { @@ -250,7 +250,7 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) { } } } else { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Math_Vec3f_Diff(&this->actor.world.pos, &this->actor.prevPos, &prevFrameDiff); Math_Vec3f_Sum(&this->unk_1E8, &prevFrameDiff, &this->unk_1E8); this->actor.shape.rot.x = Math_Atan2S(this->actor.speedXZ, -this->actor.velocity.y); @@ -278,12 +278,12 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) { } } func_80865044(this); - Audio_PlaySoundGeneral(NA_SE_IT_HOOKSHOT_STICK_OBJ, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_HOOKSHOT_STICK_OBJ, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { CollisionCheck_SpawnShieldParticlesMetal(play, &this->actor.world.pos); - Audio_PlaySoundGeneral(NA_SE_IT_HOOKSHOT_REFLECT, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_HOOKSHOT_REFLECT, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else if (CHECK_BTN_ANY(play->state.input[0].press.button, (buttonsToCheck))) { this->timer = 0; diff --git a/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c b/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c index 489a50cfa..e46758bd0 100644 --- a/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c @@ -326,7 +326,7 @@ void func_8086C6EC(BgBdanObjects* this, PlayState* play) { } void func_8086C76C(BgBdanObjects* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->dyna.actor.xzDistToPlayer < 120.0f) { this->actionFunc = func_8086C7D0; OnePointCutscene_Init(play, 3090, -99, &this->dyna.actor, MAIN_CAM); @@ -352,7 +352,7 @@ void func_8086C874(BgBdanObjects* this, PlayState* play) { this->timer--; } if (this->switchFlag == 0) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->cameraSetting = play->cameraPtrs[MAIN_CAM]->setting; Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_NORMAL2); func_8005AD1C(play->cameraPtrs[MAIN_CAM], 4); @@ -360,7 +360,7 @@ void func_8086C874(BgBdanObjects* this, PlayState* play) { } } else { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_NORMAL2); - if (!func_8004356C(&this->dyna)) { + if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->switchFlag != 0) { this->switchFlag--; } @@ -411,7 +411,7 @@ void func_8086CABC(BgBdanObjects* this, PlayState* play) { } void func_8086CB10(BgBdanObjects* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { Flags_SetSwitch(play, this->switchFlag); this->timer = 50; this->actionFunc = func_8086CB8C; diff --git a/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c b/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c index 7e0781067..13ecc51bb 100644 --- a/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c +++ b/soh/src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c @@ -254,13 +254,13 @@ void func_8086D5C4(BgBdanSwitch* this) { void func_8086D5E0(BgBdanSwitch* this, PlayState* play) { switch (this->dyna.actor.params & 0xFF) { case BLUE: - if (func_800435B4(&this->dyna)) { + if (DynaPolyActor_IsSwitchPressed(&this->dyna)) { func_8086D67C(this); func_8086D4B4(this, play); } break; case YELLOW: - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { func_8086D67C(this); func_8086D4B4(this, play); } @@ -293,7 +293,7 @@ void func_8086D730(BgBdanSwitch* this) { void func_8086D754(BgBdanSwitch* this, PlayState* play) { switch (this->dyna.actor.params & 0xFF) { case BLUE: - if (!func_800435B4(&this->dyna)) { + if (!DynaPolyActor_IsSwitchPressed(&this->dyna)) { if (this->unk_1D8 <= 0) { func_8086D7FC(this); func_8086D548(this, play); @@ -328,7 +328,7 @@ void func_8086D86C(BgBdanSwitch* this) { } void func_8086D888(BgBdanSwitch* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { func_8086D8BC(this); } } @@ -371,7 +371,7 @@ void func_8086D9F8(BgBdanSwitch* this) { void func_8086DA1C(BgBdanSwitch* this, PlayState* play) { Actor* heldActor = GET_PLAYER(play)->heldActor; - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (heldActor != NULL && heldActor->id == ACTOR_EN_RU1) { if (this->unk_1D8 <= 0) { func_8086D944(this); diff --git a/soh/src/overlays/actors/ovl_Bg_Bombwall/z_bg_bombwall.c b/soh/src/overlays/actors/ovl_Bg_Bombwall/z_bg_bombwall.c index a2f2d241c..160dc15f9 100644 --- a/soh/src/overlays/actors/ovl_Bg_Bombwall/z_bg_bombwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Bombwall/z_bg_bombwall.c @@ -234,7 +234,7 @@ void func_8086EE40(BgBombwall* this, PlayState* play) { func_8086EE94(this, play); if (((this->dyna.actor.params >> 0xF) & 1) != 0) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } } } diff --git a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index 981f25cd2..9f89e7980 100644 --- a/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -8,6 +8,7 @@ #include "scenes/dungeons/ddan/ddan_scene.h" #include "objects/object_bwall/object_bwall.h" #include "objects/object_kingdodongo/object_kingdodongo.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -307,11 +308,11 @@ void BgBreakwall_Wait(BgBreakwall* this, PlayState* play) { gSaveContext.cutsceneTrigger = 1; Player_SetCsActionWithHaltedActors(play, NULL, 0x31); } - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } if (this->dyna.actor.params < 0) { - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } Actor_Kill(&this->dyna.actor); diff --git a/soh/src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c b/soh/src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c index 701249e79..20334c893 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c +++ b/soh/src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c @@ -173,8 +173,8 @@ void BgDdanKd_LowerStairs(BgDdanKd* this, PlayState* play) { func_8003555C(play, &pos1, &sBgDdanKdVelocity, &sBgDdanKdAccel); } Camera_AddQuake(&play->mainCamera, 0, effectStrength * 0.6f, 3); - Audio_PlaySoundGeneral(NA_SE_EV_PILLAR_SINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_PILLAR_SINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c b/soh/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c index d9408a83c..8bd9ec874 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c +++ b/soh/src/overlays/actors/ovl_Bg_Dodoago/z_bg_dodoago.c @@ -160,16 +160,16 @@ void BgDodoago_WaitExplosives(BgDodoago* this, PlayState* play) { ((play->roomCtx.unk_74[BGDODOAGO_EYE_RIGHT] == 255) && (this->state == BGDODOAGO_EYE_LEFT))) { Flags_SetSwitch(play, this->dyna.actor.params & 0x3F); this->state = 0; - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); BgDodoago_SetupAction(this, BgDodoago_OpenJaw); OnePointCutscene_Init(play, 3380, 160, &this->dyna.actor, MAIN_CAM); } else if (play->roomCtx.unk_74[this->state] == 0) { OnePointCutscene_Init(play, 3065, 40, &this->dyna.actor, MAIN_CAM); BgDodoago_SetupAction(this, BgDodoago_LightOneEye); - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { OnePointCutscene_Init(play, 3065, 20, &this->dyna.actor, MAIN_CAM); - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sBgDodoagoTimer += 30; return; } @@ -247,11 +247,11 @@ void BgDodoago_OpenJaw(BgDodoago* this, PlayState* play) { if (Math_SmoothStepToS(&this->dyna.actor.shape.rot.x, 0x1333, 110 - this->state, 0x3E8, 0x32) == 0) { BgDodoago_SetupAction(this, BgDodoago_DoNothing); - Audio_PlaySoundGeneral(NA_SE_EV_STONE_BOUND, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_STONE_BOUND, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_EV_STONE_STATUE_OPEN - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_STONE_STATUE_OPEN - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c index 799a46c62..83a9e3d3e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c +++ b/soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c @@ -11,6 +11,8 @@ #include "scenes/indoors/yousei_izumi_yoko/yousei_izumi_yoko_scene.h" #include "scenes/indoors/daiyousei_izumi/daiyousei_izumi_scene.h" #include "soh/frame_interpolation.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -867,7 +869,7 @@ void BgDyYoseizo_Update(Actor* thisx, PlayState* play2) { } } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); this->heightOffset = this->scale * 7500.0f; Actor_SetFocus(&this->actor, this->heightOffset); this->actor.focus.pos.y = this->heightOffset; diff --git a/soh/src/overlays/actors/ovl_Bg_Ganon_Otyuka/z_bg_ganon_otyuka.c b/soh/src/overlays/actors/ovl_Bg_Ganon_Otyuka/z_bg_ganon_otyuka.c index a3e9ec999..48362c49d 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ganon_Otyuka/z_bg_ganon_otyuka.c +++ b/soh/src/overlays/actors/ovl_Bg_Ganon_Otyuka/z_bg_ganon_otyuka.c @@ -221,11 +221,11 @@ void BgGanonOtyuka_Fall(BgGanonOtyuka* this, PlayState* play) { } } else { if (this->dropTimer == 1) { - Audio_PlaySoundGeneral(NA_SE_EV_STONEDOOR_STOP, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_STONEDOOR_STOP, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_EV_BLOCKSINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_BLOCKSINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } Math_ApproachF(&this->dyna.actor.world.pos.y, -1000.0f, 1.0f, this->dyna.actor.speedXZ); Math_ApproachF(&this->dyna.actor.speedXZ, 100.0f, 1.0f, 0.1f); diff --git a/soh/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c b/soh/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c index 3307b6148..2c4ef32ec 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c +++ b/soh/src/overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c @@ -7,6 +7,7 @@ #include "z_bg_gate_shutter.h" #include "objects/object_spot01_matoyab/object_spot01_matoyab.h" #include "vt.h" +#include "soh/OTRGlobals.h" #define FLAGS 0 diff --git a/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c b/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c index 18eae69fb..59c72119f 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c +++ b/soh/src/overlays/actors/ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c @@ -7,6 +7,7 @@ #include "z_bg_gjyo_bridge.h" #include "objects/object_gjyo_objects/object_gjyo_objects.h" #include "scenes/dungeons/ganon_tou/ganon_tou_scene.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 diff --git a/soh/src/overlays/actors/ovl_Bg_Gnd_Darkmeiro/z_bg_gnd_darkmeiro.c b/soh/src/overlays/actors/ovl_Bg_Gnd_Darkmeiro/z_bg_gnd_darkmeiro.c index 02271a89c..9c14562e2 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gnd_Darkmeiro/z_bg_gnd_darkmeiro.c +++ b/soh/src/overlays/actors/ovl_Bg_Gnd_Darkmeiro/z_bg_gnd_darkmeiro.c @@ -123,7 +123,7 @@ void BgGndDarkmeiro_UpdateBlockTimer(BgGndDarkmeiro* this, PlayState* play) { } else { this->actionFlags |= 4; this->timer1 = 304; - Audio_PlaySoundGeneral(NA_SE_EV_RED_EYE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_RED_EYE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -138,7 +138,7 @@ void BgGndDarkmeiro_UpdateBlockTimer(BgGndDarkmeiro* this, PlayState* play) { } else { this->actionFlags |= 8; this->timer2 = 304; - Audio_PlaySoundGeneral(NA_SE_EV_RED_EYE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_RED_EYE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c b/soh/src/overlays/actors/ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c index fa66b29aa..e838191ae 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c +++ b/soh/src/overlays/actors/ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c @@ -60,7 +60,7 @@ void BgGndFiremeiro_Destroy(Actor* thisx, PlayState* play2) { void BgGndFiremeiro_Sink(BgGndFiremeiro* this, PlayState* play) { f32 sunkHeight = this->initPos.y - 150.0f; - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->timer = 10; } @@ -85,7 +85,7 @@ void BgGndFiremeiro_Shake(BgGndFiremeiro* this, PlayState* play) { s32 pad; f32 randSign; - if (func_8004356C(&this->dyna)) { // Player standing on it + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { // Player standing on it if (this->timer > 0) { this->timer--; @@ -114,7 +114,7 @@ void BgGndFiremeiro_Rise(BgGndFiremeiro* this, PlayState* play) { Player* player = GET_PLAYER(play); Actor* thisx = &this->dyna.actor; - if ((player->currentBoots != PLAYER_BOOTS_HOVER) && func_8004356C(&this->dyna)) { // Player standing on it + if ((player->currentBoots != PLAYER_BOOTS_HOVER) && DynaPolyActor_IsPlayerOnTop(&this->dyna)) { // Player standing on it if (thisx->world.pos.y < this->initPos.y) { this->actionFunc = BgGndFiremeiro_Sink; this->timer = 20; diff --git a/soh/src/overlays/actors/ovl_Bg_Gnd_Soulmeiro/z_bg_gnd_soulmeiro.c b/soh/src/overlays/actors/ovl_Bg_Gnd_Soulmeiro/z_bg_gnd_soulmeiro.c index ec4dff4e3..54bea8742 100644 --- a/soh/src/overlays/actors/ovl_Bg_Gnd_Soulmeiro/z_bg_gnd_soulmeiro.c +++ b/soh/src/overlays/actors/ovl_Bg_Gnd_Soulmeiro/z_bg_gnd_soulmeiro.c @@ -163,7 +163,7 @@ void func_8087B284(BgGndSoulmeiro* this, PlayState* play) { if (!Flags_GetSwitch(play, (this->actor.params >> 8) & 0x3F)) { this->actor.draw = BgGndSoulmeiro_Draw; if (this->collider.base.acFlags & AC_HIT) { - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->unk_198 = 40; this->actionFunc = func_8087AF38; } else { diff --git a/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c b/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c index 7b5519e43..badec15e1 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c @@ -59,7 +59,7 @@ void BgHaka_Destroy(Actor* thisx, PlayState* play) { void func_8087B758(BgHaka* this, Player* player) { Vec3f sp1C; - func_8002DBD0(&this->dyna.actor, &sp1C, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->dyna.actor, &sp1C, &player->actor.world.pos); if (fabsf(sp1C.x) < 34.6f && sp1C.z > -112.8f && sp1C.z < -36.0f) { player->stateFlags2 |= PLAYER_STATE2_FORCE_SAND_FLOOR_SOUND; } @@ -115,7 +115,7 @@ void func_8087B938(BgHaka* this, PlayState* play) { player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY; if (this->dyna.actor.params == 1) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } else if (!IS_DAY && play->sceneNum == SCENE_GRAVEYARD) { Actor_Spawn(&play->actorCtx, play, ACTOR_EN_POH, this->dyna.actor.home.pos.x, this->dyna.actor.home.pos.y, this->dyna.actor.home.pos.z, 0, this->dyna.actor.shape.rot.y, 0, @@ -124,7 +124,7 @@ void func_8087B938(BgHaka* this, PlayState* play) { // un tss un tss if (play->sceneNum == SCENE_GRAVEYARD && allPulled) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); func_800F5ACC(NA_BGM_STAFF_2); Actor* actor2 = play->actorCtx.actorLists[ACTORCAT_BG].head; @@ -196,10 +196,10 @@ void BgHaka_Draw(Actor* thisx, PlayState* play) { play->envCtx.adjLight1Color[0] = newColor.r; play->envCtx.adjLight1Color[1] = newColor.g; play->envCtx.adjLight1Color[2] = newColor.b; - D_801614B0.r = newColor.r; - D_801614B0.g = newColor.g; - D_801614B0.b = newColor.b; - D_801614B0.a = 255; + gVisMonoColor.r = newColor.r; + gVisMonoColor.g = newColor.g; + gVisMonoColor.b = newColor.b; + gVisMonoColor.a = 255; gDPSetGrayscaleColor(POLY_OPA_DISP++, newColor.r, newColor.g, newColor.b, 255); gSPGrayscale(POLY_OPA_DISP++, true); } diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_Gate/z_bg_haka_gate.c b/soh/src/overlays/actors/ovl_Bg_Haka_Gate/z_bg_haka_gate.c index 98c5138c3..fb6e77efc 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_Gate/z_bg_haka_gate.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka_Gate/z_bg_haka_gate.c @@ -242,7 +242,7 @@ void BgHakaGate_FloorClosed(BgHakaGate* this, PlayState* play) { sBgPoEventPuzzleState = SKULL_OF_TRUTH_FOUND; this->actionFunc = BgHakaGate_DoNothing; } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_GROUND_GATE_OPEN); func_8003EBF8(play, &play->colCtx.dyna, this->dyna.bgId); this->vTimer = 60; diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c b/soh/src/overlays/actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c index 923d8c721..b47a85590 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c @@ -179,7 +179,7 @@ void BgHakaShip_CrashFall(BgHakaShip* this, PlayState* play) { } } else { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCKSINK - SFX_FLAG); - if ((this->dyna.actor.home.pos.y - this->dyna.actor.world.pos.y > 500.0f) && func_8004356C(&this->dyna)) { + if ((this->dyna.actor.home.pos.y - this->dyna.actor.world.pos.y > 500.0f) && DynaPolyActor_IsPlayerOnTop(&this->dyna)) { Play_TriggerVoidOut(play); } } @@ -190,7 +190,7 @@ void BgHakaShip_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->dyna.actor.params == 0) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); } } @@ -230,6 +230,6 @@ void BgHakaShip_Draw(Actor* thisx, PlayState* play) { sp2C.z = this->dyna.actor.world.pos.z; SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &sp2C, &this->bellSoundPos); - func_80078914(&this->bellSoundPos, NA_SE_EV_SHIP_BELL - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->bellSoundPos, NA_SE_EV_SHIP_BELL - SFX_FLAG); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.c b/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.c index 9bfce3603..faf78019d 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.c @@ -210,7 +210,7 @@ void func_8087FFC0(BgHakaTrap* this, PlayState* play) { f32 zNonNegative; Player* player = GET_PLAYER(play); - func_8002DBD0(&this->dyna.actor, &sp28, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->dyna.actor, &sp28, &player->actor.world.pos); sine = Math_SinS(this->dyna.actor.shape.rot.y); cosine = Math_CosS(this->dyna.actor.shape.rot.y); @@ -434,7 +434,7 @@ void func_808809E4(BgHakaTrap* this, PlayState* play, s16 arg2) { Player* player = GET_PLAYER(play); Vec3f sp18; - func_8002DBD0(&this->dyna.actor, &sp18, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->dyna.actor, &sp18, &player->actor.world.pos); if ((fabsf(sp18.x) < 70.0f) && (fabsf(sp18.y) < 100.0f) && (sp18.z < 500.0f) && (GET_PLAYER(play)->currentBoots != PLAYER_BOOTS_IRON)) { @@ -546,7 +546,7 @@ void BgHakaTrap_Draw(Actor* thisx, PlayState* play) { sp2C.y = this->dyna.actor.world.pos.y + 110.0f; SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &sp2C, &this->unk_16C); - func_80078914(&this->unk_16C, NA_SE_EV_BRIDGE_CLOSE - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->unk_16C, NA_SE_EV_BRIDGE_CLOSE - SFX_FLAG); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c b/soh/src/overlays/actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c index e031c07cc..080d50814 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c @@ -163,7 +163,7 @@ void BgHakaTubo_DropCollectible(BgHakaTubo* this, PlayState* play) { if (sPotsDestroyed == 3) { // All 3 pots destroyed collectibleParams = -1; - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); // Drop rupees for (i = 0; i < 9; i++) { collectible = Item_DropCollectible(play, &spawnPos, i % 3); @@ -178,7 +178,7 @@ void BgHakaTubo_DropCollectible(BgHakaTubo* this, PlayState* play) { Actor_Spawn(&play->actorCtx, play, ACTOR_EN_FIREFLY, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y + 80.0f, this->dyna.actor.world.pos.z, 0, this->dyna.actor.shape.rot.y, 0, 2, true); - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } else { // Random rewards if (CVarGetInteger(CVAR_ENHANCEMENT("NoRandomDrops"), 0)) { @@ -192,7 +192,7 @@ void BgHakaTubo_DropCollectible(BgHakaTubo* this, PlayState* play) { } else { collectibleParams = ITEM00_ARROWS_SMALL; } - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } } else if (Flags_GetCollectible(play, this->dyna.actor.params) != 0) { // If small key already collected, drop recovery heart instead @@ -202,11 +202,11 @@ void BgHakaTubo_DropCollectible(BgHakaTubo* this, PlayState* play) { else { collectibleParams = ITEM00_HEART; } - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } else { // Drops a small key and sets a collect flag collectibleParams = ((this->dyna.actor.params & 0x3F) << 8) | ITEM00_SMALL_KEY; - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } if (collectibleParams != -1) { collectible = Item_DropCollectible(play, &spawnPos, collectibleParams); diff --git a/soh/src/overlays/actors/ovl_Bg_Haka_Zou/z_bg_haka_zou.c b/soh/src/overlays/actors/ovl_Bg_Haka_Zou/z_bg_haka_zou.c index 1f0c98f04..f41964603 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka_Zou/z_bg_haka_zou.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka_Zou/z_bg_haka_zou.c @@ -396,7 +396,7 @@ void BgHakaZou_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->dyna.actor.params == 3) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c b/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c index 6df97fcfc..474764d7f 100644 --- a/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c +++ b/soh/src/overlays/actors/ovl_Bg_Heavy_Block/z_bg_heavy_block.c @@ -173,7 +173,7 @@ void BgHeavyBlock_MovePiece(BgHeavyBlock* this, PlayState* play) { thisx->velocity.x *= 0.98f; thisx->velocity.z *= 0.98f; - func_8002D7EC(thisx); + Actor_UpdatePos(thisx); thisx->shape.rot.x += thisx->world.rot.x; thisx->shape.rot.y += thisx->world.rot.y; thisx->shape.rot.z += thisx->world.rot.z; @@ -385,7 +385,7 @@ void BgHeavyBlock_Fly(BgHeavyBlock* this, PlayState* play) { Vec3f pos; f32 raycastResult; - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); pos.x = this->dyna.actor.home.pos.x; pos.y = this->dyna.actor.home.pos.y + 1000.0f; pos.z = this->dyna.actor.home.pos.z; @@ -459,7 +459,7 @@ void BgHeavyBlock_Land(BgHeavyBlock* this, PlayState* play) { Math_StepToF(&this->dyna.actor.velocity.y, 0.0f, 3.0f); this->dyna.actor.gravity = 0.0f; this->dyna.actor.world.pos = this->dyna.actor.home.pos; - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); this->dyna.actor.home.pos = this->dyna.actor.world.pos; switch (this->dyna.actor.params & 0xFF) { case HEAVYBLOCK_UNBREAKABLE_OUTSIDE_CASTLE: diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.c index 3e1fd9d78..c1d402188 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Dalm/z_bg_hidan_dalm.c @@ -181,7 +181,7 @@ void BgHidanDalm_Update(Actor* thisx, PlayState* play) { BgHidanDalm* this = (BgHidanDalm*)thisx; this->actionFunc(this, play); - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 10.0f, 15.0f, 32.0f, 5); } diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Firewall/z_bg_hidan_firewall.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Firewall/z_bg_hidan_firewall.c index 6c1ce1e8f..ff44c33b8 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Firewall/z_bg_hidan_firewall.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Firewall/z_bg_hidan_firewall.c @@ -86,7 +86,7 @@ s32 BgHidanFirewall_CheckProximity(BgHidanFirewall* this, PlayState* play) { Vec3f distance; player = GET_PLAYER(play); - func_8002DBD0(&this->actor, &distance, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &distance, &player->actor.world.pos); if (fabsf(distance.x) < 100.0f && fabsf(distance.z) < 120.0f) { return 1; @@ -146,7 +146,7 @@ void BgHidanFirewall_ColliderFollowPlayer(BgHidanFirewall* this, PlayState* play player = GET_PLAYER(play); - func_8002DBD0(&this->actor, &sp30, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &sp30, &player->actor.world.pos); if (sp30.x < -70.0f) { sp30.x = -70.0f; } else { diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c index e7151be7d..9ff062dd7 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c @@ -90,7 +90,7 @@ void func_80886FCC(BgHidanFslift* this, PlayState* play) { if ((this->dyna.actor.world.pos.y - this->dyna.actor.home.pos.y) < 0.5f) { heightBool = true; } - if (func_80043590(&this->dyna) && (heightBool)) { + if (DynaPolyActor_IsPlayerAbove(&this->dyna) && (heightBool)) { this->actionFunc = func_808870D8; } else if (!heightBool) { this->actionFunc = func_8088706C; @@ -109,7 +109,7 @@ void func_8088706C(BgHidanFslift* this, PlayState* play) { } void func_808870D8(BgHidanFslift* this, PlayState* play) { - if (func_80043590(&this->dyna)) { + if (DynaPolyActor_IsPlayerAbove(&this->dyna)) { if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 790.0f, 4.0f)) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); func_80886FB4(this); @@ -126,12 +126,12 @@ void BgHidanFslift_Update(Actor* thisx, PlayState* play) { BgHidanFslift* this = (BgHidanFslift*)thisx; this->actionFunc(this, play); - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_16A == 0) { this->unk_16A = 3; } Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); - } else if (!func_8004356C(&this->dyna)) { + } else if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_16A != 0) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Fwbig/z_bg_hidan_fwbig.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Fwbig/z_bg_hidan_fwbig.c index d4e146520..5f128bda9 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Fwbig/z_bg_hidan_fwbig.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Fwbig/z_bg_hidan_fwbig.c @@ -200,7 +200,7 @@ void BgHidanFwbig_MoveCollider(BgHidanFwbig* this, PlayState* play) { f32 cs; f32 sn; - func_8002DBD0(&this->actor, &projPos, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &projPos, &player->actor.world.pos); projPos.z = ((projPos.z >= 0.0f) ? 1.0f : -1.0f) * 25.0f * -1.0f; if (this->direction == 0) { projPos.x = CLAMP(projPos.x, -360.0f, 360.0f); diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c index c0ffd1c8b..818533571 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c @@ -294,7 +294,7 @@ void func_80888860(BgHidanHamstep* this, PlayState* play) { s32 pad2; s32 quakeIndex; - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); if (((this->dyna.actor.world.pos.y - this->dyna.actor.home.pos.y) < (-20.0f - this->dyna.actor.minVelocityY)) && (this->dyna.actor.velocity.y <= 0.0f)) { @@ -343,7 +343,7 @@ void func_80888A58(BgHidanHamstep* this, PlayState* play) { s32 pad2; s32 quakeIndex; - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); func_80888694(this, (BgHidanHamstep*)this->dyna.actor.parent); if (((this->dyna.actor.params & 0xFF) <= 0) || ((this->dyna.actor.params & 0xFF) >= 6)) { @@ -376,7 +376,7 @@ void func_80888A58(BgHidanHamstep* this, PlayState* play) { func_808884C8(this, play); if ((this->dyna.actor.params & 0xFF) == 5) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } osSyncPrintf("B(%d)\n", this->dyna.actor.params); diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c index ea49fbd4f..fecd9451a 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Hrock/z_bg_hidan_hrock.c @@ -216,7 +216,7 @@ void func_808896B8(BgHidanHrock* this, PlayState* play) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); } - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y - 5.0f, 1.0f); } else { Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 1.0f); diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.c index d8ea17410..4d01df395 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.c @@ -125,12 +125,12 @@ void func_80889C18(BgHidanKousi* this, PlayState* play) { this->dyna.actor.speedXZ = 2.0f; BgHidanKousi_SetupAction(this, func_80889C90); } - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); func_8002F974(&this->dyna.actor, NA_SE_EV_METALDOOR_SLIDE - SFX_FLAG); } void func_80889C90(BgHidanKousi* this, PlayState* play) { - func_8002D7EC(&this->dyna.actor); + Actor_UpdatePos(&this->dyna.actor); if (D_80889E40[this->dyna.actor.params & 0xFF] < Math_Vec3f_DistXYZ(&this->dyna.actor.home.pos, &this->dyna.actor.world.pos)) { func_80889ACC(this); diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Kowarerukabe/z_bg_hidan_kowarerukabe.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Kowarerukabe/z_bg_hidan_kowarerukabe.c index ee303a178..c9cbb039f 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Kowarerukabe/z_bg_hidan_kowarerukabe.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Kowarerukabe/z_bg_hidan_kowarerukabe.c @@ -313,7 +313,7 @@ void BgHidanKowarerukabe_Update(Actor* thisx, PlayState* play) { SoundSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 40, NA_SE_EV_WALL_BROKEN); } - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Actor_Kill(&this->dyna.actor); return; } diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c index c5b90a4c9..108378185 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c @@ -212,7 +212,7 @@ void func_8088B5F4(BgHidanRock* this, PlayState* play) { } void func_8088B634(BgHidanRock* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->timer = 20; this->dyna.actor.world.rot.y = Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x4000; this->actionFunc = func_8088B69C; @@ -263,12 +263,12 @@ void func_8088B79C(BgHidanRock* this, PlayState* play) { this->unk_16C = CLAMP_MIN(this->unk_16C, 0.0f); if (this->type == 0) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_169 == 0) { this->unk_169 = 3; } Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); - } else if (!func_8004356C(&this->dyna)) { + } else if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_169 != 0) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } @@ -316,12 +316,12 @@ void func_8088B990(BgHidanRock* this, PlayState* play) { this->unk_16C = (this->dyna.actor.world.pos.y + 50.0f - this->dyna.actor.home.pos.y + 40.0f) / 80.0f; if (this->type == 0) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_169 == 0) { this->unk_169 = 3; } Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); - } else if (!func_8004356C(&this->dyna)) { + } else if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_169 != 0) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } @@ -335,7 +335,7 @@ void BgHidanRock_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->actionFunc == func_8088B79C) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 0.0f, 0.0f, 0.0f, 4); } @@ -396,7 +396,7 @@ void BgHidanRock_Draw(Actor* thisx, PlayState* play) { SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &this->dyna.actor.home.pos, &this->unk_170); } - func_80078914(&this->unk_170, NA_SE_EV_FIRE_PILLAR - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->unk_170, NA_SE_EV_FIRE_PILLAR - SFX_FLAG); func_8088BC40(play, this); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c index 03615e480..2b9331ab8 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c @@ -118,7 +118,7 @@ void func_8088E518(BgHidanSima* this, PlayState* play) { Player* player = GET_PLAYER(play); Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 3.4f); - if (func_8004356C(&this->dyna) && !(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE))) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna) && !(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE))) { this->timer = 20; this->dyna.actor.world.rot.y = Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x4000; if (this->dyna.actor.home.pos.y <= this->dyna.actor.world.pos.y) { @@ -150,7 +150,7 @@ void func_8088E5D0(BgHidanSima* this, PlayState* play) { } void func_8088E6D0(BgHidanSima* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->timer = 20; } else if (this->timer != 0) { this->timer--; diff --git a/soh/src/overlays/actors/ovl_Bg_Hidan_Syoku/z_bg_hidan_syoku.c b/soh/src/overlays/actors/ovl_Bg_Hidan_Syoku/z_bg_hidan_syoku.c index 44c1cc5e5..ae8e5b530 100644 --- a/soh/src/overlays/actors/ovl_Bg_Hidan_Syoku/z_bg_hidan_syoku.c +++ b/soh/src/overlays/actors/ovl_Bg_Hidan_Syoku/z_bg_hidan_syoku.c @@ -61,7 +61,7 @@ void func_8088F47C(BgHidanSyoku* this) { } void func_8088F4B8(BgHidanSyoku* this, PlayState* play) { - if (Flags_GetClear(play, this->dyna.actor.room) && func_8004356C(&this->dyna)) { + if (Flags_GetClear(play, this->dyna.actor.room) && DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->timer = 140; this->actionFunc = func_8088F514; } @@ -109,12 +109,12 @@ void BgHidanSyoku_Update(Actor* thisx, PlayState* play) { BgHidanSyoku* this = (BgHidanSyoku*)thisx; this->actionFunc(this, play); - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_168 == 0) { this->unk_168 = 3; } Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); - } else if (!func_8004356C(&this->dyna)) { + } else if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->unk_168 != 0) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } diff --git a/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c b/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c index 4d0353fcf..9810f2749 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c +++ b/soh/src/overlays/actors/ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c @@ -1,5 +1,6 @@ #include "z_bg_ice_shelter.h" #include "objects/object_ice_objects/object_ice_objects.h" +#include "soh/OTRGlobals.h" #define FLAGS 0 @@ -428,7 +429,7 @@ void func_808911D4(BgIceShelter* this, PlayState* play) { } if (type == 4) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } Actor_Kill(&this->dyna.actor); diff --git a/soh/src/overlays/actors/ovl_Bg_Ice_Turara/z_bg_ice_turara.c b/soh/src/overlays/actors/ovl_Bg_Ice_Turara/z_bg_ice_turara.c index 30c09ad33..791efd6ca 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ice_Turara/z_bg_ice_turara.c +++ b/soh/src/overlays/actors/ovl_Bg_Ice_Turara/z_bg_ice_turara.c @@ -175,7 +175,7 @@ void BgIceTurara_Fall(BgIceTurara* this, PlayState* play) { return; } } else { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); this->dyna.actor.world.pos.y += 40.0f; Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 0.0f, 0.0f, 0.0f, 4); this->dyna.actor.world.pos.y -= 40.0f; diff --git a/soh/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c b/soh/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c index 35cbc3f49..270bcd9ff 100644 --- a/soh/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c +++ b/soh/src/overlays/actors/ovl_Bg_Jya_1flift/z_bg_jya_1flift.c @@ -187,7 +187,7 @@ void BgJya1flift_Update(Actor* thisx, PlayState* play2) { // Room 0 is the first room and 6 is the room that the lift starts on if (play->roomCtx.curRoom.num == 6 || play->roomCtx.curRoom.num == 0) { this->actionFunc(this, play); - tempIsRiding = func_8004356C(&this->dyna) ? true : false; + tempIsRiding = DynaPolyActor_IsPlayerOnTop(&this->dyna) ? true : false; if ((this->actionFunc == BgJya1flift_Move) || (this->actionFunc == BgJya1flift_DelayMove)) { if (tempIsRiding) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_FIRE_PLATFORM); diff --git a/soh/src/overlays/actors/ovl_Bg_Jya_Haheniron/z_bg_jya_haheniron.c b/soh/src/overlays/actors/ovl_Bg_Jya_Haheniron/z_bg_jya_haheniron.c index a66bd8e27..1fb0d4a50 100644 --- a/soh/src/overlays/actors/ovl_Bg_Jya_Haheniron/z_bg_jya_haheniron.c +++ b/soh/src/overlays/actors/ovl_Bg_Jya_Haheniron/z_bg_jya_haheniron.c @@ -149,7 +149,7 @@ void BgJyaHaheniron_SetupChairCrumble(BgJyaHaheniron* this) { void BgJyaHaheniron_ChairCrumble(BgJyaHaheniron* this, PlayState* play) { Vec3f vec; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 5.0f, 8.0f, 0.0f, 0x85); if ((this->actor.bgCheckFlags & 9) || ((this->collider.base.atFlags & AT_HIT) && (this->collider.base.at != NULL) && (this->collider.base.at->category == ACTORCAT_PLAYER))) { @@ -173,7 +173,7 @@ void BgJyaHaheniron_SetupPillarCrumble(BgJyaHaheniron* this) { void BgJyaHaheniron_PillarCrumble(BgJyaHaheniron* this, PlayState* play) { if (this->timer >= 8) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } else if (this->timer >= 17) { BgJyaHaheniron_SpawnFragments(play, &this->actor.world.pos, D_808987A0); Actor_Kill(&this->actor); diff --git a/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c b/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c index 19bef1b67..bc7b756d8 100644 --- a/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c +++ b/soh/src/overlays/actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c @@ -6,6 +6,7 @@ #include "z_bg_jya_lift.h" #include "objects/object_jya_obj/object_jya_obj.h" +#include "soh/OTRGlobals.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -145,13 +146,14 @@ void BgJyaLift_Update(Actor* thisx, PlayState* play2) { if (this->actionFunc != NULL) { this->actionFunc(this, play); } - if ((this->dyna.unk_160 & 4) && ((this->unk_16B & 4) == 0)) { + if ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ABOVE) && + ((this->unk_16B & DYNA_INTERACT_PLAYER_ABOVE) == 0)) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DIRECTED_YAW); - } else if (((this->dyna.unk_160) & 4) == 0 && ((this->unk_16B & 4)) && + } else if (((this->dyna.interactFlags) & 4) == 0 && ((this->unk_16B & 4)) && (play->cameraPtrs[MAIN_CAM]->setting == CAM_SET_DIRECTED_YAW)) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } - this->unk_16B = this->dyna.unk_160; + this->unk_16B = this->dyna.interactFlags; // Spirit Temple room 5 is the main room with the statue room 25 is directly above room 5 if ((play->roomCtx.curRoom.num != 5) && (play->roomCtx.curRoom.num != 25)) { diff --git a/soh/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.c b/soh/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.c index 12eb0a34a..ecbcf5913 100644 --- a/soh/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.c +++ b/soh/src/overlays/actors/ovl_Bg_Jya_Megami/z_bg_jya_megami.c @@ -275,7 +275,7 @@ void BgJyaMegami_Explode(BgJyaMegami* this, PlayState* play) { func_80033480(play, &sp8C, 100.0f, 1, 150, 100, 1); } if (this->explosionTimer == 60) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } if (this->explosionTimer >= 100) { Actor_Kill(&this->dyna.actor); diff --git a/soh/src/overlays/actors/ovl_Bg_Menkuri_Eye/z_bg_menkuri_eye.c b/soh/src/overlays/actors/ovl_Bg_Menkuri_Eye/z_bg_menkuri_eye.c index 9db156041..a2610fac6 100644 --- a/soh/src/overlays/actors/ovl_Bg_Menkuri_Eye/z_bg_menkuri_eye.c +++ b/soh/src/overlays/actors/ovl_Bg_Menkuri_Eye/z_bg_menkuri_eye.c @@ -110,7 +110,7 @@ void BgMenkuriEye_Update(Actor* thisx, PlayState* play) { this->framesUntilDisable = 416; if (D_8089C1A0 == 4) { Flags_SetSwitch(play, this->actor.params); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } } if (this->framesUntilDisable == -1) { diff --git a/soh/src/overlays/actors/ovl_Bg_Menkuri_Kaiten/z_bg_menkuri_kaiten.c b/soh/src/overlays/actors/ovl_Bg_Menkuri_Kaiten/z_bg_menkuri_kaiten.c index 0b0b466b4..90a3cbee1 100644 --- a/soh/src/overlays/actors/ovl_Bg_Menkuri_Kaiten/z_bg_menkuri_kaiten.c +++ b/soh/src/overlays/actors/ovl_Bg_Menkuri_Kaiten/z_bg_menkuri_kaiten.c @@ -1,7 +1,7 @@ /* * File: z_bg_menkuri_kaiten.c * Overlay: Bg_Menkuri_Kaiten - * Description: Large rotating stone ring used in Gerudo Training Grounds and Forest Temple. + * Description: Large rotating stone ring used in Gerudo Training Ground and Forest Temple. */ #include "z_bg_menkuri_kaiten.h" @@ -51,7 +51,7 @@ void BgMenkuriKaiten_Destroy(Actor* thisx, PlayState* play) { void BgMenkuriKaiten_Update(Actor* thisx, PlayState* play) { BgMenkuriKaiten* this = (BgMenkuriKaiten*)thisx; - if (!Flags_GetSwitch(play, this->dyna.actor.params) && func_80043590(&this->dyna)) { + if (!Flags_GetSwitch(play, this->dyna.actor.params) && DynaPolyActor_IsPlayerAbove(&this->dyna)) { func_8002F974(&this->dyna.actor, NA_SE_EV_ELEVATOR_MOVE - SFX_FLAG); this->dyna.actor.shape.rot.y += 0x80; } diff --git a/soh/src/overlays/actors/ovl_Bg_Menkuri_Nisekabe/z_bg_menkuri_nisekabe.c b/soh/src/overlays/actors/ovl_Bg_Menkuri_Nisekabe/z_bg_menkuri_nisekabe.c index 8c55c2db6..ddaa5a153 100644 --- a/soh/src/overlays/actors/ovl_Bg_Menkuri_Nisekabe/z_bg_menkuri_nisekabe.c +++ b/soh/src/overlays/actors/ovl_Bg_Menkuri_Nisekabe/z_bg_menkuri_nisekabe.c @@ -1,7 +1,7 @@ /* * File: z_bg_menkuri_nisekabe.c * Overlay: ovl_Bg_Menkuri_Nisekabe - * Description: False Stone Walls (Gerudo Training Grounds) + * Description: False Stone Walls (Gerudo Training Ground) */ #include "z_bg_menkuri_nisekabe.h" diff --git a/soh/src/overlays/actors/ovl_Bg_Mizu_Bwall/z_bg_mizu_bwall.c b/soh/src/overlays/actors/ovl_Bg_Mizu_Bwall/z_bg_mizu_bwall.c index 06c2381e9..89db58c0e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mizu_Bwall/z_bg_mizu_bwall.c +++ b/soh/src/overlays/actors/ovl_Bg_Mizu_Bwall/z_bg_mizu_bwall.c @@ -475,7 +475,7 @@ void BgMizuBwall_Idle(BgMizuBwall* this, PlayState* play) { this->dList = NULL; BgMizuBwall_SpawnDebris(this, play); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_WALL_BROKEN); - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->actionFunc = BgMizuBwall_Break; } else if (this->dyna.actor.xzDistToPlayer < 600.0f) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c b/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c index f678c5031..539b72eee 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c +++ b/soh/src/overlays/actors/ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c @@ -331,7 +331,7 @@ void func_8089E650(BgMizuMovebg* this, PlayState* play) { this->dyna.actor.speedXZ = dist; } func_80035844(&this->dyna.actor.world.pos, &waypoint, &this->dyna.actor.world.rot, 1); - func_8002D97C(&this->dyna.actor); + Actor_MoveXYZ(&this->dyna.actor); dx = waypoint.x - this->dyna.actor.world.pos.x; dy = waypoint.y - this->dyna.actor.world.pos.y; dz = waypoint.z - this->dyna.actor.world.pos.z; diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c b/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c index e4531cb4a..c95fe6fd8 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c @@ -162,7 +162,7 @@ void BgMoriBigst_SetupFall(BgMoriBigst* this, PlayState* play) { } void BgMoriBigst_Fall(BgMoriBigst* this, PlayState* play) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); if (this->dyna.actor.world.pos.y <= this->dyna.actor.home.pos.y) { this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; BgMoriBigst_SetupLanding(this, play); @@ -241,7 +241,7 @@ void BgMoriBigst_Update(Actor* thisx, PlayState* play) { if (this->waitTimer > 0) { this->waitTimer--; } - if (func_80043590(&this->dyna)) { + if (DynaPolyActor_IsPlayerAbove(&this->dyna)) { func_80074CE8(play, 6); } if (this->actionFunc != NULL) { diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c b/soh/src/overlays/actors/ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c index e5e84af5a..f0ca8d96c 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c @@ -125,7 +125,8 @@ void BgMoriElevator_Destroy(Actor* thisx, PlayState* play) { } s32 BgMoriElevator_IsPlayerRiding(BgMoriElevator* this, PlayState* play) { - return ((this->dyna.unk_160 & 2) && !(this->unk_170 & 2) && + return ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) && + !(this->unk_170 & DYNA_INTERACT_PLAYER_ON_TOP) && ((GET_PLAYER(play)->actor.world.pos.y - this->dyna.actor.world.pos.y) < 80.0f)); } @@ -244,7 +245,7 @@ void BgMoriElevator_Update(Actor* thisx, PlayState* play) { BgMoriElevator* this = (BgMoriElevator*)thisx; this->actionFunc(this, play); - this->unk_170 = this->dyna.unk_160; + this->unk_170 = this->dyna.interactFlags; this->unk_16C = Flags_GetSwitch(play, (thisx->params & 0x3F)); } diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c b/soh/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c index 4ec854444..76ffcdc33 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c @@ -245,7 +245,7 @@ void BgMoriHashigo_LadderFall(BgMoriHashigo* this, PlayState* play) { static f32 bounceSpeed[3] = { 4.0f, 2.7f, 1.7f }; Actor* thisx = &this->dyna.actor; - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); if ((thisx->bgCheckFlags & 1) && (thisx->velocity.y < 0.0f)) { if (this->bounceCounter >= ARRAY_COUNT(bounceSpeed)) { BgMoriHashigo_SetupLadderRest(this); diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.c b/soh/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.c index 37402f22a..61bec679b 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Hineri/z_bg_mori_hineri.c @@ -218,7 +218,7 @@ void func_808A3E54(BgMoriHineri* this, PlayState* play) { this->moriHineriObjIdx = objBankIndex; this->dyna.actor.params ^= 1; sBgMoriHineriNextCamIdx = MAIN_CAM; - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } else { this->dyna.actor.draw = NULL; this->actionFunc = func_808A3D58; diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.c b/soh/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.c index 88ff91935..0324c43cb 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.c @@ -134,9 +134,9 @@ void BgMoriIdomizu_Main(BgMoriIdomizu* this, PlayState* play) { BgMoriIdomizu_SetWaterLevel(play, thisx->world.pos.y); if (this->drainTimer > 0) { if (switchFlagSet) { - func_800788CC(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); + Sfx_PlaySfxCentered2(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); } else { - func_800788CC(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); + Sfx_PlaySfxCentered2(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); } } } diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c b/soh/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c index f8c02704f..a57d9439a 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Kaitenkabe/z_bg_mori_kaitenkabe.c @@ -137,11 +137,11 @@ void BgMoriKaitenkabe_Rotate(BgMoriKaitenkabe* this, PlayState* play) { thisx->home.rot.y -= 0x2000; } thisx->world.rot.y = thisx->shape.rot.y = thisx->home.rot.y; - func_800788CC(NA_SE_EV_STONEDOOR_STOP); + Sfx_PlaySfxCentered2(NA_SE_EV_STONEDOOR_STOP); } else { rotY = this->rotYdeg * (0x10000 / 360.0f); thisx->world.rot.y = thisx->shape.rot.y = thisx->home.rot.y + rotY; - func_800788CC(NA_SE_EV_WALL_SLIDE - SFX_FLAG); + Sfx_PlaySfxCentered2(NA_SE_EV_WALL_SLIDE - SFX_FLAG); } if (fabsf(this->dyna.unk_150) > 0.001f) { this->dyna.unk_150 = 0.0f; diff --git a/soh/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c b/soh/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c index bc420d399..4202768a4 100644 --- a/soh/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c +++ b/soh/src/overlays/actors/ovl_Bg_Mori_Rakkatenjo/z_bg_mori_rakkatenjo.c @@ -133,7 +133,7 @@ void BgMoriRakkatenjo_Wait(BgMoriRakkatenjo* this, PlayState* play) { } } if (this->timer < 20) { - func_800788CC(NA_SE_EV_BLOCKSINK - SFX_FLAG); + Sfx_PlaySfxCentered2(NA_SE_EV_BLOCKSINK - SFX_FLAG); } } @@ -149,14 +149,14 @@ void BgMoriRakkatenjo_Fall(BgMoriRakkatenjo* this, PlayState* play) { Actor* thisx = &this->dyna.actor; s32 quake; - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); if ((thisx->velocity.y < 0.0f) && (thisx->world.pos.y <= 403.0f)) { if (this->bounceCount >= ARRAY_COUNT(bounceVel)) { BgMoriRakkatenjo_SetupRest(this); } else { if (this->bounceCount == 0) { this->fallCount++; - func_800788CC(NA_SE_EV_STONE_BOUND); + Sfx_PlaySfxCentered2(NA_SE_EV_STONE_BOUND); func_800AA000(SQ(thisx->yDistToPlayer), 0xFF, 0x14, 0x96); } thisx->world.pos.y = diff --git a/soh/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c b/soh/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c index 716868f39..c706b68a7 100644 --- a/soh/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c +++ b/soh/src/overlays/actors/ovl_Bg_Po_Event/z_bg_po_event.c @@ -343,7 +343,7 @@ void BgPoEvent_BlockIdle(BgPoEvent* this, PlayState* play) { if (amy != NULL) { OnePointCutscene_Init(play, 3170, 30, amy, MAIN_CAM); } - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); gSaveContext.timer1State = 0xA; } } else { @@ -538,7 +538,7 @@ void BgPoEvent_PaintingPresent(BgPoEvent* this, PlayState* play) { thisx->world.pos.y - 40.0f, thisx->world.pos.z, 0, thisx->shape.rot.y, 0, thisx->params + ((this->type - 1) << 8), true); OnePointCutscene_Init(play, 3160, 80, thisx, MAIN_CAM); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } else { Audio_PlayActorSound2(thisx, NA_SE_EN_PO_LAUGH2); diff --git a/soh/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.c b/soh/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.c index 8377d3d3d..720dcf09f 100644 --- a/soh/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.c +++ b/soh/src/overlays/actors/ovl_Bg_Pushbox/z_bg_pushbox.c @@ -64,7 +64,7 @@ void BgPushbox_UpdateImpl(BgPushbox* this, PlayState* play) { : ((this->dyna.actor.speedXZ > 1.0f) ? 1.0f : this->dyna.actor.speedXZ); Math_StepToF(&this->dyna.actor.speedXZ, 0.0f, 0.2f); this->dyna.actor.world.rot.y = this->dyna.unk_158; - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 20.0f, 40.0f, 40.0f, 0x1D); } diff --git a/soh/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c b/soh/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c index 4f9207abe..58458fd1c 100644 --- a/soh/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Relay_Objects/z_bg_relay_objects.c @@ -150,7 +150,7 @@ void func_808A9234(BgRelayObjects* this, PlayState* play) { func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 180, 20, 100); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND); if (this->unk_169 != play->roomCtx.curRoom.num) { - func_800788CC(NA_SE_EN_PO_LAUGH); + Sfx_PlaySfxCentered2(NA_SE_EN_PO_LAUGH); this->timer = 5; this->actionFunc = func_808A932C; return; @@ -173,7 +173,7 @@ void func_808A932C(BgRelayObjects* this, PlayState* play) { } if (this->timer == 0) { if (!Player_InCsMode(play)) { - func_80078884(NA_SE_OC_ABYSS); + Sfx_PlaySfxCentered(NA_SE_OC_ABYSS); Play_TriggerRespawn(play); this->actionFunc = BgRelayObjects_DoNothing; } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c b/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c index 675bbb3ed..2d0263afd 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot00_Hanebasi/z_bg_spot00_hanebasi.c @@ -224,7 +224,7 @@ void BgSpot00Hanebasi_Update(Actor* thisx, PlayState* play) { Flags_SetEventChkInf(EVENTCHKINF_DRAWBRIDGE_OPENED_AFTER_ZELDA_FLED); this->actionFunc = BgSpot00Hanebasi_DoNothing; Player_SetCsActionWithHaltedActors(play, &player->actor, 8); - play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; gSaveContext.nextCutsceneIndex = 0xFFF1; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; diff --git a/soh/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.c b/soh/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.c index d49830357..59ef31c4f 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot01_Idohashira/z_bg_spot01_idohashira.c @@ -50,7 +50,7 @@ const ActorInit Bg_Spot01_Idohashira_InitVars = { }; void BgSpot01Idohashira_PlayBreakSfx1(BgSpot01Idohashira* this) { - func_80078914(&this->dyna.actor.projectedPos, NA_SE_EV_BOX_BREAK); + Sfx_PlaySfxAtPos(&this->dyna.actor.projectedPos, NA_SE_EV_BOX_BREAK); } void BgSpot01Idohashira_PlayBreakSfx2(BgSpot01Idohashira* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.c b/soh/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.c index 5f035763e..b287a5da6 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot01_Idomizu/z_bg_spot01_idomizu.c @@ -14,7 +14,7 @@ void BgSpot01Idomizu_Destroy(Actor* thisx, PlayState* play); void BgSpot01Idomizu_Update(Actor* thisx, PlayState* play); void BgSpot01Idomizu_Draw(Actor* thisx, PlayState* play); -void func_808ABB84(BgSpot01Idomizu* this, PlayState* play); +void BgSpot01Idomizu_UpdateWaterLevel(BgSpot01Idomizu* this, PlayState* play); const ActorInit Bg_Spot01_Idomizu_InitVars = { ACTOR_BG_SPOT01_IDOMIZU, @@ -42,21 +42,21 @@ void BgSpot01Idomizu_Init(Actor* thisx, PlayState* play) { } else { this->waterHeight = 52.0f; } - this->actionFunc = func_808ABB84; + this->actionFunc = BgSpot01Idomizu_UpdateWaterLevel; this->actor.world.pos.y = this->waterHeight; } void BgSpot01Idomizu_Destroy(Actor* thisx, PlayState* play) { } -void func_808ABB84(BgSpot01Idomizu* this, PlayState* play) { +void BgSpot01Idomizu_UpdateWaterLevel(BgSpot01Idomizu* this, PlayState* play) { if (Flags_GetEventChkInf(EVENTCHKINF_DRAINED_WELL_IN_KAKARIKO)) { this->waterHeight = -550.0f; } play->colCtx.colHeader->waterBoxes[0].ySurface = this->actor.world.pos.y; if (this->waterHeight < this->actor.world.pos.y) { - Audio_PlaySoundGeneral(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } Math_ApproachF(&this->actor.world.pos.y, this->waterHeight, 1.0f, 2.0f); } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.c b/soh/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.c index 905106dce..a914c204c 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot01_Idosoko/z_bg_spot01_idosoko.c @@ -6,6 +6,7 @@ #include "z_bg_spot01_idosoko.h" #include "objects/object_spot01_matoya/object_spot01_matoya.h" +#include "soh/OTRGlobals.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED diff --git a/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c b/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c index c2e8e1123..cebaa088c 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.c @@ -214,7 +214,7 @@ void func_808ACC34(BgSpot02Objects* this, PlayState* play) { } if (play->csCtx.frames == 245 || play->csCtx.frames == 351) { - func_800788CC(NA_SE_EV_LIGHTNING); + Sfx_PlaySfxCentered2(NA_SE_EV_LIGHTNING); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.c b/soh/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.c index 71341097b..979a0eb0d 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.c @@ -6,6 +6,7 @@ #include "z_bg_spot03_taki.h" #include "objects/object_spot03_object/object_spot03_object.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -14,7 +15,7 @@ void BgSpot03Taki_Destroy(Actor* thisx, PlayState* play); void BgSpot03Taki_Update(Actor* thisx, PlayState* play); void BgSpot03Taki_Draw(Actor* thisx, PlayState* play); -void func_808ADEF0(BgSpot03Taki* this, PlayState* play); +void BgSpot03Taki_HandleWaterfallState(BgSpot03Taki* this, PlayState* play); const ActorInit Bg_Spot03_Taki_InitVars = { ACTOR_BG_SPOT03_TAKI, @@ -59,7 +60,7 @@ void BgSpot03Taki_Init(Actor* thisx, PlayState* play) { this->openingAlpha = 255.0f; BgSpot03Taki_ApplyOpeningAlpha(this, 0); BgSpot03Taki_ApplyOpeningAlpha(this, 1); - this->actionFunc = func_808ADEF0; + this->actionFunc = BgSpot03Taki_HandleWaterfallState; } void BgSpot03Taki_Destroy(Actor* thisx, PlayState* play) { @@ -68,7 +69,7 @@ void BgSpot03Taki_Destroy(Actor* thisx, PlayState* play) { DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId); } -void func_808ADEF0(BgSpot03Taki* this, PlayState* play) { +void BgSpot03Taki_HandleWaterfallState(BgSpot03Taki* this, PlayState* play) { if (this->state == WATERFALL_CLOSED) { if (Flags_GetSwitch(play, this->switchFlag)) { this->state = WATERFALL_OPENING_ANIMATED; diff --git a/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c b/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c index 6e5bcf8dd..823a65040 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.c @@ -343,7 +343,7 @@ void BgSpot06Objects_LockWait(BgSpot06Objects* this, PlayState* play) { EffectSsGSplash_Spawn(play, &this->dyna.actor.world.pos, NULL, NULL, 1, 700); this->collider.elements->dim.worldSphere.radius = 45; this->actionFunc = BgSpot06Objects_LockPullOutward; - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Flags_SetSwitch(play, this->switchFlag); OnePointCutscene_Init(play, 4120, 170, &this->dyna.actor, MAIN_CAM); } else { diff --git a/soh/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.c b/soh/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.c index af09141fd..e40302b66 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot08_Bakudankabe/z_bg_spot08_bakudankabe.c @@ -187,7 +187,7 @@ void BgSpot08Bakudankabe_Update(Actor* thisx, PlayState* play) { func_808B0324(this, play); Flags_SetSwitch(play, (this->dyna.actor.params & 0x3F)); SoundSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 40, NA_SE_EV_WALL_BROKEN); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Actor_Kill(&this->dyna.actor); } else if (this->dyna.actor.xzDistToPlayer < 800.0f) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c b/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c index d7b45c9b6..2eb0bef7e 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c @@ -101,7 +101,7 @@ void BgSpot08Iceblock_SinkUnderPlayer(BgSpot08Iceblock* this) { } // Sink under Player's weight if standing on it - target = (func_80043548(&this->dyna) ? -4.0f : 0.0f); + target = (DynaPolyActor_IsActorOnTop(&this->dyna) ? -4.0f : 0.0f); Math_StepToF(&this->sinkOffset, target, step); } @@ -200,7 +200,7 @@ void BgSpot08Iceblock_Roll(BgSpot08Iceblock* this, PlayState* play) { surfaceNormalHorizontal.z = this->surfaceNormal.z; // If player is standing on it or holding the edge - if (func_8004356C(&this->dyna) && (playerCentroidDist > 3.0f)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna) && (playerCentroidDist > 3.0f)) { Math_Vec3f_Diff(&playerCentroidDiff, &surfaceNormalHorizontal, &playerMoment); BgSpot08Iceblock_MultVectorScalar(&playerMoment, &playerMoment, (sInertias[rollDataIndex] * playerCentroidDist) / this->dyna.actor.scale.x); diff --git a/soh/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.c b/soh/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.c index 11241004a..3b7f7c7e4 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot11_Bakudankabe/z_bg_spot11_bakudankabe.c @@ -139,7 +139,7 @@ void BgSpot11Bakudankabe_Update(Actor* thisx, PlayState* play) { func_808B2218(this, play); Flags_SetSwitch(play, (this->dyna.actor.params & 0x3F)); SoundSource_PlaySfxAtFixedWorldPos(play, &D_808B2738, 40, NA_SE_EV_WALL_BROKEN); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Actor_Kill(&this->dyna.actor); return; } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.c b/soh/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.c index e98369169..65e70a4b6 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.c @@ -110,7 +110,7 @@ void func_808B29F0(BgSpot11Oasis* this, PlayState* play) { func_808B2AA8(this); Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, this->actor.world.pos.x, this->actor.world.pos.y + 40.0f, this->actor.world.pos.z, 0, 0, 0, FAIRY_SPAWNER, true); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } func_808B27F0(play, this->actor.world.pos.y); } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c b/soh/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c index 5d73c277f..10c6ac559 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot12_Saku/z_bg_spot12_saku.c @@ -6,6 +6,7 @@ #include "z_bg_spot12_saku.h" #include "objects/object_spot12_obj/object_spot12_obj.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 diff --git a/soh/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c b/soh/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c index d1fdca048..8a14f5046 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c @@ -286,7 +286,7 @@ void func_808B4194(BgSpot15Rrbox* this, PlayState* play) { Audio_PlayActorSound2(actor, NA_SE_EV_WOOD_BOUND); } if (func_808B3A40(this, play)) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } actor->home.pos.x = actor->world.pos.x; actor->home.pos.z = actor->world.pos.z; @@ -319,7 +319,7 @@ void func_808B43D0(BgSpot15Rrbox* this, PlayState* play) { player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY; } - Actor_MoveForward(actor); + Actor_MoveXZGravity(actor); if (actor->world.pos.y <= BGCHECK_Y_MIN + 10.0f) { // "Lon Lon wooden crate fell too much" diff --git a/soh/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.c b/soh/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.c index 34a0c5091..5f24d06e8 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot16_Bombstone/z_bg_spot16_bombstone.c @@ -472,7 +472,7 @@ void func_808B5A94(BgSpot16Bombstone* this, PlayState* play) { func_808B5240(this, play); if (this->unk_154 == 56) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } if (this->unk_154 > 60) { @@ -500,7 +500,7 @@ void func_808B5B58(BgSpot16Bombstone* this) { void func_808B5B6C(BgSpot16Bombstone* this, PlayState* play) { Actor* actor = &this->actor; - Actor_MoveForward(actor); + Actor_MoveXZGravity(actor); actor->shape.rot.x += this->unk_210; actor->shape.rot.z += this->unk_212; diff --git a/soh/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.c b/soh/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.c index 08f8e36b5..6537a1690 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot17_Bakudankabe/z_bg_spot17_bakudankabe.c @@ -118,7 +118,7 @@ void BgSpot17Bakudankabe_Update(Actor* thisx, PlayState* play) { func_808B6BC0(this, play); Flags_SetSwitch(play, (this->dyna.actor.params & 0x3F)); SoundSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 40, NA_SE_EV_WALL_BROKEN); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Actor_Kill(&this->dyna.actor); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c b/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c index 2d81c8610..9e31efbdd 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c @@ -418,9 +418,9 @@ void func_808B81A0(BgSpot18Basket* this, PlayState* play) { } } else if (this->unk_216 == 2) { if (this->unk_218 == 2) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } else { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } } else if (this->unk_216 == 200) { func_808B7BB0(this); diff --git a/soh/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.c b/soh/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.c index bcff47d6b..36855ce69 100644 --- a/soh/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.c +++ b/soh/src/overlays/actors/ovl_Bg_Spot18_Obj/z_bg_spot18_obj.c @@ -247,7 +247,7 @@ void func_808B8F08(BgSpot18Obj* this, PlayState* play) { Player* player = GET_PLAYER(play); Math_StepToF(&this->dyna.actor.speedXZ, 1.2f, 0.1f); - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); func_808B8DDC(this, play); if (Math3D_Dist2DSq(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.z, this->dyna.actor.home.pos.x, @@ -258,7 +258,7 @@ void func_808B8F08(BgSpot18Obj* this, PlayState* play) { this->dyna.unk_150 = 0.0f; player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY; Flags_SetSwitch(play, (this->dyna.actor.params >> 8) & 0x3F); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); } else { func_8002F974(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); diff --git a/soh/src/overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c b/soh/src/overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c index f62f09128..bf4d7c934 100644 --- a/soh/src/overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c +++ b/soh/src/overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c @@ -6,6 +6,7 @@ #include "z_bg_sst_floor.h" #include "objects/object_sst/object_sst.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -61,13 +62,13 @@ void BgSstFloor_Update(BgSstFloor* thisx, PlayState* play) { colHeader->vtxList = SEGMENTED_TO_VIRTUAL(colHeader->vtxList); - if (func_80043590(&this->dyna) && (this->dyna.actor.yDistToPlayer < 1000.0f)) { + if (DynaPolyActor_IsPlayerAbove(&this->dyna) && (this->dyna.actor.yDistToPlayer < 1000.0f)) { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_BOSS_BONGO); } else { Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_DUNGEON0); } - if (func_8004356C(&this->dyna) && (player->fallDistance > 1000.0f)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna) && (player->fallDistance > 1000.0f)) { this->dyna.actor.params = 1; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EN_SHADEST_TAIKO_HIGH); } @@ -81,7 +82,7 @@ void BgSstFloor_Update(BgSstFloor* thisx, PlayState* play) { this->dyna.actor.params = BONGOFLOOR_REST; this->drumPhase = 28; - if (func_8004356C(&this->dyna) && !(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE))) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna) && !(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE))) { distFromRim = 600.0f - this->dyna.actor.xzDistToPlayer; if (distFromRim > 0.0f) { if (distFromRim > 350.0f) { diff --git a/soh/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.c b/soh/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.c index 574685b04..98904f138 100644 --- a/soh/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.c +++ b/soh/src/overlays/actors/ovl_Bg_Toki_Hikari/z_bg_toki_hikari.c @@ -179,7 +179,8 @@ void func_808BA2CC(BgTokiHikari* this, PlayState* play) { gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayListOffset(POLY_XLU_DISP++, object_toki_objects_DL_0009C0, 10); + // SOH [Port] Index adjust 11 -> 14 (for LUS marker and gsSPVertex) to account for our extraction size changes + gSPDisplayListOffset(POLY_XLU_DISP++, object_toki_objects_DL_0009C0, 10 + 2 + 1); Matrix_Pop(); CLOSE_DISPS(play->state.gfxCtx); } diff --git a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c index 621ed0e7f..a1362a2bb 100644 --- a/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c +++ b/soh/src/overlays/actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c @@ -6,6 +6,7 @@ #include "z_bg_toki_swd.h" #include "objects/object_toki_objects/object_toki_objects.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -141,7 +142,7 @@ void func_808BAF40(BgTokiSwd* this, PlayState* play) { } else { Player* player = GET_PLAYER(play); if (Actor_IsFacingPlayer(&this->actor, 0x2000)) { - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); } } } diff --git a/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c b/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c index 69ecc4251..334161c2d 100644 --- a/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c +++ b/soh/src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.c @@ -7,6 +7,7 @@ #include "z_bg_treemouth.h" #include "objects/object_spot04_objects/object_spot04_objects.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -100,7 +101,7 @@ void func_808BC65C(BgTreemouth* this, PlayState* play) { if (npcAction->action == 2) { BgTreemouth_SetupAction(this, func_808BC80C); } else if (npcAction->action == 3) { - Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); BgTreemouth_SetupAction(this, func_808BC6F8); } } @@ -206,7 +207,7 @@ void func_808BCAF0(BgTreemouth* this, PlayState* play) { if (npcAction->action == 2) { BgTreemouth_SetupAction(this, func_808BC80C); } else if (npcAction->action == 3) { - Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); BgTreemouth_SetupAction(this, func_808BC6F8); } } diff --git a/soh/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.c b/soh/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.c index dcbb6c126..bf2987c91 100644 --- a/soh/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.c +++ b/soh/src/overlays/actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.c @@ -84,8 +84,8 @@ void BgVbSima_Update(Actor* thisx, PlayState* play) { this->dyna.actor.world.pos.z += 2.0f * Math_CosS(this->shakeTimer * 0x8000); this->dyna.actor.shape.rot.x = (s16)Math_SinS(this->shakeTimer * 0x7000) * 0x37; this->dyna.actor.shape.rot.z = (s16)Math_SinS(this->shakeTimer * 0x5000) * 0x37; - Audio_PlaySoundGeneral(NA_SE_EV_BLOCKSINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_BLOCKSINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (signal == VBSIMA_KILL) { Actor_Kill(&this->dyna.actor); } diff --git a/soh/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.c b/soh/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.c index 9a38cfa5e..23d7fac96 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.c +++ b/soh/src/overlays/actors/ovl_Bg_Ydan_Maruta/z_bg_ydan_maruta.c @@ -149,7 +149,7 @@ void func_808BF078(BgYdanMaruta* this, PlayState* play) { if (this->collider.base.acFlags & AC_HIT) { this->unk_16A = 20; Flags_SetSwitch(play, this->switchFlag); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); this->actionFunc = func_808BF108; OnePointCutscene_Init(play, 3010, 50, &this->dyna.actor, MAIN_CAM); } else { diff --git a/soh/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c b/soh/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c index b7c988cda..1307971c7 100644 --- a/soh/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c +++ b/soh/src/overlays/actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c @@ -6,6 +6,7 @@ #include "z_bg_ydan_sp.h" #include "objects/object_ydan_objects/object_ydan_objects.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS 0 @@ -172,7 +173,7 @@ void BgYdanSp_UpdateFloorWebCollision(BgYdanSp* this) { void BgYdanSp_BurnWeb(BgYdanSp* this, PlayState* play) { this->timer = 30; this = this; - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Flags_SetSwitch(play, this->isDestroyedSwitchFlag); if (this->dyna.actor.params == WEB_FLOOR) { this->actionFunc = BgYdanSp_BurnFloorWeb; @@ -255,7 +256,7 @@ void BgYdanSp_FloorWebBreaking(BgYdanSp* this, PlayState* play) { if (this->dyna.actor.home.pos.y - this->dyna.actor.world.pos.y > 190.0f) { func_8003EBF8(play, &play->colCtx.dyna, this->dyna.bgId); this->timer = 40; - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Flags_SetSwitch(play, this->isDestroyedSwitchFlag); this->actionFunc = BgYdanSp_FloorWebBroken; pos.y = this->dyna.actor.world.pos.y - 60.0f; @@ -291,7 +292,7 @@ void BgYdanSp_FloorWebIdle(BgYdanSp* this, PlayState* play) { BgYdanSp_BurnWeb(this, play); return; } - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { sqrtFallDistance = sqrtf(CLAMP_MIN(player->fallDistance, 0.0f)); if (player->fallDistance > 750.0f) { if (this->dyna.actor.xzDistToPlayer < 80.0f) { @@ -403,7 +404,7 @@ void BgYdanSp_WallWebIdle(BgYdanSp* this, PlayState* play) { this->dyna.actor.home.pos.y = this->dyna.actor.world.pos.y + 80.0f; BgYdanSp_BurnWeb(this, play); } else if (player->heldItemAction == PLAYER_IA_DEKU_STICK && player->unk_860 != 0) { - func_8002DBD0(&this->dyna.actor, &sp30, &player->meleeWeaponInfo[0].tip); + Actor_WorldToActorCoords(&this->dyna.actor, &sp30, &player->meleeWeaponInfo[0].tip); if (fabsf(sp30.x) < 100.0f && sp30.z < 1.0f && sp30.y < 200.0f) { OnePointCutscene_Init(play, 3020, 40, &this->dyna.actor, MAIN_CAM); Math_Vec3f_Copy(&this->dyna.actor.home.pos, &player->meleeWeaponInfo[0].tip); diff --git a/soh/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.c b/soh/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.c index bc91d519b..b0e6779cc 100644 --- a/soh/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.c +++ b/soh/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.c @@ -55,8 +55,8 @@ void BgZg_Destroy(Actor* thisx, PlayState* play) { } void func_808C0C50(BgZg* this) { - Audio_PlaySoundGeneral(NA_SE_EV_METALDOOR_OPEN, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_METALDOOR_OPEN, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } s32 func_808C0C98(BgZg* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c index 59c83fc82..4702d8376 100644 --- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c +++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c @@ -5,6 +5,8 @@ #include "scenes/dungeons/ddan_boss/ddan_boss_room_1.h" #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include // malloc #include // memcpy @@ -844,7 +846,7 @@ void BossDodongo_Walk(BossDodongo* this, PlayState* play) { } if (this->unk_1BC != 0) { - func_80078884(NA_SE_EN_DODO_K_WALK); + Sfx_PlaySfxCentered(NA_SE_EN_DODO_K_WALK); } else { Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_K_WALK); } @@ -1042,7 +1044,7 @@ void BossDodongo_Update(Actor* thisx, PlayState* play2) { thisx->shape.rot.y = thisx->world.rot.y; Math_SmoothStepToF(&thisx->shape.yOffset, this->unk_228, 1.0f, 100.0f, 0.0f); - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); BossDodongo_UpdateDamage(this, play); Actor_UpdateBgCheckInfo(play, thisx, 10.0f, 10.0f, 20.0f, 4); Math_SmoothStepToF(&this->unk_208, 0, 1, 0.001f, 0.0); diff --git a/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c b/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c index e004cc627..c44810f0b 100644 --- a/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c +++ b/soh/src/overlays/actors/ovl_Boss_Fd/z_boss_fd.c @@ -397,8 +397,8 @@ void BossFd_Fly(BossFd* this, PlayState* play) { this->fogMode = 1; } if (this->timers[0] < 50) { - Audio_PlaySoundGeneral(NA_SE_EN_DODO_K_ROLL - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_DODO_K_ROLL - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->camData.yMod = Math_CosS(this->work[BFD_MOVE_TIMER] * 0x8000) * this->camData.shake; Math_ApproachF(&this->camData.shake, 2.0f, 1.0f, 0.8 * 0.01f); } @@ -418,8 +418,8 @@ void BossFd_Fly(BossFd* this, PlayState* play) { case BFD_CS_LOOK_GROUND: this->camData.yMod = Math_CosS(this->work[BFD_MOVE_TIMER] * 0x8000) * this->camData.shake; Math_ApproachF(&this->camData.shake, 2.0f, 1.0f, 0.8 * 0.01f); - Audio_PlaySoundGeneral(NA_SE_EN_DODO_K_ROLL - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_DODO_K_ROLL - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (this->timers[0] == 0) { this->introState = BFD_CS_COLLAPSE; this->camData.nextEye.x = player2->actor.world.pos.x + 100.0f + 300.0f; @@ -439,8 +439,8 @@ void BossFd_Fly(BossFd* this, PlayState* play) { this->camData.accel = 0.005f; this->camData.yMod = Math_CosS(this->work[BFD_MOVE_TIMER] * 0x8000) * this->camData.shake; Math_ApproachF(&this->camData.shake, 2.0f, 1.0f, 0.8 * 0.01f); - Audio_PlaySoundGeneral(NA_SE_EN_DODO_K_ROLL - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_DODO_K_ROLL - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (this->timers[0] == 100) { this->platformSignal = VBSIMA_COLLAPSE; } @@ -476,8 +476,8 @@ void BossFd_Fly(BossFd* this, PlayState* play) { osSyncPrintf("WAY_SPD Y = %f\n", this->camData.atVel.y); osSyncPrintf("WAY_SPD Z = %f\n", this->camData.atVel.z); if ((this->timers[3] > 190) && !Flags_GetEventChkInf(EVENTCHKINF_BEGAN_VOLVAGIA_BATTLE)) { - Audio_PlaySoundGeneral(NA_SE_EN_DODO_K_ROLL - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_DODO_K_ROLL - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } if (this->timers[3] == 190) { this->camData.atMaxVel.x = this->camData.atMaxVel.y = this->camData.atMaxVel.z = 0.05f; @@ -683,8 +683,8 @@ void BossFd_Fly(BossFd* this, PlayState* play) { if (this->actor.bgCheckFlags & 0x10) { this->fwork[BFD_CEILING_BOUNCE] = -18384.0f; this->timers[1] = 10; - Audio_PlaySoundGeneral(NA_SE_EV_EXPLOSION, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_EXPLOSION, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); func_80033E1C(play, 3, 0xA, 0x7530); this->work[BFD_ROCK_TIMER] = 300; } @@ -783,8 +783,8 @@ void BossFd_Fly(BossFd* this, PlayState* play) { sp150 = 1; if (this->work[BFD_MOVE_TIMER] & 0x1C) { - Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_BURN - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_BURN - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } for (i1 = 0; i1 < sp150; i1++) { if (sp150) { // Needed for matching @@ -856,8 +856,8 @@ void BossFd_Fly(BossFd* this, PlayState* play) { this->work[BFD_CEILING_TARGET]++; this->timers[1] = 60; this->work[BFD_CAM_SHAKE_TIMER] = 20; - Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_LAND2, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_LAND2, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Player_SetCsActionWithHaltedActors(play, &this->actor, 5); for (i1 = 0; i1 < 15; i1++) { Vec3f sp144 = { 0.0f, 0.0f, 0.0f }; @@ -898,8 +898,8 @@ void BossFd_Fly(BossFd* this, PlayState* play) { Vec3f sp114 = { 0.0f, 0.0f, 0.0f }; Vec3f sp108 = { 0.0f, 0.03f, 0.0f }; - Audio_PlaySoundGeneral(NA_SE_EN_GOMA_LAST - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_GOMA_LAST - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sp120.x = Rand_CenteredFloat(40.0f) + this->actor.world.pos.x; sp120.y = (Rand_CenteredFloat(10.0f) + this->actor.world.pos.y) - 10.0f; @@ -950,9 +950,9 @@ void BossFd_Fly(BossFd* this, PlayState* play) { Math_ApproachF(&this->fwork[BFD_TURN_RATE], this->fwork[BFD_TURN_RATE_MAX], 1.0f, 20000.0f); Math_ApproachF(&this->actor.speedXZ, this->fwork[BFD_FLY_SPEED], 1.0f, 0.1f); if (this->work[BFD_ACTION_STATE] < BOSSFD_SKULL_FALL) { - func_8002D908(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); } - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->work[BFD_LEAD_BODY_SEG]++; if (this->work[BFD_LEAD_BODY_SEG] >= 100) { @@ -1139,8 +1139,8 @@ void BossFd_Effects(BossFd* this, PlayState* play) { if (this->work[BFD_ROAR_TIMER] != 0) { if (this->work[BFD_ROAR_TIMER] == 37) { - Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_ROAR, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_ROAR, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } jawAngle = 6000.0f; jawSpeed = 1300.0f; @@ -1160,8 +1160,8 @@ void BossFd_Effects(BossFd* this, PlayState* play) { Vec3f spawnPos1; s32 pad; - Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_APPEAR - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_APPEAR - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (this->work[BFD_SPLASH_TIMER] != 0) { this->work[BFD_SPLASH_TIMER]--; if ((this->actor.colChkInfo.health == 0) || @@ -1238,8 +1238,8 @@ void BossFd_Effects(BossFd* this, PlayState* play) { this->fogMode = 2; spawnSpeed2.z = 30.0f; - Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_FIRE - SFX_FLAG, &sFireAudioVec, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_FIRE - SFX_FLAG, &sFireAudioVec, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); spawnPos2 = this->headPos; spawnAngleY = (this->actor.world.rot.y / (f32)0x8000) * M_PI; @@ -1301,8 +1301,8 @@ void BossFd_CollisionCheck(BossFd* this, PlayState* play) { } this->work[BFD_DAMAGE_FLASH_TIMER] = 10; this->work[BFD_INVINC_TIMER] = 20; - Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_DAMAGE1, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_DAMAGE1, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c index 8e2fffe36..a418ced3a 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c @@ -11,6 +11,7 @@ #include "assets/scenes/dungeons/ganon_boss/ganon_boss_scene.h" #include "soh/frame_interpolation.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include @@ -700,7 +701,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { this->fwork[GDF_TRIFORCE_PRIM_A] = 0.0f; this->fwork[GDF_TRIFORCE_PRIM_B] = 255.0f; this->fwork[GDF_TRIFORCE_ENV_G] = 100.0f; - func_80078884(NA_SE_EV_TRIFORCE_MARK); + Sfx_PlaySfxCentered(NA_SE_EV_TRIFORCE_MARK); play->envCtx.unk_D8 = 0.0f; // fallthrough case 7: @@ -747,7 +748,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { this->fwork[GDF_TRIFORCE_PRIM_A] = 0.0f; this->fwork[GDF_TRIFORCE_PRIM_B] = 255.0f; this->fwork[GDF_TRIFORCE_ENV_G] = 100.0f; - func_80078884(NA_SE_EV_TRIFORCE_MARK); + Sfx_PlaySfxCentered(NA_SE_EV_TRIFORCE_MARK); play->envCtx.unk_D8 = 0.0f; // fallthrough case 9: @@ -956,7 +957,7 @@ void BossGanon_IntroCutscene(BossGanon* this, PlayState* play) { if (this->csTimer >= 30) { if (this->csTimer == 30) { - func_80078884(NA_SE_EV_TRIFORCE_MARK); + Sfx_PlaySfxCentered(NA_SE_EV_TRIFORCE_MARK); } // fade in ganondorf's triforce @@ -1476,7 +1477,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { this->unk_70C = Math_SinS(this->csTimer * 0x6300) * 0.2f; - func_80078884(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_EARTHQUAKE - SFX_FLAG); skip_cam_and_quake: this->envLightMode = 15; @@ -1523,7 +1524,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { } this->unk_70C = Math_SinS(this->csTimer * 0x6300) * this->unk_710; - func_80078884(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_EARTHQUAKE - SFX_FLAG); if (this->csTimer < 100) { this->windowShatterState = GDF_WINDOW_SHATTER_PARTIAL; @@ -1744,7 +1745,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { case 1055: this->unk_70C = Math_SinS(this->csTimer * 0x6300) * 0.3f; - func_80078884(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_EARTHQUAKE - SFX_FLAG); if (this->csTimer == 20) { sBossGanonZelda->unk_3C8 = 5; @@ -1759,7 +1760,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { case 1056: this->unk_70C = Math_SinS(this->csTimer * 0x6300) * 0.3f; - func_80078884(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_EARTHQUAKE - SFX_FLAG); this->csCamEye.x = -503.0f; this->csCamEye.y = 4128.0f; @@ -1777,7 +1778,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { case 1057: this->unk_70C = Math_SinS(this->csTimer * 0x6300) * (50.0f * this->csCamMovementScale); - func_80078884(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_EARTHQUAKE - SFX_FLAG); Math_ApproachF(&this->csCamEye.x, -1200.0f, 0.1f, this->csCamMovementScale * 697.0f); Math_ApproachF(&this->csCamEye.y, 4241.0f, 0.1f, this->csCamMovementScale * 113.0f); @@ -1801,7 +1802,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { this->csCamAt.z = sBossGanonZelda->actor.world.pos.z - 25.0f; this->unk_70C = Math_SinS(this->csTimer * 0x6300) * 0.3f; - func_80078884(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_EARTHQUAKE - SFX_FLAG); if (this->csTimer == 70) { sBossGanonZelda->unk_3C8 = 6; @@ -1821,7 +1822,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { case 107: this->unk_70C = Math_SinS(this->csTimer * 0x6300) * 0.8f; - func_80078884(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_EARTHQUAKE - SFX_FLAG); this->csCamEye.x = -380.0f; this->csCamEye.y = 4154.0f; @@ -1840,7 +1841,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { case 108: this->unk_70C = Math_SinS(this->csTimer * 0x6300) * 0.8f; - func_80078884(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_EARTHQUAKE - SFX_FLAG); this->csCamAt.x = (sBossGanonZelda->actor.world.pos.x - 5.0f) - 30.0f; this->csCamAt.y = (sBossGanonZelda->actor.world.pos.y + 40.0f + 5.0f) - 20.0f; @@ -1863,7 +1864,7 @@ void BossGanon_DeathAndTowerCutscene(BossGanon* this, PlayState* play) { break; case 109: - func_80078884(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_EARTHQUAKE - SFX_FLAG); break; } @@ -2306,7 +2307,7 @@ void BossGanon_Wait(BossGanon* this, PlayState* play) { this->actor.world.pos.y += this->actor.velocity.y; Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0xBB8); - func_80078914(&this->actor.projectedPos, NA_SE_EN_FANTOM_FLOAT - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EN_FANTOM_FLOAT - SFX_FLAG); } void BossGanon_SetupChargeLightBall(BossGanon* this, PlayState* play) { @@ -2803,7 +2804,7 @@ void BossGanon_UpdateDamage(BossGanon* this, PlayState* play) { BossGanon_SetupDeathCutscene(this, play); Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_DEAD); Audio_PlayActorSound2(&this->actor, NA_SE_EN_GANON_DD_THUNDER); - func_80078914(&sZeroVec, NA_SE_EN_LAST_DAMAGE); + Sfx_PlaySfxAtPos(&sZeroVec, NA_SE_EN_LAST_DAMAGE); Audio_QueueSeqCmd(0x100100FF); this->screenFlashTimer = 4; GameInteractor_ExecuteOnBossDefeat(&this->actor); @@ -2985,7 +2986,7 @@ void BossGanon_Update(Actor* thisx, PlayState* play2) { // player hit, spawn shock and play sound if (this->unk_2E8 != 0) { - func_80078914(&player->actor.projectedPos, NA_SE_PL_SPARK - SFX_FLAG); + Sfx_PlaySfxAtPos(&player->actor.projectedPos, NA_SE_PL_SPARK - SFX_FLAG); BossGanonEff_SpawnShock(play, 700.0f, GDF_SHOCK_PLAYER_YELLOW); } } @@ -4007,8 +4008,8 @@ void BossGanon_LightBall_Update(Actor* thisx, PlayState* play2) { yDistFromLink = (player->actor.world.pos.y + 40.0f) - this->actor.world.pos.y; zDistFromLink = player->actor.world.pos.z - this->actor.world.pos.z; - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); switch (this->unk_1C2) { case 0: @@ -4028,8 +4029,8 @@ void BossGanon_LightBall_Update(Actor* thisx, PlayState* play2) { if ((hitWithBottle == false) && (acHitInfo->toucher.dmgFlags & 0x100000)) { spBA = 2; - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_MG, &player->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_MG, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_800AA000(this->actor.xyzDistToPlayerSq, 0xFF, 0x14, 0x96); } else { spBA = 1; @@ -4038,8 +4039,8 @@ void BossGanon_LightBall_Update(Actor* thisx, PlayState* play2) { Math_Atan2S(sqrtf(SQ(xDistFromGanondorf) + SQ(zDistFromGanondorf)), yDistFromGanondorf); this->unk_1A4++; this->timers[1] = 2; - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_REFLECT_MG, &player->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_REFLECT_MG, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_800AA000(this->actor.xyzDistToPlayerSq, 0xB4, 0x14, 0x64); if (hitWithBottle == false) { @@ -4286,8 +4287,8 @@ void func_808E1EB4(Actor* thisx, PlayState* play2) { } } - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); this->unk_1A6++; @@ -4319,8 +4320,8 @@ void func_808E1EB4(Actor* thisx, PlayState* play2) { this->actor.speedXZ = 0.0f; if (this->actor.params == 0xC8) { - func_80078884(NA_SE_EN_GANON_DAMAGE2); - func_80078884(NA_SE_EN_GANON_DD_THUNDER); + Sfx_PlaySfxCentered(NA_SE_EN_GANON_DAMAGE2); + Sfx_PlaySfxCentered(NA_SE_EN_GANON_DD_THUNDER); for (i = 0; i < 150; i++) { @@ -4412,8 +4413,8 @@ void func_808E2544(Actor* thisx, PlayState* play) { } } - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); this->unk_1A6++; @@ -4500,8 +4501,8 @@ void func_808E2544(Actor* thisx, PlayState* play) { if ((player->meleeWeaponState != 0) && (player->meleeWeaponAnimation >= 0x18) && (this->actor.xzDistToPlayer < 80.0f)) { this->unk_1C2 = 0xC; this->actor.speedXZ = -30.0f; - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); this->unk_1F0 = dorf->unk_1FC; numEffects = 10; break; @@ -4517,8 +4518,8 @@ void func_808E2544(Actor* thisx, PlayState* play) { this->unk_1C2 = 0xC; this->actor.speedXZ = -30.0f; - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); this->unk_1F0.x = Rand_CenteredFloat(700.0f) + dorf->unk_1FC.x; this->unk_1F0.y = Rand_CenteredFloat(200.0f) + dorf->unk_1FC.y; @@ -4824,7 +4825,7 @@ void BossGanon_UpdateEffects(PlayState* play) { Math_ApproachF(&eff->unk_40, 4.0f, 1.0f, 0.15f); } else if (eff->type == GDF_EFF_IMPACT_DUST_LIGHT) { if (i == 0) { - func_80078884(NA_SE_EN_GANON_WAVE_GND - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EN_GANON_WAVE_GND - SFX_FLAG); } eff->unk_30++; // unused diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c index 97cc537b4..5270402fe 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c @@ -7,6 +7,8 @@ #include "objects/object_ganon_anime3/object_ganon_anime3.h" #include "objects/object_geff/object_geff.h" #include "soh/frame_interpolation.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include @@ -334,7 +336,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { Math_ApproachF(&this->unk_3B0.y, player->actor.world.pos.y + 47.0f + 7.0f, 0.1f, 2.0f); this->unk_339 = 4; if (this->csTimer == 10) { - func_80078914(&D_80906D6C, NA_SE_EV_STONE_BOUND); + Sfx_PlaySfxAtPos(&D_80906D6C, NA_SE_EV_STONE_BOUND); Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_STOP); } if (this->csTimer == 20) { @@ -397,7 +399,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->unk_3B0.y = (player->actor.world.pos.y + 200.0f) - 160.0f; this->unk_3B0.z = player->actor.world.pos.z; if (this->csTimer >= 20) { - func_80078884(NA_SE_EN_GOMA_LAST - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EN_GOMA_LAST - SFX_FLAG); Math_ApproachF(&this->unk_324, 255.0f, 1.0f, 10.0f); this->unk_339 = 5; if (this->csTimer == 20) { @@ -418,7 +420,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { break; case 11: this->unk_339 = 5; - func_80078884(NA_SE_EN_GOMA_LAST - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EN_GOMA_LAST - SFX_FLAG); player->actor.world.pos.x = 490.0f; player->actor.world.pos.y = 1086.0f; player->actor.world.pos.z = -166.0f; @@ -434,10 +436,10 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->unk_3B0.y = ((player->actor.world.pos.y + 200.0f) - 151.0f) - 2.0f; this->unk_3B0.z = player->actor.world.pos.z + 2.0f; if (this->csTimer == 10) { - func_80078914(&D_80906D6C, NA_SE_EV_STONE_BOUND); + Sfx_PlaySfxAtPos(&D_80906D6C, NA_SE_EV_STONE_BOUND); } if (this->csTimer == 20) { - func_80078884(NA_SE_EV_STONE_BOUND); + Sfx_PlaySfxCentered(NA_SE_EV_STONE_BOUND); } if (this->csTimer == 30) { Player_SetCsActionWithHaltedActors(play, &this->actor, 0x52); @@ -471,7 +473,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { func_800A9F6C(0.0f, 0xC8, 0x14, 0x14); } if (this->csTimer == 30) { - func_80078884(NA_SE_EV_GRAVE_EXPLOSION); + Sfx_PlaySfxCentered(NA_SE_EV_GRAVE_EXPLOSION); } if (this->csTimer >= 30) { Math_ApproachF(&this->actor.world.pos.y, 1289.0f, 0.1f, 10.0f); @@ -736,8 +738,8 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->unk_312 = 2; } if ((this->csTimer == 166) || (this->csTimer == 185) || (this->csTimer == 200)) { - func_80078884(NA_SE_EN_MGANON_SWORD); - func_80078884(NA_SE_EN_MGANON_ROAR); + Sfx_PlaySfxCentered(NA_SE_EN_MGANON_SWORD); + Sfx_PlaySfxCentered(NA_SE_EN_MGANON_ROAR); } if (this->csTimer == 215) { this->csState = 23; @@ -751,8 +753,8 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->unk_312 = 2; } if (this->csTimer == 222) { - func_80078884(NA_SE_EN_MGANON_SWORD); - func_80078884(NA_SE_EN_MGANON_ROAR); + Sfx_PlaySfxCentered(NA_SE_EN_MGANON_SWORD); + Sfx_PlaySfxCentered(NA_SE_EN_MGANON_ROAR); } this->unk_3A4.x = (player->actor.world.pos.x - 40.0f) + 6.0f; this->unk_3A4.y = player->actor.world.pos.y + 40.0f; @@ -761,7 +763,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->unk_3B0.y = ((player->actor.world.pos.y + 10.0f + 60.0f) - 20.0f) - 2.0f; this->unk_3B0.z = player->actor.world.pos.z; if (this->csTimer == 228) { - func_80078884(NA_SE_IT_SHIELD_REFLECT_SW); + Sfx_PlaySfxCentered(NA_SE_IT_SHIELD_REFLECT_SW); Player_SetCsActionWithHaltedActors(play, &this->actor, 0x56); func_800A9F6C(0.0f, 0xFF, 0xA, 0x32); } @@ -796,7 +798,7 @@ void func_808FD5F4(BossGanon2* this, PlayState* play) { this->unk_3A4.z = effect->position.z + 70.0f; } if ((this->csTimer & 3) == 0) { - func_80078884(NA_SE_IT_SWORD_SWING); + Sfx_PlaySfxCentered(NA_SE_IT_SWORD_SWING); } if (this->csTimer == 25) { Player_SetCsActionWithHaltedActors(play, &this->actor, 0x57); @@ -976,11 +978,11 @@ void func_808FF898(BossGanon2* this, PlayState* play) { } if (this->unk_392 == 4) { - func_80078884(NA_SE_EV_GRAVE_EXPLOSION); + Sfx_PlaySfxCentered(NA_SE_EV_GRAVE_EXPLOSION); } if (this->unk_392 == 3) { - func_80078884(NA_SE_EN_MGANON_SWDIMP); + Sfx_PlaySfxCentered(NA_SE_EN_MGANON_SWDIMP); } } } @@ -1349,7 +1351,7 @@ void func_80900890(BossGanon2* this, PlayState* play) { play->envCtx.unk_D8 = 0.0f; case 1: if (this->unk_1A2[1] == 50) { - func_80078884(NA_SE_EN_MGANON_WALK); + Sfx_PlaySfxCentered(NA_SE_EN_MGANON_WALK); } Matrix_RotateY(((this->actor.shape.rot.y / (f32)0x8000) * M_PI) + 0.3f, MTXMODE_NEW); sp5C.x = 0.0f; @@ -1556,12 +1558,12 @@ void func_8090120C(BossGanon2* this, PlayState* play) { Math_ApproachZeroF(&play->envCtx.unk_D8, 1.0f, 0.08f); } if (this->csTimer == 50) { - func_80078884(NA_SE_EN_MGANON_WALK); + Sfx_PlaySfxCentered(NA_SE_EN_MGANON_WALK); } if (this->csTimer > 90) { Math_ApproachF(&this->unk_380, 0.25f, 1.0f, 0.0125f); this->unk_37C = 200.0f; - func_80078884(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); } if (this->csTimer >= 110) { if (this->csTimer == 110) { @@ -1596,7 +1598,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { case 2: this->unk_339 = 22; Math_ApproachF(&play->envCtx.unk_D8, 1.0f, 1.0f, 0.1f); - func_80078884(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); this->unk_3A4.x = 250; this->unk_3A4.y = 1150.0f; this->unk_3A4.z = 0.0f; @@ -1610,7 +1612,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { break; case 3: this->unk_339 = 22; - func_80078884(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); this->unk_3A4.x = 330.0f; this->unk_3A4.y = 1120.0f; this->unk_3A4.z = -150.0f; @@ -1647,7 +1649,7 @@ void func_8090120C(BossGanon2* this, PlayState* play) { this->unk_339 = 23; if ((this->csTimer >= 60) && (this->csTimer <= 90)) { if (this->csTimer == 62) { - func_80078884(NA_SE_EV_TRIFORCE_FLASH); + Sfx_PlaySfxCentered(NA_SE_EV_TRIFORCE_FLASH); } Math_ApproachF(&this->unk_38C, 200.0f, 1.0f, 8.0f); } else { @@ -1707,12 +1709,12 @@ void func_8090120C(BossGanon2* this, PlayState* play) { player->actor.shape.rot.y = -0x4000; player->actor.world.pos.z = 30.0f; if ((this->csTimer == 20) || (this->csTimer == 30) || (this->csTimer == 65) || (this->csTimer == 40)) { - func_80078884(NA_SE_VO_LI_SWORD_N); - func_80078884(NA_SE_IT_SWORD_SWING_HARD); + Sfx_PlaySfxCentered(NA_SE_VO_LI_SWORD_N); + Sfx_PlaySfxCentered(NA_SE_IT_SWORD_SWING_HARD); } if ((this->csTimer == 22) || (this->csTimer == 35) || (this->csTimer == 72) || (this->csTimer == 45)) { - func_80078884(NA_SE_EN_MGANON_DAMAGE); - func_80078884(NA_SE_IT_SHIELD_BOUND); + Sfx_PlaySfxCentered(NA_SE_EN_MGANON_DAMAGE); + Sfx_PlaySfxCentered(NA_SE_IT_SHIELD_BOUND); play->envCtx.unk_D8 = 1.0f; } if ((this->csTimer == 22) || (this->csTimer == 35) || (this->csTimer == 72) || (this->csTimer == 45)) { @@ -2045,14 +2047,14 @@ void BossGanon2_Update(Actor* thisx, PlayState* play) { if (this->unk_392 != 0) { this->unk_392--; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); this->actor.shape.rot = this->actor.world.rot; if (this->unk_335 != 0) { Actor_UpdateBgCheckInfo(play, &this->actor, 60.0f, 60.0f, 100.0f, 5); if (this->actor.bgCheckFlags & 1) { if (this->actor.velocity.y < -5.0f) { func_80033E88(&this->actor, play, 5, 20); - func_80078884(NA_SE_IT_BOMB_EXPLOSION); + Sfx_PlaySfxCentered(NA_SE_IT_BOMB_EXPLOSION); } this->actor.velocity.y = 0.0f; } @@ -2138,7 +2140,7 @@ void BossGanon2_Update(Actor* thisx, PlayState* play) { if (Rand_ZeroOne() < 0.5f) { D_8090EB20.z = Rand_ZeroFloat(1000.0f); } - func_80078914(&D_8090EB20, NA_SE_EV_LIGHTNING); + Sfx_PlaySfxAtPos(&D_8090EB20, NA_SE_EV_LIGHTNING); this->unk_328 = 0xFF; this->unk_330 = 5; this->unk_32C = 0.0f; @@ -2916,7 +2918,7 @@ void func_80905DA8(BossGanon2* this, PlayState* play) { if (effect->velocity.y < -10.0f) { sp78 = effect->position; sp78.y = 1086.0f; - func_80078884(NA_SE_IT_SHIELD_REFLECT_SW); + Sfx_PlaySfxCentered(NA_SE_IT_SHIELD_REFLECT_SW); CollisionCheck_SpawnShieldParticlesMetal(play, &sp78); } effect->velocity.y = 0.0f; diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c index 5f800a056..1ac0d2c90 100644 --- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c +++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c @@ -11,6 +11,7 @@ #include "overlays/effects/ovl_Effect_Ss_Fhg_Flash/z_eff_ss_fhg_flash.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -316,7 +317,7 @@ void BossGanondrof_Intro(BossGanondrof* this, PlayState* play) { } if (this->timers[1] == 30) { - func_80078914(&sAudioVec, NA_SE_EN_FANTOM_TRANSFORM); + Sfx_PlaySfxAtPos(&sAudioVec, NA_SE_EN_FANTOM_TRANSFORM); } if (horse->bossGndSignal == FHG_LIGHTNING) { @@ -719,7 +720,7 @@ void BossGanondrof_Stunned(BossGanondrof* this, PlayState* play) { this->actor.gravity = 0.0f; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void BossGanondrof_SetupBlock(BossGanondrof* this, PlayState* play) { @@ -805,8 +806,8 @@ void BossGanondrof_Charge(BossGanondrof* this, PlayState* play) { Math_FAtan2F(vecToLink.y, sqrtf(SQ(vecToLink.x) + SQ(vecToLink.z))) * (0x8000 / M_PI); } - func_8002D908(thisx); - func_8002D7EC(thisx); + Actor_UpdateVelocityXYZ(thisx); + Actor_UpdatePos(thisx); Math_ApproachF(&thisx->speedXZ, 10.0f, 1.0f, 0.5f); if ((sqrtf(SQ(dxCenter) + SQ(dzCenter)) > 280.0f) || (thisx->xyzDistToPlayerSq < SQ(100.0f))) { this->work[GND_ACTION_STATE] = CHARGE_FINISH; @@ -815,7 +816,7 @@ void BossGanondrof_Charge(BossGanondrof* this, PlayState* play) { break; case CHARGE_FINISH: thisx->gravity = 0.2f; - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); osSyncPrintf("YP %f @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n", thisx->world.pos.y); if (thisx->world.pos.y < 5.0f) { thisx->world.pos.y = 5.0f; diff --git a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c index 0644f73a8..fdc16fd1e 100644 --- a/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c +++ b/soh/src/overlays/actors/ovl_Boss_Goma/z_boss_goma.c @@ -4,6 +4,7 @@ #include "overlays/actors/ovl_En_Goma/z_en_goma.h" #include "overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -1934,7 +1935,7 @@ void BossGoma_Update(Actor* thisx, PlayState* play) { this->actor.shape.rot.y = this->actor.world.rot.y; if (!this->doNotMoveThisFrame) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } else { this->doNotMoveThisFrame = false; } diff --git a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c index 12dfd415a..c1d0f7bae 100644 --- a/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c +++ b/soh/src/overlays/actors/ovl_Boss_Mo/z_boss_mo.c @@ -619,7 +619,7 @@ void BossMo_Tentacle(BossMo* this, PlayState* play) { case MO_TENT_READY: case MO_TENT_SWING: if (sMorphaCore->csState == MO_BATTLE) { - func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_APPEAR - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->tentTipPos, NA_SE_EN_MOFER_APPEAR - SFX_FLAG); } Math_ApproachF(&this->waterLevelMod, -5.0f, 0.1f, 0.4f); for (indS1 = 0; indS1 < 41; indS1++) { @@ -672,7 +672,7 @@ void BossMo_Tentacle(BossMo* this, PlayState* play) { break; case MO_TENT_ATTACK: this->actor.flags |= ACTOR_FLAG_PLAY_HIT_SFX; - func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_ATTACK - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->tentTipPos, NA_SE_EN_MOFER_ATTACK - SFX_FLAG); Math_ApproachF(&this->waterLevelMod, -5.0f, 0.1f, 0.4f); for (indS1 = 0; indS1 < 41; indS1++) { Math_ApproachF(&this->tentStretch[indS1].y, @@ -754,9 +754,9 @@ void BossMo_Tentacle(BossMo* this, PlayState* play) { if (play->grabPlayer(play, player)) { player->actor.parent = &this->actor; this->work[MO_TENT_ACTION_STATE] = MO_TENT_GRAB; - func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_CATCH); - Audio_PlaySoundGeneral(NA_SE_VO_LI_DAMAGE_S, &player->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Sfx_PlaySfxAtPos(&this->tentTipPos, NA_SE_EN_MOFER_CATCH); + Audio_PlaySoundGeneral(NA_SE_VO_LI_DAMAGE_S, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { this->work[MO_TENT_ACTION_STATE] = MO_TENT_READY; this->tentMaxAngle = .001f; @@ -885,7 +885,7 @@ void BossMo_Tentacle(BossMo* this, PlayState* play) { } break; case MO_TENT_CUT: - func_80078914(&this->tentTipPos, NA_SE_EV_WATER_WALL - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->tentTipPos, NA_SE_EV_WATER_WALL - SFX_FLAG); if (&this->actor == player->actor.parent) { player->av2.actionVar2 = 0x65; player->actor.parent = NULL; @@ -1103,7 +1103,7 @@ void BossMo_Tentacle(BossMo* this, PlayState* play) { this->drawActor = false; this->work[MO_TENT_ACTION_STATE] = MO_TENT_DEATH_6; this->timers[0] = 60; - func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_CORE_JUMP); + Sfx_PlaySfxAtPos(&this->tentTipPos, NA_SE_EN_MOFER_CORE_JUMP); for (indS1 = 0; indS1 < 300; indS1++) { spC8.x = 0.0; spC8.y = 0.0; @@ -1181,7 +1181,7 @@ void BossMo_TentCollisionCheck(BossMo* this, PlayState* play) { hurtbox = this->tentCollider.elements[i1].info.acHitInfo; this->work[MO_TENT_INVINC_TIMER] = 5; if (hurtbox->toucher.dmgFlags & 0x00020000) { - func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_CUT); + Sfx_PlaySfxAtPos(&this->tentTipPos, NA_SE_EN_MOFER_CUT); this->cutIndex = 15; this->meltIndex = this->cutIndex + 1; this->work[MO_TENT_ACTION_STATE] = MO_TENT_CUT; @@ -1292,7 +1292,7 @@ void BossMo_IntroCs(BossMo* this, PlayState* play) { EffectSsBubble_Spawn(play, &bubblePos, 0.0f, 10.0f, 50.0f, Rand_ZeroFloat(0.05f) + 0.13f); } if (this->timers[2] == 40) { - func_80078914(&sAudioZeroVec, NA_SE_EN_MOFER_BUBLE_DEMO); + Sfx_PlaySfxAtPos(&sAudioZeroVec, NA_SE_EN_MOFER_BUBLE_DEMO); } break; case MO_INTRO_SWIM: @@ -1325,7 +1325,7 @@ void BossMo_IntroCs(BossMo* this, PlayState* play) { Math_ApproachF(&this->cameraSpeedMod, 0.02f, 1.0f, 0.001f); } if (this->work[MO_TENT_MOVE_TIMER] == 190) { - func_80078914(&sAudioZeroVec, NA_SE_EN_MOFER_BUBLE_DEMO); + Sfx_PlaySfxAtPos(&sAudioZeroVec, NA_SE_EN_MOFER_BUBLE_DEMO); } if ((this->work[MO_TENT_MOVE_TIMER] > 150) && (this->work[MO_TENT_MOVE_TIMER] < 180)) { bubblePos2.x = (this->cameraEye.x + 20.0f) + 10.0f; @@ -1501,7 +1501,7 @@ void BossMo_IntroCs(BossMo* this, PlayState* play) { this->cameraAtVel.z * this->cameraSpeedMod); Math_ApproachF(&this->cameraSpeedMod, 1.0f, 1.0f, this->cameraAccel); } else if (this->csState < MO_INTRO_REVEAL) { - func_8002D908(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); this->cameraEye.x += this->actor.velocity.x; this->cameraEye.y += this->actor.velocity.y; this->cameraEye.z += this->actor.velocity.z; @@ -1517,9 +1517,9 @@ void BossMo_IntroCs(BossMo* this, PlayState* play) { } if ((this->csState > MO_INTRO_START) && (this->work[MO_TENT_MOVE_TIMER] > 540)) { - func_80078914(&sMorphaTent1->tentTipPos, NA_SE_EN_MOFER_APPEAR - SFX_FLAG); + Sfx_PlaySfxAtPos(&sMorphaTent1->tentTipPos, NA_SE_EN_MOFER_APPEAR - SFX_FLAG); } else if (this->csState >= MO_INTRO_START) { - func_80078914(&sAudioZeroVec, NA_SE_EN_MOFER_MOVE_DEMO - SFX_FLAG); + Sfx_PlaySfxAtPos(&sAudioZeroVec, NA_SE_EN_MOFER_MOVE_DEMO - SFX_FLAG); } } @@ -1718,13 +1718,13 @@ void BossMo_DeathCs(BossMo* this, PlayState* play) { } if ((this->csState > MO_DEATH_START) && (this->csState < MO_DEATH_FINISH)) { if (this->work[MO_TENT_MOVE_TIMER] < 500) { - func_80078914(&sAudioZeroVec, NA_SE_EN_MOFER_APPEAR - SFX_FLAG); + Sfx_PlaySfxAtPos(&sAudioZeroVec, NA_SE_EN_MOFER_APPEAR - SFX_FLAG); } if ((this->work[MO_TENT_MOVE_TIMER] < 490) && (this->work[MO_TENT_MOVE_TIMER] > 230)) { - func_80078914(&sAudioZeroVec, NA_SE_EV_DROP_FALL - SFX_FLAG); + Sfx_PlaySfxAtPos(&sAudioZeroVec, NA_SE_EV_DROP_FALL - SFX_FLAG); } if (this->work[MO_TENT_MOVE_TIMER] < 220) { - func_80078914(&sAudioZeroVec, NA_SE_EV_SCOOPUP_WATER - SFX_FLAG); + Sfx_PlaySfxAtPos(&sAudioZeroVec, NA_SE_EV_SCOOPUP_WATER - SFX_FLAG); } } if (sMorphaCore->waterLevel < -200.0f) { @@ -1820,7 +1820,7 @@ void BossMo_CoreCollisionCheck(BossMo* this, PlayState* play) { this->work[MO_TENT_INVINC_TIMER] = 10; } else if (!(hurtbox->toucher.dmgFlags & 0x00100000) && (hurtbox->toucher.dmgFlags & 0x80)) { if (this->work[MO_TENT_ACTION_STATE] >= MO_CORE_ATTACK) { - func_80078914(&sMorphaTent1->tentTipPos, NA_SE_EN_MOFER_CUT); + Sfx_PlaySfxAtPos(&sMorphaTent1->tentTipPos, NA_SE_EN_MOFER_CUT); sMorphaTent1->cutIndex = this->work[MO_CORE_POS_IN_TENT]; sMorphaTent1->meltIndex = sMorphaTent1->cutIndex + 1; sMorphaTent1->cutScale = 1.0f; @@ -2164,12 +2164,12 @@ void BossMo_Core(BossMo* this, PlayState* play) { spD0 = (s16)(Math_FAtan2F(spD8, sqrtf(SQ(spDC) + SQ(spD4))) * (0x8000 / M_PI)); Math_ApproachS(&this->actor.world.rot.y, spCC, this->tentMaxAngle, this->tentSpeed); Math_ApproachS(&this->actor.world.rot.x, spD0, this->tentMaxAngle, this->tentSpeed); - func_8002D908(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); } else { this->actor.world.pos.y += this->actor.velocity.y; this->actor.velocity.y -= 1.0f; } - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); temp = (this->actor.world.pos.y < -200.0f) ? 5 : 1; this->actor.world.pos.y -= 20.0f; Actor_UpdateBgCheckInfo(play, &this->actor, 50.0f, 20.0f, 100.0f, temp); @@ -2346,7 +2346,7 @@ void BossMo_UpdateTent(Actor* thisx, PlayState* play) { } } Math_ApproachS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0xA, 0xC8); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Math_ApproachF(&this->actor.speedXZ, 0.0, 1.0f, 0.02f); if (BossMo_NearLand(&this->actor.world.pos, 40)) { @@ -2386,7 +2386,7 @@ void BossMo_UpdateTent(Actor* thisx, PlayState* play) { } else { i = 0; if (this->work[MO_TENT_ACTION_STATE] < MO_TENT_CUT) { - func_80078914(&this->tentTipPos, NA_SE_EN_MOFER_CORE_ROLL - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->tentTipPos, NA_SE_EN_MOFER_CORE_ROLL - SFX_FLAG); } } bubblePos.x = this->tentPos[i].x + sp7C.x; @@ -3614,7 +3614,7 @@ void BossMo_Unknown(void) { if (BREG(32) != 0) { BREG(32)--; Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x100FF); - func_80078914(&zeroVec, unkSfx[BREG(33)]); + Sfx_PlaySfxAtPos(&zeroVec, unkSfx[BREG(33)]); } if (BREG(34) != 0) { BREG(34) = 0; diff --git a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c index ad1c87d1c..edd5c032f 100644 --- a/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c +++ b/soh/src/overlays/actors/ovl_Boss_Sst/z_boss_sst.c @@ -11,6 +11,7 @@ #include "overlays/actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "soh/frame_interpolation.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -1065,8 +1066,8 @@ void BossSst_HeadDeath(BossSst* this, PlayState* play) { player->actor.world.pos.z = sRoomCenter.z + (400.0f * Math_CosS(this->actor.shape.rot.y)) - (Math_SinS(this->actor.shape.rot.y) * -120.0f); player->actor.shape.rot.y = Actor_WorldYawTowardPoint(&player->actor, &sRoomCenter); - func_8002DBD0(&this->actor, &sCameraEye, &GET_ACTIVE_CAM(play)->eye); - func_8002DBD0(&this->actor, &sCameraAt, &GET_ACTIVE_CAM(play)->at); + Actor_WorldToActorCoords(&this->actor, &sCameraEye, &GET_ACTIVE_CAM(play)->eye); + Actor_WorldToActorCoords(&this->actor, &sCameraAt, &GET_ACTIVE_CAM(play)->at); this->radius = -350.0f; this->actor.world.pos.x = sRoomCenter.x - (Math_SinS(this->actor.shape.rot.y) * 350.0f); this->actor.world.pos.z = sRoomCenter.z - (Math_CosS(this->actor.shape.rot.y) * 350.0f); @@ -2526,7 +2527,7 @@ void BossSst_HandSetInvulnerable(BossSst* this, s32 isInv) { } void BossSst_HeadSfx(BossSst* this, u16 sfxId) { - func_80078914(&this->center, sfxId); + Sfx_PlaySfxAtPos(&this->center, sfxId); } void BossSst_HandCollisionCheck(BossSst* this, PlayState* play) { @@ -2651,8 +2652,8 @@ void BossSst_UpdateHead(Actor* thisx, PlayState* play) { s32 pad; BossSst* this = (BossSst*)thisx; - func_8002DBD0(&this->actor, &sHandOffsets[RIGHT], &sHands[RIGHT]->actor.world.pos); - func_8002DBD0(&this->actor, &sHandOffsets[LEFT], &sHands[LEFT]->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &sHandOffsets[RIGHT], &sHands[RIGHT]->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &sHandOffsets[LEFT], &sHands[LEFT]->actor.world.pos); sHandYawOffsets[LEFT] = sHands[LEFT]->actor.shape.rot.y - thisx->shape.rot.y; sHandYawOffsets[RIGHT] = sHands[RIGHT]->actor.shape.rot.y - thisx->shape.rot.y; diff --git a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c index f92526337..a0df96d42 100644 --- a/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c +++ b/soh/src/overlays/actors/ovl_Boss_Tw/z_boss_tw.c @@ -598,8 +598,8 @@ void BossTw_TurnToPlayer(BossTw* this, PlayState* play) { Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, this->rotateSpeed); Math_ApproachS(&this->actor.shape.rot.x, 0, 5, this->rotateSpeed); Math_ApproachF(&this->rotateSpeed, 4096.0f, 1.0f, 200.0f); - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); if (this->timers[0] == 0) { if ((otherTw->actionFunc != BossTw_ShootBeam) && this->work[CAN_SHOOT]) { this->work[CAN_SHOOT] = false; @@ -670,8 +670,8 @@ void BossTw_FlyTo(BossTw* this, PlayState* play) { Math_ApproachS(&this->actor.shape.rot.x, pitchTarget, 0xA, this->rotateSpeed); Math_ApproachF(&this->rotateSpeed, 4096.0f, 1.0f, 100.0f); Math_ApproachF(&this->actor.speedXZ, 10.0f, 1.0f, 1.0f); - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); if ((this->timers[0] == 0) || (xzDist < 70.0f)) { BossTw_SetupTurnToPlayer(this, play); @@ -853,7 +853,7 @@ s32 BossTw_CheckBeamReflection(BossTw* this, PlayState* play) { BossTw_AddShieldDeflectEffect(play, 10.0f, this->actor.params); play->envCtx.unk_D8 = 1.0f; this->timers[0] = 10; - func_80078884(NA_SE_IT_SHIELD_REFLECT_MG2); + Sfx_PlaySfxCentered(NA_SE_IT_SHIELD_REFLECT_MG2); } sBeamDivertTimer++; @@ -1080,7 +1080,7 @@ void BossTw_ShootBeam(BossTw* this, PlayState* play) { } this->beamShootState = 1; - func_80078914(&player->actor.projectedPos, NA_SE_IT_SHIELD_REFLECT_MG); + Sfx_PlaySfxAtPos(&player->actor.projectedPos, NA_SE_IT_SHIELD_REFLECT_MG); Matrix_MtxFToYXZRotS(&player->shieldMf, &sp128, 0); sp128.y += 0x8000; sp128.x = -sp128.x; @@ -1105,11 +1105,11 @@ void BossTw_ShootBeam(BossTw* this, PlayState* play) { &this->unk_54C, &this->actor.projectedW); if (this->actor.params == 1) { - Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_SHOOT_FIRE - SFX_FLAG, &this->unk_54C, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_SHOOT_FIRE - SFX_FLAG, &this->unk_54C, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_SHOOT_FREEZE - SFX_FLAG, &this->unk_54C, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_SHOOT_FREEZE - SFX_FLAG, &this->unk_54C, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } break; @@ -1135,15 +1135,15 @@ void BossTw_ShootBeam(BossTw* this, PlayState* play) { &this->actor.projectedW); if (this->actor.params == 1) { - Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_SHOOT_FIRE - SFX_FLAG, &this->unk_558, 4U, &D_801333E0, - &D_801333E0, &D_801333E8); - Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_REFL_FIRE - SFX_FLAG, &this->unk_558, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_SHOOT_FIRE - SFX_FLAG, &this->unk_558, 4U, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_REFL_FIRE - SFX_FLAG, &this->unk_558, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_SHOOT_FREEZE - SFX_FLAG, &this->unk_558, 4, &D_801333E0, - &D_801333E0, &D_801333E8); - Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_REFL_FREEZE - SFX_FLAG, &this->unk_558, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_SHOOT_FREEZE - SFX_FLAG, &this->unk_558, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_REFL_FREEZE - SFX_FLAG, &this->unk_558, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } break; } @@ -1671,7 +1671,7 @@ void BossTw_TwinrovaMergeCS(BossTw* this, PlayState* play) { if (this->timers[1] == 8) { this->work[TW_BLINK_IDX] = 8; - func_80078884(NA_SE_EN_TWINROBA_YOUNG_WINK); + Sfx_PlaySfxCentered(NA_SE_EN_TWINROBA_YOUNG_WINK); } if (this->timers[2] == 4) { sEnvType = 0; @@ -1749,12 +1749,12 @@ void BossTw_TwinrovaIntroCS(BossTw* this, PlayState* play) { Player* player = GET_PLAYER(play); if (this->csSfxTimer > 220 && this->csSfxTimer < 630) { - func_80078884(NA_SE_EN_TWINROBA_UNARI - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EN_TWINROBA_UNARI - SFX_FLAG); } if (this->csSfxTimer == 180) { - func_80078914(&D_8094A7D0, NA_SE_EN_TWINROBA_LAUGH); - func_80078914(&D_8094A7D0, NA_SE_EN_TWINROBA_LAUGH2); + Sfx_PlaySfxAtPos(&D_8094A7D0, NA_SE_EN_TWINROBA_LAUGH); + Sfx_PlaySfxAtPos(&D_8094A7D0, NA_SE_EN_TWINROBA_LAUGH2); Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_KOTAKE_KOUME); } @@ -1815,7 +1815,7 @@ void BossTw_TwinrovaIntroCS(BossTw* this, PlayState* play) { } if (this->work[CS_TIMER_1] == 180) { - func_80078884(NA_SE_EN_TWINROBA_APPEAR_MS); + Sfx_PlaySfxCentered(NA_SE_EN_TWINROBA_APPEAR_MS); } if (this->work[CS_TIMER_1] > 180) { @@ -2336,8 +2336,8 @@ void BossTw_DeathBall(BossTw* this, PlayState* play) { Math_ApproachS(&this->actor.world.rot.x, Math_FAtan2F(yDiff, sqrtf(SQ(xDiff) + SQ(zDiff))) * (32768 / M_PI), 5, this->rotateSpeed); Math_ApproachS(&this->actor.world.rot.y, yaw, 5, this->rotateSpeed); - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); } void BossTw_TwinrovaSetupDeathCS(BossTw* this, PlayState* play) { @@ -2433,7 +2433,7 @@ void BossTw_DeathCSMsgSfx(BossTw* this, PlayState* play) { } if (this->work[CS_TIMER_2] > 440 && this->work[CS_TIMER_2] < 860) { - func_80078884(NA_SE_EN_TWINROBA_FIGHT - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EN_TWINROBA_FIGHT - SFX_FLAG); } if (this->work[CS_TIMER_2] == 430) { @@ -2638,7 +2638,7 @@ void BossTw_TwinrovaDeathCS(BossTw* this, PlayState* play) { Vec3f spBC; Vec3f spB0; Vec3f spA4 = { 0.0f, 0.0f, 0.0f }; - func_80078884(NA_SE_EN_TWINROBA_TRANSFORM); + Sfx_PlaySfxCentered(NA_SE_EN_TWINROBA_TRANSFORM); for (i = 0; i < 100; i++) { spB0.x = Rand_CenteredFloat(5.0f); spB0.y = Rand_CenteredFloat(5.0f); @@ -2751,7 +2751,7 @@ void BossTw_TwinrovaDeathCS(BossTw* this, PlayState* play) { Actor_SetScale(&sKotakePtr->actor, 0.0f); sKoumePtr->visible = 1; sKotakePtr->visible = 1; - func_80078884(NA_SE_EN_TWINROBA_TRANSFORM); + Sfx_PlaySfxCentered(NA_SE_EN_TWINROBA_TRANSFORM); Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_KOTAKE_KOUME); this->csState2 = 3; this->work[CS_TIMER_2] = 0; @@ -3153,8 +3153,8 @@ void BossTw_TwinrovaUpdate(Actor* thisx, PlayState* play2) { if (sFreezeState == 1) { sFreezeState = 2; BossTw_AddPlayerFreezeEffect(play, NULL); - func_80078914(&player->actor.projectedPos, NA_SE_VO_LI_FREEZE); - func_80078914(&player->actor.projectedPos, NA_SE_PL_FREEZE); + Sfx_PlaySfxAtPos(&player->actor.projectedPos, NA_SE_VO_LI_FREEZE); + Sfx_PlaySfxAtPos(&player->actor.projectedPos, NA_SE_PL_FREEZE); if (sShieldFireCharge != 0) { sShieldFireCharge = 4; @@ -3680,11 +3680,11 @@ void BossTw_ShieldChargeDraw(BossTw* this, PlayState* play) { temp_t0 = sShieldFireCharge | sShieldIceCharge; if (temp_t0 == 1) { - func_80078884(NA_SE_IT_SHIELD_CHARGE_LV1 & ~SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_IT_SHIELD_CHARGE_LV1 & ~SFX_FLAG); } else if (temp_t0 == 2) { - func_80078884(NA_SE_IT_SHIELD_CHARGE_LV2 & ~SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_IT_SHIELD_CHARGE_LV2 & ~SFX_FLAG); } else if (temp_t0 == 3) { - func_80078884(NA_SE_IT_SHIELD_CHARGE_LV3 & ~SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_IT_SHIELD_CHARGE_LV3 & ~SFX_FLAG); } if (temp_t0 != 0 && temp_t0 < 4) { @@ -3928,8 +3928,8 @@ void BossTw_BlastFire(BossTw* this, PlayState* play) { case 10: this->blastActive = true; if (this->timers[0] == 0) { - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); Audio_PlayActorSound2(&this->actor, NA_SE_EN_TWINROBA_SHOOT_FIRE & ~SFX_FLAG); } else { Vec3f velocity; @@ -4118,8 +4118,8 @@ void BossTw_BlastIce(BossTw* this, PlayState* play) { this->blastActive = true; if (this->timers[0] == 0) { - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); Audio_PlayActorSound2(&this->actor, NA_SE_EN_TWINROBA_SHOOT_FREEZE - SFX_FLAG); } else { Vec3f velocity; @@ -4367,7 +4367,7 @@ s32 BossTw_BlastShieldCheck(BossTw* this, PlayState* play) { sEnvType = 0; sShieldIceCharge = 0; sShieldFireCharge = 0; - func_80078884(NA_SE_IT_SHIELD_REFLECT_MG2); + Sfx_PlaySfxCentered(NA_SE_IT_SHIELD_REFLECT_MG2); } ret = true; @@ -5438,7 +5438,7 @@ void BossTw_TwinrovaFly(BossTw* this, PlayState* play) { Math_ApproachS(&this->actor.shape.rot.y, yaw, 0xA, this->rotateSpeed); Math_ApproachF(&this->rotateSpeed, 2000.0f, 1.0f, 100.0f); Math_ApproachF(&this->actor.speedXZ, 30.0f, 1.0f, 2.0f); - func_8002D908(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); Math_ApproachF(&this->actor.world.pos.x, this->targetPos.x, 0.1f, fabsf(this->actor.velocity.x) * 1.5f); Math_ApproachF(&this->actor.world.pos.y, this->targetPos.y, 0.1f, fabsf(this->actor.velocity.y) * 1.5f); Math_ApproachF(&this->targetPos.y, 380.0f, 1.0f, 2.0f); diff --git a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c index fc00e641b..18bc927d5 100644 --- a/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c +++ b/soh/src/overlays/actors/ovl_Boss_Va/z_boss_va.c @@ -14,6 +14,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" +#include "soh/OTRGlobals.h" #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -1307,7 +1308,7 @@ void BossVa_BodyPhase3(BossVa* this, PlayState* play) { this->actor.speedXZ = 0.0f; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (SkelAnime_Update(&this->skelAnime) && (sFightPhase >= PHASE_4)) { BossVa_SetupBodyPhase4(this, play); } @@ -1507,7 +1508,7 @@ void BossVa_BodyPhase4(BossVa* this, PlayState* play) { } } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 60.0f; if (((play->gameplayFrames % 2) == 0) && (this->timer == 0)) { @@ -3937,7 +3938,7 @@ void BossVa_SpawnTumor(PlayState* play, BossVaEffect* effect, BossVa* this, Vec3 effect->scale = 0.0f; if (((i % 4) == 0) || (mode == 2)) { - Audio_PlaySoundGeneral(NA_SE_EN_BALINADE_BREAK, &effect->pos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_BALINADE_BREAK, &effect->pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } break; } diff --git a/soh/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c b/soh/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c index 3207e4e87..8b68506f2 100644 --- a/soh/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c +++ b/soh/src/overlays/actors/ovl_Demo_6K/z_demo_6k.c @@ -12,6 +12,7 @@ #include "overlays/actors/ovl_Eff_Dust/z_eff_dust.h" #include "soh/frame_interpolation.h" #include +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -236,7 +237,7 @@ void func_80966E98(Demo6K* this, PlayState* play) { } if (this->timer1 == 39) { - func_800788CC(NA_SE_EV_CONSENTRATION); + Sfx_PlaySfxCentered2(NA_SE_EV_CONSENTRATION); Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_6K, this->actor.world.pos.x, this->actor.world.pos.y + 10.0f, this->actor.world.pos.z, 0, 0, 0, 2, true); } diff --git a/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c b/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c index d05e3aa2b..dd1e97e05 100644 --- a/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c +++ b/soh/src/overlays/actors/ovl_Demo_Du/z_demo_du.c @@ -309,14 +309,14 @@ void DemoDu_InitCs_GoronsRuby(DemoDu* this, PlayState* play) { // Cutscene: Darunia gives Link the Goron's Ruby. // Sfx played when Darunia lands at the floor at the start of the cutscene. void DemoDu_CsPlaySfx_GoronLanding(DemoDu* this) { - func_80078914(&this->actor.projectedPos, NA_SE_EN_GOLON_LAND_BIG); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EN_GOLON_LAND_BIG); } // Cutscene: Darunia gives Link the Goron's Ruby. // Sfx played when Darunia is falling at the start of the cutscene. void DemoDu_CsPlaySfx_DaruniaFalling(PlayState* play) { if (play->csCtx.frames == 160) { - func_800788CC(NA_SE_EV_OBJECT_FALL); + Sfx_PlaySfxCentered2(NA_SE_EV_OBJECT_FALL); } } @@ -325,14 +325,14 @@ void DemoDu_CsPlaySfx_DaruniaHitsLink(PlayState* play) { Player* player = GET_PLAYER(play); s32 pad; - func_80078914(&player->actor.projectedPos, NA_SE_EN_DARUNIA_HIT_LINK); - Audio_PlaySoundGeneral(NA_SE_VO_LI_DAMAGE_S_KID, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Sfx_PlaySfxAtPos(&player->actor.projectedPos, NA_SE_EN_DARUNIA_HIT_LINK); + Audio_PlaySoundGeneral(NA_SE_VO_LI_DAMAGE_S_KID, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } // Cutscene: Darunia gives Link the Goron's Ruby. void DemoDu_CsPlaySfx_HitBreast(DemoDu* this) { - func_80078914(&this->actor.projectedPos, NA_SE_EN_DARUNIA_HIT_BREAST - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EN_DARUNIA_HIT_BREAST - SFX_FLAG); } // Cutscene: Darunia gives Link the Goron's Ruby. @@ -341,8 +341,8 @@ void DemoDu_CsPlaySfx_LinkEscapeFromGorons(PlayState* play) { if (play->csCtx.frames == 1400) { Player* player = GET_PLAYER(play); - Audio_PlaySoundGeneral(NA_SE_VO_LI_FALL_L_KID, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_VO_LI_FALL_L_KID, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } @@ -352,8 +352,8 @@ void DemoDu_CsPlaySfx_LinkSurprised(PlayState* play) { if (play->csCtx.frames == 174) { Player* player = GET_PLAYER(play); - Audio_PlaySoundGeneral(NA_SE_VO_LI_SURPRISE_KID, &player->actor.projectedPos, 4U, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_VO_LI_SURPRISE_KID, &player->actor.projectedPos, 4U, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } @@ -715,7 +715,7 @@ void DemoDu_InitCs_AfterGanon(DemoDu* this, PlayState* play) { } void DemoDu_CsPlaySfx_WhiteOut() { - func_800788CC(NA_SE_SY_WHITE_OUT_T); + Sfx_PlaySfxCentered2(NA_SE_SY_WHITE_OUT_T); } void DemoDu_CsAfterGanon_SpawnDemo6K(DemoDu* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c index 9ba6a8437..b15b5b17e 100644 --- a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c +++ b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c @@ -10,6 +10,8 @@ #include "objects/object_efc_tw/object_efc_tw.h" #include "objects/object_gi_jewel/object_gi_jewel.h" #include +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -332,7 +334,7 @@ void DemoEffect_Init(Actor* thisx, PlayState* play2) { break; case DEMO_EFFECT_GOD_LGT_NAYRU: - if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_0) { + if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT) { Actor_SetScale(&this->actor, 1.0f); } else { Actor_SetScale(&this->actor, 0.1f); @@ -635,7 +637,7 @@ void DemoEffect_UpdateGetItem(DemoEffect* this, PlayState* play) { Actor_SetScale(thisx, 0.20f); - if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_0 || (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_7)) { + if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_ENTRANCE || (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_WARP_PAD)) { switch (play->csCtx.npcActions[this->csActionId]->action) { case 2: DemoEffect_MedalSparkle(this, play, 0); @@ -647,11 +649,11 @@ void DemoEffect_UpdateGetItem(DemoEffect* this, PlayState* play) { } switch (play->csCtx.npcActions[this->csActionId]->action) { case 2: - if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_0 || - (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_7)) { + if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_ENTRANCE || + (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_WARP_PAD)) { Audio_PlayActorSound2(thisx, NA_SE_EV_MEDAL_APPEAR_L - SFX_FLAG); } else { - func_800788CC(NA_SE_EV_MEDAL_APPEAR_S - SFX_FLAG); + Sfx_PlaySfxCentered2(NA_SE_EV_MEDAL_APPEAR_S - SFX_FLAG); } if (this->getItem.drawId != GID_ARROW_LIGHT) { this->actor.shape.rot.y += 0x3E80; @@ -663,11 +665,11 @@ void DemoEffect_UpdateGetItem(DemoEffect* this, PlayState* play) { if (this->getItem.drawId != GID_ARROW_LIGHT) { this->actor.shape.rot.y += this->getItem.rotation; } - if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_0 || - (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_7)) { + if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_ENTRANCE || + (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_WARP_PAD)) { Audio_PlayActorSound2(thisx, NA_SE_EV_MEDAL_APPEAR_L - SFX_FLAG); } else { - func_800788CC(NA_SE_EV_MEDAL_APPEAR_S - SFX_FLAG); + Sfx_PlaySfxCentered2(NA_SE_EV_MEDAL_APPEAR_S - SFX_FLAG); } break; case 4: @@ -945,7 +947,7 @@ void DemoEffect_UpdateLightRingTriforce(DemoEffect* this, PlayState* play) { void DemoEffect_UpdateCreationFireball(DemoEffect* this, PlayState* play) { DemoEffect* effect; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); this->actor.speedXZ = this->actor.speedXZ + (this->actor.gravity * 0.5f); if (this->fireBall.timer != 0) { @@ -973,7 +975,7 @@ void DemoEffect_UpdateCreationFireball(DemoEffect* this, PlayState* play) { Actor_SetScale(&effect->actor, 0.2f); } - func_800788CC(NA_SE_IT_DM_RING_EXPLOSION); + Sfx_PlaySfxCentered2(NA_SE_IT_DM_RING_EXPLOSION); Actor_Kill(&this->actor); } @@ -1230,7 +1232,7 @@ void DemoEffect_UpdateGodLgtNayru(DemoEffect* this, PlayState* play) { } } - if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_0 && gSaveContext.sceneSetupIndex == 4) { + if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT && gSaveContext.sceneSetupIndex == 4) { if (play->csCtx.frames == 72) { Audio_PlayActorSound2(&this->actor, NA_SE_IT_DM_FLYING_GOD_DASH); } @@ -1614,15 +1616,15 @@ void DemoEffect_UpdateJewelChild(DemoEffect* this, PlayState* play) { return; default: DemoEffect_MoveToCsEndpoint(this, play, this->csActionId, 0); - if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_0 || - (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_7)) { + if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_ENTRANCE || + (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_WARP_PAD)) { DemoEffect_MoveJewelSplit(&thisx->world, this); } break; } } - if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_0 || (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_7)) { + if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_ENTRANCE || (IS_RANDO && gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_WARP_PAD)) { if (!Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME)) { hasCmdAction = play->csCtx.state && play->csCtx.npcActions[this->csActionId]; if (!hasCmdAction) { @@ -1862,13 +1864,13 @@ void DemoEffect_DrawGodLgt(Actor* thisx, PlayState* play) { if (gSaveContext.entranceIndex == ENTR_CUTSCENE_MAP_0) { if (gSaveContext.sceneSetupIndex == 4) { if (play->csCtx.frames <= 680) { - func_80078914(&this->actor.projectedPos, NA_SE_EV_GOD_FLYING - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_GOD_FLYING - SFX_FLAG); } } else { - func_80078914(&this->actor.projectedPos, NA_SE_EV_GOD_FLYING - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_GOD_FLYING - SFX_FLAG); } } else { - func_80078914(&this->actor.projectedPos, NA_SE_EV_GOD_FLYING - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_GOD_FLYING - SFX_FLAG); } gSPSegment(POLY_XLU_DISP++, 8, @@ -2126,7 +2128,7 @@ void DemoEffect_DrawGetItem(Actor* thisx, PlayState* play) { rg = RG_SHADOW_MEDALLION; break; case DEMO_EFFECT_MEDAL_LIGHT: - rc = RC_GIFT_FROM_SAGES; + rc = RC_GIFT_FROM_RAURU; rg = RG_LIGHT_MEDALLION; break; case DEMO_EFFECT_LIGHTARROW: diff --git a/soh/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.c b/soh/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.c index 15d042ff9..175785126 100644 --- a/soh/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.c +++ b/soh/src/overlays/actors/ovl_Demo_Ext/z_demo_ext.c @@ -45,8 +45,8 @@ void DemoExt_Init(Actor* thisx, PlayState* play) { void DemoExt_PlayVortexSFX(DemoExt* this) { if (this->alphaTimer <= (kREG(35) + 40.0f) - 15.0f) { - Audio_PlaySoundGeneral(NA_SE_EV_FANTOM_WARP_L - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_FANTOM_WARP_L - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.c b/soh/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.c index 357b2c0ca..e678721ef 100644 --- a/soh/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.c +++ b/soh/src/overlays/actors/ovl_Demo_Gj/z_demo_gj.c @@ -571,7 +571,7 @@ void DemoGj_InitRubblePile1(DemoGj* this, PlayState* play) { } void func_8097A000(DemoGj* this, PlayState* play) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); this->rotationVec.x += (s16)(kREG(18)); this->rotationVec.y += (s16)(kREG(19) + 1000); @@ -635,7 +635,7 @@ void DemoGj_InitRubblePile2(DemoGj* this, PlayState* play) { } void func_8097A238(DemoGj* this, PlayState* play) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); this->rotationVec.x += (s16)(kREG(31)); this->rotationVec.y += (s16)(kREG(32) + 1000); @@ -699,7 +699,7 @@ void DemoGj_InitRubblePile3(DemoGj* this, PlayState* play) { } void func_8097A474(DemoGj* this, PlayState* play) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); this->rotationVec.x += (s16)(kREG(44)); this->rotationVec.y += (s16)(kREG(45) + 1000); @@ -747,7 +747,7 @@ void DemoGj_InitRubblePile4(DemoGj* this, PlayState* play) { } void func_8097A644(DemoGj* this, PlayState* play) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); this->rotationVec.x += (s16)(kREG(57)); this->rotationVec.y += (s16)(kREG(58) + 1000); @@ -795,7 +795,7 @@ void DemoGj_InitRubblePile5(DemoGj* this, PlayState* play) { } void func_8097A814(DemoGj* this, PlayState* play) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); this->rotationVec.x += (s16)(kREG(70)); this->rotationVec.y += (s16)(kREG(71) + 1000); @@ -843,7 +843,7 @@ void DemoGj_InitRubblePile6(DemoGj* this, PlayState* play) { } void func_8097A9E4(DemoGj* this, PlayState* play) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); this->rotationVec.x += (s16)(kREG(83)); this->rotationVec.y += (s16)(kREG(84) + 1000); @@ -891,7 +891,7 @@ void DemoGj_InitRubblePile7(DemoGj* this, PlayState* play) { } void func_8097ABB4(DemoGj* this, PlayState* play) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); this->rotationVec.x += (s16)(kREG(15)); this->rotationVec.y += (s16)(kREG(14) + 1000); diff --git a/soh/src/overlays/actors/ovl_Demo_Go/z_demo_go.c b/soh/src/overlays/actors/ovl_Demo_Go/z_demo_go.c index 274de1a8b..227ad7ed1 100644 --- a/soh/src/overlays/actors/ovl_Demo_Go/z_demo_go.c +++ b/soh/src/overlays/actors/ovl_Demo_Go/z_demo_go.c @@ -101,14 +101,14 @@ void func_8097C930(DemoGo* this) { } void func_8097C9B8(DemoGo* this) { - func_80078914(&this->actor.projectedPos, NA_SE_EN_DODO_M_GND); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EN_DODO_M_GND); } void func_8097C9DC(DemoGo* this) { s32 pad[2]; if (Animation_OnFrame(&this->skelAnime, 12.0f) || Animation_OnFrame(&this->skelAnime, 25.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_EN_MORIBLIN_WALK); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EN_MORIBLIN_WALK); } } @@ -159,11 +159,11 @@ void func_8097CC08(DemoGo* this) { } else { this->actor.speedXZ = (kREG(15) * 0.01f) + 1.2f; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void func_8097CCC0(DemoGo* this) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void func_8097CCE0(DemoGo* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c b/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c index fcc989f19..083d74b88 100644 --- a/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c +++ b/soh/src/overlays/actors/ovl_Demo_Gt/z_demo_gt.c @@ -20,7 +20,7 @@ void DemoGt_Destroy(Actor* thisx, PlayState* play) { } void DemoGt_PlayEarthquakeSfx() { - func_800788CC(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered2(NA_SE_EV_EARTHQUAKE - SFX_FLAG); } void DemoGt_PlayExplosion1Sfx(PlayState* play, Vec3f* pos) { @@ -1189,7 +1189,7 @@ void func_80980F58(DemoGt* this, PlayState* play) { u16 frames = play->csCtx.frames; if (frames == 244) { - func_80078914(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG); } } @@ -1312,7 +1312,7 @@ void func_80981424(DemoGt* this, PlayState* play) { u16 frames = play->csCtx.frames; if (frames == 789) { - func_80078914(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG); } } @@ -1430,7 +1430,7 @@ void func_809818FC(DemoGt* this, PlayState* play) { u16 frames = play->csCtx.frames; if (frames == 845) { - func_80078914(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG); } } void func_80981930(DemoGt* this, PlayState* play) { @@ -1521,7 +1521,7 @@ void func_80981CEC(DemoGt* this, PlayState* play) { u16 frames = play->csCtx.frames; if (frames == 183) { - func_80078914(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG); } } @@ -1612,7 +1612,7 @@ void func_809820AC(DemoGt* this, PlayState* play) { u16 frames = play->csCtx.frames; if (frames == 154) { - func_80078914(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->dyna.actor.projectedPos, NA_SE_EV_TOWER_PARTS_BROKEN - SFX_FLAG); } } diff --git a/soh/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c b/soh/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c index c5515a6c1..c641f72bf 100644 --- a/soh/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c +++ b/soh/src/overlays/actors/ovl_Demo_Ik/z_demo_ik.c @@ -1,6 +1,7 @@ #include "z_demo_ik.h" #include "vt.h" #include "objects/object_ik/object_ik.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -93,20 +94,20 @@ void DemoIk_Type1PlaySound(DemoIk* this) { switch (this->actor.params) { case 0: if (Animation_OnFrame(&this->skelAnime, 5.0f)) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_LAND1_DEMO, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_LAND1_DEMO, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } break; case 1: if (Animation_OnFrame(&this->skelAnime, 10.0f)) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_LAND3_DEMO, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_LAND3_DEMO, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } break; case 2: if (Animation_OnFrame(&this->skelAnime, 9.0f)) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_LAND2_DEMO, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_LAND2_DEMO, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } break; } @@ -327,8 +328,8 @@ void DemoIk_Type2Init(DemoIk* this, PlayState* play) { void DemoIk_Type2PlaySoundOnFrame(DemoIk* this, f32 frame) { if (Animation_OnFrame(&this->skelAnime, frame)) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_OFF_DEMO, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_OFF_DEMO, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c index 027539451..9be309322 100644 --- a/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c +++ b/soh/src/overlays/actors/ovl_Demo_Im/z_demo_im.c @@ -10,6 +10,8 @@ #include "scenes/indoors/nakaniwa/nakaniwa_scene.h" #include "objects/object_im/object_im.h" #include "vt.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -438,7 +440,7 @@ void func_80985860(DemoIm* this, PlayState* play) { } void func_809858A8(void) { - func_800788CC(NA_SE_SY_WHITE_OUT_T); + Sfx_PlaySfxCentered2(NA_SE_SY_WHITE_OUT_T); } void DemoIm_SpawnLightBall(DemoIm* this, PlayState* play) { @@ -728,7 +730,7 @@ void func_80986570(DemoIm* this, PlayState* play) { u32 sfxId = SFX_FLAG; sfxId += SurfaceType_GetSfx(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId); - Audio_PlaySoundGeneral(sfxId, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -874,9 +876,9 @@ void func_80986B2C(PlayState* play) { // In entrance rando have impa bring link back to the front of castle grounds if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) { - play->nextEntranceIndex = ENTR_HYRULE_CASTLE_0; + play->nextEntranceIndex = ENTR_CASTLE_GROUNDS_SOUTH_EXIT; } else { - play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; } play->transitionType = TRANS_TYPE_CIRCLE(TCA_STARBURST, TCC_BLACK, TCS_FAST); play->transitionTrigger = TRANS_TRIGGER_START; diff --git a/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c b/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c index 719a8b7fa..a7a637d3e 100644 --- a/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c +++ b/soh/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c @@ -5,6 +5,7 @@ #include "objects/object_toki_objects/object_toki_objects.h" #include "soh/frame_interpolation.h" #include +#include "soh/OTRGlobals.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -257,7 +258,7 @@ void DemoKankyo_Init(Actor* thisx, PlayState* play) { this->sparkleCounter = 0; this->actor.scale.x = this->actor.scale.y = this->actor.scale.z = 1.0f; if (this->actor.params == DEMOKANKYO_WARP_OUT) { - Audio_PlaySoundGeneral(NA_SE_EV_SARIA_MELODY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_SARIA_MELODY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } break; case DEMOKANKYO_SPARKLES: @@ -561,7 +562,7 @@ void DemoKankyo_DrawRain(Actor* thisx, PlayState* play) { if (this->unk_150[i].unk_C.y + this->unk_150[i].unk_0.y < temp_f12_2 - 300.0f) { this->unk_150[i].unk_22++; } - } else if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_0) { // Hyrule Field + } else if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN) { // Hyrule Field if (temp_f12_2 + 300.0f < this->unk_150[i].unk_C.y + this->unk_150[i].unk_0.y) { this->unk_150[i].unk_22++; } @@ -585,7 +586,7 @@ void DemoKankyo_DrawRain(Actor* thisx, PlayState* play) { } gDPPipeSync(POLY_XLU_DISP++); - if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_0) { // Hyrule Field + if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN) { // Hyrule Field gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 0, 255); } else { @@ -818,8 +819,8 @@ void DemoKankyo_DrawWarpSparkles(Actor* thisx, PlayState* play) { this->unk_150[i].unk_22++; } } else { - Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP_OUT - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP_OUT - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (func_800BB2B4(&camPos, &sWarpRoll, &sWarpFoV, sWarpInCameraPoints, &this->unk_150[i].unk_20, &this->unk_150[i].unk_1C) != 0) { this->unk_150[i].unk_22++; diff --git a/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c b/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c index 09a45856b..b85ccf744 100644 --- a/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c +++ b/soh/src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.c @@ -7,6 +7,7 @@ #include "z_demo_kekkai.h" #include "objects/object_demo_kekkai/object_demo_kekkai.h" #include "scenes/dungeons/ganontika/ganontika_scene.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -259,7 +260,7 @@ void DemoKekkai_TrialBarrierIdle(Actor* thisx, PlayState* play) { CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider1.base); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider1.base); if (this->collider2.base.acFlags & AC_HIT) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); // "I got it" LOG_STRING("当ったよ"); this->actor.update = DemoKekkai_TrialBarrierDispel; diff --git a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c index 06efb9768..c78c3a897 100644 --- a/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c +++ b/soh/src/overlays/actors/ovl_Demo_Sa/z_demo_sa.c @@ -378,7 +378,7 @@ void func_8098EDB0(DemoSa* this) { } void func_8098EE08(void) { - func_800788CC(NA_SE_SY_WHITE_OUT_T); + Sfx_PlaySfxCentered2(NA_SE_SY_WHITE_OUT_T); } void func_8098EE28(DemoSa* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c b/soh/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c index b09048e47..fa7cb0123 100644 --- a/soh/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c +++ b/soh/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c @@ -119,8 +119,8 @@ void func_80993848(DemoTreLgt* this, PlayState* play) { } if ((currentFrame > 30.0f) && !(this->status & 1)) { this->status |= 1; - Audio_PlaySoundGeneral(NA_SE_EV_TRE_BOX_FLASH, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_TRE_BOX_FLASH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } if (SkelCurve_Update(play, &this->skelCurve)) { Actor_Kill(&this->actor); diff --git a/soh/src/overlays/actors/ovl_Door_Ana/z_door_ana.c b/soh/src/overlays/actors/ovl_Door_Ana/z_door_ana.c index feda50c76..d4d3d8b60 100644 --- a/soh/src/overlays/actors/ovl_Door_Ana/z_door_ana.c +++ b/soh/src/overlays/actors/ovl_Door_Ana/z_door_ana.c @@ -8,6 +8,7 @@ #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/randomizer/randomizer_grotto.h" +#include "soh/OTRGlobals.h" #define FLAGS ACTOR_FLAG_NO_FREEZE_OCARINA @@ -20,8 +21,6 @@ void DoorAna_WaitClosed(DoorAna* this, PlayState* play); void DoorAna_WaitOpen(DoorAna* this, PlayState* play); void DoorAna_GrabPlayer(DoorAna* this, PlayState* play); -void Grotto_OverrideActorEntrance(Actor* thisx); - const ActorInit Door_Ana_InitVars = { ACTOR_DOOR_ANA, ACTORCAT_ITEMACTION, @@ -121,7 +120,7 @@ void DoorAna_WaitClosed(DoorAna* this, PlayState* play) { if (openGrotto) { this->actor.params &= ~0x0300; DoorAna_SetupAction(this, DoorAna_WaitOpen); - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } func_8002F5F0(&this->actor, play); } diff --git a/soh/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c b/soh/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c index c5f05341a..99dd5e43f 100644 --- a/soh/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c +++ b/soh/src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.c @@ -68,7 +68,7 @@ f32 func_809946BC(PlayState* play, DoorGerudo* this, f32 arg2, f32 arg3, f32 arg playerPos.x = player->actor.world.pos.x; playerPos.y = player->actor.world.pos.y + arg2; playerPos.z = player->actor.world.pos.z; - func_8002DBD0(&this->dyna.actor, &sp1C, &playerPos); + Actor_WorldToActorCoords(&this->dyna.actor, &sp1C, &playerPos); if ((arg3 < fabsf(sp1C.x)) || (arg4 < fabsf(sp1C.y))) { return FLT_MAX; diff --git a/soh/src/overlays/actors/ovl_Door_Killer/z_door_killer.c b/soh/src/overlays/actors/ovl_Door_Killer/z_door_killer.c index 058b5cb23..f29b23450 100644 --- a/soh/src/overlays/actors/ovl_Door_Killer/z_door_killer.c +++ b/soh/src/overlays/actors/ovl_Door_Killer/z_door_killer.c @@ -11,6 +11,7 @@ #include "objects/object_haka_door/object_haka_door.h" #include "objects/object_door_killer/object_door_killer.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -246,7 +247,7 @@ void DoorKiller_FallAsRubble(DoorKiller* this, PlayState* play) { } else { Actor_Kill(&this->actor); } - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); } s32 DoorKiller_IsHit(Actor* thisx, PlayState* play) { @@ -373,7 +374,7 @@ void DoorKiller_FallOver(DoorKiller* this, PlayState* play) { if (!(this->hasHitPlayerOrGround & 1)) { Vec3f playerPosRelToDoor; Player* player = GET_PLAYER(play); - func_8002DBD0(&this->actor, &playerPosRelToDoor, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &playerPosRelToDoor, &player->actor.world.pos); if ((fabsf(playerPosRelToDoor.y) < 20.0f) && (fabsf(playerPosRelToDoor.x) < 20.0f) && (playerPosRelToDoor.z < 100.0f) && (playerPosRelToDoor.z > 0.0f)) { this->hasHitPlayerOrGround |= 1; @@ -435,7 +436,7 @@ void DoorKiller_Wait(DoorKiller* this, PlayState* play) { Vec3f playerPosRelToDoor; s16 angleToFacingPlayer; - func_8002DBD0(&this->actor, &playerPosRelToDoor, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &playerPosRelToDoor, &player->actor.world.pos); // playerIsOpening is set by player if (this->playerIsOpening) { diff --git a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index 9daf8bf68..c842571e7 100644 --- a/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/soh/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -261,7 +261,7 @@ void DoorShutter_Init(Actor* thisx, PlayState* play2) { DoorShutter_SetupAction(this, DoorShutter_SetupType); this->unk_16B = phi_a3; if (this->doorType == SHUTTER_KEY_LOCKED || this->doorType == SHUTTER_BOSS) { - if (!Flags_GetSwitch(play, this->dyna.actor.params & 0x3F)) { + if (GameInteractor_Should(VB_LOCK_BOSS_DOOR, !Flags_GetSwitch(play, this->dyna.actor.params & 0x3F), this)) { this->unk_16E = 10; } Actor_SetFocus(&this->dyna.actor, 60.0f); @@ -322,7 +322,7 @@ f32 func_80996840(PlayState* play, DoorShutter* this, f32 arg2, f32 arg3, f32 ar sp28.x = player->actor.world.pos.x; sp28.y = player->actor.world.pos.y + arg2; sp28.z = player->actor.world.pos.z; - func_8002DBD0(&this->dyna.actor, &sp1C, &sp28); + Actor_WorldToActorCoords(&this->dyna.actor, &sp1C, &sp28); if (arg3 < fabsf(sp1C.x) || arg4 < fabsf(sp1C.y)) { return FLT_MAX; } else { @@ -543,7 +543,7 @@ void func_80997220(DoorShutter* this, PlayState* play) { if (this->dyna.actor.room >= 0) { Vec3f vec; - func_8002DBD0(&this->dyna.actor, &vec, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->dyna.actor, &vec, &player->actor.world.pos); this->dyna.actor.room = play->transiActorCtx.list[(u16)this->dyna.actor.params >> 0xA].sides[(vec.z < 0.0f) ? 0 : 1].room; if (room != this->dyna.actor.room) { @@ -600,7 +600,7 @@ void func_80997568(DoorShutter* this, PlayState* play) { } void func_809975C0(DoorShutter* this, PlayState* play) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 0.0f, 0.0f, 0.0f, 4); if (this->dyna.actor.bgCheckFlags & 1) { DoorShutter_SetupAction(this, func_809976B8); diff --git a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index be1756613..e767135e3 100644 --- a/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/soh/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -2,6 +2,7 @@ #include "objects/object_warp1/object_warp1.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -178,11 +179,11 @@ void DoorWarp1_SetupWarp(DoorWarp1* this, PlayState* play) { DoorWarp1_SetupAction(this, DoorWarp1_AwaitClearFlag); break; case WARP_DESTINATION: - if ((!(gSaveContext.entranceIndex == ENTR_SACRED_FOREST_MEADOW_3 || // sacred forest meadow - gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_CRATER_5 || // death mountain crater - gSaveContext.entranceIndex == ENTR_LAKE_HYLIA_9 || // lake hylia - gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_8 || // desert colossus - gSaveContext.entranceIndex == ENTR_GRAVEYARD_8) && // graveyard + if ((!(gSaveContext.entranceIndex == ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP || // sacred forest meadow + gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP || // death mountain crater + gSaveContext.entranceIndex == ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP || // lake hylia + gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP || // desert colossus + gSaveContext.entranceIndex == ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP) && // graveyard gSaveContext.sceneSetupIndex < 4) || (GET_PLAYER(play)->actor.params & 0xF00) != 0x200) { Actor_Kill(&this->actor); @@ -284,7 +285,7 @@ void DoorWarp1_SetupPurpleCrystal(DoorWarp1* this, PlayState* play) { this->unk_1BC = 1.f; this->actor.shape.yOffset = 800.0f; - if (gSaveContext.entranceIndex != ENTR_TEMPLE_OF_TIME_0) { + if (gSaveContext.entranceIndex != ENTR_TEMPLE_OF_TIME_ENTRANCE) { this->actor.scale.x = 0.0499f; this->actor.scale.y = 0.077f; this->actor.scale.z = 0.09f; @@ -496,8 +497,8 @@ void DoorWarp1_ChildWarpIdle(DoorWarp1* this, PlayState* play) { if (DoorWarp1_PlayerInRange(this, play)) { player = GET_PLAYER(play); - Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); OnePointCutscene_Init(play, 0x25E7, 999, &this->actor, MAIN_CAM); Player_SetCsActionWithHaltedActors(play, &this->actor, 10); @@ -533,10 +534,10 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_GORON_RUBY)) { Item_Give(play, ITEM_GORON_RUBY); } - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_0; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT; gSaveContext.nextCutsceneIndex = 0xFFF1; } else { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP; gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_DEKU_TREE_BOSS) { @@ -549,11 +550,11 @@ void DoorWarp1_ChildWarpOut(DoorWarp1* this, PlayState* play) { play->nextEntranceIndex = ENTR_KOKIRI_FOREST_0; gSaveContext.nextCutsceneIndex = 0xFFF1; } else { - play->nextEntranceIndex = ENTR_KOKIRI_FOREST_11; + play->nextEntranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP; gSaveContext.nextCutsceneIndex = 0; } } else if (play->sceneNum == SCENE_JABU_JABU_BOSS) { - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; + play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP; gSaveContext.nextCutsceneIndex = 0; } @@ -615,7 +616,7 @@ void func_80999EE0(DoorWarp1* this, PlayState* play) { void func_80999FE4(DoorWarp1* this, PlayState* play) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_NONE) { - Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); OnePointCutscene_Init(play, 0x25E9, 999, &this->actor, MAIN_CAM); Play_CopyCamera(play, -1, sRutoWarpSubCamId); Play_ChangeCameraStatus(play, sRutoWarpSubCamId, CAM_STAT_WAIT); @@ -647,7 +648,7 @@ void DoorWarp1_RutoWarpOut(DoorWarp1* this, PlayState* play) { } gSaveContext.nextCutsceneIndex = 0xFFF0; } - play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_0; + play->nextEntranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE_SLOW; @@ -711,7 +712,7 @@ void func_8099A508(DoorWarp1* this, PlayState* play) { this->unk_1B2--; return; } - Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Animation_ChangeImpl(&this->skelAnime, &gWarpCrystalAnim, 1.0f, Animation_GetLastFrame(&gWarpCrystalAnim), Animation_GetLastFrame(&gWarpCrystalAnim), ANIMMODE_ONCE, 40.0f, 1); @@ -760,9 +761,9 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.chamberCutsceneNum = CHAMBER_CS_FOREST; } else { if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_2; + play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_WARP_PAD; } else { - play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_3; + play->nextEntranceIndex = ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP; } gSaveContext.nextCutsceneIndex = 0; } @@ -772,13 +773,13 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_FIRE)) { Item_Give(play, ITEM_MEDALLION_FIRE); } - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; + play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_FRONT_GATE; gSaveContext.nextCutsceneIndex = 0xFFF3; } else { if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_4; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD; } else { - play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5; + play->nextEntranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP; } gSaveContext.nextCutsceneIndex = 0; } @@ -793,9 +794,9 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.chamberCutsceneNum = CHAMBER_CS_WATER; } else { if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_LAKE_HYLIA_8; + play->nextEntranceIndex = ENTR_LAKE_HYLIA_WARP_PAD; } else { - play->nextEntranceIndex = ENTR_LAKE_HYLIA_9; + play->nextEntranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP; } gSaveContext.nextCutsceneIndex = 0; } @@ -810,9 +811,9 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.chamberCutsceneNum = CHAMBER_CS_SPIRIT; } else { if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_5; + play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_WARP_PAD; } else { - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_8; + play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP; } gSaveContext.nextCutsceneIndex = 0; } @@ -827,9 +828,9 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) { gSaveContext.chamberCutsceneNum = CHAMBER_CS_SHADOW; } else { if (!LINK_IS_ADULT) { - play->nextEntranceIndex = ENTR_GRAVEYARD_7; + play->nextEntranceIndex = ENTR_GRAVEYARD_WARP_PAD; } else { - play->nextEntranceIndex = ENTR_GRAVEYARD_8; + play->nextEntranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP; } gSaveContext.nextCutsceneIndex = 0; } diff --git a/soh/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.c b/soh/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.c index 82a710c35..77821cd33 100644 --- a/soh/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.c +++ b/soh/src/overlays/actors/ovl_Efc_Erupc/z_efc_erupc.c @@ -56,7 +56,7 @@ void EfcErupc_UpdateAction(EfcErupc* this, PlayState* play) { if (play->csCtx.npcActions[1] != NULL) { if (play->csCtx.npcActions[1]->action == 2) { if (this->unk_150 == 30) { - func_800788CC(NA_SE_IT_EARTHQUAKE); + Sfx_PlaySfxCentered2(NA_SE_IT_EARTHQUAKE); } if (this->unk_150 <= 64) { if (this->unk_154 < 200) { diff --git a/soh/src/overlays/actors/ovl_En_Am/z_en_am.c b/soh/src/overlays/actors/ovl_En_Am/z_en_am.c index c62e3a8fa..70a6ae5da 100644 --- a/soh/src/overlays/actors/ovl_En_Am/z_en_am.c +++ b/soh/src/overlays/actors/ovl_En_Am/z_en_am.c @@ -8,6 +8,7 @@ #include "objects/object_am/object_am.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_CAN_PRESS_SWITCH) @@ -537,7 +538,7 @@ void EnAm_MoveToHome(EnAm* this, PlayState* play) { // turn away from a wall if touching one if ((this->dyna.actor.speedXZ != 0.0f) && (this->dyna.actor.bgCheckFlags & 8)) { this->dyna.actor.world.rot.y = this->dyna.actor.wallYaw; - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); } SkelAnime_Update(&this->skelAnime); @@ -645,7 +646,7 @@ void EnAm_Lunge(EnAm* this, PlayState* play) { if ((this->dyna.actor.speedXZ != 0.0f) && (this->dyna.actor.bgCheckFlags & 8)) { this->dyna.actor.world.rot.y = (this->dyna.actor.wallYaw - this->dyna.actor.world.rot.y) + this->dyna.actor.wallYaw; - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); this->dyna.actor.bgCheckFlags &= ~8; } @@ -897,7 +898,7 @@ void EnAm_Update(Actor* thisx, PlayState* play) { } } - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 20.0f, 28.0f, 80.0f, 0x1D); } diff --git a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c index 4b0e93f52..8126a1425 100644 --- a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c +++ b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c @@ -6,6 +6,8 @@ #include "z_en_ani.h" #include "objects/object_ani/object_ani.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -247,7 +249,7 @@ void EnAni_Update(Actor* thisx, PlayState* play) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); if ((play->csCtx.state != CS_STATE_IDLE) && (play->csCtx.npcActions[0] != NULL)) { switch (this->unk_2AA) { @@ -269,7 +271,7 @@ void EnAni_Update(Actor* thisx, PlayState* play) { } if (play->csCtx.frames == 100) { - func_800788CC(NA_SE_IT_EARTHQUAKE); + Sfx_PlaySfxCentered2(NA_SE_IT_EARTHQUAKE); } } else { if (SkelAnime_Update(&this->skelAnime) != 0) { diff --git a/soh/src/overlays/actors/ovl_En_Anubice/z_en_anubice.c b/soh/src/overlays/actors/ovl_En_Anubice/z_en_anubice.c index 07a47e5bd..67d2b39a5 100644 --- a/soh/src/overlays/actors/ovl_En_Anubice/z_en_anubice.c +++ b/soh/src/overlays/actors/ovl_En_Anubice/z_en_anubice.c @@ -10,6 +10,7 @@ #include "overlays/actors/ovl_Bg_Hidan_Curtain/z_bg_hidan_curtain.h" #include "vt.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -447,7 +448,7 @@ void EnAnubice_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); this->actor.velocity.y += this->actor.gravity; - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); if (!this->isLinkOutOfRange) { Actor_UpdateBgCheckInfo(play, &this->actor, 5.0f, 5.0f, 10.0f, 0x1D); diff --git a/soh/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c b/soh/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c index a26f5a08b..1f1934c64 100644 --- a/soh/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c +++ b/soh/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c @@ -179,7 +179,7 @@ void EnAnubiceFire_Update(Actor* thisx, PlayState* play) { Actor_SetScale(&this->actor, this->scale); this->actionFunc(this, play); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->unk_160[0] = this->actor.world.pos; for (i = 4; i >= 0; i--) { diff --git a/soh/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c b/soh/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c index c13833d6d..0669d43d6 100644 --- a/soh/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c +++ b/soh/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c @@ -228,11 +228,11 @@ void EnArrow_Shoot(EnArrow* this, PlayState* play) { Math_Vec3f_Copy(&this->unk_210, &this->actor.world.pos); if (this->actor.params >= ARROW_SEED) { - func_8002D9A4(&this->actor, 80.0f); + Actor_SetProjectileSpeed(&this->actor, 80.0f); this->timer = 15; this->actor.shape.rot.x = this->actor.shape.rot.y = this->actor.shape.rot.z = 0; } else { - func_8002D9A4(&this->actor, 150.0f); + Actor_SetProjectileSpeed(&this->actor, 150.0f); this->timer = 12; } } @@ -370,7 +370,7 @@ void EnArrow_Fly(EnArrow* this, PlayState* play) { } } else { Math_Vec3f_Copy(&this->unk_210, &this->actor.world.pos); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if ((this->touchedPoly = BgCheck_ProjectileLineTest(&play->colCtx, &this->actor.prevPos, &this->actor.world.pos, &hitPoint, @@ -422,7 +422,7 @@ void func_809B45E0(EnArrow* this, PlayState* play) { void func_809B4640(EnArrow* this, PlayState* play) { SkelAnime_Update(&this->skelAnime); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (DECR(this->timer) == 0) { Actor_Kill(&this->actor); diff --git a/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c b/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c index 0fd7a83e1..8876b6e4e 100644 --- a/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c +++ b/soh/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c @@ -7,6 +7,7 @@ #include "z_en_attack_niw.h" #include "objects/object_niw/object_niw.h" #include "overlays/actors/ovl_En_Niw/z_en_niw.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -333,9 +334,9 @@ void EnAttackNiw_Update(Actor* thisx, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 60.0f, 0x1D); if (this->actionFunc == func_809B5670) { - func_8002D97C(&this->actor); + Actor_MoveXYZ(&this->actor); } else { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } if (this->actor.floorHeight <= BGCHECK_Y_MIN) { diff --git a/soh/src/overlays/actors/ovl_En_Ba/z_en_ba.c b/soh/src/overlays/actors/ovl_En_Ba/z_en_ba.c index 04b09aca8..953b4b212 100644 --- a/soh/src/overlays/actors/ovl_En_Ba/z_en_ba.c +++ b/soh/src/overlays/actors/ovl_En_Ba/z_en_ba.c @@ -216,7 +216,7 @@ void EnBa_FallAsBlob(EnBa* this, PlayState* play) { Actor_Kill(&this->actor); } } else { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 30.0f, 28.0f, 80.0f, 5); } } diff --git a/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c b/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c index 39c0e54e9..b03b6490a 100644 --- a/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c +++ b/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c @@ -8,6 +8,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_Bb/object_Bb.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_PLAY_HIT_SFX) @@ -1239,7 +1240,7 @@ void EnBb_Update(Actor* thisx, PlayState* play2) { this->actionFunc(this, play); if ((this->actor.params <= ENBB_BLUE) && (this->actor.speedXZ >= -6.0f) && ((this->actor.flags & ACTOR_FLAG_DRAGGED_BY_ARROW) == 0)) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } if (this->moveMode == BBMOVE_NORMAL) { if ((this->actor.world.pos.y - 20.0f) <= this->actor.floorHeight) { diff --git a/soh/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.c b/soh/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.c index ab0b82d65..eeeec465c 100644 --- a/soh/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.c +++ b/soh/src/overlays/actors/ovl_En_Bdfire/z_en_bdfire.c @@ -132,8 +132,8 @@ void func_809BC598(EnBdfire* this, PlayState* play) { this->unk_158 = bossDodongo->unk_1A2; phi_v1_2 = 0; if (this->actor.params == 0) { - Audio_PlaySoundGeneral(NA_SE_EN_DODO_K_FIRE - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_DODO_K_FIRE - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } Math_SmoothStepToF(&this->actor.scale.x, this->unk_188, 0.3f, 0.5f, 0.0f); Actor_SetScale(&this->actor, this->actor.scale.x); @@ -192,7 +192,7 @@ void EnBdfire_Update(Actor* thisx, PlayState* play) { this->unk_156++; this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void EnBdfire_DrawFire(EnBdfire* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c b/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c index 2f1c4abe4..aa53182c5 100644 --- a/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c +++ b/soh/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c @@ -1,6 +1,7 @@ #include "z_en_bigokuta.h" #include "objects/object_bigokuta/object_bigokuta.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -502,7 +503,7 @@ void func_809BDC08(EnBigokuta* this, PlayState* play) { } phi_v1 = (Actor_WorldDistXZToPoint(&player->actor, &this->actor.home.pos) - 180.0f) * (8.0f / 15); - func_8002DBD0(&this->actor, &sp28, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &sp28, &player->actor.world.pos); if (fabsf(sp28.x) > 263.0f || ((sp28.z > 0.0f) && !Actor_IsFacingPlayer(&this->actor, 0x1B00) && !Player_IsFacingActor(&this->actor, 0x2000, play))) { phi_v1 -= 0x80; diff --git a/soh/src/overlays/actors/ovl_En_Bili/z_en_bili.c b/soh/src/overlays/actors/ovl_En_Bili/z_en_bili.c index a50dabe01..cd927a5c2 100644 --- a/soh/src/overlays/actors/ovl_En_Bili/z_en_bili.c +++ b/soh/src/overlays/actors/ovl_En_Bili/z_en_bili.c @@ -7,6 +7,7 @@ #include "z_en_bili.h" #include "objects/object_bl/object_bl.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_IGNORE_QUAKE | ACTOR_FLAG_ARROW_DRAGGABLE) @@ -624,9 +625,9 @@ void EnBili_Update(Actor* thisx, PlayState* play2) { } } if (this->actionFunc == EnBili_Recoil) { - func_8002D97C(&this->actor); + Actor_MoveXYZ(&this->actor); } else { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } Actor_UpdateBgCheckInfo(play, &this->actor, 5.0f, this->collider.dim.radius, this->collider.dim.height, 7); diff --git a/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c b/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c index e379f0095..e5c9c2a99 100644 --- a/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c +++ b/soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c @@ -162,7 +162,7 @@ void EnBom_Move(EnBom* this, PlayState* play) { this->actor.world.rot.y = ((this->actor.wallYaw - this->actor.world.rot.y) + this->actor.wallYaw) - 0x8000; } Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMB_BOUND); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); this->actor.speedXZ *= 0.7f; this->actor.bgCheckFlags &= ~8; } @@ -176,11 +176,11 @@ void EnBom_Move(EnBom* this, PlayState* play) { this->actor.velocity.y *= -0.3f; this->actor.bgCheckFlags &= ~2; } else if (this->timer >= 4) { - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); } } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void EnBom_WaitForRelease(EnBom* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index 9e3c9c1b2..2cb108703 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -3,6 +3,8 @@ #include "overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.h" #include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h" #include "objects/object_bg/object_bg.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" diff --git a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c index 1a1ed01a6..6c68b3831 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c @@ -2,6 +2,7 @@ #include "vt.h" #include "overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h" #include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -107,7 +108,7 @@ void EnBomBowlPit_DetectHit(EnBomBowlPit* this, PlayState* play) { this->actor.textId = 0xF; Message_StartTextbox(play, this->actor.textId, NULL); this->unk_154 = TEXT_STATE_EVENT; - func_80078884(NA_SE_EV_HIT_SOUND); + Sfx_PlaySfxCentered(NA_SE_EV_HIT_SOUND); Player_SetCsActionWithHaltedActors(play, NULL, 8); this->status = 1; this->actionFunc = EnBomBowlPit_CameraDollyIn; diff --git a/soh/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c b/soh/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c index c265b3eb0..df74e5317 100644 --- a/soh/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c +++ b/soh/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c @@ -197,8 +197,8 @@ void EnBomChu_UpdateFloorPoly(EnBomChu* this, CollisionPoly* floorPoly, PlayStat // A hack for preventing bombchus from sticking to ledges. // The visual rotation reverts the sign inversion (shape.rot.x = -world.rot.x). - // The better fix would be making func_8002D908 compute XYZ velocity better, - // or not using it and make the bombchu compute its own velocity. + // The better fix would be making Actor_UpdateVelocityXYZ compute XYZ velocity + // better, or not using it and make the bombchu compute its own velocity. this->actor.world.rot.x = -this->actor.world.rot.x; } } @@ -428,7 +428,7 @@ void EnBomChu_Update(Actor* thisx, PlayState* play2) { } this->actionFunc(this, play); - func_8002D97C(&this->actor); + Actor_MoveXYZ(&this->actor); this->collider.elements[0].dim.worldSphere.center.x = this->actor.world.pos.x; this->collider.elements[0].dim.worldSphere.center.y = this->actor.world.pos.y; diff --git a/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c b/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c index f83aaf76b..2be1a20fc 100644 --- a/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c +++ b/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c @@ -91,7 +91,7 @@ void EnBombf_Init(Actor* thisx, PlayState* play) { EnBombf* this = (EnBombf*)thisx; Actor_SetScale(thisx, 0.01f); - this->unk_200 = 1; + this->isFuseEnabled = 1; Collider_InitCylinder(play, &this->bombCollider); Collider_InitJntSph(play, &this->explosionCollider); Collider_SetCylinder(play, &this->bombCollider, thisx, &sCylinderInit); @@ -174,7 +174,7 @@ void EnBombf_GrowBomb(EnBombf* this, PlayState* play) { (EnBombf*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_BOMBF, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0, true); if (bombFlower != NULL) { - bombFlower->unk_200 = 1; + bombFlower->isFuseEnabled = 1; bombFlower->timer = 0; this->timer = 180; this->actor.flags &= ~ACTOR_FLAG_TARGETABLE; @@ -194,7 +194,7 @@ void EnBombf_GrowBomb(EnBombf* this, PlayState* play) { } } else { if (!Actor_HasParent(&this->actor, play)) { - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); } else { player->actor.child = NULL; player->heldActor = NULL; @@ -244,7 +244,7 @@ void EnBombf_Move(EnBombf* this, PlayState* play) { func_8002F850(play, &this->actor); this->actor.velocity.y *= -0.5f; } else if (this->timer >= 4) { - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); } } } @@ -323,7 +323,7 @@ void EnBombf_Update(Actor* thisx, PlayState* play) { s32 pad[2]; EnBombf* this = (EnBombf*)thisx; - if ((this->unk_200 != 0) && (this->timer != 0)) { + if ((this->isFuseEnabled != 0) && (this->timer != 0)) { this->timer--; } @@ -335,7 +335,7 @@ void EnBombf_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (thisx->params == BOMBFLOWER_BODY) { - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); } if (thisx->gravity != 0.0f) { @@ -357,7 +357,7 @@ void EnBombf_Update(Actor* thisx, PlayState* play) { thisx->world.rot.y = ((thisx->wallYaw - thisx->world.rot.y) + thisx->wallYaw) - 0x8000; } Audio_PlayActorSound2(thisx, NA_SE_EV_BOMB_BOUND); - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); DREG(6) = 1; Actor_UpdateBgCheckInfo(play, thisx, 5.0f, 10.0f, 0.0f, 0x1F); DREG(6) = 0; @@ -367,7 +367,7 @@ void EnBombf_Update(Actor* thisx, PlayState* play) { if ((this->bombCollider.base.acFlags & AC_HIT) || ((this->bombCollider.base.ocFlags1 & OC1_HIT) && (this->bombCollider.base.oc->category == ACTORCAT_ENEMY))) { - this->unk_200 = 1; + this->isFuseEnabled = 1; this->timer = 0; } else { // if a lit stick touches the bomb, set timer to 100 @@ -376,7 +376,7 @@ void EnBombf_Update(Actor* thisx, PlayState* play) { } } - if (this->unk_200 != 0) { + if (this->isFuseEnabled != 0) { dustAccel.y = 0.2f; effPos = thisx->world.pos; effPos.y += 25.0f; diff --git a/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h b/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h index 33b6f3cc3..fe780742c 100644 --- a/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h +++ b/soh/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h @@ -15,7 +15,7 @@ typedef struct EnBombf { /* 0x01B8 */ ColliderJntSphElement explosionColliderItems[1]; /* 0x01F8 */ s16 timer; /* 0x01FC */ EnBombfActionFunc actionFunc; - /* 0x0200 */ s32 unk_200; + /* 0x0200 */ s32 isFuseEnabled; /* 0x0204 */ u8 bumpOn; /* 0x0206 */ s16 flashSpeedScale; /* 0x0208 */ f32 flashIntensity; diff --git a/soh/src/overlays/actors/ovl_En_Boom/z_en_boom.c b/soh/src/overlays/actors/ovl_En_Boom/z_en_boom.c index 29385eaa4..6079c1ff5 100644 --- a/soh/src/overlays/actors/ovl_En_Boom/z_en_boom.c +++ b/soh/src/overlays/actors/ovl_En_Boom/z_en_boom.c @@ -150,8 +150,8 @@ void EnBoom_Fly(EnBoom* this, PlayState* play) { } // Set xyz speed, move forward, and play the boomerang sound - func_8002D9A4(&this->actor, 12.0f); - Actor_MoveForward(&this->actor); + Actor_SetProjectileSpeed(&this->actor, 12.0f); + Actor_MoveXZGravity(&this->actor); func_8002F974(&this->actor, NA_SE_IT_BOOMERANG_FLY - SFX_FLAG); // If the boomerang collides with EnItem00 or a Skulltula token, set grabbed pointer to pick it up diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index ef7a6330b..bcb0cb1fc 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -3,6 +3,8 @@ #include "soh_assets.h" #include "soh/Enhancements/enhancementTypes.h" #include +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -11,7 +13,7 @@ /* set on init unless treasure flag is set -if clear, chest moves (Actor_MoveForward) (falls, likely) +if clear, chest moves (Actor_MoveXZGravity) (falls, likely) ends up cleared from SWITCH_FLAG_FALL types when switch flag is set */ #define ENBOX_MOVE_IMMOBILE (1 << 0) @@ -277,8 +279,8 @@ void EnBox_Fall(EnBox* this, PlayState* play) { OnePointCutscene_EndCutscene(play, this->unk_1AC); } } - Audio_PlaySoundGeneral(NA_SE_EV_COFFIN_CAP_BOUND, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_COFFIN_CAP_BOUND, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); EnBox_SpawnDust(this, play); } yDiff = this->dyna.actor.world.pos.y - this->dyna.actor.floorHeight; @@ -387,8 +389,8 @@ void EnBox_AppearInit(EnBox* this, PlayState* play) { this->unk_1A8 = 0; Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_KANKYO, this->dyna.actor.home.pos.x, this->dyna.actor.home.pos.y, this->dyna.actor.home.pos.z, 0, 0, 0, 0x0011, true); - Audio_PlaySoundGeneral(NA_SE_EV_TRE_BOX_APPEAR, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_TRE_BOX_APPEAR, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } @@ -447,10 +449,10 @@ void EnBox_WaitOpen(EnBox* this, PlayState* play) { Flags_SetTreasure(play, this->dyna.actor.params & 0x1F); } else { player = GET_PLAYER(play); - func_8002DBD0(&this->dyna.actor, &sp4C, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->dyna.actor, &sp4C, &player->actor.world.pos); if (sp4C.z > -50.0f && sp4C.z < 0.0f && fabsf(sp4C.y) < 10.0f && fabsf(sp4C.x) < 20.0f && Player_IsFacingActor(&this->dyna.actor, 0x3000, play)) { - func_8002F554(&this->dyna.actor, play, -(this->dyna.actor.params >> 5 & 0x7F)); + Actor_OfferGetItemNearby(&this->dyna.actor, play, -(this->dyna.actor.params >> 5 & 0x7F)); } if (Flags_GetTreasure(play, this->dyna.actor.params & 0x1F)) { EnBox_SetupAction(this, EnBox_Open); @@ -491,7 +493,7 @@ void EnBox_Open(EnBox* this, PlayState* play) { } if (sfxId != 0) { - Audio_PlaySoundGeneral(sfxId, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(sfxId, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } if (this->skelanime.jointTable[3].z > 0) { @@ -549,7 +551,7 @@ void EnBox_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (!(this->movementFlags & ENBOX_MOVE_IMMOBILE)) { - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); Actor_UpdateBgCheckInfo(play, &this->dyna.actor, 0.0f, 0.0f, 0.0f, 0x1C); } @@ -594,7 +596,7 @@ void EnBox_UpdateSizeAndTexture(EnBox* this, PlayState* play) { getItemCategory = ITEM_CATEGORY_JUNK; // If it's a bottle and they already have one, consider the item lesser } else if ( - (this->getItemEntry.modIndex == MOD_RANDOMIZER && this->getItemEntry.getItemId >= RG_BOTTLE_WITH_RED_POTION && this->getItemEntry.getItemId <= RG_BOTTLE_WITH_BIG_POE) || + (this->getItemEntry.modIndex == MOD_RANDOMIZER && this->getItemEntry.getItemId >= RG_BOTTLE_WITH_RED_POTION && this->getItemEntry.getItemId <= RG_BOTTLE_WITH_POE) || (this->getItemEntry.modIndex == MOD_NONE && (this->getItemEntry.getItemId == GI_BOTTLE || this->getItemEntry.getItemId == GI_MILK_BOTTLE)) ) { if (gSaveContext.inventory.items[SLOT_BOTTLE_1] != ITEM_NONE) { @@ -735,6 +737,8 @@ void EnBox_CreateExtraChestTextures() { gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, gChristmasGreenTreasureChestSideAndTopTex), }; + Gfx gNoOp[] = { gsDPNoOp() }; + Gfx* frontCmd = ResourceMgr_LoadGfxByName(gTreasureChestChestFrontDL); int frontIndex = 0; while (frontCmd->words.w0 >> 24 != G_ENDDL) { @@ -743,6 +747,20 @@ void EnBox_CreateExtraChestTextures() { gKeyTreasureChestChestFrontDL[frontIndex] = *frontCmd; gChristmasRedTreasureChestChestFrontDL[frontIndex] = *frontCmd; gChristmasGreenTreasureChestChestFrontDL[frontIndex] = *frontCmd; + + // Set the second instruction of img OTR hash opcode to noop, since we will replace it with the + // OTR filepath opcode below + if (frontCmd->words.w0 >> 24 == G_SETTIMG_OTR_HASH) { + frontIndex++; + ++frontCmd; + + gSkullTreasureChestChestFrontDL[frontIndex] = gNoOp[0]; + gGoldTreasureChestChestFrontDL[frontIndex] = gNoOp[0]; + gKeyTreasureChestChestFrontDL[frontIndex] = gNoOp[0]; + gChristmasRedTreasureChestChestFrontDL[frontIndex] = gNoOp[0]; + gChristmasGreenTreasureChestChestFrontDL[frontIndex] = gNoOp[0]; + } + frontIndex++; ++frontCmd; } @@ -781,6 +799,20 @@ void EnBox_CreateExtraChestTextures() { gKeyTreasureChestChestSideAndLidDL[sideIndex] = *sideCmd; gChristmasRedTreasureChestChestSideAndLidDL[sideIndex] = *sideCmd; gChristmasGreenTreasureChestChestSideAndLidDL[sideIndex] = *sideCmd; + + // Set the second instruction of img OTR hash opcode to noop, since we will replace it with the + // OTR filepath opcode below + if (sideCmd->words.w0 >> 24 == G_SETTIMG_OTR_HASH) { + sideIndex++; + ++sideCmd; + + gSkullTreasureChestChestSideAndLidDL[sideIndex] = gNoOp[0]; + gGoldTreasureChestChestSideAndLidDL[sideIndex] = gNoOp[0]; + gKeyTreasureChestChestSideAndLidDL[sideIndex] = gNoOp[0]; + gChristmasRedTreasureChestChestSideAndLidDL[sideIndex] = gNoOp[0]; + gChristmasGreenTreasureChestChestSideAndLidDL[sideIndex] = gNoOp[0]; + } + sideIndex++; ++sideCmd; } diff --git a/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c b/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c index a7d1b7a6c..fbedc59bd 100644 --- a/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c +++ b/soh/src/overlays/actors/ovl_En_Brob/z_en_brob.c @@ -6,6 +6,7 @@ #include "z_en_brob.h" #include "objects/object_brob/object_brob.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -153,7 +154,7 @@ void func_809CB054(EnBrob* this, PlayState* play) { this->timer--; } if (this->timer == 0) { - if (func_8004356C(&this->dyna) != 0) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna) != 0) { func_8002F71C(play, &this->dyna.actor, 5.0f, this->dyna.actor.yawTowardsPlayer, 1.0f); func_809CAE44(this, play); } else if (this->dyna.actor.xzDistToPlayer < 300.0f) { diff --git a/soh/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c b/soh/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c index 89642a9fd..7965d2df1 100644 --- a/soh/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c +++ b/soh/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c @@ -401,7 +401,7 @@ void EnBubble_Regrow(EnBubble* this, PlayState* play) { void EnBubble_Update(Actor* thisx, PlayState* play) { EnBubble* this = (EnBubble*)thisx; - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 16.0f, 16.0f, 0.0f, 7); this->actionFunc(this, play); Actor_SetFocus(&this->actor, this->actor.shape.yOffset); diff --git a/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c b/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c index 7dac97580..3bdfe377d 100644 --- a/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c +++ b/soh/src/overlays/actors/ovl_En_Butte/z_en_butte.c @@ -8,6 +8,7 @@ #include "overlays/actors/ovl_En_Elf/z_en_elf.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS 0 @@ -413,7 +414,7 @@ void EnButte_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->actor.update != NULL) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Math_StepToF(&this->actor.world.pos.y, this->posYTarget, 0.6f); if (this->actor.xyzDistToPlayerSq < 5000.0f) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_En_Bw/z_en_bw.c b/soh/src/overlays/actors/ovl_En_Bw/z_en_bw.c index 501c7ec9e..84754caba 100644 --- a/soh/src/overlays/actors/ovl_En_Bw/z_en_bw.c +++ b/soh/src/overlays/actors/ovl_En_Bw/z_en_bw.c @@ -8,6 +8,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_bw/object_bw.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -794,7 +795,7 @@ void EnBw_Update(Actor* thisx, PlayState* play2) { this->unk_234 = Actor_TestFloorInDirection(thisx, play, 50.0f, thisx->world.rot.y); if ((this->unk_220 == 4) || (this->unk_220 == 6) || (this->unk_220 == 5) || (this->unk_220 == 1) || (this->unk_234 != 0)) { - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); } Actor_UpdateBgCheckInfo(play, thisx, 20.0f, 30.0f, 21.0f, 0x1F); } diff --git a/soh/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c b/soh/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c index c19f43dc3..753c3d537 100644 --- a/soh/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c +++ b/soh/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c @@ -245,9 +245,9 @@ void EnClearTag_Init(Actor* thisx, PlayState* play) { this->state = CLEAR_TAG_STATE_LASER; this->timers[CLEAR_TAG_TIMER_LASER_DEATH] = 70; this->actor.speedXZ = 35.0f; - func_8002D908(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); for (j = 0; j <= 0; j++) { - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); } this->actor.scale.x = 0.4f; this->actor.scale.y = 0.4f; @@ -255,7 +255,7 @@ void EnClearTag_Init(Actor* thisx, PlayState* play) { this->actor.speedXZ = 70.0f; this->actor.shape.rot.x = -this->actor.shape.rot.x; - func_8002D908(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); Collider_SetCylinder(play, &this->collider, &this->actor, &sLaserCylinderInit); Audio_PlayActorSound2(&this->actor, NA_SE_IT_SWORD_REFLECT_MG); } else { // Initialize the Arwing. @@ -495,7 +495,7 @@ void EnClearTag_Update(Actor* thisx, PlayState* play2) { this->actor.shape.rot.x = -this->actor.shape.rot.x; // Update the Arwing's velocity. - func_8002D908(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); this->actor.velocity.x += this->acceleration.x; this->actor.velocity.y += this->acceleration.y; this->actor.velocity.z += this->acceleration.z; @@ -517,7 +517,7 @@ void EnClearTag_Update(Actor* thisx, PlayState* play2) { this->crashingTimer--; } - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Actor_SetFocus(&this->actor, 0.0f); @@ -562,7 +562,7 @@ void EnClearTag_Update(Actor* thisx, PlayState* play2) { break; case CLEAR_TAG_STATE_LASER: - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); // Check if the laser has hit a target. if (this->collider.base.atFlags & AT_HIT) { diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index c01ac30b5..40d206ecc 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -6,6 +6,8 @@ #include "z_en_cow.h" #include "objects/object_cow/object_cow.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -306,7 +308,7 @@ void EnCow_Update(Actor* thisx, PlayState* play2) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliders[0].base); CollisionCheck_SetOC(play, &play->colChkCtx, &this->colliders[1].base); - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); Actor_UpdateBgCheckInfo(play, thisx, 0.0f, 0.0f, 0.0f, 4); if (SkelAnime_Update(&this->skelAnime) != 0) { if (this->skelAnime.animation == &gCowBodyChewAnim) { diff --git a/soh/src/overlays/actors/ovl_En_Crow/z_en_crow.c b/soh/src/overlays/actors/ovl_En_Crow/z_en_crow.c index bb7236e04..2ff76ab68 100644 --- a/soh/src/overlays/actors/ovl_En_Crow/z_en_crow.c +++ b/soh/src/overlays/actors/ovl_En_Crow/z_en_crow.c @@ -1,6 +1,7 @@ #include "z_en_crow.h" #include "objects/object_crow/object_crow.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_IGNORE_QUAKE | ACTOR_FLAG_ARROW_DRAGGABLE) @@ -451,10 +452,10 @@ void EnCrow_Update(Actor* thisx, PlayState* play) { if (this->actionFunc != EnCrow_Respawn) { if (this->actor.colChkInfo.health != 0) { height = 20.0f * scale; - func_8002D97C(&this->actor); + Actor_MoveXYZ(&this->actor); } else { height = 0.0f; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } Actor_UpdateBgCheckInfo(play, &this->actor, 12.0f * scale, 25.0f * scale, 50.0f * scale, 7); } else { diff --git a/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c b/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c index d1659d21c..78d4350c6 100644 --- a/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c +++ b/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c @@ -1,6 +1,7 @@ #include "z_en_cs.h" #include "objects/object_cs/object_cs.h" #include "objects/object_link_child/object_link_child.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -248,7 +249,7 @@ void EnCs_HandleTalking(EnCs* this, PlayState* play) { } if (this->actor.textId == 0x2023) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } this->talkState = 1; @@ -316,7 +317,7 @@ s32 EnCs_HandleWalking(EnCs* this, PlayState* play) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->walkAngle, 1, 2500, 0); this->actor.world.rot.y = this->actor.shape.rot.y; this->actor.speedXZ = this->walkSpeed; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); return 0; diff --git a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c index 50ec1532e..75ae78404 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c +++ b/soh/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c @@ -2,6 +2,7 @@ #include "overlays/actors/ovl_En_GeldB/z_en_geldb.h" #include "objects/object_daiku/object_daiku.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -544,7 +545,7 @@ void EnDaiku_EscapeRun(EnDaiku* this, PlayState* play) { Math_SmoothStepToS(&this->actor.shape.rot.y, ry, 1, 0xFA0, 0); this->actor.world.rot.y = this->actor.shape.rot.y; Math_SmoothStepToF(&this->actor.speedXZ, this->runSpeed, 0.6f, dxz, 0.0f); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); if (this->subCamActive) { diff --git a/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c b/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c index 6cc91e0c7..77e8bda81 100644 --- a/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c +++ b/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c @@ -6,6 +6,7 @@ #include "z_en_daiku_kakariko.h" #include "objects/object_daiku/object_daiku.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -432,7 +433,7 @@ void EnDaikuKakariko_Run(EnDaikuKakariko* this, PlayState* play) { Math_SmoothStepToF(&this->actor.speedXZ, this->runSpeed, 0.8f, runDist, 0.0f); } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->flags & 0x40) { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); diff --git a/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c b/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c index 2b4344f68..735cb025d 100644 --- a/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c +++ b/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c @@ -3,6 +3,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -1028,7 +1029,7 @@ void EnDekubaba_DeadStickDrop(EnDekubaba* this, PlayState* play) { return; } - func_8002F554(&this->actor, play, GI_STICKS_1); + Actor_OfferGetItemNearby(&this->actor, play, GI_STICKS_1); } // Update and associated functions @@ -1129,7 +1130,7 @@ void EnDekubaba_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->actionFunc == EnDekubaba_PrunedSomersault) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, this->size * 15.0f, 10.0f, 5); } else if (this->actionFunc != EnDekubaba_DeadStickDrop) { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); diff --git a/soh/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c b/soh/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c index 79ed4433e..138639f1c 100644 --- a/soh/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c +++ b/soh/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c @@ -8,6 +8,7 @@ #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "objects/object_dekunuts/object_dekunuts.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -479,7 +480,7 @@ void EnDekunuts_Update(Actor* thisx, PlayState* play) { if (this->actor.params != DEKUNUTS_FLOWER) { EnDekunuts_ColliderCheck(this, play); this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, this->collider.dim.radius, this->collider.dim.height, 0x1D); Collider_UpdateCylinder(&this->actor, &this->collider); diff --git a/soh/src/overlays/actors/ovl_En_Dh/z_en_dh.c b/soh/src/overlays/actors/ovl_En_Dh/z_en_dh.c index 997d9aaa5..8e4fd6413 100644 --- a/soh/src/overlays/actors/ovl_En_Dh/z_en_dh.c +++ b/soh/src/overlays/actors/ovl_En_Dh/z_en_dh.c @@ -1,6 +1,7 @@ #include "z_en_dh.h" #include "objects/object_dh/object_dh.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAGGED_BY_HOOKSHOT) @@ -511,7 +512,7 @@ void EnDh_Update(Actor* thisx, PlayState* play) { EnDh_CollisionCheck(this, play); this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 45.0f, 45.0f, 0x1D); this->actor.focus.pos = this->headPos; Collider_UpdateCylinder(&this->actor, &this->collider1); diff --git a/soh/src/overlays/actors/ovl_En_Dha/z_en_dha.c b/soh/src/overlays/actors/ovl_En_Dha/z_en_dha.c index da6f43388..2b6b036b2 100644 --- a/soh/src/overlays/actors/ovl_En_Dha/z_en_dha.c +++ b/soh/src/overlays/actors/ovl_En_Dha/z_en_dha.c @@ -7,6 +7,7 @@ #include "z_en_dha.h" #include "overlays/actors/ovl_En_Dh/z_en_dh.h" #include "objects/object_dh/object_dh.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) diff --git a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c index 0a2d4c6fe..40663941b 100644 --- a/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c +++ b/soh/src/overlays/actors/ovl_En_Diving_Game/z_en_diving_game.c @@ -8,6 +8,8 @@ #include "overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.h" #include "objects/object_zo/object_zo.h" #include "vt.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -134,7 +136,7 @@ s32 EnDivingGame_HasMinigameFinished(EnDivingGame* this, PlayState* play) { // Failed. gSaveContext.timer1State = 0; func_800F5B58(); - func_80078884(NA_SE_SY_FOUND); + Sfx_PlaySfxCentered(NA_SE_SY_FOUND); this->actor.textId = 0x71AD; Message_StartTextbox(play, this->actor.textId, NULL); this->unk_292 = TEXT_STATE_EVENT; diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c index d2d8963c3..fb665f74d 100644 --- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -8,6 +8,8 @@ #include "objects/object_shopnuts/object_shopnuts.h" #include "vt.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -492,7 +494,7 @@ void EnDns_Update(Actor* thisx, PlayState* play) { Actor_SetFocus(&this->actor, 60.0f); Actor_SetScale(&this->actor, 0.01f); SkelAnime_Update(&this->skelAnime); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); this->actionFunc(this, play); if (this->standOnGround) { Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 20.0f, 4); diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c b/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c index d63cb14c8..ef9228dc2 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c @@ -9,6 +9,7 @@ #include "overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.h" #include "overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.h" #include "vt.h" +#include "soh/OTRGlobals.h" #define FLAGS 0 @@ -165,8 +166,8 @@ void EnDntDemo_Judge(EnDntDemo* this, PlayState* play) { } case PLAYER_MASK_TRUTH: if (!Flags_GetItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE) && (Player_GetMask(play) != PLAYER_MASK_SKULL)) { - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->prize = DNT_PRIZE_NUTS; this->leader->stageSignal = DNT_LEADER_SIGNAL_UP; reaction = DNT_SIGNAL_LOOK; diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c b/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c index 95dbb144a..85ebef2d0 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c @@ -9,6 +9,7 @@ #include "overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -101,9 +102,6 @@ void EnDntJiji_Destroy(Actor* thisx, PlayState* play) { } void EnDntJiji_SetFlower(EnDntJiji* this, PlayState* play) { - // SOH: Due to removed object dependencies, parent was still NULL when Init was called. In order to properly set - // stage, redo it here now that we are a frame later. - this->stage = (EnDntDemo*)this->actor.parent; if (this->actor.bgCheckFlags & 1) { this->flowerPos = this->actor.world.pos; this->actionFunc = EnDntJiji_SetupWait; @@ -424,7 +422,7 @@ void EnDntJiji_Update(Actor* thisx, PlayState* play) { } } this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 60.0f, 0x1D); Collider_UpdateCylinder(&this->actor, &this->collider); if (this->isSolid != 0) { diff --git a/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c b/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c index eaee07ae7..e629277f4 100644 --- a/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c +++ b/soh/src/overlays/actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c @@ -12,6 +12,7 @@ #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "objects/object_hintnuts/object_hintnuts.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -247,7 +248,7 @@ void EnDntNomal_TargetWait(EnDntNomal* this, PlayState* play) { scorePos.z = this->actor.world.pos.z; EffectSsExtra_Spawn(play, &scorePos, &scoreVel, &scoreAccel, 4, 2); Audio_StopSfxById(NA_SE_SY_TRE_BOX_APPEAR); - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); // "Big hit" osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆☆ 大当り ☆☆☆☆☆ %d\n" VT_RST, this->hitCounter); if (!LINK_IS_ADULT && !Flags_GetItemGetInf(ITEMGETINF_1D)) { @@ -594,7 +595,7 @@ void EnDntNomal_StageDance(EnDntNomal* this, PlayState* play) { void EnDntNomal_SetupStageHide(EnDntNomal* this, PlayState* play) { if (this->timer3 != 0) { if ((this->timer3 == 1) && (this->ignore == 1)) { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } else { this->endFrame = (f32)Animation_GetLastFrame(&gDntStageHideAnim); @@ -636,7 +637,7 @@ void EnDntNomal_StageHide(EnDntNomal* this, PlayState* play) { if (rupee->colorIdx == 2) { rupee->actor.velocity.y = 7.0f; } - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } this->action = DNT_ACTION_NONE; this->actionFunc = EnDntNomal_SetupStageWait; @@ -813,7 +814,7 @@ void EnDntNomal_Update(Actor* thisx, PlayState* play) { } } this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 60.0f, 0x1D); if (this->type == ENDNTNOMAL_TARGET) { Collider_SetQuadVertices(&this->targetQuad, &this->targetVtx[0], &this->targetVtx[1], &this->targetVtx[2], diff --git a/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c b/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c index 96b18b372..96121dfc6 100644 --- a/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c +++ b/soh/src/overlays/actors/ovl_En_Dodojr/z_en_dodojr.c @@ -8,6 +8,7 @@ #include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "objects/object_dodojr/object_dodojr.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -433,7 +434,7 @@ void func_809F74C4(EnDodojr* this, PlayState* play) { } void func_809F758C(EnDodojr* this, PlayState* play) { - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); func_809F6730(this, play, &this->actor.world.pos); if (DECR(this->timer4) == 0) { @@ -490,7 +491,7 @@ void func_809F773C(EnDodojr* this, PlayState* play) { void func_809F77AC(EnDodojr* this, PlayState* play) { this->rootScale = 1.2f; this->rootScale *= ((f32)this->actor.colorFilterTimer / 8); - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); if (func_809F68B0(this, play) != 0) { this->timer3 = 60; @@ -505,7 +506,7 @@ void func_809F784C(EnDodojr* this, PlayState* play) { } void func_809F786C(EnDodojr* this, PlayState* play) { - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); if (func_809F68B0(this, play) != 0) { func_809F6AC4(this); @@ -538,7 +539,7 @@ void func_809F78EC(EnDodojr* this, PlayState* play) { void func_809F799C(EnDodojr* this, PlayState* play) { this->actor.flags |= ACTOR_FLAG_PLAY_HIT_SFX; - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); if (func_809F68B0(this, play) != 0) { func_809F6994(this); @@ -562,7 +563,7 @@ void func_809F7A00(EnDodojr* this, PlayState* play) { } void func_809F7AB8(EnDodojr* this, PlayState* play) { - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); Math_SmoothStepToS(&this->actor.shape.rot.y, 0, 4, 1000, 10); this->actor.world.rot.x = this->actor.shape.rot.x; @@ -612,7 +613,7 @@ void EnDodojr_Update(Actor* thisx, PlayState* play) { EnDodojr* this = (EnDodojr*)thisx; SkelAnime_Update(&this->skelAnime); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); func_809F70E8(this, play); if (this->actionFunc != func_809F73AC) { diff --git a/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c b/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c index 359477614..d714093ac 100644 --- a/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c +++ b/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c @@ -3,6 +3,7 @@ #include "overlays/actors/ovl_En_Bombf/z_en_bombf.h" #include "objects/object_dodongo/object_dodongo.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -773,7 +774,7 @@ void EnDodongo_Update(Actor* thisx, PlayState* play) { EnDodongo_CollisionCheck(this, play); if (this->actor.colChkInfo.damageEffect != 0xE) { this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 75.0f, 60.0f, 70.0f, 0x1D); if (this->actor.bgCheckFlags & 2) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_DOWN); diff --git a/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c b/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c index b226d00f2..27619c492 100644 --- a/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c +++ b/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c @@ -6,6 +6,7 @@ #include "z_en_dog.h" #include "objects/object_dog/object_dog.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS 0 @@ -483,7 +484,7 @@ void EnDog_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); Actor_UpdateBgCheckInfo(play, &this->actor, this->collider.dim.radius, this->collider.dim.height * 0.5f, 0.0f, 5); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); this->actionFunc(this, play); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_En_Door/z_en_door.c b/soh/src/overlays/actors/ovl_En_Door/z_en_door.c index cbfd5f018..92670921d 100644 --- a/soh/src/overlays/actors/ovl_En_Door/z_en_door.c +++ b/soh/src/overlays/actors/ovl_En_Door/z_en_door.c @@ -10,6 +10,7 @@ #include "objects/object_hidan_objects/object_hidan_objects.h" #include "objects/object_mizu_objects/object_mizu_objects.h" #include "objects/object_haka_door/object_haka_door.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -194,7 +195,7 @@ void EnDoor_Idle(EnDoor* this, PlayState* play) { s16 phi_v0; doorType = this->actor.params >> 7 & 7; - func_8002DBD0(&this->actor, &playerPosRelToDoor, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &playerPosRelToDoor, &player->actor.world.pos); if (this->playerIsOpening != 0) { this->actionFunc = EnDoor_Open; Animation_PlayOnceSetSpeed(&this->skelAnime, D_809FCECC[this->animStyle], diff --git a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c index 874b62cea..497ba9388 100644 --- a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c +++ b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c @@ -6,6 +6,9 @@ #include "z_en_ds.h" #include "objects/object_ds/object_ds.h" +#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -224,7 +227,7 @@ void EnDs_Wait(EnDs* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, play)) { if (func_8002F368(play) == EXCH_ITEM_ODD_MUSHROOM) { - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); player->actor.textId = 0x504A; this->actionFunc = EnDs_OfferOddPotion; } else if (GameInteractor_Should(VB_OFFER_BLUE_POTION, Flags_GetItemGetInf(ITEMGETINF_30), this)) { // Traded odd mushroom diff --git a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c index 20acdec4c..04d979127 100644 --- a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c +++ b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c @@ -1,6 +1,7 @@ #include "z_en_du.h" #include "objects/object_du/object_du.h" #include "scenes/overworld/spot18/spot18_scene.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -385,7 +386,7 @@ void func_809FE4A4(EnDu* this, PlayState* play) { EnDu_SetupAction(this, func_809FE890); play->msgCtx.ocarinaMode = OCARINA_MODE_04; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (GameInteractor_Should(VB_PLAY_DARUNIAS_JOY_CS, true)) { play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gGoronCityDaruniaCorrectCs); gSaveContext.cutsceneTrigger = 1; @@ -614,7 +615,7 @@ void EnDu_Update(Actor* thisx, PlayState* play) { this->actor.world.pos.y += this->actor.velocity.y; this->actor.world.pos.z += this->actor.velocity.z; } else { - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); } Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); diff --git a/soh/src/overlays/actors/ovl_En_Dy_Extra/z_en_dy_extra.c b/soh/src/overlays/actors/ovl_En_Dy_Extra/z_en_dy_extra.c index 7018da6ca..cf4ceaee2 100644 --- a/soh/src/overlays/actors/ovl_En_Dy_Extra/z_en_dy_extra.c +++ b/soh/src/overlays/actors/ovl_En_Dy_Extra/z_en_dy_extra.c @@ -7,6 +7,7 @@ #include "z_en_dy_extra.h" #include "objects/object_dy_obj/object_dy_obj.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -85,14 +86,14 @@ void EnDyExtra_Update(Actor* thisx, PlayState* play) { this->actor.scale.z = this->scale.z; Audio_PlayActorSound2(&this->actor, NA_SE_PL_SPIRAL_HEAL_BEAM - SFX_FLAG); this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void EnDyExtra_Draw(Actor* thisx, PlayState* play) { static Color_RGBA8 primColors[] = { { 255, 255, 170, 255 }, { 255, 255, 170, 255 } }; static Color_RGBA8 envColors[] = { { 255, 100, 255, 255 }, { 100, 255, 255, 255 } }; - static u8 D_809FFC50[] = { 0x02, 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, - 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x01, 0x02 }; + static u8 D_809FFC50[] = { 0x02, 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, + 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x01, 0x02, 0x00 }; EnDyExtra* this = (EnDyExtra*)thisx; s32 pad; GraphicsContext* gfxCtx = play->state.gfxCtx; diff --git a/soh/src/overlays/actors/ovl_En_Eg/z_en_eg.c b/soh/src/overlays/actors/ovl_En_Eg/z_en_eg.c index 69121bb3e..f204e146e 100644 --- a/soh/src/overlays/actors/ovl_En_Eg/z_en_eg.c +++ b/soh/src/overlays/actors/ovl_En_Eg/z_en_eg.c @@ -36,7 +36,7 @@ const ActorInit En_Eg_InitVars = { }; void EnEg_PlayVoidOutSFX() { - func_800788CC(NA_SE_OC_ABYSS); + Sfx_PlaySfxCentered2(NA_SE_OC_ABYSS); } void EnEg_Destroy(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c b/soh/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c index 7340d9cf5..70cefaa65 100644 --- a/soh/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c +++ b/soh/src/overlays/actors/ovl_En_Eiyer/z_en_eiyer.c @@ -1,6 +1,7 @@ #include "z_en_eiyer.h" #include "objects/object_ei/object_ei.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -647,9 +648,9 @@ void EnEiyer_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->actor.world.rot.x == 0 || this->actionFunc == EnEiyer_Stunned) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } else { - func_8002D97C(&this->actor); + Actor_MoveXYZ(&this->actor); } if (this->actionFunc == EnEiyer_Glide || this->actionFunc == EnEiyer_DiveAttack || diff --git a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c index 477d60d64..7b0e49674 100644 --- a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c +++ b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c @@ -7,6 +7,8 @@ #include "z_en_elf.h" #include "objects/gameplay_keep/gameplay_keep.h" #include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -399,9 +401,11 @@ void EnElf_Init(Actor* thisx, PlayState* play) { EnElf_SetupAction(this, func_80A03604); func_80A01C38(this, 8); - for (i = 0; i < 8; i++) { - Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, thisx->world.pos.x, - thisx->world.pos.y - 30.0f, thisx->world.pos.z, 0, 0, 0, FAIRY_HEAL, true); + if (GameInteractor_Should(VB_SPAWN_FOUNTAIN_FAIRIES, true, this)) { + for (i = 0; i < 8; i++) { + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, thisx->world.pos.x, + thisx->world.pos.y - 30.0f, thisx->world.pos.z, 0, 0, 0, FAIRY_HEAL, true); + } } break; default: @@ -506,14 +510,14 @@ void func_80A02C98(EnElf* this, Vec3f* targetPos, f32 arg2) { func_80A02BD8(this, targetPos, arg2); Math_StepToF(&this->actor.velocity.x, xVelTarget, 1.5f); Math_StepToF(&this->actor.velocity.z, zVelTarget, 1.5f); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); } void func_80A02E30(EnElf* this, Vec3f* targetPos) { func_80A02BD8(this, targetPos, 0.2f); this->actor.velocity.x = (targetPos->x + this->unk_28C.x) - this->actor.world.pos.x; this->actor.velocity.z = (targetPos->z + this->unk_28C.z) - this->actor.world.pos.z; - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->actor.world.pos.x = targetPos->x + this->unk_28C.x; this->actor.world.pos.z = targetPos->z + this->unk_28C.z; } @@ -521,7 +525,7 @@ void func_80A02E30(EnElf* this, Vec3f* targetPos) { void func_80A02EC0(EnElf* this, Vec3f* targetPos) { func_80A02BD8(this, targetPos, 0.2f); this->actor.velocity.x = this->actor.velocity.z = 0.0f; - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->actor.world.pos.x = targetPos->x + this->unk_28C.x; this->actor.world.pos.z = targetPos->z + this->unk_28C.z; } @@ -568,7 +572,7 @@ void func_80A03018(EnElf* this, PlayState* play) { Math_SmoothStepToS(&this->unk_2BC, targetYaw, 10, this->unk_2AC, 0x20); this->actor.world.rot.y = this->unk_2BC; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void func_80A03148(EnElf* this, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4) { @@ -596,7 +600,7 @@ void func_80A03148(EnElf* this, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4) { Math_StepToF(&this->actor.velocity.x, xVelTarget, 5.0f); Math_StepToF(&this->actor.velocity.z, zVelTarget, 5.0f); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); } void func_80A0329C(EnElf* this, PlayState* play) { @@ -631,19 +635,7 @@ void func_80A0329C(EnElf* this, PlayState* play) { if ((heightDiff > 0.0f) && (heightDiff < 60.0f)) { if (!func_80A01F90(&this->actor.world.pos, &refActor->actor.world.pos, 10.0f)) { - if (CVarGetInteger(CVAR_ENHANCEMENT("FairyEffect"), 0) && !(this->fairyFlags & FAIRY_FLAG_BIG)) - { - if (CVarGetInteger(CVAR_ENHANCEMENT("FairyPercentRestore"), 0)) - { - Health_ChangeBy(play, (gSaveContext.healthCapacity * CVarGetInteger(CVAR_ENHANCEMENT("FairyHealth"), 100) / 100 + 15) / 16 * 16); - } - else - { - Health_ChangeBy(play, CVarGetInteger(CVAR_ENHANCEMENT("FairyHealth"), 8) * 16); - } - } - else - { + if (GameInteractor_Should(VB_FAIRY_HEAL, true, this)) { Health_ChangeBy(play, 128); } if (this->fairyFlags & FAIRY_FLAG_BIG) { @@ -1097,7 +1089,7 @@ void func_80A0461C(EnElf* this, PlayState* play) { } else { arrowPointedActor = play->actorCtx.targetCtx.arrowPointedActor; - if ((player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM) || ((YREG(15) & 0x10) && func_800BC56C(play, 2))) { + if ((player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM) || ((YREG(15) & 0x10) && Play_CheckViewpoint(play, 2))) { temp = 12; this->unk_2C0 = 100; } else if (arrowPointedActor == NULL || arrowPointedActor->category == ACTORCAT_NPC) { @@ -1399,7 +1391,7 @@ void func_80A053F0(Actor* thisx, PlayState* play) { } if (Actor_ProcessTalkRequest(thisx, play)) { - func_800F4524(&D_801333D4, NA_SE_VO_SK_LAUGH, 0x20); + func_800F4524(&gSfxDefaultPos, NA_SE_VO_SK_LAUGH, 0x20); thisx->focus.pos = thisx->world.pos; if (thisx->textId == ElfMessage_GetCUpText(play)) { diff --git a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.h b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.h index 7f8e4c84e..da77ac778 100644 --- a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.h +++ b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.h @@ -4,6 +4,7 @@ #include #include "global.h" #include "overlays/actors/ovl_Elf_Msg/z_elf_msg.h" +#include "soh/Enhancements/randomizer/ShuffleFairies.h" struct EnElf; @@ -42,6 +43,9 @@ typedef struct EnElf { /* 0x02C7 */ u8 unk_2C7; /* 0x02C8 */ EnElfUnkFunc func_2C8; /* 0x02CC */ EnElfActionFunc actionFunc; + // #region SOH [Randomizer] + /* */ FairyIdentity sohFairyIdentity; + // #endregion } EnElf; // size = 0x02D0 typedef enum { diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c index 3101988a8..99be5f022 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c +++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c @@ -8,6 +8,7 @@ #include "overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "vt.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -157,7 +158,7 @@ void EnExItem_WaitForObject(EnExItem* this, PlayState* play) { this->prizeRotateTimer = 35; this->scale = 0.5f; if (!onCounter) { - func_80078884(NA_SE_SY_PIECE_OF_HEART); + Sfx_PlaySfxCentered(NA_SE_SY_PIECE_OF_HEART); this->actionFunc = EnExItem_BowlPrize; } else { this->actionFunc = EnExItem_SetupBowlCounter; @@ -336,7 +337,7 @@ void EnExItem_ExitChest(EnExItem* this, PlayState* play) { Actor_Kill(&this->actor); } } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void EnExItem_FairyMagic(EnExItem* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.c b/soh/src/overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.c index 120461f8f..6864ad652 100644 --- a/soh/src/overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.c +++ b/soh/src/overlays/actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.c @@ -211,7 +211,7 @@ void EnExRuppy_DropIntoWater(EnExRuppy* this, PlayState* play) { this->actor.shape.rot.y += 0x7A8; Math_ApproachF(&this->actor.gravity, -2.0f, 0.3f, 1.0f); EnExRuppy_SpawnSparkles(this, play, 2, 0); - func_80078884(NA_SE_EV_RAINBOW_SHOWER - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_RAINBOW_SHOWER - SFX_FLAG); divingGame = (EnDivingGame*)this->actor.parent; if ((divingGame != NULL) && (divingGame->actor.update != NULL) && ((divingGame->unk_296 == 0) || (this->actor.bgCheckFlags & 0x20) || (this->timer == 0))) { @@ -219,7 +219,7 @@ void EnExRuppy_DropIntoWater(EnExRuppy* this, PlayState* play) { this->actor.speedXZ = 0.0f; this->actor.velocity.x = this->actor.velocity.y = this->actor.velocity.z = 0.0f; this->actor.gravity = 0.0f; - func_80078914(&this->actor.projectedPos, NA_SE_EV_BOMB_DROP_WATER); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_BOMB_DROP_WATER); this->actionFunc = EnExRuppy_EnterWater; } } @@ -256,7 +256,7 @@ void EnExRuppy_Sink(EnExRuppy* this, PlayState* play) { this->actor.velocity.y = -1.0f; this->actor.gravity = -0.2f; EffectSsGSplash_Spawn(play, &pos, 0, 0, 0, 800); - func_80078914(&this->actor.projectedPos, NA_SE_EV_BOMB_DROP_WATER); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_BOMB_DROP_WATER); this->actionFunc = EnExRuppy_WaitInGame; } divingGame = (EnDivingGame*)this->actor.parent; @@ -284,7 +284,7 @@ void EnExRuppy_WaitInGame(EnExRuppy* this, PlayState* play) { this->actionFunc = EnExRuppy_Kill; } else if (this->actor.xyzDistToPlayerSq < SQ(localConst)) { Rupees_ChangeBy(this->rupeeValue); - func_80078884(NA_SE_SY_GET_RUPY); + Sfx_PlaySfxCentered(NA_SE_SY_GET_RUPY); divingGame->grabbedRupeesCounter++; Actor_Kill(&this->actor); } @@ -348,7 +348,7 @@ void EnExRuppy_WaitAsCollectible(EnExRuppy* this, PlayState* play) { f32 localConst = 30.0f; if (this->actor.xyzDistToPlayerSq < SQ(localConst)) { - func_80078884(NA_SE_SY_GET_RUPY); + Sfx_PlaySfxCentered(NA_SE_SY_GET_RUPY); Item_DropCollectible(play, &this->actor.world.pos, (sEnExRuppyCollectibleTypes[this->colorIdx] | 0x8000)); Actor_Kill(&this->actor); } @@ -370,7 +370,7 @@ void EnExRuppy_Update(Actor* thisx, PlayState* play) { if (this->timer != 0) { this->timer--; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 50.0f, 0x1C); } diff --git a/soh/src/overlays/actors/ovl_En_Fd/z_en_fd.c b/soh/src/overlays/actors/ovl_En_Fd/z_en_fd.c index 277ee851a..c71d8c9b7 100644 --- a/soh/src/overlays/actors/ovl_En_Fd/z_en_fd.c +++ b/soh/src/overlays/actors/ovl_En_Fd/z_en_fd.c @@ -9,6 +9,7 @@ #include "objects/object_fw/object_fw.h" #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_HOOKSHOT_DRAGS) @@ -680,7 +681,7 @@ void EnFd_Update(Actor* thisx, PlayState* play) { } else if (this->actionFunc != EnFd_WaitForCore) { EnFd_ColliderCheck(this, play); } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); EnFd_Fade(this, play); this->actionFunc(this, play); diff --git a/soh/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.c b/soh/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.c index bd59e6f51..7db366ca4 100644 --- a/soh/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.c +++ b/soh/src/overlays/actors/ovl_En_Fd_Fire/z_en_fd_fire.c @@ -193,13 +193,13 @@ void EnFdFire_DanceTowardsPlayer(EnFdFire* this, PlayState* play) { if (this->actor.speedXZ < 0.1f) { this->actor.speedXZ = 5.0f; } - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); } } void EnFdFire_Disappear(EnFdFire* this, PlayState* play) { Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.6f, 9.0f, 0.0f); - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); Math_SmoothStepToF(&this->scale, 0.0f, 0.3f, 0.1f, 0.0f); this->actor.shape.shadowScale = 20.0f; this->actor.shape.shadowScale *= (this->scale / 3.0f); @@ -218,7 +218,7 @@ void EnFdFire_Update(Actor* thisx, PlayState* play) { } } - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->actionFunc(this, play); Actor_UpdateBgCheckInfo(play, &this->actor, 12.0f, 10.0f, 0.0f, 5); diff --git a/soh/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c b/soh/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c index 31f1aebbb..1647e034c 100644 --- a/soh/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c +++ b/soh/src/overlays/actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c @@ -296,7 +296,7 @@ void EnFhgFire_LightningShock(EnFhgFire* this, PlayState* play) { EffectSsFhgFlash_SpawnShock(play, &this->actor, &pos, 200, FHGFLASH_SHOCK_NO_ACTOR); } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Collider_UpdateCylinder(&this->actor, &this->collider); if (player->invincibilityTimer == 0) { CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base); @@ -440,8 +440,8 @@ void EnFhgFire_EnergyBall(EnFhgFire* this, PlayState* play) { dxL = player->actor.world.pos.x - this->actor.world.pos.x; dyL = player->actor.world.pos.y + 40.0f - this->actor.world.pos.y; dzL = player->actor.world.pos.z - this->actor.world.pos.z; - func_8002D908(&this->actor); - func_8002D7EC(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); + Actor_UpdatePos(&this->actor); if (this->work[FHGFIRE_VARIANCE_TIMER] & 1) { Actor_SetScale(&this->actor, 6.0f); } else { @@ -494,8 +494,8 @@ void EnFhgFire_EnergyBall(EnFhgFire* this, PlayState* play) { canBottleReflect2 = canBottleReflect1; if (!canBottleReflect2 && (hurtbox->toucher.dmgFlags & 0x00100000)) { killMode = BALL_IMPACT; - Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_MG, &player->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_MG, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_800AA000(this->actor.xyzDistToPlayerSq, 0xFF, 0x14, 0x96); } else { if (bossGnd->flyMode == GND_FLY_NEUTRAL) { @@ -523,8 +523,8 @@ void EnFhgFire_EnergyBall(EnFhgFire* this, PlayState* play) { angleModX; this->work[FHGFIRE_FIRE_MODE] = FHGFIRE_LIGHT_BLUE; this->work[FHGFIRE_FX_TIMER] = 2; - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_REFLECT_MG, &player->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_REFLECT_MG, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_800AA000(this->actor.xyzDistToPlayerSq, 0xB4, 0x14, 0x64); } } else if (sqrtf(SQ(dxL) + SQ(dyL) + SQ(dzL)) <= 25.0f) { @@ -556,9 +556,9 @@ void EnFhgFire_EnergyBall(EnFhgFire* this, PlayState* play) { killMode = BALL_IMPACT; bossGnd->returnCount = this->work[FHGFIRE_RETURN_COUNT] + 1; Audio_PlaySoundGeneral(NA_SE_EN_FANTOM_HIT_THUNDER, &bossGnd->actor.projectedPos, 4, - &D_801333E0, &D_801333E0, &D_801333E8); - Audio_PlaySoundGeneral(NA_SE_EN_FANTOM_DAMAGE, &bossGnd->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_EN_FANTOM_DAMAGE, &bossGnd->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } break; diff --git a/soh/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c b/soh/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c index aa52d53ae..e85844a2f 100644 --- a/soh/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c +++ b/soh/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c @@ -336,7 +336,7 @@ void EnFireRock_Update(Actor* thisx, PlayState* play) { thisx->gravity = -0.3f - (this->scale * 7.0f); } if (this->type != FIRE_ROCK_ON_FLOOR) { - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); Actor_UpdateBgCheckInfo(play, thisx, 50.0f, 50.0f, 100.0f, 0x1C); } diff --git a/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c b/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c index 7797cba9c..46b1f502d 100644 --- a/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c +++ b/soh/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c @@ -8,6 +8,7 @@ #include "objects/object_firefly/object_firefly.h" #include "overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_IGNORE_QUAKE | ACTOR_FLAG_ARROW_DRAGGABLE) @@ -691,12 +692,12 @@ void EnFirefly_Update(Actor* thisx, PlayState* play2) { if (!(this->actor.flags & ACTOR_FLAG_DRAGGED_BY_ARROW)) { if ((this->actor.colChkInfo.health == 0) || (this->actionFunc == EnFirefly_Stunned)) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } else { if (this->actionFunc != EnFirefly_Rebound) { this->actor.world.rot.x = 0x1554 - this->actor.shape.rot.x; } - func_8002D97C(&this->actor); + Actor_MoveXYZ(&this->actor); } } diff --git a/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c b/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c index 766b15640..ecf368b91 100644 --- a/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c +++ b/soh/src/overlays/actors/ovl_En_Fish/z_en_fish.c @@ -7,6 +7,7 @@ #include "z_en_fish.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS 0 @@ -691,7 +692,7 @@ void EnFish_OrdinaryUpdate(EnFish* this, PlayState* play) { } if ((this->actionFunc == NULL) || (this->actionFunc(this, play), (this->actor.update != NULL))) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->unk_250 != 0) { Actor_UpdateBgCheckInfo(play, &this->actor, 17.5f, 4.0f, 0.0f, this->unk_250); @@ -730,7 +731,7 @@ void EnFish_RespawningUpdate(EnFish* this, PlayState* play) { } if ((this->actionFunc == NULL) || (this->actionFunc(this, play), (this->actor.update != NULL))) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->respawnTimer == 20) { this->actor.draw = EnFish_Draw; diff --git a/soh/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c b/soh/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c index 1a906e5b7..636203c55 100644 --- a/soh/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c +++ b/soh/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c @@ -7,6 +7,7 @@ #include "z_en_floormas.h" #include "objects/object_wallmaster/object_wallmaster.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_DRAGGED_BY_HOOKSHOT) @@ -1051,7 +1052,7 @@ void EnFloormas_Update(Actor* thisx, PlayState* play) { } if (this->actionFunc != EnFloormas_GrabLink) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, this->actor.scale.x * 3000.0f, 0.0f, 0x1D); diff --git a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c index 4d41bb1f8..1606fbc1d 100644 --- a/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c +++ b/soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c @@ -4,6 +4,8 @@ #include "objects/object_fr/object_fr.h" #include #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -581,7 +583,7 @@ void EnFr_UpdateActive(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); SkelAnime_Update(&this->skelAnimeButterfly); EnFr_ButterflyPath(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } } @@ -734,7 +736,7 @@ void EnFr_ChildSong(EnFr* this, PlayState* play) { EnFr_SetupReward(this, play, false); } else if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { frog = sEnFrPointers.frogs[sSongToFrog[songIndex]]; - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); if (frog->actionFunc == EnFr_ChooseJumpFromLogSpot) { frog->isJumpingUp = true; frog->isActive = true; @@ -874,7 +876,7 @@ s32 EnFr_IsFrogSongComplete(EnFr* this, PlayState* play) { void EnFr_OcarinaMistake(EnFr* this, PlayState* play) { Message_CloseTextbox(play); this->reward = GI_NONE; - func_80078884(NA_SE_SY_OCARINA_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_OCARINA_ERROR); Audio_OcaSetInstrument(0); sEnFrPointers.flags = 12; EnFr_DeactivateButterfly(); @@ -940,9 +942,9 @@ void EnFr_ContinueFrogSong(EnFr* this, PlayState* play) { void EnFr_SetupReward(EnFr* this, PlayState* play, u8 unkCondition) { EnFr_DeactivateButterfly(); if (unkCondition) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } else { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } Audio_OcaSetInstrument(0); @@ -974,9 +976,7 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); - if (GameInteractor_Should(VB_GIVE_ITEM_FROM_FROGS, true, this)) { - this->reward = GI_RUPEE_PURPLE; - } + this->reward = GI_RUPEE_PURPLE; } else { this->reward = GI_RUPEE_BLUE; } @@ -984,9 +984,7 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); - if (GameInteractor_Should(VB_GIVE_ITEM_FROM_FROGS, true, this)) { - this->reward = GI_HEART_PIECE; - } + this->reward = GI_HEART_PIECE; } else { this->reward = GI_RUPEE_BLUE; } @@ -994,9 +992,7 @@ void EnFr_SetReward(EnFr* this, PlayState* play) { if (!(gSaveContext.eventChkInf[13] & sSongIndex[songIndex])) { gSaveContext.eventChkInf[13] |= sSongIndex[songIndex]; GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SONGS_FOR_FROGS_INDEX << 4) + sSongIndexShift[songIndex]); - if (GameInteractor_Should(VB_GIVE_ITEM_FROM_FROGS, true, this)) { - this->reward = GI_HEART_PIECE; - } + this->reward = GI_HEART_PIECE; } else { this->reward = GI_RUPEE_PURPLE; } @@ -1042,18 +1038,16 @@ void EnFr_Deactivate(EnFr* this, PlayState* play) { play->msgCtx.ocarinaMode = OCARINA_MODE_04; Audio_PlayActorSound2(&this->actor, NA_SE_EV_FROG_CRY_0); - if (this->reward == GI_NONE) { + if (GameInteractor_Should(VB_FROGS_GO_TO_IDLE, this->reward == GI_NONE, this)) { this->actionFunc = EnFr_Idle; } else { this->actionFunc = EnFr_GiveReward; - if (GameInteractor_Should(VB_GIVE_ITEM_FROM_FROGS, true, this)) { - Actor_OfferGetItem(&this->actor, play, this->reward, 30.0f, 100.0f); - } + Actor_OfferGetItem(&this->actor, play, this->reward, 30.0f, 100.0f); } } void EnFr_GiveReward(EnFr* this, PlayState* play) { - if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_GIVE_ITEM_FROM_FROGS, true, this)) { + if (Actor_HasParent(&this->actor, play)) { this->actor.parent = NULL; this->actionFunc = EnFr_SetIdle; } else { diff --git a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c index 98b8a4dda..38553196c 100644 --- a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -7,6 +7,8 @@ #include "z_en_fu.h" #include "objects/object_fu/object_fu.h" #include "scenes/indoors/hakasitarelay/hakasitarelay_scene.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -183,7 +185,7 @@ void func_80A1DBD4(EnFu* this, PlayState* play) { play->msgCtx.ocarinaMode = OCARINA_MODE_04; this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); this->actionFunc = func_80A1DB60; this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; @@ -250,7 +252,7 @@ void EnFu_Update(Actor* thisx, PlayState* play) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); if ((!(this->behaviorFlags & FU_WAIT)) && (SkelAnime_Update(&this->skelanime) != 0)) { Animation_Change(&this->skelanime, this->skelanime.animation, 1.0f, 0.0f, diff --git a/soh/src/overlays/actors/ovl_En_Fw/z_en_fw.c b/soh/src/overlays/actors/ovl_En_Fw/z_en_fw.c index 61f009e47..9603d4af0 100644 --- a/soh/src/overlays/actors/ovl_En_Fw/z_en_fw.c +++ b/soh/src/overlays/actors/ovl_En_Fw/z_en_fw.c @@ -9,6 +9,7 @@ #include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "soh/frame_interpolation.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_HOOKSHOT_DRAGS) @@ -366,7 +367,7 @@ void EnFw_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) { // not attached to hookshot. - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 20.0f, 0.0f, 5); this->actionFunc(this, play); if (this->damageTimer == 0 && this->explosionTimer == 0 && this->actionFunc == EnFw_Run) { diff --git a/soh/src/overlays/actors/ovl_En_Fz/z_en_fz.c b/soh/src/overlays/actors/ovl_En_Fz/z_en_fz.c index 60afdd293..e439bfe41 100644 --- a/soh/src/overlays/actors/ovl_En_Fz/z_en_fz.c +++ b/soh/src/overlays/actors/ovl_En_Fz/z_en_fz.c @@ -698,7 +698,7 @@ void EnFz_Update(Actor* thisx, PlayState* play) { } Math_StepToF(&this->actor.speedXZ, this->speedXZ, 0.2f); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->updateBgInfo) { Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 20.0f, 5); diff --git a/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c b/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c index eaaa7c800..cbfa88b7b 100644 --- a/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c +++ b/soh/src/overlays/actors/ovl_En_G_Switch/z_en_g_switch.c @@ -215,7 +215,7 @@ void EnGSwitch_SilverRupeeTracker(EnGSwitch* this, PlayState* play) { if (sCollectedCount < (CVarGetInteger(CVAR_ENHANCEMENT("SilverRupeeJingleExtend"), 0) ? 10 : 5)) { // "sound?" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 音? ☆☆☆☆☆ %d\n" VT_RST, this->noteIndex); - Audio_PlaySoundTransposed(&D_801333D4, NA_SE_EV_FIVE_COUNT_LUPY, majorScale[this->noteIndex]); + Audio_PlaySoundTransposed(&gSfxDefaultPos, NA_SE_EV_FIVE_COUNT_LUPY, majorScale[this->noteIndex]); this->noteIndex = sCollectedCount; } } @@ -228,10 +228,10 @@ void EnGSwitch_SilverRupeeTracker(EnGSwitch* this, PlayState* play) { if ((play->sceneNum == SCENE_GERUDO_TRAINING_GROUND) && (this->actor.room == 2)) { Flags_SetTempClear(play, this->actor.room); } else { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Flags_SetSwitch(play, this->switchFlag); } - func_80078884(NA_SE_SY_GET_RUPY); + Sfx_PlaySfxCentered(NA_SE_SY_GET_RUPY); Actor_Kill(&this->actor); } } @@ -243,7 +243,7 @@ void EnGSwitch_SilverRupeeIdle(EnGSwitch* this, PlayState* play) { if (this->actor.xyzDistToPlayerSq < 900.0f) { Rupees_ChangeBy(5); sCollectedCount++; - func_80078884(NA_SE_SY_GET_RUPY); + Sfx_PlaySfxCentered(NA_SE_SY_GET_RUPY); this->actor.world.pos = player->actor.world.pos; this->actor.world.pos.y += 40.0f; if (LINK_IS_ADULT) { @@ -278,7 +278,7 @@ void EnGSwitch_GalleryRupee(EnGSwitch* this, PlayState* play) { if (this->delayTimer == 0) { switch (this->moveMode) { case GSWITCH_THROW: - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if ((this->actor.velocity.y < 0.0f) && (this->actor.world.pos.y < (this->actor.home.pos.y - 50.0f))) { gallery = ((EnSyatekiItm*)this->actor.parent); this->actor.velocity.y = 0.0f; @@ -290,7 +290,7 @@ void EnGSwitch_GalleryRupee(EnGSwitch* this, PlayState* play) { } break; case GSWITCH_LEFT: - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); if ((this->actor.velocity.x < 0.0f) && (this->actor.world.pos.x < this->targetPos.x)) { gallery = ((EnSyatekiItm*)this->actor.parent); if (gallery->actor.update != NULL) { @@ -300,7 +300,7 @@ void EnGSwitch_GalleryRupee(EnGSwitch* this, PlayState* play) { } break; case GSWITCH_RIGHT: - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); if (this->actor.world.pos.x > this->targetPos.x) { gallery = ((EnSyatekiItm*)this->actor.parent); if (gallery->actor.update != NULL) { @@ -345,8 +345,8 @@ void EnGSwitch_GalleryRupee(EnGSwitch* this, PlayState* play) { if (gallery->actor.update != NULL) { gallery->hitCount++; gallery->targetState[this->index] = ENSYATEKIHIT_HIT; - func_80078884(NA_SE_EV_HIT_SOUND); - func_80078884(NA_SE_SY_GET_RUPY); + Sfx_PlaySfxCentered(NA_SE_EV_HIT_SOUND); + Sfx_PlaySfxCentered(NA_SE_SY_GET_RUPY); // "Yeah !" osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ いぇぇーす!HIT!! ☆☆☆☆☆ %d\n" VT_RST, gallery->hitCount); EnGSwitch_Break(this, play); @@ -433,7 +433,7 @@ void EnGSwitch_Update(Actor* thisx, PlayState* play) { } if ((this->type != ENGSWITCH_SILVER_TRACKER) && (this->type != ENGSWITCH_SILVER_RUPEE) && (this->type != ENGSWITCH_TARGET_RUPEE)) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 50.0f, 50.0f, 100.0f, 0x1C); } if (this->actor.draw != NULL) { diff --git a/soh/src/overlays/actors/ovl_En_Ganon_Mant/z_en_ganon_mant.c b/soh/src/overlays/actors/ovl_En_Ganon_Mant/z_en_ganon_mant.c index 0fc08ba4a..3c3b40295 100644 --- a/soh/src/overlays/actors/ovl_En_Ganon_Mant/z_en_ganon_mant.c +++ b/soh/src/overlays/actors/ovl_En_Ganon_Mant/z_en_ganon_mant.c @@ -6,6 +6,8 @@ #include "z_en_ganon_mant.h" #include "overlays/actors/ovl_Boss_Ganon/z_boss_ganon.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) diff --git a/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c b/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c index 8fd732aeb..935e3dc40 100644 --- a/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c +++ b/soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c @@ -7,6 +7,8 @@ #include "z_en_gb.h" #include "objects/object_ps/object_ps.h" #include "soh/frame_interpolation.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) diff --git a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c index 91eb44530..cfc7bc8e1 100644 --- a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c +++ b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c @@ -8,6 +8,8 @@ #include "vt.h" #include "objects/object_ge1/object_ge1.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -181,7 +183,7 @@ void EnGe1_Init(Actor* thisx, PlayState* play) { } break; - case GE1_TYPE_TRAINING_GROUNDS_GUARD: + case GE1_TYPE_TRAINING_GROUND_GUARD: this->hairstyle = GE1_HAIR_STRAIGHT; if (GameInteractor_Should(VB_GERUDOS_BE_FRIENDLY, EnGe1_CheckCarpentersFreed())) { @@ -270,7 +272,7 @@ void EnGe1_SpotPlayer(EnGe1* this, PlayState* play) { this->cutsceneTimer = 30; this->actionFunc = EnGe1_KickPlayer; Player_SetCsActionWithHaltedActors(play, &this->actor, 0x5F); - func_80078884(NA_SE_SY_FOUND); + Sfx_PlaySfxCentered(NA_SE_SY_FOUND); Message_StartTextbox(play, 0x6000, &this->actor); } @@ -610,7 +612,7 @@ void EnGe1_BeginGame_Archery(EnGe1* this, PlayState* play) { this->actionFunc = EnGe1_TalkTooPoor_Archery; } else { Rupees_ChangeBy(-20); - play->nextEntranceIndex = ENTR_GERUDOS_FORTRESS_0; + play->nextEntranceIndex = ENTR_GERUDOS_FORTRESS_EAST_EXIT; gSaveContext.nextCutsceneIndex = 0xFFF0; play->transitionType = TRANS_TYPE_CIRCLE(TCA_STARBURST, TCC_BLACK, TCS_FAST); play->transitionTrigger = TRANS_TRIGGER_START; @@ -752,7 +754,7 @@ void EnGe1_Update(Actor* thisx, PlayState* play) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 40.0f, 25.0f, 40.0f, 5); this->animFunc(this); this->actionFunc(this, play); diff --git a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h index afb57fb41..2c0c6d4f9 100644 --- a/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h +++ b/soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.h @@ -16,7 +16,7 @@ typedef enum { /* 0x04 */ GE1_TYPE_NORMAL = 4, /* 0x05 */ GE1_TYPE_VALLEY_FLOOR, /* 0x45 */ GE1_TYPE_HORSEBACK_ARCHERY = 0x45, - /* 0x46 */ GE1_TYPE_TRAINING_GROUNDS_GUARD + /* 0x46 */ GE1_TYPE_TRAINING_GROUND_GUARD } EnGe1Type; typedef enum { diff --git a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c index 0e26fca52..fd1317bdb 100644 --- a/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c +++ b/soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c @@ -10,6 +10,8 @@ #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -496,7 +498,7 @@ void EnGe2_SetupCapturePlayer(EnGe2* this, PlayState* play) { this->actor.speedXZ = 0.0f; EnGe2_ChangeAction(this, GE2_ACTION_CAPTURETURN); Player_SetCsActionWithHaltedActors(play, &this->actor, 95); - func_80078884(NA_SE_SY_FOUND); + Sfx_PlaySfxCentered(NA_SE_SY_FOUND); Message_StartTextbox(play, 0x6000, &this->actor); } @@ -514,7 +516,7 @@ void EnGe2_MaintainColliderAndSetAnimState(EnGe2* this, PlayState* play) { } void EnGe2_MoveAndBlink(EnGe2* this, PlayState* play) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (DECR(this->blinkTimer) == 0) { this->blinkTimer = Rand_S16Offset(60, 60); diff --git a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c index eb3042dd3..811e0a673 100644 --- a/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c +++ b/soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c @@ -6,6 +6,8 @@ #include "z_en_ge3.h" #include "objects/object_geldb/object_geldb.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -190,7 +192,7 @@ void EnGe3_UpdateCollision(EnGe3* this, PlayState* play) { void EnGe3_MoveAndBlink(EnGe3* this, PlayState* play) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (DECR(this->blinkTimer) == 0) { this->blinkTimer = Rand_S16Offset(60, 60); diff --git a/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c b/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c index 293f19669..af3107097 100644 --- a/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c +++ b/soh/src/overlays/actors/ovl_En_GeldB/z_en_geldb.c @@ -8,6 +8,7 @@ #include "objects/object_geldb/object_geldb.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -1383,8 +1384,8 @@ void EnGeldB_CollisionCheck(EnGeldB* this, PlayState* play) { if (key != NULL) { key->actor.world.rot.y = Math_Vec3f_Yaw(&key->actor.world.pos, &this->actor.home.pos); key->actor.speedXZ = 6.0f; - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } EnGeldB_SetupDefeated(this); @@ -1403,7 +1404,7 @@ void EnGeldB_Update(Actor* thisx, PlayState* play) { EnGeldB_CollisionCheck(this, play); if (this->actor.colChkInfo.damageEffect != GELDB_DMG_UNK_6) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 15.0f, 30.0f, 60.0f, 0x1D); this->actionFunc(this, play); this->actor.focus.pos = this->actor.world.pos; diff --git a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c index 5ca459672..2a653edc9 100644 --- a/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c +++ b/soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c @@ -10,6 +10,8 @@ #include "vt.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) diff --git a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c index 20d1c5326..4718cac79 100644 --- a/soh/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/soh/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -3,6 +3,8 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_oF1d_map/object_oF1d_map.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/OTRGlobals.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -769,8 +771,8 @@ void EnGo_FireGenericActionFunc(EnGo* this, PlayState* play) { void EnGo_CurledUp(EnGo* this, PlayState* play) { if ((DECR(this->unk_210) == 0) && EnGo_IsCameraModified(this, play)) { - Audio_PlaySoundGeneral(NA_SE_EN_GOLON_WAKE_UP, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_GOLON_WAKE_UP, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->skelAnime.playSpeed = 0.1f; this->skelAnime.playSpeed *= (this->actor.params & 0xF0) == 0x90 ? 0.5f : 1.0f; @@ -804,8 +806,8 @@ void EnGo_WakeUp(EnGo* this, PlayState* play) { } if (DECR(this->unk_212) == 0) { - Audio_PlaySoundGeneral(NA_SE_EN_GOLON_SIT_DOWN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_GOLON_SIT_DOWN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); EnGo_SetupAction(this, func_80A405CC); } else if (!EnGo_IsCameraModified(this, play)) { EnGo_ReverseAnimation(this); @@ -823,8 +825,8 @@ void func_80A40494(EnGo* this, PlayState* play) { frame += this->skelAnime.playSpeed; if (!(frame >= 0.0f)) { - Audio_PlaySoundGeneral(NA_SE_EN_DODO_M_GND, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_DODO_M_GND, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); EnGo_SpawnDust(this, 10, 0.4f, 0.1f, 16, 26.0f, 2.0f); EnGo_ReverseAnimation(this); this->skelAnime.playSpeed = 0.0f; @@ -915,8 +917,8 @@ void func_80A408D8(EnGo* this, PlayState* play) { EnGo_SetupAction(this, func_80A40494); } else if (EnGo_IsCameraModified(this, play)) { EnGo_ReverseAnimation(this); - Audio_PlaySoundGeneral(NA_SE_EN_GOLON_SIT_DOWN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_GOLON_SIT_DOWN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->skelAnime.playSpeed = 0.0f; EnGo_SetupAction(this, func_80A405CC); } @@ -1035,7 +1037,7 @@ void EnGo_Update(Actor* thisx, PlayState* play) { EnGo_UpdateShadow(this); if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); diff --git a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c index f4ef8703f..82abfca31 100644 --- a/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c +++ b/soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c @@ -3,6 +3,9 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_oF1d_map/object_oF1d_map.h" #include "soh/frame_interpolation.h" +#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -609,12 +612,12 @@ s16 EnGo2_UpdateTalkStateGoronDmtBiggoron(PlayState* play, EnGo2* this) { } case 0x3059: if (dialogState == TEXT_STATE_NONE) { - func_800F4524(&D_801333D4, NA_SE_EN_GOLON_WAKE_UP, 60); + func_800F4524(&gSfxDefaultPos, NA_SE_EN_GOLON_WAKE_UP, 60); } case 0x3054: if (dialogState == TEXT_STATE_NONE) { - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } return 1; @@ -885,7 +888,7 @@ s32 func_80A44AB0(EnGo2* this, PlayState* play) { return false; } else { if (this->collider.base.acFlags & 2) { - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->actor.flags &= ~ACTOR_FLAG_PLAY_HIT_SFX; this->collider.base.acFlags &= ~0x2; EnGo2_StopRolling(this, play); @@ -1115,7 +1118,7 @@ void EnGo2_RollForward(EnGo2* this) { } if (this->actionFunc != EnGo2_ContinueRolling) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } this->actor.speedXZ = speedXZ; @@ -1277,7 +1280,7 @@ void EnGo2_SitDownAnimation(EnGo2* this) { if ((this->actor.params & 0x1F) != GORON_DMT_BIGGORON) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_SIT_DOWN); } else { - func_800F4524(&D_801333D4, NA_SE_EN_GOLON_SIT_DOWN, 60); + func_800F4524(&gSfxDefaultPos, NA_SE_EN_GOLON_SIT_DOWN, 60); } } if (this->skelAnime.playSpeed < 0.0f) { @@ -1325,7 +1328,7 @@ void EnGo2_WakeUp(EnGo2* this, PlayState* play) { if ((this->actor.params & 0x1F) != GORON_DMT_BIGGORON) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_WAKE_UP); } else { - func_800F4524(&D_801333D4, NA_SE_EN_GOLON_WAKE_UP, 60); + func_800F4524(&gSfxDefaultPos, NA_SE_EN_GOLON_WAKE_UP, 60); } } if ((this->actor.params & 0x1F) == GORON_DMT_BIGGORON) { @@ -1510,7 +1513,7 @@ void EnGo2_BiggoronAnimation(EnGo2* this) { (this->actor.params & 0x1F) == GORON_DMT_BIGGORON && this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { if (DECR(this->animTimer) == 0) { this->animTimer = Rand_S16Offset(30, 30); - func_800F4524(&D_801333D4, NA_SE_EN_GOLON_EYE_BIG, 60); + func_800F4524(&gSfxDefaultPos, NA_SE_EN_GOLON_EYE_BIG, 60); } } } @@ -1765,8 +1768,10 @@ void EnGo2_GroundRolling(EnGo2* this, PlayState* play) { if (this->unk_59C == 0) { switch (this->actor.params & 0x1F) { case GORON_CITY_LINK: - this->goronState = 0; - this->actionFunc = EnGo2_GoronLinkStopRolling; + if (GameInteractor_Should(VB_GORON_LINK_BE_SCARED, true, this)) { + this->goronState = 0; + this->actionFunc = EnGo2_GoronLinkStopRolling; + } break; case GORON_CITY_ROLLING_BIG: EnGo2_WakeUp(this, play); @@ -1850,10 +1855,10 @@ void EnGo2_BiggoronEyedrops(EnGo2* this, PlayState* play) { if (DECR(this->animTimer)) { if (this->animTimer == 60 || this->animTimer == 120) { func_8005B1A4(GET_ACTIVE_CAM(play)); - func_800F4524(&D_801333D4, NA_SE_EV_GORON_WATER_DROP, 60); + func_800F4524(&gSfxDefaultPos, NA_SE_EV_GORON_WATER_DROP, 60); } } else { - func_800F4524(&D_801333D4, NA_SE_EN_GOLON_GOOD_BIG, 60); + func_800F4524(&gSfxDefaultPos, NA_SE_EN_GOLON_GOOD_BIG, 60); Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_6); Message_ContinueTextbox(play, 0x305A); this->eyeMouthTexState = 3; @@ -1916,8 +1921,10 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { switch (this->goronState) { case 0: // Wake up if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { - EnGo2_GoronFireCamera(this, play); - play->msgCtx.msgMode = MSGMODE_PAUSED; + if (GameInteractor_Should(VB_PLAY_GORON_FREE_CS, true)) { + EnGo2_GoronFireCamera(this, play); + play->msgCtx.msgMode = MSGMODE_PAUSED; + } Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENGO2_ANIM_2); this->waypoint = 1; this->skelAnime.playSpeed = 2.0f; @@ -1936,7 +1943,9 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { (f32)((Math_SinS(this->actor.world.rot.y) * -30.0f) + this->actor.world.pos.x); player->actor.world.pos.z = (f32)((Math_CosS(this->actor.world.rot.y) * -30.0f) + this->actor.world.pos.z); - Player_SetCsActionWithHaltedActors(play, &this->actor, 8); + if (GameInteractor_Should(VB_PLAY_GORON_FREE_CS, true)) { + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); + } Audio_PlayFanfare(NA_BGM_APPEAR); } break; @@ -1945,7 +1954,7 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { if (!(this->animTimer % 8)) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_MORIBLIN_WALK); } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } else { this->animTimer = 0; this->actor.speedXZ = 0.0f; @@ -1972,8 +1981,10 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) { } case 4: // Finalize walking away Message_CloseTextbox(play); - EnGo2_GoronFireClearCamera(this, play); - Player_SetCsActionWithHaltedActors(play, &this->actor, 7); + if (GameInteractor_Should(VB_PLAY_GORON_FREE_CS, true)) { + EnGo2_GoronFireClearCamera(this, play); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); + } Actor_Kill(&this->actor); break; case 1: diff --git a/soh/src/overlays/actors/ovl_En_Goma/z_en_goma.c b/soh/src/overlays/actors/ovl_En_Goma/z_en_goma.c index efaaed84c..11016dcc7 100644 --- a/soh/src/overlays/actors/ovl_En_Goma/z_en_goma.c +++ b/soh/src/overlays/actors/ovl_En_Goma/z_en_goma.c @@ -4,6 +4,7 @@ #include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -424,7 +425,7 @@ void EnGoma_Dead(EnGoma* this, PlayState* play) { parent->childrenGohmaState[this->actor.params] = -1; } - Audio_PlaySoundGeneral(NA_SE_EN_EXTINCT, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_EXTINCT, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Actor_Kill(&this->actor); Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, 0x30); } @@ -715,7 +716,7 @@ void EnGoma_Update(Actor* thisx, PlayState* play) { } this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); this->actor.world.pos.x = this->actor.world.pos.x + this->shieldKnockbackVel.x; this->actor.world.pos.z = this->actor.world.pos.z + this->shieldKnockbackVel.z; Math_ApproachZeroF(&this->shieldKnockbackVel.x, 1.0f, 3.0f); diff --git a/soh/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c b/soh/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c index 8b52be1fd..72adefe3b 100644 --- a/soh/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c +++ b/soh/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c @@ -300,7 +300,7 @@ s32 EnGoroiwa_MoveAndFall(EnGoroiwa* this, PlayState* play) { Vec3s* nextPointPos; Math_StepToF(&this->actor.speedXZ, R_EN_GOROIWA_SPEED * 0.01f, 0.3f); - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); path = &play->setupPathList[this->actor.params & 0xFF]; nextPointPos = (Vec3s*)SEGMENTED_TO_VIRTUAL(path->points) + this->nextWaypoint; result = true; diff --git a/soh/src/overlays/actors/ovl_En_Gs/z_en_gs.c b/soh/src/overlays/actors/ovl_En_Gs/z_en_gs.c index 64329bb04..2bb7534d1 100644 --- a/soh/src/overlays/actors/ovl_En_Gs/z_en_gs.c +++ b/soh/src/overlays/actors/ovl_En_Gs/z_en_gs.c @@ -8,6 +8,7 @@ #include "objects/object_gs/object_gs.h" #include "overlays/actors/ovl_En_Elf/z_en_elf.h" #include "objects/gameplay_keep/gameplay_keep.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -149,8 +150,7 @@ void func_80A4E470(EnGs* this, PlayState* play) { func_8010BD58(play, OCARINA_ACTION_FREE_PLAY); this->unk_19D |= 1; } - - } else if (this->unk_19D & 1) { + } else if (GameInteractor_Should(VB_SPAWN_GOSSIP_STONE_FAIRY, this->unk_19D & 1, this)) { if (play->msgCtx.ocarinaMode == OCARINA_MODE_04) { if ((play->msgCtx.unk_E3F2 == OCARINA_SONG_SARIAS) || (play->msgCtx.unk_E3F2 == OCARINA_SONG_EPONAS) || @@ -326,14 +326,14 @@ void func_80A4ED34(EnGs* this, PlayState* play) { if (this->unk_200 < 20) { Color_RGBA8_Copy(&this->flashColor, &flashRed); if ((this->unk_200 % 20) == 7) { - Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_E, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_E, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } else { Color_RGBA8_Copy(&this->flashColor, &flashBlue); if ((this->unk_200 % 20) == 7) { - Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } } @@ -382,7 +382,7 @@ void func_80A4ED34(EnGs* this, PlayState* play) { func_8002F974(&this->actor, NA_SE_EV_STONE_LAUNCH - SFX_FLAG); } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->actor.yDistToPlayer < -12000.0f) { Actor_Kill(&this->actor); } diff --git a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c index 2d09ea016..e69e4e610 100644 --- a/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c +++ b/soh/src/overlays/actors/ovl_En_Guest/z_en_guest.c @@ -9,6 +9,7 @@ #include "objects/object_boj/object_boj.h" #include "vt.h" #include +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) diff --git a/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c b/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c index 5b5a97a08..90d47b098 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c +++ b/soh/src/overlays/actors/ovl_En_Heishi1/z_en_heishi1.c @@ -7,6 +7,7 @@ #include "z_en_heishi1.h" #include "objects/object_sd/object_sd.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -389,7 +390,7 @@ void EnHeishi1_WaitNight(EnHeishi1* this, PlayState* play) { if (this->actor.xzDistToPlayer < 100.0f) { Message_StartTextbox(play, 0x702D, &this->actor); - func_80078884(NA_SE_SY_FOUND); + Sfx_PlaySfxCentered(NA_SE_SY_FOUND); osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST); // "Discovered!" Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->actionFunc = EnHeishi1_SetupKick; @@ -472,7 +473,7 @@ void EnHeishi1_Update(Actor* thisx, PlayState* play) { this->linkDetected = false; // this 60 unit height check is so the player doesnt get caught when on the upper path if (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 60.0f) { - func_80078884(NA_SE_SY_FOUND); + Sfx_PlaySfxCentered(NA_SE_SY_FOUND); // "Discovered!" osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST); Player_SetCsActionWithHaltedActors(play, &this->actor, 1); diff --git a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c index 89dcc6808..89fd574d0 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c +++ b/soh/src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.c @@ -11,6 +11,7 @@ #include "overlays/actors/ovl_Bg_Gate_Shutter/z_bg_gate_shutter.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "overlays/actors/ovl_Bg_Spot15_Saku/z_bg_spot15_saku.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -407,7 +408,7 @@ void func_80A53AD4(EnHeishi2* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, play)) { exchangeItemId = func_8002F368(play); if (exchangeItemId == EXCH_ITEM_LETTER_ZELDA) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); player->actor.textId = 0x2010; this->unk_300 = TEXT_STATE_EVENT; this->actionFunc = func_80A53C0C; @@ -728,7 +729,7 @@ void func_80A5475C(EnHeishi2* this, PlayState* play) { if (this->unk_300 == TEXT_STATE_CHOICE) { this->unk_309 = 1; - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); this->actionFunc = func_80A540C0; } return; @@ -783,7 +784,7 @@ void EnHeishi2_Update(Actor* thisx, PlayState* play) { } } this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); switch (this->type) { case 6: break; diff --git a/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c b/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c index 665a06470..372075806 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c +++ b/soh/src/overlays/actors/ovl_En_Heishi3/z_en_heishi3.c @@ -7,6 +7,7 @@ #include "z_en_heishi3.h" #include "objects/object_sd/object_sd.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS 0 @@ -135,7 +136,7 @@ void EnHeishi3_StandSentinelInGrounds(EnHeishi3* this, PlayState* play) { (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 100.0f) && (sPlayerCaught == 0)) { sPlayerCaught = 1; Message_StartTextbox(play, 0x702D, &this->actor); - func_80078884(NA_SE_SY_FOUND); + Sfx_PlaySfxCentered(NA_SE_SY_FOUND); osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST); // "Discovered!" Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->actionFunc = EnHeishi3_CatchStart; @@ -163,7 +164,7 @@ void EnHeishi3_StandSentinelInCastle(EnHeishi3* this, PlayState* play) { } sPlayerCaught = 1; Message_StartTextbox(play, 0x702D, &this->actor); - func_80078884(NA_SE_SY_FOUND); + Sfx_PlaySfxCentered(NA_SE_SY_FOUND); osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 発見! ☆☆☆☆☆ \n" VT_RST); // "Discovered!" Player_SetCsActionWithHaltedActors(play, &this->actor, 1); this->actionFunc = EnHeishi3_CatchStart; @@ -225,7 +226,7 @@ void EnHeishi3_Update(Actor* thisx, PlayState* play) { } this->actionFunc(this, play); this->actor.shape.rot = this->actor.world.rot; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 50.0f, 0x1C); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c index 947a65c99..f118a55ec 100644 --- a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c +++ b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c @@ -1,6 +1,8 @@ #include "z_en_heishi4.h" #include "objects/object_sd/object_sd.h" #include "vt.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -358,9 +360,9 @@ void EnHeishi4_MarketSneak(EnHeishi4* this, PlayState* play) { switch (play->msgCtx.choiceIndex) { case 0: //yes if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES) != RO_GENERIC_OFF){ - play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_HYRULE_FIELD_7); // Market Entrance -> HF + play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN); // Market Entrance -> HF } else { - play->nextEntranceIndex = ENTR_HYRULE_FIELD_0; // HF Near bridge (OoT cutscene entrance) to not fall in the water + play->nextEntranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; // HF Near bridge (OoT cutscene entrance) to not fall in the water } play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_CIRCLE(TCA_STARBURST, TCC_WHITE, TCS_FAST); @@ -394,7 +396,7 @@ void EnHeishi4_Update(Actor* thisx, PlayState* play) { } this->unk_27E += 1; this->actionFunc(this, play); - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); Actor_UpdateBgCheckInfo(play, thisx, 10.0f, 10.0f, 30.0f, 0x1D); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c b/soh/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c index 93df97cd3..36a7ae115 100644 --- a/soh/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c +++ b/soh/src/overlays/actors/ovl_En_Hintnuts/z_en_hintnuts.c @@ -7,6 +7,7 @@ #include "z_en_hintnuts.h" #include "objects/object_hintnuts/object_hintnuts.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -214,7 +215,7 @@ void EnHintnuts_SetupFreeze(EnHintnuts* this) { this->animFlagAndTimer = 0; Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_FAINT); if (sPuzzleCounter == -3) { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); sPuzzleCounter = -4; } this->actionFunc = EnHintnuts_Freeze; @@ -487,7 +488,7 @@ void EnHintnuts_Update(Actor* thisx, PlayState* play) { EnHintnuts_ColliderCheck(this, play); this->actionFunc(this, play); if (this->actionFunc != EnHintnuts_Freeze && this->actionFunc != EnHintnuts_BeginFreeze) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, this->collider.dim.radius, this->collider.dim.height, 0x1D); } diff --git a/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.c b/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.c index f996cdd5d..f40668343 100644 --- a/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.c +++ b/soh/src/overlays/actors/ovl_En_Holl/z_en_holl.c @@ -125,7 +125,7 @@ void func_80A58DD4(EnHoll* this, PlayState* play) { f32 absZ; s32 transitionActorIdx; - func_8002DBD0(&this->actor, &vec, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &vec, &player->actor.world.pos); this->side = (vec.z < 0.0f) ? 0 : 1; absZ = fabsf(vec.z); if (vec.y > PLANE_Y_MIN && vec.y < PLANE_Y_MAX && fabsf(vec.x) < PLANE_HALFWIDTH && @@ -162,7 +162,7 @@ void func_80A59014(EnHoll* this, PlayState* play) { f32 planeHalfWidth; f32 absZ; - func_8002DBD0(&this->actor, &vec, (useViewEye) ? &play->view.eye : &player->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &vec, (useViewEye) ? &play->view.eye : &player->actor.world.pos); planeHalfWidth = (((this->actor.params >> 6) & 7) == 6) ? PLANE_HALFWIDTH : PLANE_HALFWIDTH_2; temp = EnHoll_IsKokiriSetup8(); @@ -278,7 +278,7 @@ void func_80A59618(EnHoll* this, PlayState* play) { this->unk_14F = 0; } } else { - func_8002DBD0(&this->actor, &vec, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->actor, &vec, &player->actor.world.pos); absZ = fabsf(vec.z); if (PLANE_Y_MIN < vec.y && vec.y < PLANE_Y_MAX && fabsf(vec.x) < PLANE_HALFWIDTH_2 && absZ < 100.0f) { this->unk_14F = 1; diff --git a/soh/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.c b/soh/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.c index 24a389685..6c3745b62 100644 --- a/soh/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.c +++ b/soh/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.c @@ -413,12 +413,12 @@ void EnHonotrap_FlameChase(EnHonotrap* this, PlayState* play) { Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0x300); Math_StepToF(&this->actor.speedXZ, 3.0f, 0.1f); this->actor.gravity = (-this->actor.yDistToPlayer < 10.0f) ? 0.08f : -0.08f; - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); if (this->actor.velocity.y > 1.0f) { this->actor.velocity.y = 1.0f; } this->actor.velocity.y *= 0.95f; - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 7.0f, 10.0f, 0.0f, 0x1D); if (this->collider.cyl.base.atFlags & AT_BOUNCED) { Player* player = GET_PLAYER(play); @@ -447,7 +447,7 @@ void EnHonotrap_FlameVanish(EnHonotrap* this, PlayState* play) { s32 ready = Math_StepToF(&this->actor.scale.x, 0.0001f, 0.00015f); this->actor.scale.z = this->actor.scale.y = this->actor.scale.x; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 7.0f, 10.0f, 0.0f, 0x1D); if (ready) { Actor_Kill(&this->actor); diff --git a/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c b/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c index 82e5a70c9..73cfd07cc 100644 --- a/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c +++ b/soh/src/overlays/actors/ovl_En_Horse/z_en_horse.c @@ -611,8 +611,8 @@ void EnHorse_PlayWalkingSound(EnHorse* this) { return; } - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_WALK, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_WALK, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (++this->soundTimer > 1) { this->soundTimer = 0; } @@ -620,11 +620,11 @@ void EnHorse_PlayWalkingSound(EnHorse* this) { } void EnHorse_PlayTrottingSound(EnHorse* this) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } void EnHorse_PlayGallopingSound(EnHorse* this) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } f32 EnHorse_SlopeSpeedMultiplier(EnHorse* this, PlayState* play) { @@ -659,13 +659,13 @@ void EnHorse_IdleAnimSounds(EnHorse* this, PlayState* play) { (this->curFrame > 28.0f && this->type == HORSE_HNI)) && !(this->stateFlags & ENHORSE_SANDDUST_SOUND)) { this->stateFlags |= ENHORSE_SANDDUST_SOUND; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (this->animationIdx == ENHORSE_ANIM_REARING && this->curFrame > 25.0f && !(this->stateFlags & ENHORSE_LAND2_SOUND)) { this->stateFlags |= ENHORSE_LAND2_SOUND; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } @@ -1076,8 +1076,8 @@ void EnHorse_StartMountedIdle(EnHorse* this) { if ((this->curFrame > 35.0f && this->type == HORSE_EPONA) || (this->curFrame > 28.0f && this->type == HORSE_HNI)) { if (!(this->stateFlags & ENHORSE_SANDDUST_SOUND)) { this->stateFlags |= ENHORSE_SANDDUST_SOUND; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } curFrame = this->skin.skelAnime.curFrame; @@ -1129,7 +1129,7 @@ void EnHorse_MountedIdleWhinney(EnHorse* this) { Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -1401,7 +1401,7 @@ void EnHorse_StartRearing(EnHorse* this) { this->stateFlags &= ~ENHORSE_LAND2_SOUND; this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } func_800AA000(0.0f, 180, 20, 100); Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, @@ -1416,8 +1416,8 @@ void EnHorse_MountedRearing(EnHorse* this, PlayState* play) { if (this->curFrame > 25.0f) { if (!(this->stateFlags & ENHORSE_LAND2_SOUND)) { this->stateFlags |= ENHORSE_LAND2_SOUND; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); func_800AA000(0, 180, 20, 100); } } @@ -1450,7 +1450,7 @@ void EnHorse_StartBraking(EnHorse* this, PlayState* play) { this->action = ENHORSE_ACT_STOPPING; this->animationIdx = ENHORSE_ANIM_STOPPING; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SLIP, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SLIP, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.5f, 0.0f, Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); @@ -1471,7 +1471,7 @@ void EnHorse_Stopping(EnHorse* this, PlayState* play) { if (Rand_ZeroOne() > 0.5) { this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } func_800AA000(0.0f, 180, 20, 100); this->stateFlags &= ~ENHORSE_STOPPING_NEIGH_SOUND; @@ -1602,7 +1602,7 @@ void EnHorse_StartLowJump(EnHorse* this, PlayState* play) { y = jointTable->y; this->riderPos.y -= y * 0.01f; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_JUMP, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_JUMP, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_800AA000(0.0f, 170, 10, 10); } @@ -1636,8 +1636,8 @@ void EnHorse_LowJump(EnHorse* this, PlayState* play) { if (SkelAnime_Update(&this->skin.skelAnime) || (curFrame > 17.0f && this->actor.world.pos.y < this->actor.floorHeight - this->actor.velocity.y + 80.0f)) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); func_800AA000(0.0f, 255, 10, 80); this->stateFlags &= ~ENHORSE_JUMPING; this->actor.gravity = -3.5f; @@ -1676,7 +1676,7 @@ void EnHorse_StartHighJump(EnHorse* this, PlayState* play) { this->riderPos.y -= y * 0.01f; this->stateFlags |= ENHORSE_CALC_RIDER_POS; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_JUMP, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_JUMP, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_800AA000(0.0f, 170, 10, 10); } @@ -1711,8 +1711,8 @@ void EnHorse_HighJump(EnHorse* this, PlayState* play) { if (SkelAnime_Update(&this->skin.skelAnime) || (curFrame > 23.0f && this->actor.world.pos.y < this->actor.floorHeight - this->actor.velocity.y + 80.0f)) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); func_800AA000(0.0f, 255, 10, 80); this->stateFlags &= ~ENHORSE_JUMPING; this->actor.gravity = -3.5f; @@ -1740,8 +1740,8 @@ void EnHorse_Inactive(EnHorse* this, PlayState* play2) { if (DREG(53) != 0 && this->type == HORSE_EPONA) { DREG(53) = 0; if (EnHorse_Spawn(this, play) != 0) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->stateFlags &= ~ENHORSE_INACTIVE; gSaveContext.horseData.scene = play->sceneNum; @@ -1774,12 +1774,12 @@ void EnHorse_PlayIdleAnimation(EnHorse* this, s32 anim, f32 morphFrames, f32 sta } else if (this->animationIdx == ENHORSE_ANIM_WHINNEY) { this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else if (this->animationIdx == ENHORSE_ANIM_REARING) { this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } this->stateFlags &= ~ENHORSE_LAND2_SOUND; } @@ -1814,8 +1814,8 @@ void EnHorse_Idle(EnHorse* this, PlayState* play) { DREG(53) = 0; if (!func_80A5BBBC(play, this, &this->actor.world.pos)) { if (EnHorse_Spawn(this, play)) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->followTimer = 0; EnHorse_SetFollowAnimation(this, play); Camera_SetParam(play->cameraPtrs[0], 8, this); @@ -1823,8 +1823,8 @@ void EnHorse_Idle(EnHorse* this, PlayState* play) { Camera_SetCameraData(play->cameraPtrs[0], 4, NULL, NULL, 0x51, 0, 0); } } else { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->followTimer = 0; EnHorse_StartMovingAnimation(this, 6, -3.0f, 0.0f); } @@ -1933,8 +1933,8 @@ void EnHorse_FollowPlayer(EnHorse* this, PlayState* play) { if (this->curFrame > 25.0f) { if (!(this->stateFlags & ENHORSE_LAND2_SOUND)) { this->stateFlags |= ENHORSE_LAND2_SOUND; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } } else { @@ -1961,7 +1961,7 @@ void EnHorse_FollowPlayer(EnHorse* this, PlayState* play) { this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -1989,7 +1989,7 @@ void EnHorse_InitIngoHorse(EnHorse* this) { EnHorse_UpdateIngoHorseAnim(this); this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_IT_INGO_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_INGO_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -2042,10 +2042,10 @@ void EnHorse_UpdateIngoHorseAnim(EnHorse* this) { animSpeed = this->actor.speedXZ * 0.5f; } else if (this->animationIdx == ENHORSE_ANIM_TROT) { animSpeed = this->actor.speedXZ * 0.25f; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (this->animationIdx == ENHORSE_ANIM_GALLOP) { animSpeed = this->actor.speedXZ * 0.2f; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { animSpeed = 1.0f; } @@ -2161,7 +2161,7 @@ void EnHorse_CsPlayHighJumpAnim(EnHorse* this, PlayState* play) { this->riderPos.y -= y * 0.01f; this->stateFlags |= ENHORSE_CALC_RIDER_POS; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_JUMP, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_JUMP, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_800AA000(0.0f, 170, 10, 10); } @@ -2205,8 +2205,8 @@ void EnHorse_CsJump(EnHorse* this, PlayState* play, CsCmdActorCue* action) { f32 y; this->cutsceneFlags |= 1; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); func_800AA000(0.0f, 255, 10, 80); this->stateFlags &= ~ENHORSE_JUMPING; this->actor.gravity = -3.5f; @@ -2230,7 +2230,7 @@ void EnHorse_CsRearingInit(EnHorse* this, PlayState* play, CsCmdActorCue* action this->stateFlags &= ~ENHORSE_LAND2_SOUND; this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); @@ -2241,8 +2241,8 @@ void EnHorse_CsRearing(EnHorse* this, PlayState* play, CsCmdActorCue* action) { if (this->curFrame > 25.0f) { if (!(this->stateFlags & ENHORSE_LAND2_SOUND)) { this->stateFlags |= ENHORSE_LAND2_SOUND; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } if (SkelAnime_Update(&this->skin.skelAnime)) { @@ -2309,7 +2309,7 @@ void EnHorse_CsWarpRearingInit(EnHorse* this, PlayState* play, CsCmdActorCue* ac this->stateFlags &= ~ENHORSE_LAND2_SOUND; this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); @@ -2320,8 +2320,8 @@ void EnHorse_CsWarpRearing(EnHorse* this, PlayState* play, CsCmdActorCue* action if (this->curFrame > 25.0f) { if (!(this->stateFlags & ENHORSE_LAND2_SOUND)) { this->stateFlags |= ENHORSE_LAND2_SOUND; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } if (SkelAnime_Update(&this->skin.skelAnime)) { @@ -2471,11 +2471,11 @@ void EnHorse_UpdateHbaAnim(EnHorse* this) { animSpeed = this->actor.speedXZ * 0.5f; } else if (this->animationIdx == ENHORSE_ANIM_TROT) { animSpeed = this->actor.speedXZ * 0.25f; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_800AA000(0.0f, 60, 8, 255); } else if (this->animationIdx == ENHORSE_ANIM_GALLOP) { animSpeed = this->actor.speedXZ * 0.2f; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_800AA000(0.0f, 120, 8, 255); } else { animSpeed = 1.0f; @@ -2577,8 +2577,8 @@ void EnHorse_FleePlayer(EnHorse* this, PlayState* play) { if (DREG(53) || this->type == HORSE_HNI) { EnHorse_StartIdleRidable(this); - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } distToHome = Math3D_Vec3f_DistXYZ(&this->actor.home.pos, &this->actor.world.pos); @@ -2688,8 +2688,8 @@ void EnHorse_FleePlayer(EnHorse* this, PlayState* play) { this->animationIdx = ENHORSE_ANIM_WHINNEY; this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_21C, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, @@ -2745,9 +2745,9 @@ void EnHorse_BridgeJumpInit(EnHorse* this, PlayState* play) { Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_JUMP, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_JUMP, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_800AA000(0.0f, 170, 10, 10); this->postDrawFunc = NULL; } @@ -2796,8 +2796,8 @@ void EnHorse_CheckBridgeJumpLanding(EnHorse* this, PlayState* play) { this->actor.world.pos.y = sBridgeJumps[this->bridgeJumpIdx].pos.y; func_80028A54(play, 25.0f, &this->actor.world.pos); EnHorse_JumpLanding(this, play); - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); func_800AA000(0.0f, 255, 10, 80); } } @@ -3127,8 +3127,8 @@ void EnHorse_UpdateBgCheckInfo(EnHorse* this, PlayState* play) { if (this->actor.bgCheckFlags & 8 && Math_CosS(this->actor.wallYaw - ((void)0, this->actor.world).rot.y) < -0.3f) { if (this->actor.speedXZ > 4.0f) { this->actor.speedXZ -= 1.0f; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } @@ -3333,8 +3333,8 @@ void EnHorse_CheckBoost(EnHorse* thisx, PlayState* play2) { this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { if (Rand_ZeroOne() < 0.1f) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } } @@ -3351,7 +3351,7 @@ void EnHorse_RegenBoost(EnHorse* this, PlayState* play) { this->numBoosts = this->numBoosts + 1; if (!EN_HORSE_CHECK_4(this)) { - Audio_PlaySoundGeneral(NA_SE_SY_CARROT_RECOVER, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CARROT_RECOVER, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } if (this->numBoosts < 6) { @@ -3367,7 +3367,7 @@ void EnHorse_RegenBoost(EnHorse* this, PlayState* play) { this->numBoosts = 6; if (!EN_HORSE_CHECK_4(this)) { - Audio_PlaySoundGeneral(NA_SE_SY_CARROT_RECOVER, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CARROT_RECOVER, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } } @@ -3375,7 +3375,7 @@ void EnHorse_RegenBoost(EnHorse* this, PlayState* play) { if (this->boostTimer == 8 && Rand_ZeroOne() < 0.25f) { this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } play->interfaceCtx.numHorseBoosts = this->numBoosts; @@ -3498,7 +3498,7 @@ void EnHorse_Update(Actor* thisx, PlayState* play2) { if (this->playerControlled == true) { EnHorse_RegenBoost(this, play); } - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); if (this->action == ENHORSE_ACT_INGO_RACE) { if (this->rider != NULL) { this->rider->world.pos.x = thisx->world.pos.x; @@ -3516,7 +3516,7 @@ void EnHorse_Update(Actor* thisx, PlayState* play2) { if (this->jntSph.base.acFlags & 2) { this->unk_21C = this->unk_228; if (this->stateFlags & ENHORSE_DRAW) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_21C, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } if (this->action != ENHORSE_ACT_INGO_RACE) { @@ -3581,7 +3581,7 @@ void EnHorse_Update(Actor* thisx, PlayState* play2) { this->cyl1.base.atFlags &= ~1; } - if (gSaveContext.entranceIndex != ENTR_LON_LON_RANCH_0 || gSaveContext.sceneSetupIndex != 9) { + if (gSaveContext.entranceIndex != ENTR_LON_LON_RANCH_ENTRANCE || gSaveContext.sceneSetupIndex != 9) { if (this->dustFlags & 1) { this->dustFlags &= ~1; func_800287AC(play, &this->frontRightHoof, &dustVel, &dustAcc, EnHorse_RandInt(100) + 200, diff --git a/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c b/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c index 0935eac86..5ed12cf45 100644 --- a/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c +++ b/soh/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c @@ -152,7 +152,7 @@ s32 EnHorseGameCheck_UpdateIngoRace(EnHorseGameCheckBase* base, PlayState* play) ingoHorse->inRace = 1; this->startFlags |= INGORACE_INGO_MOVE; - Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } this->startTimer++; @@ -184,7 +184,7 @@ s32 EnHorseGameCheck_UpdateIngoRace(EnHorseGameCheckBase* base, PlayState* play) this->result = INGORACE_PLAYER_WIN; this->finishTimer = 55; Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_HORSE_GOAL); - Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } for (i = 0; i < 3; i++) { this->playerCheck[i] = 0; @@ -199,7 +199,7 @@ s32 EnHorseGameCheck_UpdateIngoRace(EnHorseGameCheckBase* base, PlayState* play) this->finishTimer = 70; ingoHorse->stateFlags |= ENHORSE_INGO_WON; Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_HORSE_GOAL); - Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } for (i = 0; i < 3; i++) { this->ingoCheck[i] = 0; @@ -307,7 +307,7 @@ void EnHorseGameCheck_FinishMalonRace(EnHorseGameCheckMalonRace* this, PlayState // "not supported" osSyncPrintf("En_HGC_Spot20_Ta_end():対応せず\n"); gSaveContext.cutsceneIndex = 0; - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; play->transitionType = TRANS_TYPE_CIRCLE(TCA_STARBURST, TCC_WHITE, TCS_FAST); play->transitionTrigger = TRANS_TRIGGER_START; } @@ -335,7 +335,7 @@ s32 EnHorseGameCheck_UpdateMalonRace(EnHorseGameCheckBase* base, PlayState* play horse->inRace = 1; } else if ((this->startTimer > 81) && !(this->raceFlags & MALONRACE_START_SFX)) { this->raceFlags |= MALONRACE_START_SFX; - Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } this->startTimer++; @@ -377,7 +377,7 @@ s32 EnHorseGameCheck_UpdateMalonRace(EnHorseGameCheckBase* base, PlayState* play } else if (this->fenceCheck[15] == 1) { this->lapCount = 2; Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_HORSE_GOAL); - Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_START_SHOT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->result = MALONRACE_SUCCESS; this->finishTimer = 70; gSaveContext.timer1State = 0xF; diff --git a/soh/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.c b/soh/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.c index d36c1c690..ac61462d7 100644 --- a/soh/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.c +++ b/soh/src/overlays/actors/ovl_En_Horse_Ganon/z_en_horse_ganon.c @@ -155,8 +155,8 @@ void func_80A686A8(EnHorseGanon* this, PlayState* play) { void func_80A68870(EnHorseGanon* this) { if ((this->skin.skelAnime.curFrame > D_80A692B8[this->soundCount]) && (this->soundCount != 0 || !(this->skin.skelAnime.curFrame > D_80A692B8[1]))) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_WALK, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_WALK, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->soundCount++; if (this->soundCount >= 2) { @@ -236,10 +236,10 @@ void func_80A68B20(EnHorseGanon* this) { sp30 = this->actor.speedXZ / 3.0f; } else if (this->currentAnimation == 3) { sp30 = this->actor.speedXZ / 5.0f; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (this->currentAnimation == 4) { sp30 = this->actor.speedXZ / 7.0f; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { sp30 = 1.0f; } @@ -289,7 +289,7 @@ void EnHorseGanon_Update(Actor* thisx, PlayState* play) { s32 pad; sActionFuncs[this->action](this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 55.0f, 100.0f, 29); this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 70.0f; diff --git a/soh/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c b/soh/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c index b502a11e4..a4ea35ed5 100644 --- a/soh/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c +++ b/soh/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c @@ -90,8 +90,8 @@ void func_80A693D0(EnHorseLinkChild* this) { if ((this->skin.skelAnime.curFrame > D_80A6AF5C[this->unk_1F0]) && !((this->unk_1F0 == 0) && (this->skin.skelAnime.curFrame > D_80A6AF5C[1]))) { - Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_WALK, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_WALK, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->unk_1F0++; if (this->unk_1F0 >= ARRAY_COUNT(D_80A6AF5C)) { this->unk_1F0 = 0; @@ -104,15 +104,15 @@ void func_80A6948C(EnHorseLinkChild* this) { func_80A693D0(this); } else if (this->skin.skelAnime.curFrame == 0.0f) { if ((this->animationIdx == 3) || (this->animationIdx == 4)) { - Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (this->animationIdx == 1) { if (Rand_ZeroOne() > 0.5f) { - Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_GROAN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_GROAN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_NEIGH, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } } @@ -353,8 +353,8 @@ void func_80A6A068(EnHorseLinkChild* this, PlayState* play) { distFromLink = Actor_WorldDistXZToActor(&this->actor, &player->actor); if (gSaveContext.entranceIndex == ENTR_LON_LON_RANCH_1) { - Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_NEIGH, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); func_80A6A724(this); return; } @@ -445,8 +445,8 @@ void func_80A6A5A4(EnHorseLinkChild* this, PlayState* play) { if (DREG(53) != 0) { DREG(53) = 0; - Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_NEIGH, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_KID_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); func_80A6A724(this); } else { this->actor.speedXZ = 0.0f; @@ -555,7 +555,7 @@ void EnHorseLinkChild_Update(Actor* thisx, PlayState* play) { s32 pad; sActionFuncs[this->action](this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 55.0f, 100.0f, 0x1D); if ((play->sceneNum == SCENE_LON_LON_RANCH) && (this->actor.world.pos.z < -2400.0f)) { diff --git a/soh/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c b/soh/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c index 0aa46f9c2..ead91b06b 100644 --- a/soh/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c +++ b/soh/src/overlays/actors/ovl_En_Horse_Normal/z_en_horse_normal.c @@ -151,8 +151,8 @@ void func_80A6B250(EnHorseNormal* this) { if (D_80A6D4C0[this->unk_200] < this->skin.skelAnime.curFrame && ((this->unk_200 != 0) || !(D_80A6D4C0[1] < this->skin.skelAnime.curFrame))) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_WALK, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_WALK, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->unk_200++; if (this->unk_200 >= ARRAY_COUNT(D_80A6D4C0)) { this->unk_200 = 0; @@ -344,9 +344,9 @@ void func_80A6BC48(EnHorseNormal* this) { void func_80A6BCEC(EnHorseNormal* this) { if (this->animationIdx == 5) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (this->animationIdx == 6) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -355,12 +355,12 @@ void func_80A6BD7C(EnHorseNormal* this) { if (this->animationIdx == 0 && frame > 28.0f && !(this->unk_1E4 & 1)) { this->unk_1E4 |= 1; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (this->animationIdx == 3 && frame > 25.0f && !(this->unk_1E4 & 2)) { this->unk_1E4 |= 2; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } @@ -429,9 +429,9 @@ void EnHorseNormal_Wander(EnHorseNormal* this, PlayState* play) { this->unk_1E4 &= ~1; this->unk_1E4 &= ~2; if (phi_t0 == 1) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (phi_t0 == 3) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { func_80A6BCEC(this); } @@ -458,9 +458,9 @@ void EnHorseNormal_Wander(EnHorseNormal* this, PlayState* play) { this->unk_1E4 &= ~1; this->unk_1E4 &= ~2; if (phi_t0 == 1) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (phi_t0 == 3) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { func_80A6BCEC(this); } @@ -495,10 +495,10 @@ void EnHorseNormal_Wait(EnHorseNormal* this, PlayState* play) { this->animationIdx = 0; } else if (rand < 0.8f) { this->animationIdx = 1; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { this->animationIdx = 3; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } Animation_Change(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, @@ -529,11 +529,11 @@ void EnHorseNormal_WaitClone(EnHorseNormal* this, PlayState* play) { } else if (rand < 0.8f) { this->animationIdx = 1; this->unk_1E4 |= 0x20; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_204, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { this->animationIdx = 3; this->unk_1E4 |= 0x20; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_204, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } Animation_Change(&this->skin.skelAnime, sAnimations[this->animationIdx], func_80A6B30C(this), 0.0f, @@ -570,7 +570,7 @@ void EnHorseNormal_Update(Actor* thisx, PlayState* play) { s32 pad; sActionFuncs[this->action](this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 35.0f, 100.0f, 0x1D); if (play->sceneNum == SCENE_LON_LON_RANCH && this->actor.world.pos.z < -2400.0f) { this->actor.world.pos.z = -2400.0f; @@ -620,16 +620,16 @@ void func_80A6CC88(PlayState* play, EnHorseNormal* this, Vec3f* arg2) { if (this->animationIdx == 0 && curFrame > 28.0f && !(this->unk_1E4 & 8)) { this->unk_1E4 |= 8; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->unk_1E8, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_SANDDUST, &this->unk_1E8, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (this->animationIdx == 3 && curFrame > 25.0f && !(this->unk_1E4 & 0x10)) { this->unk_1E4 |= 0x10; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->unk_1E8, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_LAND2, &this->unk_1E8, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (this->animationIdx == 3 && this->unk_1E4 & 0x20) { this->unk_1E4 &= ~0x20; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_1F4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->unk_1F4, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (this->animationIdx == 1 && this->unk_1E4 & 0x20) { this->unk_1E4 &= ~0x20; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_1F4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->unk_1F4, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c b/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c index 869f03e84..9eb87644f 100644 --- a/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c +++ b/soh/src/overlays/actors/ovl_En_Horse_Zelda/z_en_horse_zelda.c @@ -200,7 +200,7 @@ void func_80A6DD14(EnHorseZelda* this) { this->action = 1; this->animationIndex = 0; sp34 = this->actor.speedXZ / 6.0f; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_RUN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->animationIndex], splaySpeeds[this->animationIndex] * sp34 * 1.5f, 0.0f, Animation_GetLastFrame(sAnimationHeaders[this->animationIndex]), ANIMMODE_ONCE, 0.0f); @@ -233,7 +233,7 @@ void EnHorseZelda_Update(Actor* thisx, PlayState* play) { sActionFuncs[this->action](this, play); this->actor.speedXZ = 0.0f; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 55.0f, 100.0f, 0x1D); this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 70.0f; diff --git a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c index af9f83fc2..fcf06de4e 100644 --- a/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c +++ b/soh/src/overlays/actors/ovl_En_Hs/z_en_hs.c @@ -7,6 +7,9 @@ #include "z_en_hs.h" #include "vt.h" #include "objects/object_hs/object_hs.h" +#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -221,7 +224,7 @@ void func_80A6E9AC(EnHs* this, PlayState* play) { Animation_Change(&this->skelAnime, &object_hs_Anim_000304, 1.0f, 0.0f, Animation_GetLastFrame(&object_hs_Anim_000304), ANIMMODE_LOOP, 8.0f); this->unk_2AA = 40; - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } else { player->actor.textId = 0x10B1; func_80A6E3A0(this, func_80A6E6D8); @@ -241,7 +244,7 @@ void EnHs_Update(Actor* thisx, PlayState* play) { Collider_UpdateCylinder(thisx, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); if (SkelAnime_Update(&this->skelAnime)) { this->skelAnime.curFrame = 0.0f; diff --git a/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c b/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c index 3f8e61481..6801247ec 100644 --- a/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c +++ b/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c @@ -7,6 +7,7 @@ #include "z_en_hs2.h" #include "vt.h" #include "objects/object_hs/object_hs.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -114,7 +115,7 @@ void EnHs2_Update(Actor* thisx, PlayState* play) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); if (SkelAnime_Update(&this->skelAnime) != 0) { this->skelAnime.curFrame = 0.0f; diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c index 76ca5049e..961106225 100644 --- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c +++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c @@ -14,6 +14,8 @@ #include "objects/object_cne/object_cne.h" #include "objects/object_cob/object_cob.h" #include "objects/object_os_anime/object_os_anime.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -574,7 +576,7 @@ s16 func_80A70058(PlayState* play, Actor* thisx) { case 0x709F: if (!this->unk_215) { Audio_PlaySoundGeneral(this->actor.textId == 0x709F ? NA_SE_SY_CORRECT_CHIME : NA_SE_SY_ERROR, - &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->unk_215 = true; } break; @@ -1093,7 +1095,7 @@ void EnHy_Update(Actor* thisx, PlayState* play) { EnHy_UpdateEyes(this); if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); diff --git a/soh/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c b/soh/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c index 3503aef08..30a24d4a2 100644 --- a/soh/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c +++ b/soh/src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.c @@ -247,7 +247,7 @@ void EnIceHono_DropFlame(EnIceHono* this, PlayState* play) { } EnIceHono_SetupActionSpreadFlames(this); } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, this->actor.scale.x * 3500.0f, 0.0f, 5); Collider_UpdateCylinder(&this->actor, &this->collider); @@ -275,7 +275,7 @@ void EnIceHono_SpreadFlames(EnIceHono* this, PlayState* play) { Math_StepToF(&this->actor.scale.y, 0.0001f, 0.00015f); } this->actor.scale.z = this->actor.scale.x; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, this->actor.scale.x * 3500.0f, 0.0f, 4); if (this->timer < 25) { this->alpha -= 10; @@ -326,7 +326,7 @@ void EnIceHono_SmallFlameMove(EnIceHono* this, PlayState* play) { } this->actor.scale.z = this->actor.scale.x; Math_StepToF(&this->actor.speedXZ, 0, 0.06f); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 10.0f, 0.0f, 5); if (this->timer < 25) { diff --git a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c index 9ab8735dd..ea09efa20 100644 --- a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c +++ b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c @@ -9,6 +9,7 @@ #include "objects/object_ik/object_ik.h" #include "vt.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -787,7 +788,7 @@ void func_80A75FA0(Actor* thisx, PlayState* play) { player->invincibilityTimer = prevInvincibilityTimer; } } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 75.0f, 30.0f, 30.0f, 0x1D); this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 45.0f; @@ -983,29 +984,29 @@ void EnIk_StartMusic(void) { void func_80A76C14(EnIk* this) { if (Animation_OnFrame(&this->skelAnime, 1.0f)) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_WAKEUP, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_WAKEUP, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (Animation_OnFrame(&this->skelAnime, 33.0f)) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_WALK, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_WALK, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (Animation_OnFrame(&this->skelAnime, 68.0f) || Animation_OnFrame(&this->skelAnime, 80.0f)) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_DEMO, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_DEMO, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (Animation_OnFrame(&this->skelAnime, 107.0f)) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_FINGER_DEMO, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_FINGER_DEMO, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (Animation_OnFrame(&this->skelAnime, 156.0f)) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_DEMO, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_ARMOR_DEMO, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else if (Animation_OnFrame(&this->skelAnime, 188.0f)) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_WAVE_DEMO, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_WAVE_DEMO, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } void func_80A76DDC(EnIk* this, PlayState* play, Vec3f* pos) { - Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_TRANSFORM, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_TRANSFORM, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } void func_80A76E2C(EnIk* this, PlayState* play, Vec3f* pos) { @@ -1112,8 +1113,8 @@ void func_80A77264(EnIk* this, PlayState* play, s32 arg2) { } void func_80A772A4(EnIk* this) { - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_STAGGER_DEMO, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_STAGGER_DEMO, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } void func_80A772EC(EnIk* this, PlayState* play) { @@ -1122,7 +1123,7 @@ void func_80A772EC(EnIk* this, PlayState* play) { f32 wDest; SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &this->actor.world.pos, &D_80A78FA0, &wDest); - Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_DEAD, &D_80A78FA0, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_IRONNACK_DEAD, &D_80A78FA0, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } void func_80A7735C(EnIk* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_In/z_en_in.c b/soh/src/overlays/actors/ovl_En_In/z_en_in.c index 6edf01333..7bfc68dbe 100644 --- a/soh/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/soh/src/overlays/actors/ovl_En_In/z_en_in.c @@ -1,6 +1,7 @@ #include "z_en_in.h" #include "overlays/actors/ovl_En_Horse/z_en_horse.h" #include "objects/object_in/object_in.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -426,7 +427,7 @@ void func_80A79AB4(EnIn* this, PlayState* play) { } void func_80A79BAC(EnIn* this, PlayState* play, s32 index, u32 transitionType) { - s16 entrances[] = { ENTR_LON_LON_RANCH_8, ENTR_LON_LON_RANCH_6, ENTR_LON_LON_RANCH_0 }; + s16 entrances[] = { ENTR_LON_LON_RANCH_8, ENTR_LON_LON_RANCH_6, ENTR_LON_LON_RANCH_ENTRANCE }; play->nextEntranceIndex = entrances[index]; if (index == 2) { @@ -625,10 +626,10 @@ void func_80A7A304(EnIn* this, PlayState* play) { this->animationIdx %= 8; this->unk_1E8 = this->animationIdx; if (this->animationIdx == 3 || this->animationIdx == 4) { - Audio_PlaySoundGeneral(NA_SE_IT_LASH, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_LASH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (Rand_ZeroOne() < 0.3f) { - Audio_PlaySoundGeneral(NA_SE_IT_INGO_HORSE_NEIGH, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_INGO_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } Animation_Change(&this->skelAnime, D_80A7B918[this->animationIdx], 1.0f, 0.0f, @@ -661,7 +662,7 @@ void func_80A7A568(EnIn* this, PlayState* play) { Flags_SetInfTable(INFTABLE_AB); } if (gSaveContext.timer1State == 10) { - Audio_PlaySoundGeneral(NA_SE_SY_FOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FOUND, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); func_80A79C78(this, play); this->actionFunc = func_80A7B024; gSaveContext.timer1State = 0; @@ -679,7 +680,7 @@ void func_80A7A568(EnIn* this, PlayState* play) { phi_a2 = 2; transitionType = TRANS_TYPE_FADE_BLACK; } else { - Audio_PlaySoundGeneral(NA_SE_SY_FOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FOUND, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (!Flags_GetEventChkInf(EVENTCHKINF_RENTED_HORSE_FROM_INGO)) { if (Flags_GetInfTable(INFTABLE_AB)) { Flags_SetEventChkInf(EVENTCHKINF_RENTED_HORSE_FROM_INGO); @@ -1007,4 +1008,4 @@ void EnIn_Draw(Actor* thisx, PlayState* play) { void EnIn_Reset(void) { D_80A7B998 = 0; -} \ No newline at end of file +} diff --git a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c index 71891328f..21eafc5ac 100644 --- a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c +++ b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c @@ -7,6 +7,7 @@ #include "z_en_insect.h" #include "vt.h" #include "objects/gameplay_keep/gameplay_keep.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS 0 @@ -683,7 +684,7 @@ void func_80A7D460(EnInsect* this, PlayState* play) { if (this->soilActor != NULL) { if (!(GET_GS_FLAGS(((this->soilActor->actor.params >> 8) & 0x1F) - 1) & (this->soilActor->actor.params & 0xFF))) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } } this->unk_314 |= 0x80; @@ -744,7 +745,7 @@ void EnInsect_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->actor.update != NULL) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->unk_314 & 0x100) { if (this->unk_314 & 1) { if (this->actor.bgCheckFlags & 1) { diff --git a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index c79033250..5109e920f 100644 --- a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -7,6 +7,7 @@ #include "z_en_ishi.h" #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "soh/OTRGlobals.h" #include "vt.h" @@ -403,7 +404,7 @@ void EnIshi_LiftedUp(EnIshi* this, PlayState* play) { EnIshi_SetupFly(this); EnIshi_Fall(this); func_80A7ED94(&this->actor.velocity, D_80A7FA28[this->actor.params & 1]); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5); } } @@ -470,7 +471,7 @@ void EnIshi_Fly(EnIshi* this, PlayState* play) { Math_StepToF(&this->actor.shape.yOffset, 0.0f, 2.0f); EnIshi_Fall(this); func_80A7ED94(&this->actor.velocity, D_80A7FA28[type]); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->actor.shape.rot.x += sRockRotSpeedX; this->actor.shape.rot.y += sRockRotSpeedY; Actor_UpdateBgCheckInfo(play, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5); diff --git a/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c b/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c index 28d8967c2..12863e4c6 100644 --- a/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c +++ b/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c @@ -7,6 +7,7 @@ #include "z_en_jj.h" #include "objects/object_jj/object_jj.h" #include "overlays/actors/ovl_Eff_Dust/z_eff_dust.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -223,7 +224,7 @@ void EnJj_BeginCutscene(EnJj* this, PlayState* play) { func_8003EBF8(play, &play->colCtx.dyna, bodyCollisionActor->bgId); func_8005B1A4(GET_ACTIVE_CAM(play)); Flags_SetEventChkInf(EVENTCHKINF_OFFERED_FISH_TO_JABU_JABU); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } } diff --git a/soh/src/overlays/actors/ovl_En_Js/z_en_js.c b/soh/src/overlays/actors/ovl_En_Js/z_en_js.c index ef6646bbd..26e004f2f 100644 --- a/soh/src/overlays/actors/ovl_En_Js/z_en_js.c +++ b/soh/src/overlays/actors/ovl_En_Js/z_en_js.c @@ -6,6 +6,8 @@ #include "z_en_js.h" #include "objects/object_js/object_js.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -184,7 +186,7 @@ void EnJs_Update(Actor* thisx, PlayState* play) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); if (this->actor.bgCheckFlags & 1) { diff --git a/soh/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.c b/soh/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.c index 9140023ce..ffd428f21 100644 --- a/soh/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.c +++ b/soh/src/overlays/actors/ovl_En_Jsjutan/z_en_jsjutan.c @@ -6,6 +6,7 @@ #include "z_en_jsjutan.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -151,7 +152,7 @@ void func_80A89A6C(EnJsjutan* this, PlayState* play) { i = 1; // Credits scene. The magic carpet man is friends with the bean guy and the lakeside professor. - if ((gSaveContext.entranceIndex == ENTR_LON_LON_RANCH_0) && (gSaveContext.sceneSetupIndex == 8)) { + if ((gSaveContext.entranceIndex == ENTR_LON_LON_RANCH_ENTRANCE) && (gSaveContext.sceneSetupIndex == 8)) { isInCreditsScene = true; actorProfessor = play->actorCtx.actorLists[ACTORCAT_NPC].head; diff --git a/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c b/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c index 99cc81540..3bea92f0d 100644 --- a/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c +++ b/soh/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c @@ -329,7 +329,7 @@ void EnKakasi_Update(Actor* thisx, PlayState* play) { this->height = 60.0f; Actor_SetFocus(&this->actor, this->height); this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 50.0f, 50.0f, 100.0f, 28); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c b/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c index 38331e50b..543564684 100644 --- a/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c +++ b/soh/src/overlays/actors/ovl_En_Kakasi2/z_en_kakasi2.c @@ -7,6 +7,7 @@ #include "z_en_kakasi2.h" #include "vt.h" #include "objects/object_ka/object_ka.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -128,7 +129,7 @@ void func_80A90264(EnKakasi2* this, PlayState* play) { OnePointCutscene_Attention(play, &this->actor); this->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_NO_LOCKON; - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); if (this->switchFlag >= 0) { Flags_SetSwitch(play, this->switchFlag); } @@ -152,7 +153,7 @@ void func_80A90264(EnKakasi2* this, PlayState* play) { SkelAnime_InitFlex(play, &this->skelAnime, &object_ka_Skel_0065B0, &object_ka_Anim_000214, NULL, NULL, 0); OnePointCutscene_Attention(play, &this->actor); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); this->actor.flags |= ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_NO_LOCKON; this->actionFunc = func_80A904D8; @@ -209,7 +210,7 @@ void EnKakasi2_Update(Actor* thisx, PlayState* play2) { this->actor.world.rot = this->actor.shape.rot; Actor_SetFocus(&this->actor, this->height); this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->actor.shape.yOffset == 0.0f) { Collider_UpdateCylinder(&this->actor, &this->collider); diff --git a/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c b/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c index 9cb4e5de5..e60551bd0 100644 --- a/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c +++ b/soh/src/overlays/actors/ovl_En_Kakasi3/z_en_kakasi3.c @@ -426,7 +426,7 @@ void EnKakasi3_Update(Actor* thisx, PlayState* play) { Actor_SetFocus(&this->actor, 60.0f); this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 50.0f, 50.0f, 100.0f, 28); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c b/soh/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c index 4250404ec..6b48d0dd7 100644 --- a/soh/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c +++ b/soh/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c @@ -426,7 +426,7 @@ void EnKanban_Update(Actor* thisx, PlayState* play2) { f32 tempYDistToWater; u8 onGround; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 30.0f, 30.0f, 50.0f, 5); tempX = this->actor.world.pos.x; @@ -598,7 +598,7 @@ void EnKanban_Update(Actor* thisx, PlayState* play2) { if (this->actor.bgCheckFlags & 1) { this->actor.speedXZ = 0.0f; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->actor.speedXZ != 0.0f) { Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 10.0f, 50.0f, 5); if (this->actor.bgCheckFlags & 8) { @@ -716,8 +716,8 @@ void EnKanban_Update(Actor* thisx, PlayState* play2) { (play->msgCtx.unk_E3F2 == OCARINA_SONG_LULLABY)) { this->actionState = ENKANBAN_REPAIR; this->bounceX = 1; - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } break; } diff --git a/soh/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c b/soh/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c index d78cf0820..449653b9a 100644 --- a/soh/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c +++ b/soh/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c @@ -9,6 +9,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -367,7 +368,7 @@ void EnKarebaba_DeadItemDrop(EnKarebaba* this, PlayState* play) { if (Actor_HasParent(&this->actor, play) || this->actor.params == 0) { EnKarebaba_SetupDead(this); } else { - func_8002F554(&this->actor, play, GI_STICKS_1); + Actor_OfferGetItemNearby(&this->actor, play, GI_STICKS_1); } } @@ -420,7 +421,7 @@ void EnKarebaba_Update(Actor* thisx, PlayState* play) { if (this->actionFunc != EnKarebaba_Dead) { if (this->actionFunc == EnKarebaba_Dying) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 15.0f, 10.0f, 5); } else { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c index 466f7271d..dc069b7a8 100644 --- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c +++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c @@ -10,6 +10,9 @@ #include "objects/object_km1/object_km1.h" #include "objects/object_kw1/object_kw1.h" #include "vt.h" +#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -541,8 +544,8 @@ s16 func_80A97738(PlayState* play, Actor* thisx) { case 0x10B7: case 0x10B8: if (this->unk_210 == 0) { - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->unk_210 = 1; } } @@ -1270,7 +1273,7 @@ void EnKo_Update(Actor* thisx, PlayState* play) { } } if (this->interactInfo.talkState == NPC_TALK_STATE_IDLE) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } if (func_80A97C7C(this)) { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); diff --git a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c index a0e529991..7389db34b 100644 --- a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c +++ b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c @@ -335,7 +335,7 @@ void EnKusa_Main(EnKusa* this, PlayState* play) { if (this->actor.xzDistToPlayer < 400.0f) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); if (this->actor.xzDistToPlayer < 100.0f) { - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); } } } @@ -358,7 +358,7 @@ void EnKusa_LiftedUp(EnKusa* this, PlayState* play) { this->actor.gravity = -0.1f; EnKusa_UpdateVelY(this); EnKusa_RandScaleVecToZero(&this->actor.velocity, 0.005f); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5); this->actor.gravity = -3.2f; } @@ -419,7 +419,7 @@ void EnKusa_Fall(EnKusa* this, PlayState* play) { this->actor.shape.rot.x += rotSpeedX; this->actor.shape.rot.y += rotSpeedY; EnKusa_RandScaleVecToZero(&this->actor.velocity, 0.05f); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c index 69b2d5a11..22e0fa413 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c @@ -6,6 +6,9 @@ #include "z_en_kz.h" #include "objects/object_kz/object_kz.h" +#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -91,9 +94,8 @@ u16 EnKz_GetTextNoMaskAdult(PlayState* play, EnKz* this) { // this works because both ITEM_NONE and later trade items are > ITEM_FROG if (INV_CONTENT(ITEM_TRADE_ADULT) >= ITEM_FROG) { if (!Flags_GetInfTable(INFTABLE_139)) { - if (!GameInteractor_Should(VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, ( - !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA) - ), this)) { + if (GameInteractor_Should(VB_KING_ZORA_TUNIC_CHECK, + CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA), this)) { return 0x401F; } else { return 0x4012; @@ -145,7 +147,7 @@ s16 func_80A9C6C0(PlayState* play, Actor* thisx) { case 0x401F: Flags_SetInfTable(INFTABLE_139); break; - } + } } break; case TEXT_STATE_CLOSING: @@ -168,12 +170,12 @@ s16 func_80A9C6C0(PlayState* play, Actor* thisx) { case TEXT_STATE_DONE_FADING: if (this->actor.textId != 0x4014) { if (this->actor.textId == 0x401B && !this->sfxPlayed) { - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->sfxPlayed = true; } } else if (!this->sfxPlayed) { - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->sfxPlayed = true; } break; @@ -303,15 +305,13 @@ void func_80A9CB18(EnKz* this, PlayState* play) { if (LINK_IS_ADULT) { if ((INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_PRESCRIPTION) && (func_8002F368(play) == EXCH_ITEM_PRESCRIPTION)) { - if (GameInteractor_Should(VB_TRADE_PRESCRIPTION, true, this)) { - this->actor.textId = 0x4014; - this->sfxPlayed = false; - player->actor.textId = this->actor.textId; - if (!CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { - this->isTrading = true; - } - return; + this->actor.textId = 0x4014; + this->sfxPlayed = false; + player->actor.textId = this->actor.textId; + if (!CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { + this->isTrading = true; } + return; } if (!CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { this->isTrading = false; @@ -321,11 +321,10 @@ void func_80A9CB18(EnKz* this, PlayState* play) { player->actor.textId = this->actor.textId; } else { this->actor.textId = - !GameInteractor_Should(VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, - (!CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA)), this) + GameInteractor_Should(VB_KING_ZORA_TUNIC_CHECK, + CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA), this) ? 0x401F : 0x4012; - player->actor.textId = this->actor.textId; } } @@ -434,17 +433,23 @@ void EnKz_SetupMweep(EnKz* this, PlayState* play) { Vec3f pos; Vec3f initPos; - this->cutsceneCamera = Play_CreateSubCamera(play); - this->gameplayCamera = play->activeCamera; - Play_ChangeCameraStatus(play, this->gameplayCamera, CAM_STAT_WAIT); - Play_ChangeCameraStatus(play, this->cutsceneCamera, CAM_STAT_ACTIVE); + bool shouldPlayCutscene = GameInteractor_Should(VB_PLAY_MWEEP_CS, true); + + if (shouldPlayCutscene) { + this->cutsceneCamera = Play_CreateSubCamera(play); + this->gameplayCamera = play->activeCamera; + Play_ChangeCameraStatus(play, this->gameplayCamera, CAM_STAT_WAIT); + Play_ChangeCameraStatus(play, this->cutsceneCamera, CAM_STAT_ACTIVE); + } pos = this->actor.world.pos; initPos = this->actor.home.pos; pos.y += 60.0f; initPos.y += -100.0f; initPos.z += 260.0f; - Play_CameraSetAtEye(play, this->cutsceneCamera, &pos, &initPos); - Player_SetCsActionWithHaltedActors(play, &this->actor, 8); + if (shouldPlayCutscene) { + Play_CameraSetAtEye(play, this->cutsceneCamera, &pos, &initPos); + Player_SetCsActionWithHaltedActors(play, &this->actor, 8); + } this->actor.speedXZ = 0.1f * CVarGetFloat(CVAR_ENHANCEMENT("MweepSpeed"), 1.0f); this->actionFunc = EnKz_Mweep; } @@ -459,7 +464,9 @@ void EnKz_Mweep(EnKz* this, PlayState* play) { pos.y += 60.0f; initPos.y += -100.0f; initPos.z += 260.0f; - Play_CameraSetAtEye(play, this->cutsceneCamera, &pos, &initPos); + if (GameInteractor_Should(VB_PLAY_MWEEP_CS, true)) { + Play_CameraSetAtEye(play, this->cutsceneCamera, &pos, &initPos); + } if ((EnKz_FollowPath(this, play) == 1) && (this->waypoint == 0)) { Animation_ChangeByInfo(&this->skelanime, sAnimationInfo, ENKZ_ANIM_1); Inventory_ReplaceItem(play, ITEM_LETTER_RUTO, ITEM_BOTTLE); @@ -474,9 +481,11 @@ void EnKz_Mweep(EnKz* this, PlayState* play) { } void EnKz_StopMweep(EnKz* this, PlayState* play) { - Play_ChangeCameraStatus(play, this->gameplayCamera, CAM_STAT_ACTIVE); - Play_ClearCamera(play, this->cutsceneCamera); - Player_SetCsActionWithHaltedActors(play, &this->actor, 7); + if (GameInteractor_Should(VB_PLAY_MWEEP_CS, true)) { + Play_ChangeCameraStatus(play, this->gameplayCamera, CAM_STAT_ACTIVE); + Play_ClearCamera(play, this->cutsceneCamera); + Player_SetCsActionWithHaltedActors(play, &this->actor, 7); + } this->actionFunc = EnKz_Wait; } @@ -498,18 +507,10 @@ void EnKz_SetupGetItem(EnKz* this, PlayState* play) { f32 xzRange; f32 yRange; - if (Actor_HasParent(&this->actor, play) || ( - (this->isTrading && !GameInteractor_Should(VB_TRADE_PRESCRIPTION, true, this)) || - (!this->isTrading && !GameInteractor_Should(VB_GIVE_ITEM_FROM_THAWING_KING_ZORA, true, this)) - )) { + if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_ADULT_KING_ZORA_ITEM_GIVE, true, this)) { this->actor.parent = NULL; this->interactInfo.talkState = NPC_TALK_STATE_TALKING; this->actionFunc = EnKz_StartTimer; - if (!this->isTrading) { - Flags_SetRandomizerInf(RAND_INF_KING_ZORA_THAWED); - } else { - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_ZD_TRADE_PRESCRIPTION); - } } else { if (CVarGetInteger(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 0)) { getItemId = func_8002F368(play) == EXCH_ITEM_PRESCRIPTION ? GI_FROG : GI_TUNIC_ZORA; @@ -524,7 +525,7 @@ void EnKz_SetupGetItem(EnKz* this, PlayState* play) { void EnKz_StartTimer(EnKz* this, PlayState* play) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { - if (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_FROG && GameInteractor_Should(VB_TRADE_TIMER_FROG, true)) { + if (GameInteractor_Should(VB_TRADE_TIMER_FROG, INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_FROG)) { func_80088AA0(180); // start timer2 with 3 minutes gSaveContext.eventInf[1] &= ~1; } @@ -544,7 +545,7 @@ void EnKz_Update(Actor* thisx, PlayState* play) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); SkelAnime_Update(&this->skelanime); EnKz_UpdateEyes(this); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->actionFunc != EnKz_StartTimer) { func_80A9CB18(this, play); } diff --git a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h index c97732356..0b48ff202 100644 --- a/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h +++ b/soh/src/overlays/actors/ovl_En_Kz/z_en_kz.h @@ -28,6 +28,5 @@ typedef struct EnKz { /* 0x02BE */ s16 unk_2BE[12]; } EnKz; // size = 0x02D8 -void EnKz_SetupGetItem(EnKz* enKz, PlayState* play); #endif diff --git a/soh/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c b/soh/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c index c6246b6c9..5f7aae79a 100644 --- a/soh/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c +++ b/soh/src/overlays/actors/ovl_En_Lightbox/z_en_lightbox.c @@ -52,8 +52,8 @@ void EnLightbox_Init(Actor* thisx, PlayState* play) { thisx->colChkInfo.cylRadius = 30; thisx->colChkInfo.cylHeight = 50; ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 6.0f); - this->dyna.unk_160 = 0; - this->dyna.unk_15C = 0; + this->dyna.interactFlags = 0; + this->dyna.transformFlags = 0; thisx->targetMode = 0; thisx->gravity = -2.0f; CollisionHeader_GetVirtual(&object_lightbox_Col_001F10, &colHeader); @@ -80,8 +80,8 @@ void EnLightbox_Update(Actor* thisx, PlayState* play) { if (thisx->speedXZ) { if (thisx->bgCheckFlags & 8) { thisx->world.rot.y = (thisx->world.rot.y + thisx->wallYaw) - thisx->world.rot.y; - Audio_PlaySoundGeneral(NA_SE_EV_BOMB_BOUND, &thisx->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_BOMB_BOUND, &thisx->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); thisx->speedXZ *= 0.7f; thisx->bgCheckFlags &= ~0x8; } @@ -92,17 +92,17 @@ void EnLightbox_Update(Actor* thisx, PlayState* play) { } else { Math_StepToF(&thisx->speedXZ, 0, IREG(58) / 100.0f); if ((thisx->bgCheckFlags & 2) && (thisx->velocity.y < IREG(59) / 100.0f)) { - Audio_PlaySoundGeneral(NA_SE_EV_BOMB_BOUND, &thisx->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_BOMB_BOUND, &thisx->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); thisx->velocity.y *= IREG(60) / 100.0f; thisx->bgCheckFlags &= ~0x1; } else { - func_8002F580(thisx, play); + Actor_OfferCarry(thisx, play); } } } } - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); Actor_UpdateBgCheckInfo(play, thisx, thisx->colChkInfo.cylHeight, thisx->colChkInfo.cylRadius, thisx->colChkInfo.cylRadius, 0x1D); thisx->focus.pos = thisx->world.pos; diff --git a/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c b/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c index 2143aa6e6..0031ab766 100644 --- a/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c +++ b/soh/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c @@ -88,10 +88,10 @@ void EnMThunder_Init(Actor* thisx, PlayState* play2) { if (!gSaveContext.isMagicAcquired || (gSaveContext.magicState != MAGIC_STATE_IDLE) || (((this->actor.params & 0xFF00) >> 8) && !(Magic_RequestChange(play, (this->actor.params & 0xFF00) >> 8, MAGIC_CONSUME_NOW)))) { - Audio_PlaySoundGeneral(NA_SE_IT_ROLLING_CUT, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING_HARD, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_ROLLING_CUT, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING_HARD, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); Actor_Kill(&this->actor); return; } @@ -103,8 +103,8 @@ void EnMThunder_Init(Actor* thisx, PlayState* play2) { this->unk_1C9 = ((this->unk_1C7 == 1) ? 2 : 4); func_80A9EFE0(this, func_80A9F9B4); this->unk_1C4 = 8; - Audio_PlaySoundGeneral(NA_SE_IT_ROLLING_CUT_LV1, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_ROLLING_CUT_LV1, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->unk_1AC = 1.0f; } else { func_80A9EFE0(this, func_80A9F408); @@ -133,10 +133,10 @@ void func_80A9F350(EnMThunder* this, PlayState* play) { if (player->stateFlags2 & PLAYER_STATE2_SPIN_ATTACKING) { if (player->meleeWeaponAnimation >= 0x18) { - Audio_PlaySoundGeneral(NA_SE_IT_ROLLING_CUT, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING_HARD, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_ROLLING_CUT, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING_HARD, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } Actor_Kill(&this->actor); @@ -183,10 +183,10 @@ void func_80A9F408(EnMThunder* this, PlayState* play) { if (player->unk_858 <= 0.15f) { if ((player->unk_858 >= 0.1f) && (player->meleeWeaponAnimation >= 0x18)) { - Audio_PlaySoundGeneral(NA_SE_IT_ROLLING_CUT, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING_HARD, &player->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_ROLLING_CUT, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING_HARD, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } Actor_Kill(&this->actor); return; @@ -207,8 +207,8 @@ void func_80A9F408(EnMThunder* this, PlayState* play) { func_80A9EFE0(this, func_80A9F9B4); this->unk_1C4 = 8; - Audio_PlaySoundGeneral(sSfxIds[this->unk_1C6], &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(sSfxIds[this->unk_1C6], &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->unk_1AC = 1.0f; return; } diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c index e8a79b437..e4ceacfb2 100644 --- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c +++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c @@ -6,6 +6,7 @@ #include "z_en_ma1.h" #include "objects/object_ma1/object_ma1.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -399,7 +400,7 @@ void func_80AA1150(EnMa1* this, PlayState* play) { if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { Flags_SetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG); - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; gSaveContext.nextCutsceneIndex = 0xFFF1; play->transitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); play->transitionTrigger = TRANS_TRIGGER_START; diff --git a/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c b/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c index 1519e57c7..248d5a8c4 100644 --- a/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c +++ b/soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c @@ -282,7 +282,7 @@ void func_80AA20E4(EnMa2* this, PlayState* play) { this->actionFunc = func_80AA204C; play->msgCtx.ocarinaMode = OCARINA_MODE_04; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->unk_208 = 0x1E; Flags_SetInfTable(INFTABLE_8E); this->actionFunc = func_80AA21C8; diff --git a/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c b/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c index 63c4f4da6..ad93a3755 100644 --- a/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c +++ b/soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c @@ -115,7 +115,7 @@ s16 func_80AA2BD4(PlayState* play, Actor* thisx) { switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_EVENT: if (Message_ShouldAdvance(play)) { - play->nextEntranceIndex = ENTR_LON_LON_RANCH_0; + play->nextEntranceIndex = ENTR_LON_LON_RANCH_ENTRANCE; gSaveContext.nextCutsceneIndex = 0xFFF0; play->transitionType = TRANS_TYPE_CIRCLE(TCA_STARBURST, TCC_BLACK, TCS_FAST); play->transitionTrigger = TRANS_TRIGGER_START; diff --git a/soh/src/overlays/actors/ovl_En_Mag/z_en_mag.c b/soh/src/overlays/actors/ovl_En_Mag/z_en_mag.c index 44b3399b0..48710d4a3 100644 --- a/soh/src/overlays/actors/ovl_En_Mag/z_en_mag.c +++ b/soh/src/overlays/actors/ovl_En_Mag/z_en_mag.c @@ -6,7 +6,8 @@ #include "z_en_mag.h" #include "objects/object_mag/object_mag.h" -#include +#include +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -217,7 +218,7 @@ void EnMag_UpdateMq(Actor* thisx, PlayState* play) { CHECK_BTN_ALL(play->state.input[0].press.button, BTN_A) || CHECK_BTN_ALL(play->state.input[0].press.button, BTN_B)) { - Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->mainAlpha = 210; this->subAlpha = 255; @@ -247,8 +248,8 @@ void EnMag_UpdateMq(Actor* thisx, PlayState* play) { if (play->transitionTrigger != TRANS_TRIGGER_START) { Audio_SetCutsceneFlag(0); - Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); gSaveContext.gameMode = 2; play->transitionTrigger = TRANS_TRIGGER_START; @@ -377,7 +378,7 @@ void EnMag_UpdateVanilla(Actor* thisx, PlayState* play) { CHECK_BTN_ALL(play->state.input[0].press.button, BTN_A) || CHECK_BTN_ALL(play->state.input[0].press.button, BTN_B)) { - Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->mainAlpha = 210; this->subAlpha = 255; @@ -407,8 +408,8 @@ void EnMag_UpdateVanilla(Actor* thisx, PlayState* play) { if (play->transitionTrigger != TRANS_TRIGGER_START) { Audio_SetCutsceneFlag(0); - Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); gSaveContext.gameMode = 2; play->transitionTrigger = TRANS_TRIGGER_START; @@ -930,8 +931,21 @@ void EnMag_DrawInnerVanilla(Actor* thisx, PlayState* play, Gfx** gfxp) { gDPSetAlphaCompare(gfx++, G_AC_NONE); gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); - gDPSetPrimColor(gfx++, 0, 0, (s16)this->copyrightAlpha, (s16)this->copyrightAlpha, (s16)this->copyrightAlpha, - (s16)this->copyrightAlpha); + if (CVarGetInteger(CVAR_COSMETIC("Title.Copyright.Changed"), 0)) { + Color_RGBA8 copyrightColor = CVarGetColor(CVAR_COSMETIC("Title.Copyright.Value"), (Color_RGBA8){ 255, 255, 255, 255 }); + gDPSetPrimColor( + gfx++, + 0, + 0, + (s16)(((f32)copyrightColor.r / 255.0f) * this->copyrightAlpha), + (s16)(((f32)copyrightColor.g / 255.0f) * this->copyrightAlpha), + (s16)(((f32)copyrightColor.b / 255.0f) * this->copyrightAlpha), + (s16)(((f32)copyrightColor.a / 255.0f) * this->copyrightAlpha) + ); + } else { + gDPSetPrimColor(gfx++, 0, 0, (s16)this->copyrightAlpha, (s16)this->copyrightAlpha, (s16)this->copyrightAlpha, + (s16)this->copyrightAlpha); + } if ((s16)this->copyrightAlpha != 0) { gDPLoadTextureBlock(gfx++, copy_tex, G_IM_FMT_IA, G_IM_SIZ_8b, copy_width, 16, 0, G_TX_NOMIRROR | G_TX_CLAMP, diff --git a/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c b/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c index b0aff3750..96bcac036 100644 --- a/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c +++ b/soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c @@ -7,6 +7,7 @@ #include "z_en_mb.h" #include "objects/object_mb/object_mb.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" /* * This actor can have three behaviors: @@ -1467,7 +1468,7 @@ void EnMb_Update(Actor* thisx, PlayState* play) { EnMb_CheckColliding(this, play); if (thisx->colChkInfo.damageEffect != ENMB_DMGEFF_FREEZE) { this->actionFunc(this, play); - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); Actor_UpdateBgCheckInfo(play, thisx, 40.0f, 40.0f, 70.0f, 0x1D); Actor_SetFocus(thisx, thisx->scale.x * 4500.0f); Collider_UpdateCylinder(thisx, &this->hitbox); diff --git a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c index 5567f3e29..eaa8d9b2d 100644 --- a/soh/src/overlays/actors/ovl_En_Md/z_en_md.c +++ b/soh/src/overlays/actors/ovl_En_Md/z_en_md.c @@ -7,6 +7,7 @@ #include "z_en_md.h" #include "objects/object_md/object_md.h" #include "overlays/actors/ovl_En_Elf/z_en_elf.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -628,7 +629,7 @@ void func_80AAB5A4(EnMd* this, PlayState* play) { : 400.0f; } - this->alpha = func_80034DD4(&this->actor, play, this->alpha, temp); + this->alpha = Actor_UpdateAlphaByDistance(&this->actor, play, this->alpha, temp); this->actor.shape.shadowAlpha = this->alpha; } else { this->alpha = 255; @@ -773,7 +774,7 @@ void func_80AABC10(EnMd* this, PlayState* play) { this->actionFunc = func_80AAB948; play->msgCtx.ocarinaMode = OCARINA_MODE_04; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->actor.textId = 0x1067; func_8002F2CC(&this->actor, play, this->collider.dim.radius + 30.0f); @@ -818,7 +819,7 @@ void EnMd_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); EnMd_UpdateEyes(this); func_80AAB5A4(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); func_80AAB158(this, play); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); this->actionFunc(this, play); diff --git a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c index 36a8b34c5..f742b4671 100644 --- a/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c +++ b/soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c @@ -6,6 +6,9 @@ #include "z_en_mk.h" #include "objects/object_mk/object_mk.h" +#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -95,9 +98,8 @@ void func_80AACA40(EnMk* this, PlayState* play) { void func_80AACA94(EnMk* this, PlayState* play) { if (Actor_HasParent(&this->actor, play) != 0 || !GameInteractor_Should(VB_TRADE_FROG, true, this)) { this->actor.parent = NULL; - this->actionFunc = func_80AACA40; - Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG); - if (GameInteractor_Should(VB_TRADE_TIMER_EYEDROPS, true)) { + if (GameInteractor_Should(VB_TRADE_TIMER_EYEDROPS, true, this)) { + this->actionFunc = func_80AACA40; func_80088AA0(240); gSaveContext.eventInf[1] &= ~1; } @@ -267,7 +269,7 @@ void EnMk_Wait(EnMk* this, PlayState* play) { Animation_GetLastFrame(&object_mk_Anim_000368), ANIMMODE_ONCE, -4.0f); this->flags &= ~2; gSaveContext.timer2State = 0; - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); break; default: player->actor.textId = 0x4018; @@ -301,7 +303,7 @@ void EnMk_Update(Actor* thisx, PlayState* play) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); if ((!(this->flags & 2)) && (SkelAnime_Update(&this->skelAnime))) { @@ -347,7 +349,7 @@ void EnMk_Update(Actor* thisx, PlayState* play) { if ((!(this->flags & 4)) && (this->swimFlag >= 8)) { this->flags |= 4; - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } } } diff --git a/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c b/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c index f76c61674..2b9733f1c 100644 --- a/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c +++ b/soh/src/overlays/actors/ovl_En_Mm/z_en_mm.c @@ -7,6 +7,7 @@ #include "z_en_mm.h" #include "objects/object_mm/object_mm.h" #include "objects/object_link_child/object_link_child.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -297,7 +298,7 @@ void func_80AADCD0(EnMm* this, PlayState* play) { if (this->curAnimIndex != 5) { if ((this->actor.textId == 0x202A) || (this->actor.textId == 0x202B)) { EnMm_ChangeAnim(this, RM_ANIM_EXCITED, &this->curAnimIndex); - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } } } else { @@ -391,7 +392,7 @@ s32 func_80AADEF0(EnMm* this, PlayState* play) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->yawToWaypoint, 1, 2500, 0); this->actor.world.rot.y = this->actor.shape.rot.y; Math_SmoothStepToF(&this->actor.speedXZ, this->speedXZ, 0.6f, this->distToWaypoint, 0.0f); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); return 0; diff --git a/soh/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c b/soh/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c index b1bbc09a5..2226dbdea 100644 --- a/soh/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c +++ b/soh/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c @@ -7,6 +7,7 @@ #include "z_en_mm2.h" #include "vt.h" #include "objects/object_mm/object_mm.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -304,7 +305,7 @@ void EnMm2_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); } diff --git a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c index a28f1c19c..dc3966357 100644 --- a/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c +++ b/soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c @@ -6,6 +6,8 @@ #include "z_en_ms.h" #include "objects/object_ms/object_ms.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -175,8 +177,8 @@ void EnMs_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); this->actionFunc(this, play); - if (gSaveContext.entranceIndex == ENTR_LON_LON_RANCH_0 && gSaveContext.sceneSetupIndex == 8) { // ride carpet if in credits - Actor_MoveForward(&this->actor); + if (gSaveContext.entranceIndex == ENTR_LON_LON_RANCH_ENTRANCE && gSaveContext.sceneSetupIndex == 8) { // ride carpet if in credits + Actor_MoveXZGravity(&this->actor); osSyncPrintf("OOOHHHHHH %f\n", this->actor.velocity.y); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); } diff --git a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c index c3ee312cc..ace23084e 100644 --- a/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c +++ b/soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c @@ -8,6 +8,7 @@ #include "vt.h" #include "objects/object_nb/object_nb.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -461,7 +462,7 @@ void EnNb_SetupLightArrowOrSealingCs(EnNb* this, PlayState* play) { } void EnNb_PlaySealingSound(void) { - func_800788CC(NA_SE_SY_WHITE_OUT_T); + Sfx_PlaySfxCentered2(NA_SE_SY_WHITE_OUT_T); } void EnNb_InitializeDemo6K(EnNb* this, PlayState* play) { @@ -576,13 +577,13 @@ void EnNb_InitKidnap(EnNb* this, PlayState* play) { void EnNb_PlayCrySFX(EnNb* this, PlayState* play) { if (play->csCtx.frames == 3) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_NB_CRY_0); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_NB_CRY_0); } } void EnNb_PlayAgonySFX(EnNb* this, PlayState* play) { if (play->csCtx.frames == 420) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_NB_AGONY); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_NB_AGONY); } } @@ -708,8 +709,8 @@ void EnNb_PlayKnuckleDefeatSFX(EnNb* this, PlayState* play) { s32 pad[2]; if (play->csCtx.frames == 548) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_NB_CRY_0); - func_80078914(&this->actor.projectedPos, NA_SE_EN_FANTOM_HIT_THUNDER); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_NB_CRY_0); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EN_FANTOM_HIT_THUNDER); } } @@ -718,7 +719,7 @@ void EnNb_PlayKneelingOnGroundSFX(EnNb* this) { if ((this->skelAnime.mode == 2) && (Animation_OnFrame(&this->skelAnime, 18.0f) || Animation_OnFrame(&this->skelAnime, 25.0f))) { - func_80078914(&this->actor.projectedPos, NA_SE_EV_HUMAN_BOUND); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HUMAN_BOUND); } } @@ -726,7 +727,7 @@ void EnNb_PlayLookRightSFX(EnNb* this) { s32 pad[2]; if ((this->skelAnime.mode == 2) && Animation_OnFrame(&this->skelAnime, 9.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_WALK_CONCRETE); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WALK_CONCRETE); } } @@ -734,7 +735,7 @@ void EnNb_PlayLookLeftSFX(EnNb* this) { s32 pad[2]; if (Animation_OnFrame(&this->skelAnime, 9.0f) || Animation_OnFrame(&this->skelAnime, 13.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_WALK_CONCRETE); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WALK_CONCRETE); } } @@ -1148,7 +1149,7 @@ void func_80AB359C(EnNb* this) { } void EnNb_SetNoticeSFX(EnNb* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_NB_NOTICE); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_NB_NOTICE); } s32 EnNb_GetNoticedStatus(EnNb* this, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c b/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c index 45433afd6..203a7af59 100644 --- a/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c +++ b/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c @@ -9,6 +9,7 @@ #include "overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h" #include "vt.h" #include "soh/frame_interpolation.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_ALWAYS_THROWN) @@ -489,7 +490,7 @@ void func_80AB6570(EnNiw* this, PlayState* play) { this->actionFunc = func_80AB6BF8; return; } - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); } else { if (this->path != 0) { this->unk_2A6 = 1; @@ -694,7 +695,7 @@ void func_80AB6D08(EnNiw* this, PlayState* play) { this->actionFunc = func_80AB6BF8; } else { if (this->timer5 >= 6) { - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); } func_80AB5BF8(this, play, 2); } @@ -973,7 +974,7 @@ void EnNiw_Update(Actor* thisx, PlayState* play) { thisx->shape.shadowScale = 15.0f; this->actionFunc(this, play); Actor_SetFocus(&this->actor, this->unk_304); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->actionFunc != func_80AB6EB4 && this->actionFunc != func_80AB6450 && play->sceneNum != SCENE_ZORAS_RIVER) { Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 60.0f, 31); diff --git a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c index 5113b8a68..ffb752c6c 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c @@ -7,6 +7,7 @@ #include "z_en_niw_girl.h" #include "objects/object_gr/object_gr.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -226,7 +227,7 @@ void EnNiwGirl_Update(Actor* thisx, PlayState* play) { this->jumpTimer--; } this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 100.0f, 100.0f, 200.0f, 0x1C); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index a03319dfc..63d4104de 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -3,6 +3,9 @@ #include "objects/object_os_anime/object_os_anime.h" #include "overlays/actors/ovl_En_Niw/z_en_niw.h" #include "vt.h" +#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -266,7 +269,7 @@ void func_80ABA244(EnNiwLady* this, PlayState* play) { osSyncPrintf("\n\n"); if (Text_GetFaceReaction(play, 8) == 0) { if (this->actor.textId == 0x503C) { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); this->unk_26C = 2; this->unk_262 = TEXT_STATE_EVENT; this->actionFunc = func_80ABA654; @@ -274,7 +277,7 @@ void func_80ABA244(EnNiwLady* this, PlayState* play) { } this->unk_26E = phi_s1 + 1; if (phi_s1 == 7) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); this->unk_26C = 1; this->unk_262 = TEXT_STATE_EVENT; this->unk_26A = this->cuccosInPen; @@ -287,9 +290,9 @@ void func_80ABA244(EnNiwLady* this, PlayState* play) { } if (this->unk_26A != this->cuccosInPen) { if (this->cuccosInPen < this->unk_26A) { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } else if (phi_s1 + 1 < 9) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } } if (this->unk_26A < this->cuccosInPen) { @@ -379,7 +382,7 @@ void func_80ABA878(EnNiwLady* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, play)) { playerExchangeItemId = func_8002F368(play); if ((playerExchangeItemId == 6) && (Flags_GetEventChkInf(EVENTCHKINF_TALON_WOKEN_IN_KAKARIKO))) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); player->actor.textId = sTradeItemTextIds[5]; this->unk_26E = this->unk_27A + 21; this->unk_262 = TEXT_STATE_CHOICE; diff --git a/soh/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c b/soh/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c index a9c2a7361..34afa674f 100644 --- a/soh/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c +++ b/soh/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c @@ -159,7 +159,7 @@ void EnNutsball_Update(Actor* thisx, PlayState* play) { if (!(player->stateFlags1 & (PLAYER_STATE1_TALKING | PLAYER_STATE1_DEAD | PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE)) || (this->actionFunc == func_80ABBB34)) { this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10, sCylinderInit.dim.radius, sCylinderInit.dim.height, 5); Collider_UpdateCylinder(&this->actor, &this->collider); diff --git a/soh/src/overlays/actors/ovl_En_Ny/z_en_ny.c b/soh/src/overlays/actors/ovl_En_Ny/z_en_ny.c index 5bcf2f7a8..5ce3f9380 100644 --- a/soh/src/overlays/actors/ovl_En_Ny/z_en_ny.c +++ b/soh/src/overlays/actors/ovl_En_Ny/z_en_ny.c @@ -384,7 +384,7 @@ void EnNy_Update(Actor* thisx, PlayState* play) { temp_f22 = (24.0f * temp_f20) + 12.0f; this->actor.shape.rot.x += (s16)(this->unk_1E8 * 1000.0f); func_80ABD3B8(this, temp_f22 + 10.0f, temp_f22 - 10.0f); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Math_StepToF(&this->unk_1E4, this->unk_1E8, 0.1f); this->actionFunc(this, play); this->actor.prevPos.y -= temp_f22; @@ -514,7 +514,7 @@ void EnNy_UpdateUnused(Actor* thisx, PlayState* play2) { CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Math_StepToF(&this->unk_1E4, this->unk_1E8, 0.1f); } static Vec3f sFireOffsets[] = { diff --git a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c index 017c3fac1..b0d9ecda4 100644 --- a/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c +++ b/soh/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c @@ -8,6 +8,7 @@ #include "scenes/misc/hakaana_ouke/hakaana_ouke_scene.h" #include "scenes/overworld/spot02/spot02_scene.h" #include "vt.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -156,7 +157,7 @@ void func_80ABF0CC(EnOkarinaTag* this, PlayState* play) { if ((play->sceneNum != SCENE_GREAT_FAIRYS_FOUNTAIN_MAGIC) && (play->sceneNum != SCENE_GREAT_FAIRYS_FOUNTAIN_SPELLS)) { play->msgCtx.ocarinaMode = OCARINA_MODE_04; } - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); this->actionFunc = func_80ABEF2C; return; } @@ -172,7 +173,7 @@ void func_80ABF0CC(EnOkarinaTag* this, PlayState* play) { Flags_SetSwitch(play, this->switchFlag); } play->msgCtx.ocarinaMode = OCARINA_MODE_04; - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); this->actionFunc = func_80ABEF2C; return; } @@ -235,7 +236,7 @@ void func_80ABF4C8(EnOkarinaTag* this, PlayState* play) { if (play->msgCtx.ocarinaMode == OCARINA_MODE_04) { this->actionFunc = func_80ABF28C; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_03) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); if (this->switchFlag >= 0) { Flags_SetSwitch(play, this->switchFlag); } @@ -264,7 +265,7 @@ void func_80ABF4C8(EnOkarinaTag* this, PlayState* play) { gSaveContext.cutsceneTrigger = 1; } Flags_SetEventChkInf(EVENTCHKINF_DESTROYED_ROYAL_FAMILY_TOMB); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); break; default: break; diff --git a/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c b/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c index 54fc2d2fa..60a3452a0 100644 --- a/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c +++ b/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c @@ -2,6 +2,7 @@ #include "objects/object_okuta/object_okuta.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -651,7 +652,7 @@ void EnOkuta_Update(Actor* thisx, PlayState* play2) { this->actor.scale.y * 100.0f); } else { sp34 = false; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Math_Vec3f_Copy(&sp38, &this->actor.world.pos); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 15.0f, 30.0f, 5); if ((this->actor.bgCheckFlags & 8) && diff --git a/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c b/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c index 230584252..3eaa944b0 100644 --- a/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c +++ b/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c @@ -17,6 +17,7 @@ #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include +#include "soh/OTRGlobals.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -679,7 +680,7 @@ void EnOssan_EndInteraction(PlayState* play, EnOssan* this) { play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; play->msgCtx.stateTimer = 4; player->stateFlags2 &= ~PLAYER_STATE2_DISABLE_DRAW; - func_800BC490(play, 1); + Play_SetViewpoint(play, 1); Interface_ChangeAlpha(50); this->drawCursor = 0; this->stickLeftPrompt.isEnabled = false; @@ -751,7 +752,7 @@ void EnOssan_ChooseTalkToOwner(PlayState* play, EnOssan* this) { } void EnOssan_SetLookToShopkeeperFromShelf(PlayState* play, EnOssan* this) { - func_80078884(NA_SE_SY_CURSOR); + Sfx_PlaySfxCentered(NA_SE_SY_CURSOR); this->drawCursor = 0; this->stateFlag = OSSAN_STATE_LOOK_SHOPKEEPER; } @@ -763,7 +764,7 @@ void EnOssan_State_Idle(EnOssan* this, PlayState* play, Player* player) { // "Start conversation!!" osSyncPrintf(VT_FGCOL(YELLOW) "★★★ 会話開始!! ★★★" VT_RST "\n"); player->stateFlags2 |= PLAYER_STATE2_DISABLE_DRAW; - func_800BC590(play); + Play_SetShopBrowsingViewpoint(play); EnOssan_SetStateStartShopping(play, this, false); } else if (this->actor.xzDistToPlayer < 100.0f) { func_8002F2CC(&this->actor, play, 100); @@ -929,7 +930,7 @@ void EnOssan_State_StartConversation(EnOssan* this, PlayState* play, Player* pla } } } else if (dialogState == TEXT_STATE_EVENT && Message_ShouldAdvance(play)) { - func_80078884(NA_SE_SY_MESSAGE_PASS); + Sfx_PlaySfxCentered(NA_SE_SY_MESSAGE_PASS); switch (this->happyMaskShopState) { case OSSAN_HAPPY_STATE_ALL_MASKS_SOLD: @@ -948,9 +949,9 @@ void EnOssan_State_StartConversation(EnOssan* this, PlayState* play, Player* pla case OSSAN_HAPPY_STATE_ANGRY: // In ER, handle happy mask throwing link out with not enough rupees if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { - play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_MARKET_DAY_9); + play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_MARKET_DAY_OUTSIDE_HAPPY_MASK_SHOP); } else { - play->nextEntranceIndex = ENTR_MARKET_DAY_9; + play->nextEntranceIndex = ENTR_MARKET_DAY_OUTSIDE_HAPPY_MASK_SHOP; } play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_CIRCLE(TCA_STARBURST, TCC_WHITE, TCS_FAST); @@ -986,7 +987,7 @@ void EnOssan_State_FacingShopkeeper(EnOssan* this, PlayState* play, Player* play if ((Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE) && !EnOssan_TestEndInteraction(this, play, &play->state.input[0])) { if (Message_ShouldAdvance(play) && EnOssan_FacingShopkeeperDialogResult(this, play)) { - func_80078884(NA_SE_SY_DECIDE); + Sfx_PlaySfxCentered(NA_SE_SY_DECIDE); return; } @@ -1005,7 +1006,7 @@ void EnOssan_State_FacingShopkeeper(EnOssan* this, PlayState* play, Player* play this->stateFlag = OSSAN_STATE_LOOK_SHELF_LEFT; Interface_SetDoAction(play, DO_ACTION_DECIDE); this->stickLeftPrompt.isEnabled = false; - func_80078884(NA_SE_SY_CURSOR); + Sfx_PlaySfxCentered(NA_SE_SY_CURSOR); GameInteractor_ExecuteOnShopSlotChangeHooks(this->cursorIndex, this->shelfSlots[this->cursorIndex]->basePrice); } } else if ((this->stickAccumX > 0) || (dpad && CHECK_BTN_ALL(input->press.button, dRight))) { @@ -1015,7 +1016,7 @@ void EnOssan_State_FacingShopkeeper(EnOssan* this, PlayState* play, Player* play this->stateFlag = OSSAN_STATE_LOOK_SHELF_RIGHT; Interface_SetDoAction(play, DO_ACTION_DECIDE); this->stickRightPrompt.isEnabled = false; - func_80078884(NA_SE_SY_CURSOR); + Sfx_PlaySfxCentered(NA_SE_SY_CURSOR); GameInteractor_ExecuteOnShopSlotChangeHooks(this->cursorIndex, this->shelfSlots[this->cursorIndex]->basePrice); } } @@ -1174,23 +1175,23 @@ s32 EnOssan_HasPlayerSelectedItem(PlayState* play, EnOssan* this, Input* input) case SI_ZORA_MASK: case SI_GORON_MASK: case SI_GERUDO_MASK: - func_80078884(NA_SE_SY_DECIDE); + Sfx_PlaySfxCentered(NA_SE_SY_DECIDE); this->drawCursor = 0; this->stateFlag = OSSAN_STATE_SELECT_ITEM_MASK; return true; case SI_MILK_BOTTLE: - func_80078884(NA_SE_SY_DECIDE); + Sfx_PlaySfxCentered(NA_SE_SY_DECIDE); this->drawCursor = 0; this->stateFlag = OSSAN_STATE_SELECT_ITEM_MILK_BOTTLE; return true; case SI_WEIRD_EGG: - func_80078884(NA_SE_SY_DECIDE); + Sfx_PlaySfxCentered(NA_SE_SY_DECIDE); this->drawCursor = 0; this->stateFlag = OSSAN_STATE_SELECT_ITEM_WEIRD_EGG; return true; case SI_19: case SI_20: - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); this->drawCursor = 0; this->stateFlag = OSSAN_STATE_SELECT_ITEM_UNIMPLEMENTED; return true; @@ -1199,18 +1200,18 @@ s32 EnOssan_HasPlayerSelectedItem(PlayState* play, EnOssan* this, Input* input) case SI_BOMBS_20: case SI_BOMBS_30: case SI_BOMBS_5_R35: - func_80078884(NA_SE_SY_DECIDE); + Sfx_PlaySfxCentered(NA_SE_SY_DECIDE); this->drawCursor = 0; this->stateFlag = OSSAN_STATE_SELECT_ITEM_BOMBS; return true; default: - func_80078884(NA_SE_SY_DECIDE); + Sfx_PlaySfxCentered(NA_SE_SY_DECIDE); this->drawCursor = 0; this->stateFlag = OSSAN_STATE_SELECT_ITEM; return true; } } - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); return true; } return false; @@ -1282,7 +1283,7 @@ void EnOssan_State_BrowseLeftShelf(EnOssan* this, PlayState* play, Player* playe if (this->cursorIndex != prevIndex) { GameInteractor_ExecuteOnShopSlotChangeHooks(this->cursorIndex, this->shelfSlots[this->cursorIndex]->basePrice); Message_ContinueTextbox(play, this->shelfSlots[this->cursorIndex]->actor.textId); - func_80078884(NA_SE_SY_CURSOR); + Sfx_PlaySfxCentered(NA_SE_SY_CURSOR); } } } @@ -1352,7 +1353,7 @@ void EnOssan_State_BrowseRightShelf(EnOssan* this, PlayState* play, Player* play if (this->cursorIndex != prevIndex) { GameInteractor_ExecuteOnShopSlotChangeHooks(this->cursorIndex, this->shelfSlots[this->cursorIndex]->basePrice); Message_ContinueTextbox(play, this->shelfSlots[this->cursorIndex]->actor.textId); - func_80078884(NA_SE_SY_CURSOR); + Sfx_PlaySfxCentered(NA_SE_SY_CURSOR); } } } @@ -1392,7 +1393,7 @@ void EnOssan_GiveItemWithFanfare(PlayState* play, EnOssan* this) { play->msgCtx.msgMode = MSGMODE_TEXT_CLOSING; play->msgCtx.stateTimer = 4; player->stateFlags2 &= ~PLAYER_STATE2_DISABLE_DRAW; - func_800BC490(play, 1); + Play_SetViewpoint(play, 1); Interface_ChangeAlpha(50); this->drawCursor = 0; EnOssan_UpdateCameraDirection(this, play, 0.0f); @@ -1432,19 +1433,19 @@ void EnOssan_HandleCanBuyItem(PlayState* play, EnOssan* this) { selectedItem->setOutOfStockFunc(play, selectedItem); break; case CANBUY_RESULT_CANT_GET_NOW: - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); EnOssan_SetStateCantGetItem(play, this, 0x86); break; case CANBUY_RESULT_NEED_BOTTLE: - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); EnOssan_SetStateCantGetItem(play, this, 0x96); break; case CANBUY_RESULT_NEED_RUPEES: - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); EnOssan_SetStateCantGetItem(play, this, 0x85); break; case CANBUY_RESULT_CANT_GET_NOW_5: - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); EnOssan_SetStateCantGetItem(play, this, 0x86); break; } @@ -1493,11 +1494,11 @@ void EnOssan_HandleCanBuyWeirdEgg(PlayState* play, EnOssan* this) { item->setOutOfStockFunc(play, item); break; case CANBUY_RESULT_CANT_GET_NOW: - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); EnOssan_SetStateCantGetItem(play, this, 0x9D); break; case CANBUY_RESULT_NEED_RUPEES: - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); EnOssan_SetStateCantGetItem(play, this, 0x85); break; } @@ -1516,11 +1517,11 @@ void EnOssan_HandleCanBuyBombs(PlayState* play, EnOssan* this) { item->setOutOfStockFunc(play, item); break; case CANBUY_RESULT_CANT_GET_NOW: - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); EnOssan_SetStateCantGetItem(play, this, 0x86); break; case CANBUY_RESULT_NEED_RUPEES: - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); EnOssan_SetStateCantGetItem(play, this, 0x85); break; } @@ -1770,7 +1771,7 @@ void EnOssan_State_ContinueShoppingPrompt(EnOssan* this, PlayState* play, Player osSyncPrintf(VT_FGCOL(YELLOW) "★★★ 続けるよ!! ★★★" VT_RST "\n"); player->actor.shape.rot.y += 0x8000; player->stateFlags2 |= PLAYER_STATE2_DISABLE_DRAW; - func_800BC490(play, 2); + Play_SetViewpoint(play, 2); Message_StartTextbox(play, this->actor.textId, &this->actor); EnOssan_SetStateStartShopping(play, this, true); func_8002F298(&this->actor, play, 100.0f, -1); @@ -1789,7 +1790,7 @@ void EnOssan_State_ContinueShoppingPrompt(EnOssan* this, PlayState* play, Player selectedItem->updateStockedItemFunc(play, selectedItem); player->actor.shape.rot.y += 0x8000; player->stateFlags2 |= PLAYER_STATE2_DISABLE_DRAW; - func_800BC490(play, 2); + Play_SetViewpoint(play, 2); Message_StartTextbox(play, this->actor.textId, &this->actor); EnOssan_SetStateStartShopping(play, this, true); func_8002F298(&this->actor, play, 100.0f, -1); @@ -2289,7 +2290,7 @@ void EnOssan_MainActionFunc(EnOssan* this, PlayState* play) { sStateFunc[this->stateFlag](this, play, player); } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 26.0f, 10.0f, 0.0f, 5); Actor_SetFocus(&this->actor, 90.0f); Actor_SetScale(&this->actor, sShopkeeperScale[this->actor.params]); diff --git a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c index 776c59149..72aa6e9a2 100644 --- a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -10,6 +10,8 @@ #include "scenes/overworld/spot16/spot16_scene.h" #include "vt.h" #include +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -963,9 +965,9 @@ void func_80ACC00C(EnOwl* this, PlayState* play) { osSyncPrintf(VT_RST); if (IS_RANDO) { if (Randomizer_GetSettingValue(RSK_SHUFFLE_OWL_DROPS)) { - play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_HYRULE_FIELD_9); + play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_HYRULE_FIELD_OWL_DROP); } else { - play->nextEntranceIndex = ENTR_HYRULE_FIELD_9; + play->nextEntranceIndex = ENTR_HYRULE_FIELD_OWL_DROP; } play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; @@ -978,9 +980,9 @@ void func_80ACC00C(EnOwl* this, PlayState* play) { case 9: if (IS_RANDO) { if (Randomizer_GetSettingValue(RSK_SHUFFLE_OWL_DROPS)) { - play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_KAKARIKO_VILLAGE_14); + play->nextEntranceIndex = Entrance_OverrideNextIndex(ENTR_KAKARIKO_VILLAGE_OWL_DROP); } else { - play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_14; + play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_OWL_DROP; } play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_BLACK; @@ -994,7 +996,7 @@ void func_80ACC00C(EnOwl* this, PlayState* play) { break; } - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); gSaveContext.cutsceneTrigger = 1; func_800F44EC(0x14, 0xA); this->actionFunc = EnOwl_WaitDefault; @@ -1146,7 +1148,7 @@ void EnOwl_Update(Actor* thisx, PlayState* play) { } if (this->actor.draw != NULL) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } if (this->actionFlags & 2) { diff --git a/soh/src/overlays/actors/ovl_En_Part/z_en_part.c b/soh/src/overlays/actors/ovl_En_Part/z_en_part.c index be1143ff1..0539e980b 100644 --- a/soh/src/overlays/actors/ovl_En_Part/z_en_part.c +++ b/soh/src/overlays/actors/ovl_En_Part/z_en_part.c @@ -244,7 +244,7 @@ void EnPart_Update(Actor* thisx, PlayState* play) { EnPart* this = (EnPart*)thisx; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if ((this->actor.params > 4 && this->actor.params < 9) || this->actor.params < 0) { Actor_UpdateBgCheckInfo(play, &this->actor, 5.0f, 15.0f, 0.0f, 5); diff --git a/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c b/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c index f0097b5bd..20db2a510 100644 --- a/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c +++ b/soh/src/overlays/actors/ovl_En_Partner/z_en_partner.c @@ -11,6 +11,8 @@ #include #include #include +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_DRAGGED_BY_HOOKSHOT | ACTOR_FLAG_CAN_PRESS_SWITCH) @@ -196,7 +198,7 @@ void UseBow(Actor* thisx, PlayState* play, u8 started, u8 arrowType) { if (this->itemTimer <= 0) { if (AMMO(ITEM_BOW) > 0) { if (arrowType >= 1 && !Magic_RequestChange(play, magicArrowCosts[arrowType], MAGIC_CONSUME_NOW)) { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); this->canMove = 1; return; } @@ -244,7 +246,7 @@ void UseSlingshot(Actor* thisx, PlayState* play, u8 started) { newarrow->parent = NULL; Inventory_ChangeAmmo(ITEM_SLINGSHOT, -1); } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } } @@ -261,7 +263,7 @@ void UseBombs(Actor* thisx, PlayState* play, u8 started) { this->actor.world.pos.z, 0, 0, 0, 0, false); Inventory_ChangeAmmo(ITEM_BOMB, -1); } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } } @@ -302,7 +304,7 @@ void UseBombchus(Actor* thisx, PlayState* play, u8 started) { bomb->timer = 0; Inventory_ChangeAmmo(ITEM_BOMBCHU, -1); } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } } @@ -322,7 +324,7 @@ void UseDekuStick(Actor* thisx, PlayState* play, u8 started) { if (AMMO(ITEM_STICK) > 0) { func_808328EC(this, NA_SE_EV_FLAME_IGNITION); } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } @@ -358,7 +360,7 @@ void UseNuts(Actor* thisx, PlayState* play, u8 started) { this->actor.world.pos.z, 0x1000, this->actor.world.rot.y, 0, ARROW_NUT, false); Inventory_ChangeAmmo(ITEM_NUT, -1); } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } } @@ -415,12 +417,12 @@ void UseLens(Actor* thisx, PlayState* play, u8 started) { if (this->itemTimer <= 0) { if (started == 1) { - func_80078884(NA_SE_SY_GLASSMODE_ON); + Sfx_PlaySfxCentered(NA_SE_SY_GLASSMODE_ON); this->shouldDraw = 0; } if (started == 0) { - func_80078884(NA_SE_SY_GLASSMODE_OFF); + Sfx_PlaySfxCentered(NA_SE_SY_GLASSMODE_OFF); this->shouldDraw = 1; } } @@ -436,7 +438,7 @@ void UseBeans(Actor* thisx, PlayState* play, u8 started) { if (gSaveContext.rupees >= 100 && GiveItemEntryWithoutActor(play, this->entry)) { Rupees_ChangeBy(-100); } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } } @@ -629,7 +631,7 @@ void EnPartner_Update(Actor* thisx, PlayState* play) { this->actor.gravity = this->yVelocity; if (this->canMove == 1) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 19.0f, 20.0f, 0.0f, 5); } diff --git a/soh/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c b/soh/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c index 5526ad49c..2667bb099 100644 --- a/soh/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c +++ b/soh/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c @@ -3,6 +3,7 @@ #include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_PLAY_HIT_SFX) @@ -939,7 +940,7 @@ void EnPeehat_Update(Actor* thisx, PlayState* play) { } if (thisx->colChkInfo.damageEffect != PEAHAT_DMG_EFF_LIGHT_ICE_ARROW) { if (thisx->speedXZ != 0.0f || thisx->velocity.y != 0.0f) { - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); Actor_UpdateBgCheckInfo(play, thisx, 25.0f, 30.0f, 30.0f, 5); } diff --git a/soh/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c b/soh/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c index 2c00b284b..7b0bdcee5 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c +++ b/soh/src/overlays/actors/ovl_En_Po_Desert/z_en_po_desert.c @@ -6,6 +6,7 @@ #include "z_en_po_desert.h" #include "objects/object_po_field/object_po_field.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_LENS | ACTOR_FLAG_IGNORE_QUAKE) @@ -194,7 +195,7 @@ void EnPoDesert_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); EnPoDesert_UpdateSpeedModifier(this); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 27.0f, 60.0f, 4); Actor_SetFocus(&this->actor, 42.0f); diff --git a/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c b/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c index d391840ba..ca0e7b3ba 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c +++ b/soh/src/overlays/actors/ovl_En_Po_Field/z_en_po_field.c @@ -8,6 +8,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_po_field/object_po_field.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #include @@ -332,7 +333,7 @@ void func_80AD42B0(EnPoField* this) { this->actor.scale.y = 0.0f; Audio_PlayActorSound2(&this->actor, NA_SE_EV_METAL_BOX_BOUND); if (this->actor.params == EN_PO_FIELD_BIG) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } this->actionFunc = func_80AD587C; } @@ -620,7 +621,7 @@ void EnPoField_SoulIdle(EnPoField* this, PlayState* play) { } else if (this->actionTimer == 0) { EnPoField_SetupWaitForSpawn(this, play); } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 10.0f, 10.0f, 4); } @@ -866,7 +867,7 @@ void EnPoField_Update(Actor* thisx, PlayState* play) { EnPoField_UpdateFlame(this, play); if (this->actionFunc == EnPoField_Flee || this->actionFunc == EnPoField_Damage || this->actionFunc == EnPoField_Appear) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } if (this->actionFunc != EnPoField_WaitForSpawn) { Actor_SetFocus(&this->actor, 42.0f); diff --git a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c index 8489b1032..7ce6cc8df 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c +++ b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c @@ -7,6 +7,7 @@ #include "z_en_po_relay.h" #include "overlays/actors/ovl_En_Honotrap/z_en_honotrap.h" #include "objects/object_tk/object_tk.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_IGNORE_QUAKE | ACTOR_FLAG_WILL_TALK) @@ -381,7 +382,7 @@ void EnPoRelay_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); EnPoRelay_CorrectY(this); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 27.0f, 60.0f, 4); Collider_UpdateCylinder(&this->actor, &this->collider); diff --git a/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c b/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c index e1a1d1f31..6014aebbe 100644 --- a/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c +++ b/soh/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c @@ -9,6 +9,8 @@ #include "objects/object_po_sisters/object_po_sisters.h" #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_HOOKSHOT_DRAGS | ACTOR_FLAG_IGNORE_QUAKE | ACTOR_FLAG_ARROW_DRAGGABLE) @@ -823,7 +825,7 @@ void func_80ADB17C(EnPoSisters* this, PlayState* play) { Flags_UnsetSwitch(play, 0x1B); } play->envCtx.unk_BF = 0xFF; - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Actor_Kill(&this->actor); } else if (this->unk_19A < 32) { func_80AD9240(this, this->unk_19A, &this->actor.world.pos); @@ -1196,7 +1198,7 @@ void EnPoSisters_Update(Actor* thisx, PlayState* play) { if (this->unk_199 & 8) { func_80ADA35C(this, play); } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->unk_199 & 0x10) { Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 0.0f, 5); diff --git a/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.c b/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.c index 2c7e90416..0d5e1e2cc 100644 --- a/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.c +++ b/soh/src/overlays/actors/ovl_En_Poh/z_en_poh.c @@ -8,6 +8,7 @@ #include "objects/object_poh/object_poh.h" #include "objects/object_po_composer/object_po_composer.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_IGNORE_QUAKE) @@ -733,7 +734,7 @@ void EnPoh_Death(EnPoh* this, PlayState* play) { Actor_Kill(&this->actor); return; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 10.0f, 10.0f, 4); } @@ -1002,7 +1003,7 @@ void EnPoh_UpdateLiving(Actor* thisx, PlayState* play) { func_80AE032C(this, play); EnPoh_UpdateVisibility(this); this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->actionFunc == EnPoh_Attack && this->unk_198 < 10) { this->actor.flags |= ACTOR_FLAG_PLAY_HIT_SFX; CollisionCheck_SetAT(play, &play->colChkCtx, &this->colliderSph.base); diff --git a/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c b/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c index 3a76aefc4..536032a8d 100644 --- a/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c +++ b/soh/src/overlays/actors/ovl_En_Pu_box/z_en_pu_box.c @@ -52,8 +52,8 @@ void EnPubox_Init(Actor* thisx, PlayState* play) { thisx->uncullZoneDownward = 1200.0f; thisx->uncullZoneScale = 720.0f; ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 6.0f); - this->dyna.unk_160 = 0; - this->dyna.unk_15C = DPM_UNK; + this->dyna.interactFlags = 0; + this->dyna.transformFlags = DPM_UNK; thisx->targetMode = 1; thisx->gravity = -2.0f; CollisionHeader_GetVirtual(&gBlockMediumCol, &colHeader); @@ -74,12 +74,12 @@ void EnPubox_Update(Actor* thisx, PlayState* play) { thisx->speedXZ = (thisx->speedXZ < -2.5f) ? -2.5f : ((thisx->speedXZ > 2.5f) ? 2.5f : thisx->speedXZ); Math_SmoothStepToF(&thisx->speedXZ, 0.0f, 1.0f, 1.0f, 0.0f); if (thisx->speedXZ != 0.0f) { - Audio_PlaySoundGeneral(NA_SE_EV_ROCK_SLIDE - SFX_FLAG, &thisx->projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_ROCK_SLIDE - SFX_FLAG, &thisx->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } this->dyna.unk_154 = 0.0f; this->dyna.unk_150 = 0.0f; - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); Actor_UpdateBgCheckInfo(play, thisx, thisx->colChkInfo.cylHeight, thisx->colChkInfo.cylRadius, thisx->colChkInfo.cylRadius, 0x1D); thisx->focus.pos = thisx->world.pos; diff --git a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c index 8990f67ea..a5fd7872c 100644 --- a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c +++ b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c @@ -1,6 +1,7 @@ #include "z_en_rd.h" #include "objects/object_rd/object_rd.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAGGED_BY_HOOKSHOT) @@ -823,7 +824,7 @@ void EnRd_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->unk_31B != 8 && this->actor.speedXZ != 0.0f) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } if ((this->actor.shape.rot.x == 0) && (this->unk_31B != 8) && (this->actor.speedXZ != 0.0f)) { diff --git a/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c b/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c index 76e5ae871..bab1bf046 100644 --- a/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c +++ b/soh/src/overlays/actors/ovl_En_Reeba/z_en_reeba.c @@ -10,6 +10,7 @@ #include "vt.h" #include "objects/object_reeba/object_reeba.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_LOCKON) @@ -607,7 +608,7 @@ void EnReeba_Update(Actor* thisx, PlayState* play2) { this->unk_276--; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 35.0f, 60.0f, 60.0f, 0x1D); if (this->collider.base.atFlags & AT_BOUNCED) { diff --git a/soh/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c b/soh/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c index 5012dff2b..2885e6cdf 100644 --- a/soh/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c +++ b/soh/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c @@ -201,7 +201,7 @@ void EnRiverSound_Update(Actor* thisx, PlayState* play) { } } } else if ((thisx->params == RS_UNK_13) || (thisx->params == RS_UNK_19)) { - func_8002DBD0(&player->actor, &thisx->home.pos, &thisx->world.pos); + Actor_WorldToActorCoords(&player->actor, &thisx->home.pos, &thisx->world.pos); } else if (play->sceneNum == SCENE_DODONGOS_CAVERN_BOSS && Flags_GetClear(play, thisx->room)) { Actor_Kill(thisx); } @@ -250,7 +250,7 @@ void EnRiverSound_Draw(Actor* thisx, PlayState* play) { Audio_PlaySariaBgm(&this->actor.home.pos, NA_BGM_GREAT_FAIRY, 800); } else if ((this->actor.params == RS_SANDSTORM) || (this->actor.params == RS_CHAMBER_OF_SAGES_1) || (this->actor.params == RS_CHAMBER_OF_SAGES_2) || (this->actor.params == RS_RUMBLING)) { - func_800788CC(soundEffects[this->actor.params]); + Sfx_PlaySfxCentered2(soundEffects[this->actor.params]); } else { Audio_PlayActorSound2(&this->actor, soundEffects[this->actor.params]); } diff --git a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c index f999f3486..a748bd380 100644 --- a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c +++ b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c @@ -795,7 +795,7 @@ void EnRr_Update(Actor* thisx, PlayState* play) { } Math_StepToF(&this->actor.speedXZ, 0.0f, 0.1f); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Collider_UpdateCylinder(&this->actor, &this->collider1); this->collider2.dim.pos.x = this->mouthPos.x; this->collider2.dim.pos.y = this->mouthPos.y; diff --git a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c index afc51e291..b6bb1a725 100644 --- a/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c +++ b/soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c @@ -7,6 +7,8 @@ #include "z_en_ru1.h" #include "objects/object_ru1/object_ru1.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_CAN_PRESS_SWITCH) @@ -563,14 +565,14 @@ void func_80AEBA2C(EnRu1* this, PlayState* play) { void func_80AEBAFC(EnRu1* this) { if (this->unk_298 == 0) { - func_80078914(&this->actor.projectedPos, NA_SE_EV_DIVE_INTO_WATER); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_DIVE_INTO_WATER); this->unk_298 = 1; } } void func_80AEBB3C(EnRu1* this) { if (Animation_OnFrame(&this->skelAnime, 5.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_FACE_UP); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_FACE_UP); } } @@ -579,13 +581,13 @@ void func_80AEBB78(EnRu1* this) { if (Animation_OnFrame(skelAnime, 4.0f) || Animation_OnFrame(skelAnime, 13.0f) || Animation_OnFrame(skelAnime, 22.0f) || Animation_OnFrame(skelAnime, 31.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_SWIM); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_SWIM); } } void func_80AEBBF4(EnRu1* this) { if (Animation_OnFrame(&this->skelAnime, 8.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_SUBMERGE); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_SUBMERGE); } } @@ -594,14 +596,14 @@ void func_80AEBC30(PlayState* play) { if (play->csCtx.frames == 0xCD) { player = GET_PLAYER(play); - Audio_PlaySoundGeneral(NA_SE_EV_DIVE_INTO_WATER, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_DIVE_INTO_WATER, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } void func_80AEBC84(EnRu1* this, PlayState* play) { if (play->csCtx.frames == 0x82) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_RT_LAUGH_0); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_RT_LAUGH_0); } } @@ -762,14 +764,6 @@ void func_80AEC2C0(EnRu1* this, PlayState* play) { func_80AEC070(this, play, something); } -// Convenience function used so that Ruto always spawns in Jabu in rando, even after she's been kidnapped -// Equivalent to !Flags_GetInfTable(INFTABLE_145) in vanilla -bool shouldSpawnRuto() { - // Flags_GetInfTable(INFTABLE_146) check is to prevent Ruto from spawning during the short period of time when - // she's on the Zora's Sapphire pedestal but hasn't been kidnapped yet (would result in multiple Rutos otherwise) - return !Flags_GetInfTable(INFTABLE_145) || (IS_RANDO && (Flags_GetInfTable(INFTABLE_146))); -} - void func_80AEC320(EnRu1* this, PlayState* play) { s8 actorRoom; @@ -777,7 +771,10 @@ void func_80AEC320(EnRu1* this, PlayState* play) { func_80AEB264(this, &gRutoChildWait2Anim, 0, 0, 0); this->action = 7; EnRu1_SetMouthIndex(this, 1); - } else if ((Flags_GetInfTable(INFTABLE_147)) && !Flags_GetInfTable(INFTABLE_140) && shouldSpawnRuto()) { + } else if ( + Flags_GetInfTable(INFTABLE_147) && !Flags_GetInfTable(INFTABLE_140) && + GameInteractor_Should(VB_RUTO_BE_CONSIDERED_NOT_KIDNAPPED, !Flags_GetInfTable(INFTABLE_145), this) + ) { if (!func_80AEB020(this, play)) { func_80AEB264(this, &gRutoChildWait2Anim, 0, 0, 0); actorRoom = this->actor.room; @@ -804,12 +801,12 @@ void func_80AEC40C(EnRu1* this) { this->actor.speedXZ = (kREG(3) * 0.01f) + 2.7f; } this->actor.velocity.y = -1.0f; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void func_80AEC4CC(EnRu1* this) { this->actor.velocity.y = -1.0f; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void func_80AEC4F4(EnRu1* this) { @@ -824,7 +821,7 @@ void func_80AEC4F4(EnRu1* this) { *speedXZ = 0.0f; this->actor.velocity.y = -((kREG(4) * 0.01f) + 13.0f); } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } s32 func_80AEC5FC(EnRu1* this, PlayState* play) { @@ -843,14 +840,14 @@ void func_80AEC650(EnRu1* this) { if (this->unk_280 == 0) { if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 7.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_WALK_DIRT); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WALK_DIRT); } } } void func_80AEC6B0(EnRu1* this) { - func_80078914(&this->actor.projectedPos, NA_SE_EV_FALL_DOWN_DIRT); - func_80078914(&this->actor.projectedPos, NA_SE_VO_RT_FALL); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_FALL_DOWN_DIRT); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_RT_FALL); } void func_80AEC6E4(EnRu1* this, PlayState* play) { @@ -866,9 +863,9 @@ void func_80AEC780(EnRu1* this, PlayState* play) { s32 pad; Player* player = GET_PLAYER(play); - if ((func_80AEC5FC(this, play)) && (!Play_InCsMode(play)) && + if (GameInteractor_Should(VB_PLAY_CHILD_RUTO_INTRO, (func_80AEC5FC(this, play)) && (!Play_InCsMode(play)) && (!(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_CLIMBING_LADDER))) && - (player->actor.bgCheckFlags & 1)) { + (player->actor.bgCheckFlags & 1), this)) { play->csCtx.segment = &D_80AF0880; gSaveContext.cutsceneTrigger = 1; @@ -1182,8 +1179,11 @@ void func_80AED414(EnRu1* this, PlayState* play) { void func_80AED44C(EnRu1* this, PlayState* play) { s8 actorRoom; - if ((Flags_GetInfTable(INFTABLE_RUTO_IN_JJ_MEET_RUTO)) && shouldSpawnRuto() && !Flags_GetInfTable(INFTABLE_140) && - !Flags_GetInfTable(INFTABLE_147)) { + if ( + Flags_GetInfTable(INFTABLE_RUTO_IN_JJ_MEET_RUTO) && + GameInteractor_Should(VB_RUTO_BE_CONSIDERED_NOT_KIDNAPPED, !Flags_GetInfTable(INFTABLE_145), this) && + !Flags_GetInfTable(INFTABLE_140) && !Flags_GetInfTable(INFTABLE_147) + ) { if (!func_80AEB020(this, play)) { func_80AEB264(this, &gRutoChildWait2Anim, 0, 0, 0); actorRoom = this->actor.room; @@ -1201,33 +1201,33 @@ void func_80AED44C(EnRu1* this, PlayState* play) { } void func_80AED4FC(EnRu1* this) { - func_80078914(&this->actor.projectedPos, NA_SE_EV_LAND_DIRT); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_LAND_DIRT); } void func_80AED520(EnRu1* this, PlayState* play) { Player* player = GET_PLAYER(play); - Audio_PlaySoundGeneral(NA_SE_PL_PULL_UP_RUTO, &player->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); - func_80078914(&this->actor.projectedPos, NA_SE_VO_RT_LIFT); + Audio_PlaySoundGeneral(NA_SE_PL_PULL_UP_RUTO, &player->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_RT_LIFT); } void func_80AED57C(EnRu1* this) { if (this->actor.speedXZ != 0.0f) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_RT_THROW); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_RT_THROW); } } void func_80AED5B8(EnRu1* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_RT_CRASH); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_RT_CRASH); } void func_80AED5DC(EnRu1* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_RT_UNBALLANCE); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_RT_UNBALLANCE); } void func_80AED600(EnRu1* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_RT_DISCOVER); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_RT_DISCOVER); } s32 func_80AED624(EnRu1* this, PlayState* play) { @@ -1439,7 +1439,7 @@ void func_80AEDEF4(EnRu1* this, PlayState* play) { void func_80AEDFF4(EnRu1* this, PlayState* play) { func_80AEDB30(this, play); func_80AEDEF4(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void func_80AEE02C(EnRu1* this) { @@ -1479,7 +1479,7 @@ void func_80AEE050(EnRu1* this) { } this->actor.velocity.x = Math_SinS(this->actor.world.rot.y) * this->actor.speedXZ; this->actor.velocity.z = Math_CosS(this->actor.world.rot.y) * this->actor.speedXZ; - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); } } else { if (this->unk_350 == 1) { @@ -1549,8 +1549,8 @@ s32 func_80AEE394(EnRu1* this, PlayState* play) { colCtx = &play->colCtx; floorBgId = this->actor.floorBgId; // necessary match, can't move this out of this block unfortunately dynaPolyActor = DynaPoly_GetActor(colCtx, floorBgId); - if (dynaPolyActor != NULL && dynaPolyActor->actor.id == ACTOR_BG_BDAN_OBJECTS && - dynaPolyActor->actor.params == 0 && !Player_InCsMode(play) && play->msgCtx.msgLength == 0) { + if (GameInteractor_Should(VB_RUTO_RUN_TO_SAPPHIRE, dynaPolyActor != NULL && dynaPolyActor->actor.id == ACTOR_BG_BDAN_OBJECTS && + dynaPolyActor->actor.params == 0 && !Player_InCsMode(play) && play->msgCtx.msgLength == 0, this, dynaPolyActor)) { func_80AEE02C(this); play->csCtx.segment = &D_80AF10A4; gSaveContext.cutsceneTrigger = 1; @@ -1583,7 +1583,7 @@ void func_80AEE568(EnRu1* this, PlayState* play) { if (!func_80AEE394(this, play)) { if ((this->actor.bgCheckFlags & 1) && (this->actor.speedXZ == 0.0f) && (this->actor.minVelocityY == 0.0f)) { func_80AEE02C(this); - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); this->action = 27; func_80AEADD8(this); } else if (this->actor.yDistToWater > 0.0f) { @@ -1610,7 +1610,7 @@ s32 func_80AEE6D0(EnRu1* this, PlayState* play) { s32 pad; s8 curRoomNum = play->roomCtx.curRoom.num; - if (!Flags_GetInfTable(INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE) && (func_80AEB124(play) != 0)) { + if (GameInteractor_Should(VB_RUTO_WANT_TO_BE_TOSSED_TO_SAPPHIRE, !Flags_GetInfTable(INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE) && (func_80AEB124(play) != 0), this)) { if (!Player_InCsMode(play)) { Animation_Change(&this->skelAnime, &gRutoChildSeesSapphireAnim, 1.0f, 0, Animation_GetLastFrame(&gRutoChildSquirmAnim), ANIMMODE_LOOP, -8.0f); @@ -1684,7 +1684,7 @@ void func_80AEE7C4(EnRu1* this, PlayState* play) { s32 func_80AEEAC8(EnRu1* this, PlayState* play) { if (this->actor.bgCheckFlags & 1) { func_80AEE02C(this); - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); this->action = 27; func_80AEADD8(this); return true; @@ -1702,7 +1702,7 @@ void func_80AEEB24(EnRu1* this, PlayState* play) { } void func_80AEEBB4(EnRu1* this, PlayState* play) { - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); } void func_80AEEBD4(EnRu1* this, PlayState* play) { @@ -1743,7 +1743,7 @@ void func_80AEECF0(EnRu1* this, PlayState* play) { void func_80AEED58(EnRu1* this, PlayState* play) { func_80AED83C(this); func_80AEAECC(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); EnRu1_UpdateSkelAnime(this); EnRu1_UpdateEyes(this); func_80AEEAC8(this, play); @@ -1815,7 +1815,7 @@ void func_80AEEFEC(EnRu1* this, PlayState* play) { void func_80AEF080(EnRu1* this) { if (Animation_OnFrame(&this->skelAnime, 11.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_EV_LAND_DIRT); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_LAND_DIRT); } } @@ -1854,7 +1854,7 @@ void func_80AEF1F0(EnRu1* this, PlayState* play, UNK_TYPE arg2) { Message_CloseTextbox(play); Flags_SetInfTable(INFTABLE_143); func_80AED6DC(this, play); - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); this->action = 27; func_80AEADD8(this); } @@ -1908,7 +1908,7 @@ void func_80AEF40C(EnRu1* this) { if (Animation_OnFrame(skelAnime, 2.0f) || Animation_OnFrame(skelAnime, 7.0f) || Animation_OnFrame(skelAnime, 12.0f) || Animation_OnFrame(skelAnime, 18.0f) || Animation_OnFrame(skelAnime, 25.0f) || Animation_OnFrame(skelAnime, 33.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_WALK_DIRT); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WALK_DIRT); } } @@ -1918,12 +1918,12 @@ void func_80AEF4A8(EnRu1* this, PlayState* play) { void func_80AEF4E0(EnRu1* this) { if (Animation_OnFrame(&this->skelAnime, 5.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_RT_LAUGH_0); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_RT_LAUGH_0); } } void func_80AEF51C(EnRu1* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_RT_THROW); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_RT_THROW); } void func_80AEF540(EnRu1* this) { @@ -2189,8 +2189,11 @@ void func_80AEFF40(EnRu1* this, PlayState* play) { void func_80AEFF94(EnRu1* this, PlayState* play) { s8 actorRoom; - if ((Flags_GetInfTable(INFTABLE_RUTO_IN_JJ_MEET_RUTO)) && (Flags_GetInfTable(INFTABLE_140)) && shouldSpawnRuto() && - (!(func_80AEB020(this, play)))) { + if ( + Flags_GetInfTable(INFTABLE_RUTO_IN_JJ_MEET_RUTO) && Flags_GetInfTable(INFTABLE_140) && + GameInteractor_Should(VB_RUTO_BE_CONSIDERED_NOT_KIDNAPPED, !Flags_GetInfTable(INFTABLE_145), this) && + (!(func_80AEB020(this, play))) + ) { func_80AEB264(this, &gRutoChildWait2Anim, 0, 0, 0); actorRoom = this->actor.room; this->action = 22; diff --git a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c index dee36edfa..b4c4d9053 100644 --- a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c +++ b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c @@ -8,6 +8,7 @@ #include "objects/object_ru2/object_ru2.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -17,32 +18,61 @@ void EnRu2_Destroy(Actor* thisx, PlayState* play); void EnRu2_Update(Actor* thisx, PlayState* play); void EnRu2_Draw(Actor* thisx, PlayState* play); -void func_80AF2CB4(EnRu2* this, PlayState* play); -void func_80AF2CD4(EnRu2* this, PlayState* play); -void func_80AF2CF4(EnRu2* this, PlayState* play); -void func_80AF2D2C(EnRu2* this, PlayState* play); -void func_80AF2D6C(EnRu2* this, PlayState* play); -void func_80AF2DAC(EnRu2* this, PlayState* play); -void func_80AF2DEC(EnRu2* this, PlayState* play); -void func_80AF3144(EnRu2* this, PlayState* play); -void func_80AF3174(EnRu2* this, PlayState* play); -void func_80AF31C8(EnRu2* this, PlayState* play); -void func_80AF3604(EnRu2* this, PlayState* play); -void func_80AF3624(EnRu2* this, PlayState* play); -void func_80AF366C(EnRu2* this, PlayState* play); -void func_80AF36AC(EnRu2* this, PlayState* play); -void func_80AF3BC8(EnRu2* this, PlayState* play); -void func_80AF3C04(EnRu2* this, PlayState* play); -void func_80AF3C64(EnRu2* this, PlayState* play); -void func_80AF3CB8(EnRu2* this, PlayState* play); -void func_80AF3D0C(EnRu2* this, PlayState* play); -void func_80AF3D60(EnRu2* this, PlayState* play); +void EnRu2_SetupWaterMedallionCutscene(EnRu2* this, PlayState* play); +void EnRu2_AwaitBlueWarp(EnRu2* this, PlayState* play); +void EnRu2_RiseThroughBlueWarp(EnRu2* this, PlayState* play); +void EnRu2_SageOfWaterDialog(EnRu2* this, PlayState* play); +void EnRu2_RaiseArms(EnRu2* this, PlayState* play); +void EnRu2_AwaitWaterMedallion(EnRu2* this, PlayState* play); +void EnRu2_FinishWaterMedallionCutscene(EnRu2* this, PlayState* play); +void EnRu2_WaterTrialInvisible(EnRu2* this, PlayState* play); +void EnRu2_WaterTrialFade(EnRu2* this, PlayState* play); +void EnRu2_AwaitSpawnLightBall(EnRu2* this, PlayState* play); +void EnRu2_CreditsInvisible(EnRu2* this, PlayState* play); +void EnRu2_CreditsFadeIn(EnRu2* this, PlayState* play); +void EnRu2_CreditsVisible(EnRu2* this, PlayState* play); +void EnRu2_CreditsTurnHeadDownLeft(EnRu2* this, PlayState* play); +void EnRu2_WaterTempleEncounterRangeCheck(EnRu2* this, PlayState* play); +void EnRu2_WaterTempleEncounterUnconditional(EnRu2* this, PlayState* play); +void EnRu2_WaterTempleEncounterBegin(EnRu2* this, PlayState* play); +void EnRu2_WaterTempleEncounterDialog(EnRu2* this, PlayState* play); +void EnRu2_WaterTempleEncounterEnd(EnRu2* this, PlayState* play); +void EnRu2_WaterTempleSwimmingUp(EnRu2* this, PlayState* play); -void func_80AF3F14(EnRu2* this, PlayState* play); -void func_80AF3F20(EnRu2* this, PlayState* play); -void func_80AF321C(EnRu2* this, PlayState* play); +void EnRu2_DrawNothing(EnRu2* this, PlayState* play); +void EnRu2_DrawOpa(EnRu2* this, PlayState* play); +void EnRu2_DrawXlu(EnRu2* this, PlayState* play); -void func_80AF2AB4(EnRu2* this, PlayState* play); +void EnRu2_CheckWaterMedallionCutscene(EnRu2* this, PlayState* play); + +typedef enum { + /* 00 */ ENRU2_SETUP_WATER_MEDALLION_CS, + /* 01 */ ENRU2_AWAIT_BLUE_WARP, + /* 02 */ ENRU2_RISE_THROUGH_BLUE_WARP, + /* 03 */ ENRU2_SAGE_OF_WATER_DIALOG, + /* 04 */ ENRU2_RAISE_ARMS, + /* 05 */ ENRU2_AWAIT_SPAWN_WATER_MEDALLION, + /* 06 */ ENRU2_FINISH_WATER_MEDALLION_CS, + /* 07 */ ENRU2_WATER_TRIAL_INVISIBLE, + /* 08 */ ENRU2_WATER_TRIAL_FADE, + /* 09 */ ENRU2_AWAIT_SPAWN_LIGHT_BALL, + /* 10 */ ENRU2_CREDITS_INVISIBLE, + /* 11 */ ENRU2_CREDITS_FADE_IN, + /* 12 */ ENRU2_CREDITS_VISIBLE, + /* 13 */ ENRU2_CREDITS_TURN_HEAD_DOWN_LEFT, + /* 14 */ ENRU2_WATER_TEMPLE_ENCOUNTER_RANGE_CHECK, + /* 15 */ ENRU2_WATER_TEMPLE_ENCOUNTER_UNCONDITIONAL, // unused + /* 16 */ ENRU2_WATER_TEMPLE_ENCOUNTER_BEGINNING, + /* 17 */ ENRU2_WATER_TEMPLE_ENCOUNTER_DIALOG, + /* 18 */ ENRU2_WATER_TEMPLE_ENCOUNTER_END, + /* 19 */ ENRU2_WATER_TEMPLE_SWIMMING_UP, +} EnRu2Action; + +typedef enum { + /* 00 */ ENRU2_DRAW_NOTHING, + /* 01 */ ENRU2_DRAW_OPA, + /* 02 */ ENRU2_DRAW_XLU, +} EnRu2DrawConfig; static ColliderCylinderInitType1 sCylinderInit = { { @@ -67,15 +97,32 @@ static UNK_TYPE D_80AF4118 = 0; #include "z_en_ru2_cutscene_data.c" EARLY static EnRu2ActionFunc sActionFuncs[] = { - func_80AF2CB4, func_80AF2CD4, func_80AF2CF4, func_80AF2D2C, func_80AF2D6C, func_80AF2DAC, func_80AF2DEC, - func_80AF3144, func_80AF3174, func_80AF31C8, func_80AF3604, func_80AF3624, func_80AF366C, func_80AF36AC, - func_80AF3BC8, func_80AF3C04, func_80AF3C64, func_80AF3CB8, func_80AF3D0C, func_80AF3D60, + EnRu2_SetupWaterMedallionCutscene, + EnRu2_AwaitBlueWarp, + EnRu2_RiseThroughBlueWarp, + EnRu2_SageOfWaterDialog, + EnRu2_RaiseArms, + EnRu2_AwaitWaterMedallion, + EnRu2_FinishWaterMedallionCutscene, + EnRu2_WaterTrialInvisible, + EnRu2_WaterTrialFade, + EnRu2_AwaitSpawnLightBall, + EnRu2_CreditsInvisible, + EnRu2_CreditsFadeIn, + EnRu2_CreditsVisible, + EnRu2_CreditsTurnHeadDownLeft, + EnRu2_WaterTempleEncounterRangeCheck, + EnRu2_WaterTempleEncounterUnconditional, + EnRu2_WaterTempleEncounterBegin, + EnRu2_WaterTempleEncounterDialog, + EnRu2_WaterTempleEncounterEnd, + EnRu2_WaterTempleSwimmingUp, }; static EnRu2DrawFunc sDrawFuncs[] = { - func_80AF3F14, - func_80AF3F20, - func_80AF321C, + EnRu2_DrawNothing, + EnRu2_DrawOpa, + EnRu2_DrawXlu, }; const ActorInit En_Ru2_InitVars = { @@ -91,14 +138,14 @@ const ActorInit En_Ru2_InitVars = { NULL, }; -void func_80AF2550(Actor* thisx, PlayState* play) { +void EnRu2_InitCollider(Actor* thisx, PlayState* play) { EnRu2* this = (EnRu2*)thisx; Collider_InitCylinder(play, &this->collider); Collider_SetCylinderType1(play, &this->collider, &this->actor, &sCylinderInit); } -void func_80AF259C(EnRu2* this, PlayState* play) { +void EnRu2_UpdateCollider(EnRu2* this, PlayState* play) { s32 pad[5]; Collider_UpdateCylinder(&this->actor, &this->collider); @@ -113,40 +160,40 @@ void EnRu2_Destroy(Actor* thisx, PlayState* play) { ResourceMgr_UnregisterSkeleton(&this->skelAnime); } -void func_80AF2608(EnRu2* this) { +void EnRu2_UpdateEyes(EnRu2* this) { s32 pad[3]; - s16* unk_2A6 = &this->unk_2A6; - s16* unk_2A4 = &this->unk_2A4; + s16* blinkTimer = &this->blinkTimer; + s16* eyeIndex = &this->eyeIndex; - if (!DECR(*unk_2A6)) { - *unk_2A6 = Rand_S16Offset(0x3C, 0x3C); + if (!DECR(*blinkTimer)) { + *blinkTimer = Rand_S16Offset(0x3C, 0x3C); } - *unk_2A4 = *unk_2A6; - if (*unk_2A4 >= 3) { - *unk_2A4 = 0; + *eyeIndex = *blinkTimer; + if (*eyeIndex >= 3) { + *eyeIndex = 0; } } -s32 func_80AF2690(EnRu2* this) { - s32 params_shift = this->actor.params >> 8; +s32 EnRu2_GetSwitchFlag(EnRu2* this) { + s32 switchFlag = this->actor.params >> 8; - return params_shift & 0xFF; + return switchFlag & 0xFF; } -s32 func_80AF26A0(EnRu2* this) { +s32 EnRu2_GetType(EnRu2* this) { s16 params = this->actor.params; return params & 0xFF; } void func_80AF26AC(EnRu2* this) { - this->action = 7; - this->drawConfig = 0; + this->action = ENRU2_WATER_TRIAL_INVISIBLE; + this->drawConfig = ENRU2_DRAW_NOTHING; this->alpha = 0; - this->unk_2B8 = 0; + this->isLightBall = false; this->actor.shape.shadowAlpha = 0; - this->unk_2B0 = 0.0f; + this->fadeTimer = 0.0f; } void func_80AF26D0(EnRu2* this, PlayState* play) { @@ -154,6 +201,7 @@ void func_80AF26D0(EnRu2* this, PlayState* play) { if (play->csCtx.state == CS_STATE_IDLE) { if (D_80AF4118 != 0) { + // Seems like this state is never reached if (this->actor.params == 2) { func_80AF26AC(this); } @@ -168,7 +216,7 @@ void func_80AF26D0(EnRu2* this, PlayState* play) { } } -void func_80AF2744(EnRu2* this, PlayState* play) { +void EnRu2_UpdateBgCheckInfo(EnRu2* this, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 75.0f, 30.0f, 30.0f, 4); } @@ -176,75 +224,93 @@ s32 EnRu2_UpdateSkelAnime(EnRu2* this) { return SkelAnime_Update(&this->skelAnime); } -CsCmdActorCue* func_80AF27AC(PlayState* play, s32 npcActionIdx) { +CsCmdActorCue* EnRu2_GetCue(PlayState* play, s32 cueChannel) { if (play->csCtx.state != CS_STATE_IDLE) { - return play->csCtx.npcActions[npcActionIdx]; + return play->csCtx.npcActions[cueChannel]; } return NULL; } -s32 func_80AF27D0(EnRu2* this, PlayState* play, u16 arg2, s32 npcActionIdx) { - CsCmdActorCue* csCmdActorAction = func_80AF27AC(play, npcActionIdx); +s32 EnRu2_CheckCueMatchingId(EnRu2* this, PlayState* play, u16 cueId, s32 cueChannel) { + CsCmdActorCue* cue = EnRu2_GetCue(play, cueChannel); - if ((csCmdActorAction != NULL) && (csCmdActorAction->action == arg2)) { + if ((cue != NULL) && (cue->action == cueId)) { return true; } return false; } -s32 func_80AF281C(EnRu2* this, PlayState* play, u16 arg2, s32 npcActionIdx) { - CsCmdActorCue* csCmdNPCAction = func_80AF27AC(play, npcActionIdx); +s32 EnRu2_CheckCueNotMatchingId(EnRu2* this, PlayState* play, u16 cueId, s32 cueChannel) { + CsCmdActorCue* cue = EnRu2_GetCue(play, cueChannel); - if ((csCmdNPCAction != NULL) && (csCmdNPCAction->action != arg2)) { + if ((cue != NULL) && (cue->action != cueId)) { return true; } return false; } -void func_80AF2868(EnRu2* this, PlayState* play, u32 npcActionIdx) { - CsCmdActorCue* csCmdNPCAction = func_80AF27AC(play, npcActionIdx); +/** + * Checks cutscene data and, if applicable, configures Ruto's position accordingly. + */ +void EnRu2_InitPositionFromCue(EnRu2* this, PlayState* play, u32 npcActionIdx) { + CsCmdActorCue* cue = EnRu2_GetCue(play, npcActionIdx); s16 newRotY; Actor* thisx = &this->actor; - if (csCmdNPCAction != NULL) { - thisx->world.pos.x = csCmdNPCAction->startPos.x; - thisx->world.pos.y = csCmdNPCAction->startPos.y; - thisx->world.pos.z = csCmdNPCAction->startPos.z; - newRotY = csCmdNPCAction->rot.y; + if (cue != NULL) { + thisx->world.pos.x = cue->startPos.x; + thisx->world.pos.y = cue->startPos.y; + thisx->world.pos.z = cue->startPos.z; + newRotY = cue->rot.y; thisx->shape.rot.y = newRotY; thisx->world.rot.y = newRotY; } } -void func_80AF28E8(EnRu2* this, AnimationHeader* animation, u8 arg2, f32 transitionRate, s32 arg4) { +/** + * Changes the animation for Ruto's actor. The direction argument decides whether to play the animation + * forwards (if 0) or backwards (otherwise). + */ +void EnRu2_AnimationChange(EnRu2* this, AnimationHeader* animation, u8 mode, f32 transitionRate, s32 direction) { f32 frameCount = Animation_GetLastFrame(animation); f32 playbackSpeed; - f32 unk0; - f32 fc; + f32 startFrame; + f32 endFrame; - if (arg4 == 0) { - unk0 = 0.0f; - fc = frameCount; + if (direction == 0) { + startFrame = 0.0f; + endFrame = frameCount; playbackSpeed = 1.0f; } else { - unk0 = frameCount; - fc = 0.0f; + startFrame = frameCount; + endFrame = 0.0f; playbackSpeed = -1.0f; } - Animation_Change(&this->skelAnime, animation, playbackSpeed, unk0, fc, arg2, transitionRate); + Animation_Change(&this->skelAnime, animation, playbackSpeed, startFrame, endFrame, mode, transitionRate); } -void func_80AF2978(EnRu2* this, PlayState* play) { +/** + * Gradually increases Ruto's model's Y-offset as she rises up through the blue warp in the Chamber of Sages. + */ +void EnRu2_Rise(EnRu2* this, PlayState* play) { this->actor.shape.yOffset += 250.0f / 3.0f; } -void func_80AF2994(EnRu2* this, PlayState* play) { - func_80AF28E8(this, &gAdultRutoIdleAnim, 0, 0.0f, 0); +/** + * Sets up Ruto's actor in the Chamber of Sages. + * Note: All sages actors are present in the Chamber of Sages, regardless of which dungeon was just completed. + * This function runs unconditionally, even if it is not relevant for Ruto. + */ +void EnRu2_InitChamberOfSages(EnRu2* this, PlayState* play) { + EnRu2_AnimationChange(this, &gAdultRutoIdleAnim, 0, 0.0f, 0); this->actor.shape.yOffset = -10000.0f; } -void func_80AF29DC(EnRu2* this, PlayState* play) { +/** + * Spawns the blue warp for Ruto to rise up through in the Chamber of Sages. + */ +void EnRu2_SpawnBlueWarp(EnRu2* this, PlayState* play) { Actor* thisx = &this->actor; f32 posX = thisx->world.pos.x; f32 posY = thisx->world.pos.y; @@ -254,229 +320,265 @@ void func_80AF29DC(EnRu2* this, PlayState* play) { WARP_SAGES); } -void func_80AF2A38(EnRu2* this, PlayState* play) { +/** + * Spawns the Water Medallion. + */ +void EnRu2_SpawnWaterMedallion(EnRu2* this, PlayState* play) { Player* player = GET_PLAYER(play); f32 posX = player->actor.world.pos.x; f32 posY = player->actor.world.pos.y + 50.0f; f32 posZ = player->actor.world.pos.z; Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_EFFECT, posX, posY, posZ, 0, 0, 0, 10); + // Give the water medallion. This is redundant as it was already given in `EnRu2_CheckWaterMedallionCutscene` if (GameInteractor_Should(VB_GIVE_ITEM_WATER_MEDALLION, true)) { Item_Give(play, ITEM_MEDALLION_WATER); } } -void func_80AF2AB4(EnRu2* this, PlayState* play) { +/** + * Sets up the Water Medallion Cutscene if coming from Water Temple. + * All sage actors are present in the Chamber of Sages regardless of which dungeon was just completed. + * This function will loop endlessly if the current sage cutscene is not for the Water Medallion. + */ +void EnRu2_CheckWaterMedallionCutscene(EnRu2* this, PlayState* play) { s32 pad[2]; Player* player; - s16 temp; + s16 yaw; if ((gSaveContext.chamberCutsceneNum == 2) && (gSaveContext.sceneSetupIndex < 4)) { player = GET_PLAYER(play); - this->action = 1; - play->csCtx.segment = &D_80AF411C; + this->action = ENRU2_AWAIT_BLUE_WARP; + play->csCtx.segment = &gWaterMedallionCs; gSaveContext.cutsceneTrigger = 2; if (GameInteractor_Should(VB_GIVE_ITEM_WATER_MEDALLION, true)) { Item_Give(play, ITEM_MEDALLION_WATER); } - temp = this->actor.world.rot.y + 0x8000; - player->actor.shape.rot.y = temp; - player->actor.world.rot.y = temp; + yaw = this->actor.world.rot.y + 0x8000; + player->actor.shape.rot.y = yaw; + player->actor.world.rot.y = yaw; } } -void func_80AF2B44(EnRu2* this, PlayState* play) { +void EnRu2_CheckIfBlueWarpShouldSpawn(EnRu2* this, PlayState* play) { CutsceneContext* csCtx = &play->csCtx; - CsCmdActorCue* csCmdNPCAction; + CsCmdActorCue* cue; if (csCtx->state != CS_STATE_IDLE) { - csCmdNPCAction = csCtx->npcActions[3]; - if ((csCmdNPCAction != NULL) && (csCmdNPCAction->action == 2)) { - this->action = 2; - this->drawConfig = 1; - func_80AF29DC(this, play); + cue = csCtx->npcActions[3]; + if ((cue != NULL) && (cue->action == 2)) { + this->action = ENRU2_RISE_THROUGH_BLUE_WARP; + this->drawConfig = ENRU2_DRAW_OPA; + EnRu2_SpawnBlueWarp(this, play); } } } -void func_80AF2B94(EnRu2* this) { +/* Halts Ruto's rise up through the blue warp in the Chamber of Sages once finished. */ +void EnRu2_EndRise(EnRu2* this) { if (this->actor.shape.yOffset >= 0.0f) { - this->action = 3; + this->action = ENRU2_SAGE_OF_WATER_DIALOG; this->actor.shape.yOffset = 0.0f; } } -void func_80AF2BC0(EnRu2* this, PlayState* play) { +/** + * Sets up the animation for Ruto to raise her arms to give Link the Water Medallion. + */ +void EnRu2_CheckStartRaisingArms(EnRu2* this, PlayState* play) { AnimationHeader* animation = &gAdultRutoRaisingArmsUpAnim; - CsCmdActorCue* csCmdNPCAction; + CsCmdActorCue* cue; if (play->csCtx.state != CS_STATE_IDLE) { - csCmdNPCAction = play->csCtx.npcActions[3]; - if ((csCmdNPCAction != NULL) && (csCmdNPCAction->action == 3)) { + cue = play->csCtx.npcActions[3]; + if ((cue != NULL) && (cue->action == 3)) { Animation_Change(&this->skelAnime, animation, 1.0f, 0.0f, Animation_GetLastFrame(animation), ANIMMODE_ONCE, 0.0f); - this->action = 4; + this->action = ENRU2_RAISE_ARMS; } } } -void func_80AF2C54(EnRu2* this, s32 arg1) { - if (arg1 != 0) { - this->action = 5; +/** + * At the end of Ruto's arms-raising animation, cues the next action: spawning the + * Water Medallion. + */ +void EnRu2_HoldArmsUp(EnRu2* this, s32 doneRaising) { + if (doneRaising != 0) { + this->action = ENRU2_AWAIT_SPAWN_WATER_MEDALLION; } } -void func_80AF2C68(EnRu2* this, PlayState* play) { - CsCmdActorCue* csCmdNPCAction; +/** + * Checks to see if the Water Medallion should spawn. + */ +void EnRu2_CheckIfWaterMedallionShouldSpawn(EnRu2* this, PlayState* play) { + CsCmdActorCue* cue; if (play->csCtx.state != CS_STATE_IDLE) { - csCmdNPCAction = play->csCtx.npcActions[6]; - if ((csCmdNPCAction != NULL) && (csCmdNPCAction->action == 2)) { - this->action = 6; - func_80AF2A38(this, play); + cue = play->csCtx.npcActions[6]; + if ((cue != NULL) && (cue->action == 2)) { + this->action = ENRU2_FINISH_WATER_MEDALLION_CS; + EnRu2_SpawnWaterMedallion(this, play); } } } -void func_80AF2CB4(EnRu2* this, PlayState* play) { - func_80AF2AB4(this, play); +void EnRu2_SetupWaterMedallionCutscene(EnRu2* this, PlayState* play) { + EnRu2_CheckWaterMedallionCutscene(this, play); } -void func_80AF2CD4(EnRu2* this, PlayState* play) { - func_80AF2B44(this, play); +void EnRu2_AwaitBlueWarp(EnRu2* this, PlayState* play) { + EnRu2_CheckIfBlueWarpShouldSpawn(this, play); } -void func_80AF2CF4(EnRu2* this, PlayState* play) { - func_80AF2978(this, play); +void EnRu2_RiseThroughBlueWarp(EnRu2* this, PlayState* play) { + EnRu2_Rise(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); - func_80AF2B94(this); + EnRu2_UpdateEyes(this); + EnRu2_EndRise(this); } -void func_80AF2D2C(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); +void EnRu2_SageOfWaterDialog(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); - func_80AF2BC0(this, play); + EnRu2_UpdateEyes(this); + EnRu2_CheckStartRaisingArms(this, play); } -void func_80AF2D6C(EnRu2* this, PlayState* play) { - s32 something; +void EnRu2_RaiseArms(EnRu2* this, PlayState* play) { + s32 animDone; - func_80AF2744(this, play); - something = EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); - func_80AF2C54(this, something); + EnRu2_UpdateBgCheckInfo(this, play); + animDone = EnRu2_UpdateSkelAnime(this); + EnRu2_UpdateEyes(this); + EnRu2_HoldArmsUp(this, animDone); } -void func_80AF2DAC(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); +void EnRu2_AwaitWaterMedallion(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); - func_80AF2C68(this, play); + EnRu2_UpdateEyes(this); + EnRu2_CheckIfWaterMedallionShouldSpawn(this, play); } -void func_80AF2DEC(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); +void EnRu2_FinishWaterMedallionCutscene(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); + EnRu2_UpdateEyes(this); } -void func_80AF2E1C(EnRu2* this, PlayState* play) { - func_80AF28E8(this, &gAdultRutoCrossingArmsAnim, 2, 0.0f, 0); - this->action = 7; +/** + * Sets up Ruto in her arms-crossing pose. Used in the Water Trial in Ganon's Castle and in the + * Chamber of Sages during the "Sealing Ganon" cutscene. + */ +void EnRu2_InitWaterTrial(EnRu2* this, PlayState* play) { + EnRu2_AnimationChange(this, &gAdultRutoCrossingArmsAnim, 2, 0.0f, 0); + this->action = ENRU2_WATER_TRIAL_INVISIBLE; this->actor.shape.shadowAlpha = 0; } -void func_80AF2E64() { - func_800788CC(NA_SE_SY_WHITE_OUT_T); +void EnRu2_PlayWhiteOutSound() { + Sfx_PlaySfxCentered2(NA_SE_SY_WHITE_OUT_T); } -void func_80AF2E84(EnRu2* this, PlayState* play) { +/** + * Spawns the ball of light that replaces Ruto's actor in the Water Trial. + */ +void EnRu2_SpawnLightBall(EnRu2* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DEMO_6K, this->actor.world.pos.x, kREG(19) + 24.0f + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 8); } -void func_80AF2F04(EnRu2* this, PlayState* play) { - if (func_80AF27D0(this, play, 4, 3)) { - this->action = 8; - this->drawConfig = 2; +/** + * Checks to see if it's time for Ruto to fade in while crossing her arms. + */ +void EnRu2_CheckFadeIn(EnRu2* this, PlayState* play) { + if (EnRu2_CheckCueMatchingId(this, play, 4, 3)) { + this->action = ENRU2_WATER_TRIAL_FADE; + this->drawConfig = ENRU2_DRAW_XLU; this->alpha = 0; this->actor.shape.shadowAlpha = 0; - this->unk_2B0 = 0.0f; - func_80AF2E64(); + this->fadeTimer = 0.0f; + EnRu2_PlayWhiteOutSound(); } } -void func_80AF2F58(EnRu2* this, PlayState* play) { - f32* unk_2B0 = &this->unk_2B0; +/** + * Fades Ruto's actor in or out. Both happen during the Water Trial. + */ +void EnRu2_Fade(EnRu2* this, PlayState* play) { + f32* fadeTimer = &this->fadeTimer; s32 alpha; - if (func_80AF27D0(this, play, 4, 3)) { - *unk_2B0 += 1.0f; - if (*unk_2B0 >= kREG(5) + 10.0f) { - this->action = 9; - this->drawConfig = 1; - *unk_2B0 = kREG(5) + 10.0f; + if (EnRu2_CheckCueMatchingId(this, play, 4, 3)) { + *fadeTimer += 1.0f; + if (*fadeTimer >= kREG(5) + 10.0f) { + this->action = ENRU2_AWAIT_SPAWN_LIGHT_BALL; + this->drawConfig = ENRU2_DRAW_OPA; + *fadeTimer = kREG(5) + 10.0f; this->alpha = 255; this->actor.shape.shadowAlpha = 0xFF; return; } } else { - *unk_2B0 -= 1.0f; - if (*unk_2B0 <= 0.0f) { - this->action = 7; - this->drawConfig = 0; - *unk_2B0 = 0.0f; + *fadeTimer -= 1.0f; + if (*fadeTimer <= 0.0f) { + this->action = ENRU2_WATER_TRIAL_INVISIBLE; + this->drawConfig = ENRU2_DRAW_NOTHING; + *fadeTimer = 0.0f; this->alpha = 0; this->actor.shape.shadowAlpha = 0; return; } } - alpha = (*unk_2B0 / (kREG(5) + 10.0f)) * 255.0f; + alpha = (*fadeTimer / (kREG(5) + 10.0f)) * 255.0f; this->alpha = alpha; this->actor.shape.shadowAlpha = alpha; } -void func_80AF30AC(EnRu2* this, PlayState* play) { - if (func_80AF281C(this, play, 4, 3)) { - this->action = 8; - this->drawConfig = 2; - this->unk_2B0 = kREG(5) + 10.0f; +/** + * Checks to see if it's time for Ruto to fade out while her arms are crossed. + */ +void EnRu2_CheckFadeOut(EnRu2* this, PlayState* play) { + if (EnRu2_CheckCueNotMatchingId(this, play, 4, 3)) { + this->action = ENRU2_WATER_TRIAL_FADE; + this->drawConfig = ENRU2_DRAW_XLU; + this->fadeTimer = kREG(5) + 10.0f; this->alpha = 255; - if (this->unk_2B8 == 0) { - func_80AF2E84(this, play); - this->unk_2B8 = 1; + if (!this->isLightBall) { + EnRu2_SpawnLightBall(this, play); + this->isLightBall = true; } this->actor.shape.shadowAlpha = 0xFF; } } -void func_80AF3144(EnRu2* this, PlayState* play) { - func_80AF2F04(this, play); +void EnRu2_WaterTrialInvisible(EnRu2* this, PlayState* play) { + EnRu2_CheckFadeIn(this, play); func_80AF26D0(this, play); } -void func_80AF3174(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); +void EnRu2_WaterTrialFade(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); - func_80AF2F58(this, play); + EnRu2_UpdateEyes(this); + EnRu2_Fade(this, play); func_80AF26D0(this, play); } -void func_80AF31C8(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); +void EnRu2_AwaitSpawnLightBall(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); - func_80AF30AC(this, play); + EnRu2_UpdateEyes(this); + EnRu2_CheckFadeOut(this, play); func_80AF26D0(this, play); } -void func_80AF321C(EnRu2* this, PlayState* play) { +void EnRu2_DrawXlu(EnRu2* this, PlayState* play) { s32 pad[2]; - s16 temp = this->unk_2A4; - void* tex = sEyeTextures[temp]; + s16 eyeIndex = this->eyeIndex; + void* tex = sEyeTextures[eyeIndex]; SkelAnime* skelAnime = &this->skelAnime; OPEN_DISPS(play->state.gfxCtx); @@ -494,140 +596,164 @@ void func_80AF321C(EnRu2* this, PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } -void func_80AF3394(EnRu2* this, PlayState* play) { - func_80AF28E8(this, &gAdultRutoIdleHandsOnHipsAnim, 0, 0.0f, 0); - this->action = 10; - this->drawConfig = 0; +/** + * Sets up Ruto's hands-on-hips pose during the credits sequence. + */ +void EnRu2_InitCredits(EnRu2* this, PlayState* play) { + EnRu2_AnimationChange(this, &gAdultRutoIdleHandsOnHipsAnim, 0, 0.0f, 0); + this->action = ENRU2_CREDITS_INVISIBLE; + this->drawConfig = ENRU2_DRAW_NOTHING; this->actor.shape.shadowAlpha = 0; } -void func_80AF33E0(EnRu2* this) { - f32* unk_2B0 = &this->unk_2B0; - f32 temp_f0; - s32 temp_f18; +/** + * Fades in Ruto's actor during the credits sequence. + */ +void EnRu2_FadeInCredits(EnRu2* this) { + f32* fadeTimer = &this->fadeTimer; + f32 fadeDuration; + s32 alpha; - *unk_2B0 += 1.0f; + *fadeTimer += 1.0f; - temp_f0 = kREG(17) + 10.0f; - if (temp_f0 <= *unk_2B0) { + fadeDuration = kREG(17) + 10.0f; + if (fadeDuration <= *fadeTimer) { this->alpha = 255; this->actor.shape.shadowAlpha = 0xFF; } else { - temp_f18 = (*unk_2B0 / temp_f0) * 255.0f; - this->alpha = temp_f18; - this->actor.shape.shadowAlpha = temp_f18; + alpha = (*fadeTimer / fadeDuration) * 255.0f; + this->alpha = alpha; + this->actor.shape.shadowAlpha = alpha; } } -void func_80AF346C(EnRu2* this, PlayState* play) { - func_80AF2868(this, play, 3); - this->action = 11; - this->drawConfig = 2; +void EnRu2_InitCreditsPosition(EnRu2* this, PlayState* play) { + EnRu2_InitPositionFromCue(this, play, 3); + this->action = ENRU2_CREDITS_FADE_IN; + this->drawConfig = ENRU2_DRAW_XLU; } -void func_80AF34A4(EnRu2* this) { - if (this->unk_2B0 >= kREG(17) + 10.0f) { - this->action = 12; - this->drawConfig = 1; +/** + * Checks for the end of Ruto's fade-in during the credits sequence. + */ +void EnRu2_CheckVisibleInCredits(EnRu2* this) { + if (this->fadeTimer >= kREG(17) + 10.0f) { + this->action = ENRU2_CREDITS_VISIBLE; + this->drawConfig = ENRU2_DRAW_OPA; } } -void func_80AF34F0(EnRu2* this) { - func_80AF28E8(this, &gAdultRutoHeadTurnDownLeftAnim, 2, 0.0f, 0); - this->action = 13; +/** + * Starts Ruto's animation to look down towards Nabooru during the credits sequence. + */ +void EnRu2_SetupTurnHeadDownLeftAnimation(EnRu2* this) { + EnRu2_AnimationChange(this, &gAdultRutoHeadTurnDownLeftAnim, 2, 0.0f, 0); + this->action = ENRU2_CREDITS_TURN_HEAD_DOWN_LEFT; } -void func_80AF3530(EnRu2* this, s32 arg1) { - if (arg1 != 0) { - func_80AF28E8(this, &gAdultRutoLookingDownLeftAnim, 0, 0.0f, 0); +/** + * Holds Ruto's pose looking down towards Nabooru during the credits sequence. + */ +void EnRu2_HoldLookingDownLeftPose(EnRu2* this, s32 isDoneTurning) { + if (isDoneTurning != 0) { + EnRu2_AnimationChange(this, &gAdultRutoLookingDownLeftAnim, 0, 0.0f, 0); } } -void func_80AF3564(EnRu2* this, PlayState* play) { - CsCmdActorCue* csCmdNPCAction = func_80AF27AC(play, 3); - s32 action; - s32 unk_2BC; +/** + * Advances Ruto's actions in two different places. + */ +void EnRu2_NextCreditsAction(EnRu2* this, PlayState* play) { + CsCmdActorCue* cue = EnRu2_GetCue(play, 3); + s32 nextCueId; + s32 currentCueId; - if (csCmdNPCAction != NULL) { - action = csCmdNPCAction->action; - unk_2BC = this->unk_2BC; - if (action != unk_2BC) { - switch (action) { + if (cue != NULL) { + nextCueId = cue->action; + currentCueId = this->cueId; + if (nextCueId != currentCueId) { + switch (nextCueId) { case 7: - func_80AF346C(this, play); + EnRu2_InitCreditsPosition(this, play); break; case 8: - func_80AF34F0(this); + EnRu2_SetupTurnHeadDownLeftAnimation(this); break; default: // "There is no such action!" osSyncPrintf("En_Ru2_inEnding_Check_DemoMode:そんな動作は無い!!!!!!!!\n"); break; } - this->unk_2BC = action; + this->cueId = nextCueId; } } } -void func_80AF3604(EnRu2* this, PlayState* play) { - func_80AF3564(this, play); +void EnRu2_CreditsInvisible(EnRu2* this, PlayState* play) { + EnRu2_NextCreditsAction(this, play); } -void func_80AF3624(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); +void EnRu2_CreditsFadeIn(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); - func_80AF33E0(this); - func_80AF34A4(this); + EnRu2_UpdateEyes(this); + EnRu2_FadeInCredits(this); + EnRu2_CheckVisibleInCredits(this); } -void func_80AF366C(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); +void EnRu2_CreditsVisible(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); - func_80AF3564(this, play); + EnRu2_UpdateEyes(this); + EnRu2_NextCreditsAction(this, play); } -void func_80AF36AC(EnRu2* this, PlayState* play) { - s32 something; +void EnRu2_CreditsTurnHeadDownLeft(EnRu2* this, PlayState* play) { + s32 animDone; - func_80AF2744(this, play); - something = EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); - func_80AF3530(this, something); + EnRu2_UpdateBgCheckInfo(this, play); + animDone = EnRu2_UpdateSkelAnime(this); + EnRu2_UpdateEyes(this); + EnRu2_HoldLookingDownLeftPose(this, animDone); } -void func_80AF36EC(EnRu2* this, PlayState* play) { - Flags_SetSwitch(play, func_80AF2690(this)); +void EnRu2_SetEncounterSwitchFlag(EnRu2* this, PlayState* play) { + Flags_SetSwitch(play, EnRu2_GetSwitchFlag(this)); } -s32 func_80AF3718(EnRu2* this, PlayState* play) { - return Flags_GetSwitch(play, func_80AF2690(this)); +s32 EnRu2_GetEncounterSwitchFlag(EnRu2* this, PlayState* play) { + return Flags_GetSwitch(play, EnRu2_GetSwitchFlag(this)); } -void func_80AF3744(EnRu2* this, PlayState* play) { - if (func_80AF3718(this, play)) { +/** + * Initializes Ruto's actor in the Water Temple, or destroys it if the encounter already happened. + */ +void EnRu2_InitWaterTempleEncounter(EnRu2* this, PlayState* play) { + if (EnRu2_GetEncounterSwitchFlag(this, play)) { Actor_Kill(&this->actor); } else { - func_80AF28E8(this, &gAdultRutoIdleAnim, 0, 0.0f, 0); - this->action = 14; - this->drawConfig = 1; + EnRu2_AnimationChange(this, &gAdultRutoIdleAnim, 0, 0.0f, 0); + this->action = ENRU2_WATER_TEMPLE_ENCOUNTER_RANGE_CHECK; + this->drawConfig = ENRU2_DRAW_OPA; } } -void func_80AF37AC(void) { +void EnRu2_PlayFanfare(void) { Audio_PlayFanfare(NA_BGM_APPEAR); } -void func_80AF37CC(EnRu2* this) { +/** + * Accelerates Ruto's actor upwards as she swims. + */ +void EnRu2_SwimUpProgress(EnRu2* this) { f32 funcFloat; - this->unk_2C0++; - funcFloat = Environment_LerpWeightAccelDecel((kREG(2) + 0x96) & 0xFFFF, 0, this->unk_2C0, 8, 0); + this->swimmingUpFrame++; + funcFloat = Environment_LerpWeightAccelDecel((kREG(2) + 0x96) & 0xFFFF, 0, this->swimmingUpFrame, 8, 0); this->actor.world.pos.y = this->actor.home.pos.y + (300.0f * funcFloat); } -s32 func_80AF383C(EnRu2* this, PlayState* play) { +s32 EnRu2_IsPlayerInRangeForEncounter(EnRu2* this, PlayState* play) { Player* player = GET_PLAYER(play); f32 thisPosX = this->actor.world.pos.x; f32 playerPosX = player->actor.world.pos.x; @@ -638,32 +764,42 @@ s32 func_80AF383C(EnRu2* this, PlayState* play) { return 0; } -void func_80AF3878(EnRu2* this, PlayState* play) { - if (func_80AF383C(this, play) && !Play_InCsMode(play)) { - this->action = 16; +/** + * Checks if Link is close enough to Ruto and conditionally triggers the encounter cutscene in the Water Temple. + */ +void EnRu2_CheckRangeToStartEncounter(EnRu2* this, PlayState* play) { + if (EnRu2_IsPlayerInRangeForEncounter(this, play) && !Play_InCsMode(play)) { + this->action = ENRU2_WATER_TEMPLE_ENCOUNTER_BEGINNING; this->subCamId = OnePointCutscene_Init(play, 3130, -99, &this->actor, MAIN_CAM); } } -void func_80AF38D0(EnRu2* this, PlayState* play) { - this->action = 16; +/** + * Triggers the encounter cutscene in the Water Temple, unconditionally. Appears to be unused. + */ +void EnRu2_StartEncounter(EnRu2* this, PlayState* play) { + this->action = ENRU2_WATER_TEMPLE_ENCOUNTER_BEGINNING; this->subCamId = OnePointCutscene_Init(play, 3130, -99, &this->actor, MAIN_CAM); } -void func_80AF390C(EnRu2* this, PlayState* play) { - f32* unk_2C4 = &this->unk_2C4; +/** + * Handles the starting moments of Ruto's encounter with Link at the Water Temple. Responds to a running timer to + * initiate, on cue, both the fanfare and Ruto's dialogue. + */ +void EnRu2_EncounterBeginningHandler(EnRu2* this, PlayState* play) { + f32* encounterTimer = &this->encounterTimer; - *unk_2C4 += 1.0f; - if (*unk_2C4 == kREG(6) + 40.0f) { - func_80AF37AC(); - } else if (*unk_2C4 > kREG(4) + 50.0f) { + *encounterTimer += 1.0f; + if (*encounterTimer == kREG(6) + 40.0f) { + EnRu2_PlayFanfare(); + } else if (*encounterTimer > kREG(4) + 50.0f) { this->actor.textId = 0x403E; Message_StartTextbox(play, this->actor.textId, NULL); - this->action = 17; + this->action = ENRU2_WATER_TEMPLE_ENCOUNTER_DIALOG; } } -void func_80AF39DC(EnRu2* this, PlayState* play) { +void EnRu2_DialogCameraHandler(EnRu2* this, PlayState* play) { s32 pad; MessageContext* msgCtx; s32 pad2; @@ -675,11 +811,11 @@ void func_80AF39DC(EnRu2* this, PlayState* play) { dialogState = Message_GetState(msgCtx); if (dialogState == TEXT_STATE_DONE_FADING) { - if (this->unk_2C3 != TEXT_STATE_DONE_FADING) { + if (this->lastDialogState != TEXT_STATE_DONE_FADING) { // "I'm Komatsu!" (cinema scene dev) osSyncPrintf("おれが小松だ! \n"); - this->unk_2C2++; - if (this->unk_2C2 % 6 == 3) { + this->textboxCount++; + if (this->textboxCount % 6 == 3) { player = GET_PLAYER(play); // "uorya-!" (screeming sound) osSyncPrintf("うおりゃー! \n"); @@ -691,75 +827,76 @@ void func_80AF39DC(EnRu2* this, PlayState* play) { } } - this->unk_2C3 = dialogState; + this->lastDialogState = dialogState; if (Message_GetState(msgCtx) == TEXT_STATE_CLOSING) { - this->action = 18; + this->action = ENRU2_WATER_TEMPLE_ENCOUNTER_END; func_8005B1A4(GET_ACTIVE_CAM(play)); } } -void func_80AF3ADC(EnRu2* this, PlayState* play) { - this->unk_2C4 += 1.0f; - if (this->unk_2C4 > kREG(5) + 100.0f) { - func_80AF28E8(this, &gAdultRutoSwimmingUpAnim, 0, -12.0f, 0); - this->action = 19; - func_80AF36EC(this, play); +void EnRu2_StartSwimmingUp(EnRu2* this, PlayState* play) { + this->encounterTimer += 1.0f; + if (this->encounterTimer > kREG(5) + 100.0f) { + EnRu2_AnimationChange(this, &gAdultRutoSwimmingUpAnim, 0, -12.0f, 0); + this->action = ENRU2_WATER_TEMPLE_SWIMMING_UP; + EnRu2_SetEncounterSwitchFlag(this, play); } } -void func_80AF3B74(EnRu2* this, PlayState* play) { - if (this->unk_2C0 > ((((u16)(kREG(3) + 0x28)) + ((u16)(kREG(2) + 0x96))) & 0xFFFF)) { +void EnRu2_EndSwimmingUp(EnRu2* this, PlayState* play) { + if (this->swimmingUpFrame > ((((u16)(kREG(3) + 0x28)) + ((u16)(kREG(2) + 0x96))) & 0xFFFF)) { Actor_Kill(&this->actor); OnePointCutscene_EndCutscene(play, this->subCamId); } } -void func_80AF3BC8(EnRu2* this, PlayState* play) { - func_80AF3878(this, play); +void EnRu2_WaterTempleEncounterRangeCheck(EnRu2* this, PlayState* play) { + EnRu2_CheckRangeToStartEncounter(this, play); Actor_SetFocus(&this->actor, 50.0f); - func_80AF259C(this, play); + EnRu2_UpdateCollider(this, play); } -void func_80AF3C04(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); - func_80AF259C(this, play); +// This one seems to be unused. +void EnRu2_WaterTempleEncounterUnconditional(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); + EnRu2_UpdateCollider(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); + EnRu2_UpdateEyes(this); Actor_SetFocus(&this->actor, 50.0f); - func_80AF38D0(this, play); + EnRu2_StartEncounter(this, play); } -void func_80AF3C64(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); +void EnRu2_WaterTempleEncounterBegin(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); + EnRu2_UpdateEyes(this); Actor_SetFocus(&this->actor, 50.0f); - func_80AF390C(this, play); + EnRu2_EncounterBeginningHandler(this, play); } -void func_80AF3CB8(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); +void EnRu2_WaterTempleEncounterDialog(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); + EnRu2_UpdateEyes(this); Actor_SetFocus(&this->actor, 50.0f); - func_80AF39DC(this, play); + EnRu2_DialogCameraHandler(this, play); } -void func_80AF3D0C(EnRu2* this, PlayState* play) { - func_80AF2744(this, play); +void EnRu2_WaterTempleEncounterEnd(EnRu2* this, PlayState* play) { + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); + EnRu2_UpdateEyes(this); Actor_SetFocus(&this->actor, 50.0f); - func_80AF3ADC(this, play); + EnRu2_StartSwimmingUp(this, play); } -void func_80AF3D60(EnRu2* this, PlayState* play) { - func_80AF37CC(this); - func_80AF2744(this, play); +void EnRu2_WaterTempleSwimmingUp(EnRu2* this, PlayState* play) { + EnRu2_SwimUpProgress(this); + EnRu2_UpdateBgCheckInfo(this, play); EnRu2_UpdateSkelAnime(this); - func_80AF2608(this); + EnRu2_UpdateEyes(this); Actor_SetFocus(&this->actor, 50.0f); - func_80AF3B74(this, play); + EnRu2_EndSwimmingUp(this, play); } void EnRu2_Update(Actor* thisx, PlayState* play) { @@ -777,36 +914,36 @@ void EnRu2_Init(Actor* thisx, PlayState* play) { EnRu2* this = (EnRu2*)thisx; ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); - func_80AF2550(thisx, play); + EnRu2_InitCollider(thisx, play); SkelAnime_InitFlex(play, &this->skelAnime, &gAdultRutoSkel, NULL, this->jointTable, this->morphTable, 23); - switch (func_80AF26A0(this)) { + switch (EnRu2_GetType(this)) { case 2: - func_80AF2E1C(this, play); + EnRu2_InitWaterTrial(this, play); break; case 3: - func_80AF3394(this, play); + EnRu2_InitCredits(this, play); break; case 4: - func_80AF3744(this, play); + EnRu2_InitWaterTempleEncounter(this, play); break; default: - func_80AF2994(this, play); + EnRu2_InitChamberOfSages(this, play); break; } - this->unk_2C2 = 0; - this->unk_2C3 = TEXT_STATE_DONE_FADING; + this->textboxCount = 0; + this->lastDialogState = TEXT_STATE_DONE_FADING; this->subCamId = 0; } -void func_80AF3F14(EnRu2* this, PlayState* play) { +void EnRu2_DrawNothing(EnRu2* this, PlayState* play) { } -void func_80AF3F20(EnRu2* this, PlayState* play) { +void EnRu2_DrawOpa(EnRu2* this, PlayState* play) { s32 pad[2]; - s16 temp = this->unk_2A4; - void* tex = sEyeTextures[temp]; + s16 eyeIndex = this->eyeIndex; + void* tex = sEyeTextures[eyeIndex]; SkelAnime* skelAnime = &this->skelAnime; OPEN_DISPS(play->state.gfxCtx); diff --git a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.h b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.h index 5334857fc..4d3da728b 100644 --- a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.h +++ b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.h @@ -14,18 +14,18 @@ typedef struct EnRu2 { /* 0x014C */ SkelAnime skelAnime; /* 0x0190 */ Vec3s jointTable[23]; /* 0x021A */ Vec3s morphTable[23]; - /* 0x02A4 */ s16 unk_2A4; - /* 0x02A6 */ s16 unk_2A6; + /* 0x02A4 */ s16 eyeIndex; + /* 0x02A6 */ s16 blinkTimer; /* 0x02A8 */ s32 action; /* 0x02AC */ s32 drawConfig; - /* 0x02B0 */ f32 unk_2B0; + /* 0x02B0 */ f32 fadeTimer; /* 0x02B4 */ u32 alpha; - /* 0x02B8 */ s32 unk_2B8; - /* 0x02BC */ s32 unk_2BC; - /* 0x02C0 */ u16 unk_2C0; - /* 0x02C2 */ u8 unk_2C2; - /* 0x02C3 */ u8 unk_2C3; - /* 0x02C4 */ f32 unk_2C4; + /* 0x02B8 */ s32 isLightBall; + /* 0x02BC */ s32 cueId; + /* 0x02C0 */ u16 swimmingUpFrame; + /* 0x02C2 */ u8 textboxCount; + /* 0x02C3 */ u8 lastDialogState; + /* 0x02C4 */ f32 encounterTimer; /* 0x02C8 */ ColliderCylinder collider; /* 0x02C8 */ s16 subCamId; } EnRu2; // size = 0x0314 diff --git a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2_cutscene_data.c b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2_cutscene_data.c index e265d10a9..998ae8b24 100644 --- a/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2_cutscene_data.c +++ b/soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2_cutscene_data.c @@ -2,7 +2,7 @@ #include "z64cutscene_commands.h" // clang-format off -static CutsceneData D_80AF411C[] = { +static CutsceneData gWaterMedallionCs[] = { CS_BEGIN_CUTSCENE(35, 3338), CS_UNK_DATA_LIST(0x00000020, 1), CS_UNK_DATA(0x00010000, 0x0BB80000, 0x00000000, 0x00000000, 0xFFFFFFFC, 0x00000002, 0x00000000, 0xFFFFFFFC, 0x00000002, 0x00000000, 0x00000000, 0x00000000), diff --git a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c index ca1da32cc..c350fe0bd 100644 --- a/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c +++ b/soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c @@ -3,6 +3,8 @@ #include "objects/object_sa/object_sa.h" #include "scenes/overworld/spot04/spot04_scene.h" #include "scenes/overworld/spot05/spot05_scene.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -679,8 +681,8 @@ void func_80AF68E4(EnSa* this, PlayState* play) { phi_v0 = this->unk_20C; } if (phi_v0 == 0) { - Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->unk_20C = 8; } } @@ -740,10 +742,10 @@ void EnSa_Update(Actor* thisx, PlayState* play) { if (this->actionFunc != func_80AF68E4) { if (CVarGetInteger(CVAR_ENHANCEMENT("DisableKokiriDrawDistance"), 0) != 0) { - this->alpha = func_80034DD4(&this->actor, play, this->alpha, 32767); + this->alpha = Actor_UpdateAlphaByDistance(&this->actor, play, this->alpha, 32767); } else { - this->alpha = func_80034DD4(&this->actor, play, this->alpha, 400.0f); + this->alpha = Actor_UpdateAlphaByDistance(&this->actor, play, this->alpha, 400.0f); } } else { this->alpha = 255; @@ -756,7 +758,7 @@ void EnSa_Update(Actor* thisx, PlayState* play) { this->actor.world.pos.y += this->actor.velocity.y; this->actor.world.pos.z += this->actor.velocity.z; } else { - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); } if (play->sceneNum != SCENE_SACRED_FOREST_MEADOW) { diff --git a/soh/src/overlays/actors/ovl_En_Sb/z_en_sb.c b/soh/src/overlays/actors/ovl_En_Sb/z_en_sb.c index ad279d22c..24b4632fa 100644 --- a/soh/src/overlays/actors/ovl_En_Sb/z_en_sb.c +++ b/soh/src/overlays/actors/ovl_En_Sb/z_en_sb.c @@ -463,7 +463,7 @@ void EnSb_Update(Actor* thisx, PlayState* play) { } else { Actor_SetFocus(&this->actor, 20.0f); Actor_SetScale(&this->actor, 0.006f); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); this->actionFunc(this, play); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 20.0f, 5); EnSb_UpdateDamage(this, play); diff --git a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c index c6aa6d56a..e099480b5 100644 --- a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c +++ b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c @@ -1,5 +1,7 @@ #include "z_en_shopnuts.h" #include "objects/object_shopnuts/object_shopnuts.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) diff --git a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c index 832e3c45d..338dfaf12 100644 --- a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c +++ b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c @@ -7,6 +7,7 @@ #include "z_en_si.h" #include "soh/Enhancements/custom-message/CustomMessageTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOOKSHOT_DRAGS) @@ -97,7 +98,7 @@ void func_80AFB768(EnSi* this, PlayState* play) { this->collider.base.ocFlags2 &= ~OC2_HIT_PLAYER; if (GameInteractor_Should(VB_GIVE_ITEM_SKULL_TOKEN, true, this)) { Item_Give(play, ITEM_SKULL_TOKEN); - if (GameInteractor_Should(VB_FREEZE_ON_SKULL_TOKEN, true, this)) { + if (GameInteractor_Should(VB_FREEZE_ON_SKULL_TOKEN, true)) { player->actor.freezeTimer = 10; } Message_StartTextbox(play, TEXT_GS_NO_FREEZE, NULL); @@ -123,7 +124,7 @@ void func_80AFB89C(EnSi* this, PlayState* play) { if (!CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_HOOKSHOT_ATTACHED)) { if (GameInteractor_Should(VB_GIVE_ITEM_SKULL_TOKEN, true, this)) { Item_Give(play, ITEM_SKULL_TOKEN); - if (GameInteractor_Should(VB_FREEZE_ON_SKULL_TOKEN, true, this)) { + if (GameInteractor_Should(VB_FREEZE_ON_SKULL_TOKEN, true)) { player->actor.freezeTimer = 10; } Message_StartTextbox(play, TEXT_GS_NO_FREEZE, NULL); @@ -136,7 +137,7 @@ void func_80AFB89C(EnSi* this, PlayState* play) { void func_80AFB950(EnSi* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (Message_GetState(&play->msgCtx) != TEXT_STATE_CLOSING && GameInteractor_Should(VB_FREEZE_ON_SKULL_TOKEN, true, this)) { + if (Message_GetState(&play->msgCtx) != TEXT_STATE_CLOSING && GameInteractor_Should(VB_FREEZE_ON_SKULL_TOKEN, true)) { player->actor.freezeTimer = 10; } else { SET_GS_FLAGS((this->actor.params & 0x1F00) >> 8, this->actor.params & 0xFF); @@ -148,7 +149,7 @@ void func_80AFB950(EnSi* this, PlayState* play) { void EnSi_Update(Actor* thisx, PlayState* play) { EnSi* this = (EnSi*)thisx; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); this->actionFunc(this, play); Actor_SetFocus(&this->actor, 16.0f); diff --git a/soh/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c b/soh/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c index e577a3d45..8e4596ff3 100644 --- a/soh/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c +++ b/soh/src/overlays/actors/ovl_En_Siofuki/z_en_siofuki.c @@ -128,7 +128,7 @@ void func_80AFBE8C(EnSiofuki* this, PlayState* play) { if ((dX > (this->dyna.actor.scale.x * -346.0f)) && (dX < (this->dyna.actor.scale.x * 346.0f)) && (dZ > (this->dyna.actor.scale.z * -400.0f)) && (dZ < (this->dyna.actor.scale.z * 400.0f)) && (dY < 0.0f)) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->splashTimer <= 0) { EffectSsGSplash_Spawn(play, &player->actor.world.pos, NULL, NULL, 1, 1); this->splashTimer = 10; diff --git a/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c b/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c index e985fe862..1fcb2708a 100644 --- a/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c +++ b/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c @@ -2,6 +2,7 @@ #include "overlays/actors/ovl_En_Encount1/z_en_encount1.h" #include "objects/object_skb/object_skb.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -502,7 +503,7 @@ void EnSkb_Update(Actor* thisx, PlayState* play) { s32 pad; func_80AFD968(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 15.0f, 30.0f, 60.0f, 0x1D); this->actionFunc(this, play); this->actor.focus.pos = this->actor.world.pos; diff --git a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c index b903adc55..de42b24bf 100644 --- a/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c +++ b/soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c @@ -2,6 +2,8 @@ #include "overlays/actors/ovl_En_Skjneedle/z_en_skjneedle.h" #include "objects/object_skj/object_skj.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -920,7 +922,7 @@ void EnSkj_WaitInRange(EnSkj* this, PlayState* play) { player->actor.world.pos.y = sSmallStumpSkullKid.skullkid->actor.world.pos.y; player->actor.world.pos.z = sSmallStumpSkullKid.skullkid->actor.world.pos.z; if ((Player_GetMask(play) == PLAYER_MASK_SKULL) && !Flags_GetItemGetInf(ITEMGETINF_39)) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); EnSkj_SetupMaskTrade(this); } else { EnSkj_SetupTalk(this); @@ -980,7 +982,7 @@ void EnSkj_WaitForSong(EnSkj* this, PlayState* play) { if (!Flags_GetItemGetInf(ITEMGETINF_16)) { // Saria's song has been played for the first titme play->msgCtx.ocarinaMode = OCARINA_MODE_04; - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); player->unk_6A8 = &this->actor; func_8002F2CC(&this->actor, play, EnSkj_GetItemXzRange(this)); this->textId = 0x10BB; @@ -1342,7 +1344,7 @@ void EnSkj_Update(Actor* thisx, PlayState* play) { CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); SkelAnime_Update(&this->skelAnime); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 20.0f, 7); } @@ -1436,7 +1438,7 @@ void EnSkj_WaitForPlayback(EnSkj* this, PlayState* play) { this->textId = 0x102D; this->actionFunc = EnSkj_FailedMiniGame; } else if (play->msgCtx.ocarinaMode == OCARINA_MODE_0F) { // completed the game - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Message_CloseTextbox(play); play->msgCtx.ocarinaMode = OCARINA_MODE_04; player->unk_6A8 = &this->actor; @@ -1477,7 +1479,7 @@ void EnSkj_WaitForPlayback(EnSkj* this, PlayState* play) { this->songFailTimer--; } } else { // took too long, game failed - func_80078884(NA_SE_SY_OCARINA_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_OCARINA_ERROR); Message_CloseTextbox(play); play->msgCtx.ocarinaMode = OCARINA_MODE_04; player->unk_6A8 = &this->actor; diff --git a/soh/src/overlays/actors/ovl_En_Skjneedle/z_en_skjneedle.c b/soh/src/overlays/actors/ovl_En_Skjneedle/z_en_skjneedle.c index 1a9531ae1..228bd9c5e 100644 --- a/soh/src/overlays/actors/ovl_En_Skjneedle/z_en_skjneedle.c +++ b/soh/src/overlays/actors/ovl_En_Skjneedle/z_en_skjneedle.c @@ -93,7 +93,7 @@ void EnSkjneedle_Update(Actor* thisx, PlayState* play2) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 20.0f, 7); } } diff --git a/soh/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c b/soh/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c index fc814f915..b7d69b40a 100644 --- a/soh/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c +++ b/soh/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c @@ -1,5 +1,7 @@ #include "z_en_ssh.h" #include "objects/object_ssh/object_ssh.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -824,7 +826,7 @@ void EnSsh_Update(Actor* thisx, PlayState* play) { EnSsh_Damaged(this); } else { SkelAnime_Update(&this->skelAnime); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); this->actionFunc(this, play); } diff --git a/soh/src/overlays/actors/ovl_En_St/z_en_st.c b/soh/src/overlays/actors/ovl_En_St/z_en_st.c index 59d4be6f3..cbc701cee 100644 --- a/soh/src/overlays/actors/ovl_En_St/z_en_st.c +++ b/soh/src/overlays/actors/ovl_En_St/z_en_st.c @@ -7,6 +7,7 @@ #include "z_en_st.h" #include "objects/object_st/object_st.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED) @@ -940,7 +941,7 @@ void EnSt_ReturnToCeiling(EnSt* this, PlayState* play) { */ void EnSt_BounceAround(EnSt* this, PlayState* play) { this->actor.colorFilterTimer = this->deathTimer; - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); this->actor.world.rot.x += 0x800; this->actor.world.rot.z -= 0x800; this->actor.shape.rot = this->actor.world.rot; @@ -978,7 +979,7 @@ void EnSt_FinishBouncing(EnSt* this, PlayState* play) { this->actor.shape.rot = this->actor.world.rot; - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); this->groundBounces = 2; EnSt_IsDoneBouncing(this, play); } @@ -1022,7 +1023,7 @@ void EnSt_Update(Actor* thisx, PlayState* play) { } if (this->swayTimer == 0 && this->stunTimer == 0) { - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); } Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); diff --git a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c index c55af5cd4..cc3dd3eb0 100644 --- a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c +++ b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c @@ -10,6 +10,8 @@ #include "objects/object_boj/object_boj.h" #include #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -345,7 +347,7 @@ void EnSth_Update2(Actor* thisx, PlayState* play) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); if (SkelAnime_Update(&this->skelAnime)) { this->skelAnime.curFrame = 0.0f; diff --git a/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c b/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c index 00f859e70..c0bc087bd 100644 --- a/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c +++ b/soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c @@ -1,6 +1,7 @@ #include "z_en_sw.h" #include "objects/object_st/object_st.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -214,16 +215,6 @@ s32 func_80B0C0CC(EnSw* this, PlayState* play, s32 arg2) { return sp64; } -// Presumably, due to the removal of object dependency, there is a race condition where -// the GS on the Kak construction site spawns to early and fails to detect the -// construction site dyna poly. This custom action func rechecks moving the GS -// to the nearest poly one frame after init. Further explanation available: -// https://github.com/HarbourMasters/Shipwright/issues/2310#issuecomment-1492829517 -void EnSw_MoveGoldLater(EnSw* this, PlayState* play) { - func_80B0C0CC(this, play, 1); - this->actionFunc = func_80B0D590; -} - void EnSw_Init(Actor* thisx, PlayState* play) { EnSw* this = (EnSw*)thisx; s32 phi_v0; @@ -277,7 +268,7 @@ void EnSw_Init(Actor* thisx, PlayState* play) { } if (((thisx->params & 0xE000) >> 0xD) >= 3) { - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } switch ((thisx->params & 0xE000) >> 0xD) { @@ -315,14 +306,6 @@ void EnSw_Init(Actor* thisx, PlayState* play) { } else { this->actionFunc = func_80B0D590; } - - // If a normal GS failed to get attached to a poly during init - // try once more on the next frame via a custom action func - if ((((thisx->params & 0xE000) >> 0xD) == 1 || - ((thisx->params & 0xE000) >> 0xD) == 2) && - this->actor.floorPoly == NULL) { - this->actionFunc = EnSw_MoveGoldLater; - } } void EnSw_Destroy(Actor* thisx, PlayState* play) { @@ -635,7 +618,7 @@ void func_80B0D878(EnSw* this, PlayState* play) { this->actor.shape.rot = this->actor.world.rot; if ((this->unk_394 == 0) && (this->unk_392 == 0)) { - Audio_PlaySoundGeneral(NA_SE_SY_KINSTA_MARK_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_KINSTA_MARK_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); x = (this->unk_364.x * 10.0f); y = (this->unk_364.y * 10.0f); z = (this->unk_364.z * 10.0f); @@ -660,7 +643,7 @@ void func_80B0D878(EnSw* this, PlayState* play) { } void func_80B0DB00(EnSw* this, PlayState* play) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); this->actor.shape.rot.x += 0x1000; this->actor.shape.rot.z += 0x1000; Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 0.0f, 5); diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.c b/soh/src/overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.c index dbd6007a2..4122cef6b 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.c @@ -162,7 +162,7 @@ void EnSyatekiItm_StartRound(EnSyatekiItm* this, PlayState* play) { this->timer = (this->roundNum == 1) ? 50 : 30; - func_80078884(NA_SE_SY_FOUND); + Sfx_PlaySfxCentered(NA_SE_SY_FOUND); this->actionFunc = EnSyatekiItm_SpawnTargets; } } diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c index dcaaa897b..60955727b 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c @@ -4,6 +4,8 @@ #include "objects/object_ossan/object_ossan.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/custom-message/CustomMessageTypes.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_LOCKON) diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c b/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c index 7ab2d6f7b..9ffe7080d 100644 --- a/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c +++ b/soh/src/overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.c @@ -8,6 +8,7 @@ #include "objects/object_niw/object_niw.h" #include "vt.h" #include "soh/frame_interpolation.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -458,8 +459,8 @@ void func_80B12460(EnSyatekiNiw* this, PlayState* play) { } if ((this->unk_25A == 0) && ((player->actor.world.pos.z - 30.0f) < this->actor.world.pos.z)) { - Audio_PlaySoundGeneral(NA_SE_VO_LI_DOWN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_VO_LI_DOWN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); this->unk_25E = 0x14; this->unk_29A = 6; this->actor.speedXZ = 0.0f; @@ -619,7 +620,7 @@ void EnSyatekiNiw_Update(Actor* thisx, PlayState* play) { this->actor.shape.shadowScale = 15.0f; this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 20.0f, 20.0f, 60.0f, 0x1D); if (this->unk_2A0 != 0) { diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c index 6a4676fdd..1e923335b 100644 --- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c +++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c @@ -7,6 +7,8 @@ #include "z_en_ta.h" #include "vt.h" #include "objects/object_ta/object_ta.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -394,7 +396,7 @@ void func_80B14818(EnTa* this, PlayState* play) { if (this->actor.speedXZ < 6.0f) { this->actor.speedXZ += 0.4f; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void func_80B14898(EnTa* this, PlayState* play) { @@ -747,7 +749,7 @@ void EnTa_RunCuccoGame(EnTa* this, PlayState* play) { if (gSaveContext.timer1Value == 0 && !Play_InCsMode(play)) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_STOP); this->unk_2E0 &= ~0x200; - func_80078884(NA_SE_SY_FOUND); + Sfx_PlaySfxCentered(NA_SE_SY_FOUND); gSaveContext.timer1State = 0; Player_SetCsActionWithHaltedActors(play, &this->actor, 1); Message_StartTextbox(play, 0x2081, &this->actor); @@ -1151,7 +1153,7 @@ void EnTa_Update(Actor* thisx, PlayState* play) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4); this->unk_260(this); this->actionFunc(this, play); diff --git a/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c b/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c index e15d481fd..3afae38cf 100644 --- a/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c +++ b/soh/src/overlays/actors/ovl_En_Takara_Man/z_en_takara_man.c @@ -7,6 +7,8 @@ #include "z_en_takara_man.h" #include "vt.h" #include "objects/object_ts/object_ts.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_LOCKON) diff --git a/soh/src/overlays/actors/ovl_En_Test/z_en_test.c b/soh/src/overlays/actors/ovl_En_Test/z_en_test.c index 75c4f6c6a..5accba57a 100644 --- a/soh/src/overlays/actors/ovl_En_Test/z_en_test.c +++ b/soh/src/overlays/actors/ovl_En_Test/z_en_test.c @@ -7,6 +7,7 @@ #include "z_en_test.h" #include "objects/object_sk2/object_sk2.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -1711,7 +1712,7 @@ void EnTest_Update(Actor* thisx, PlayState* play) { EnTest_UpdateDamage(this, play); if (this->actor.colChkInfo.damageEffect != STALFOS_DMGEFF_FIREMAGIC) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 75.0f, 30.0f, 30.0f, 0x1D); if (this->actor.params == STALFOS_TYPE_1) { diff --git a/soh/src/overlays/actors/ovl_En_Tite/z_en_tite.c b/soh/src/overlays/actors/ovl_En_Tite/z_en_tite.c index ba583c155..1fa105ef3 100644 --- a/soh/src/overlays/actors/ovl_En_Tite/z_en_tite.c +++ b/soh/src/overlays/actors/ovl_En_Tite/z_en_tite.c @@ -10,6 +10,7 @@ #include "vt.h" #include "objects/object_tite/object_tite.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -899,7 +900,7 @@ void EnTite_Update(Actor* thisx, PlayState* play) { // Stay still if hit by immunity damage type this frame if (thisx->colChkInfo.damageEffect != 0xE) { this->actionFunc(this, play); - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); Actor_UpdateBgCheckInfo(play, thisx, 25.0f, 40.0f, 20.0f, this->unk_2DC); // If on water, snap feet to surface and spawn ripples if ((this->actor.params == TEKTITE_BLUE) && (thisx->bgCheckFlags & 0x20)) { diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 68979daca..e9535c3b5 100644 --- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -8,6 +8,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_tk/object_tk.h" #include "soh/frame_interpolation.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -637,7 +638,7 @@ void EnTk_Dig(EnTk* this, PlayState* play) { Audio_PlayActorSound2(&this->actor, NA_SE_SY_ERROR); } else if (this->currentReward == 4) { /* Heart piece */ - Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { /* Rupee */ Audio_PlayActorSound2(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); @@ -670,7 +671,7 @@ void EnTk_Update(Actor* thisx, PlayState* play) { SkelAnime_Update(&this->skelAnime); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 40.0f, 10.0f, 0.0f, 5); diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c index 594d72bca..f0abb973f 100644 --- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c +++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c @@ -6,6 +6,9 @@ #include "z_en_toryo.h" #include "objects/object_toryo/object_toryo.h" +#include "soh/Enhancements/randomizer/adult_trade_shuffle.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -243,7 +246,7 @@ u32 func_80B20634(EnToryo* this, PlayState* play) { if (this->unk_1E0 != 0) { if (this->unk_1E0 == 10) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); if (Flags_GetInfTable(INFTABLE_171)) { ret = 0x606E; } else { diff --git a/soh/src/overlays/actors/ovl_En_Tp/z_en_tp.c b/soh/src/overlays/actors/ovl_En_Tp/z_en_tp.c index 30ff3c37f..6f849948a 100644 --- a/soh/src/overlays/actors/ovl_En_Tp/z_en_tp.c +++ b/soh/src/overlays/actors/ovl_En_Tp/z_en_tp.c @@ -243,8 +243,8 @@ void EnTp_Head_ApproachPlayer(EnTp* this, PlayState* play) { Player* player = GET_PLAYER(play); Math_SmoothStepToF(&this->actor.world.pos.y, player->actor.world.pos.y + 30.0f, 1.0f, 0.5f, 0.0f); - Audio_PlaySoundGeneral(NA_SE_EN_TAIL_FLY - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TAIL_FLY - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (this->collider.base.atFlags & AT_HIT) { this->collider.base.atFlags &= ~AT_HIT; @@ -356,7 +356,7 @@ void EnTp_Fragment_SetupFade(EnTp* this) { } void EnTp_Fragment_Fade(EnTp* this, PlayState* play) { - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->alpha -= 20; if (this->alpha < 20) { @@ -381,8 +381,8 @@ void EnTp_Head_TakeOff(EnTp* this, PlayState* play) { Math_SmoothStepToF(&this->actor.speedXZ, 2.5f, 0.1f, 0.2f, 0.0f); Math_SmoothStepToF(&this->actor.world.pos.y, player->actor.world.pos.y + 85.0f + this->horizontalVariation, 1.0f, this->actor.speedXZ * 0.25f, 0.0f); - Audio_PlaySoundGeneral(NA_SE_EN_TAIL_FLY - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TAIL_FLY - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); if (this->collider.base.atFlags & AT_HIT) { this->collider.base.atFlags &= ~AT_HIT; @@ -479,8 +479,8 @@ void EnTp_Head_Wait(EnTp* this, PlayState* play) { this->actor.shape.rot.y = this->actor.world.rot.y; if (this->actor.world.pos.y != this->actor.home.pos.y) { - Audio_PlaySoundGeneral(NA_SE_EN_TAIL_FLY - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TAIL_FLY - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } @@ -549,8 +549,8 @@ void EnTp_Head_BurrowReturnHome(EnTp* this, PlayState* play) { } if (this->actor.world.pos.y != this->actor.home.pos.y) { - Audio_PlaySoundGeneral(NA_SE_EN_TAIL_FLY - SFX_FLAG, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TAIL_FLY - SFX_FLAG, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } if (closeToFloor && ((play->gameplayFrames & 1) != 0)) { @@ -668,7 +668,7 @@ void EnTp_Update(Actor* thisx, PlayState* play) { this->actionFunc(this, play); if (this->actor.params <= TAILPASARAN_HEAD) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (this->actionIndex != TAILPASARAN_ACTION_HEAD_BURROWRETURNHOME) { Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 15.0f, 10.0f, 5); @@ -692,8 +692,8 @@ void EnTp_Update(Actor* thisx, PlayState* play) { this->actor.shape.rot.z += 0x800; if (this->actor.shape.rot.z == 0) { - Audio_PlaySoundGeneral(NA_SE_EN_TAIL_CRY, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TAIL_CRY, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } if (this->actionIndex >= TAILPASARAN_ACTION_TAIL_FOLLOWHEAD) { diff --git a/soh/src/overlays/actors/ovl_En_Tr/z_en_tr.c b/soh/src/overlays/actors/ovl_En_Tr/z_en_tr.c index adf6c3ddc..eded6eda6 100644 --- a/soh/src/overlays/actors/ovl_En_Tr/z_en_tr.c +++ b/soh/src/overlays/actors/ovl_En_Tr/z_en_tr.c @@ -7,6 +7,7 @@ #include "z_en_tr.h" #include "objects/object_tr/object_tr.h" #include +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -130,8 +131,8 @@ void EnTr_CrySpellcast(EnTr* this, PlayState* play) { if (this->timer == 11) { // Both cry in the title screen cutscene, but only Kotake in the in-game cutscene if ((this->actor.params != TR_KOUME) || (gSaveContext.sceneSetupIndex == 6)) { - Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_SHOOT_VOICE, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_TWINROBA_SHOOT_VOICE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } @@ -492,7 +493,7 @@ void func_80B24038(EnTr* this, PlayState* play, s32 actionIndex) { Math_StepToF(&this->actor.velocity.x, endPos.x, 1.0f); Math_StepToF(&this->actor.velocity.y, endPos.y, 1.0f); Math_StepToF(&this->actor.velocity.z, endPos.z, 1.0f); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); } void EnTr_UpdateRotation(EnTr* this, PlayState* play, s32 actionIndex) { diff --git a/soh/src/overlays/actors/ovl_En_Trap/z_en_trap.c b/soh/src/overlays/actors/ovl_En_Trap/z_en_trap.c index 5d5eef982..bdfb475cd 100644 --- a/soh/src/overlays/actors/ovl_En_Trap/z_en_trap.c +++ b/soh/src/overlays/actors/ovl_En_Trap/z_en_trap.c @@ -369,7 +369,7 @@ void EnTrap_Update(Actor* thisx, PlayState* play) { } } } - Actor_MoveForward(thisx); // Only used by straight line logic + Actor_MoveXZGravity(thisx); // Only used by straight line logic // Adjust position using bgcheck, but do not adjust x, z position if in straight line mode: if (thisx->params & SPIKETRAP_MODE_LINEAR) { posTemp = thisx->world.pos; diff --git a/soh/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c b/soh/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c index c2a765648..a9ce7232b 100644 --- a/soh/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c +++ b/soh/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c @@ -283,7 +283,7 @@ void EnTuboTrap_Update(Actor* thisx, PlayState* play) { s32 pad; this->actionFunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 10.0f, 20.0f, 0x1D); Actor_SetFocus(&this->actor, 0.0f); Collider_UpdateCylinder(&this->actor, &this->collider); diff --git a/soh/src/overlays/actors/ovl_En_Vali/z_en_vali.c b/soh/src/overlays/actors/ovl_En_Vali/z_en_vali.c index 11772cd90..e6c62d961 100644 --- a/soh/src/overlays/actors/ovl_En_Vali/z_en_vali.c +++ b/soh/src/overlays/actors/ovl_En_Vali/z_en_vali.c @@ -8,6 +8,7 @@ #include "objects/object_vali/object_vali.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_IGNORE_QUAKE) diff --git a/soh/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.c b/soh/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.c index 756f46cb5..dce0ad448 100644 --- a/soh/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.c +++ b/soh/src/overlays/actors/ovl_En_Vb_Ball/z_en_vb_ball.c @@ -136,8 +136,8 @@ void EnVbBall_UpdateBones(EnVbBall* this, PlayState* play) { this->actor.velocity.z = cosf(angle) * 10.0f; this->actor.velocity.y *= -0.5f; if (this->actor.params & 1) { - Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_LAND, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_LAND, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } for (i = 0; i < 10; i++) { Vec3f dustVel = { 0.0f, 0.0f, 0.0f }; @@ -180,7 +180,7 @@ void EnVbBall_Update(Actor* thisx, PlayState* play2) { this->actor.shape.rot.y += (s16)this->yRotVel; this->actor.velocity.y += -1.0f; this->actor.gravity = -1.0f; - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); if (this->actor.params >= 200) { EnVbBall_UpdateBones(this, play); } else { @@ -222,7 +222,7 @@ void EnVbBall_Update(Actor* thisx, PlayState* play2) { if (newActor != NULL) { if ((i == 0) && (this->actor.params == 100)) { Audio_PlaySoundGeneral(NA_SE_EN_VALVAISA_ROCK, &newActor->actor.projectedPos, 4, - &D_801333E0, &D_801333E0, &D_801333E8); + &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } newActor->actor.parent = this->actor.parent; newActor->actor.velocity = spawnOffset; diff --git a/soh/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c b/soh/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c index 56d126a2c..2b34ffde7 100644 --- a/soh/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c +++ b/soh/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c @@ -228,7 +228,7 @@ void EnViewer_UpdateImpl(EnViewer* this, PlayState* play) { case 380: case 409: case 438: - Audio_PlaySoundGeneral(NA_SE_SY_DEMO_CUT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DEMO_CUT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); break; } } @@ -245,8 +245,8 @@ void EnViewer_UpdateImpl(EnViewer* this, PlayState* play) { Audio_QueueSeqCmd(SEQ_PLAYER_FANFARE << 24 | NA_BGM_OPENING_GANON); } if (play->csCtx.frames == 960) { - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_GROAN, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } else if (type == ENVIEWER_TYPE_6_HORSE_GANONDORF) { if (gSaveContext.sceneSetupIndex == 5 || gSaveContext.sceneSetupIndex == 10) { @@ -276,7 +276,7 @@ void EnViewer_UpdateImpl(EnViewer* this, PlayState* play) { } EnViewer_UpdatePosition(this, play); - Actor_MoveForward(&this->actor); // has no effect, speed/velocity and gravity are 0 + Actor_MoveXZGravity(&this->actor); // has no effect, speed/velocity and gravity are 0 animationEnded = SkelAnime_Update(&this->skin.skelAnime); if (type == ENVIEWER_TYPE_3_GANONDORF || type == ENVIEWER_TYPE_4_HORSE_GANONDORF) { @@ -432,7 +432,7 @@ void EnViewer_UpdateImpl(EnViewer* this, PlayState* play) { case 0: if (play->csCtx.state != CS_STATE_IDLE && play->csCtx.npcActions[1] != NULL && play->csCtx.npcActions[1]->action == 7) { - Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Animation_MorphToPlayOnce(&this->skin.skelAnime, &gYoungGanondorfLaughStartAnim, -5.0f); this->state++; } @@ -723,8 +723,8 @@ void EnViewer_UpdatePosition(EnViewer* this, PlayState* play) { if (type == ENVIEWER_TYPE_0_HORSE_ZELDA) { if (!sHorseSfxPlayed) { sHorseSfxPlayed = true; - Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_HORSE_NEIGH, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } Audio_PlayActorSound2(&this->actor, NA_SE_EV_HORSE_RUN_LEVEL - SFX_FLAG); } @@ -773,7 +773,7 @@ void EnViewer_UpdatePosition(EnViewer* this, PlayState* play) { } } if (type == ENVIEWER_TYPE_5_GANONDORF) { - Audio_PlaySoundGeneral(NA_SE_EV_BURNING - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_BURNING - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); EnViewer_DrawFireEffects(this, play); } } diff --git a/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c b/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c index ba0a75613..2f6241ef8 100644 --- a/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c +++ b/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c @@ -9,6 +9,7 @@ #include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -377,7 +378,7 @@ void EnVm_Die(EnVm* this, PlayState* play) { this->beamRot.x += 0x5DC; this->headRotY += 0x9C4; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (--this->timer == 0) { bomb = (EnBom*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_BOM, this->actor.world.pos.x, diff --git a/soh/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c b/soh/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c index e9ab11371..f3e602981 100644 --- a/soh/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c +++ b/soh/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c @@ -89,7 +89,7 @@ void EnWallTubo_DetectChu(EnWallTubo* this, PlayState* play) { (fabsf(chuPosDiff.z) < 40.0f || (BREG(2)))) { this->chuGirl->wallStatus[this->actor.params] = 1; chu->timer = 2; - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); this->timer = 60; EffectSsBomb2_SpawnLayered(play, &this->explosionCenter, &effVelocity, &effAccel, 200, 40); quakeIndex = Quake_Add(GET_ACTIVE_CAM(play), 1); diff --git a/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c b/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c index 1a711b644..3590f620d 100644 --- a/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c +++ b/soh/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c @@ -8,6 +8,7 @@ #include "objects/object_wallmaster/object_wallmaster.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -497,7 +498,7 @@ void EnWallmas_TakePlayer(EnWallmas* this, PlayState* play) { Math_StepToF(&this->actor.world.pos.z, player->actor.world.pos.z, 3.0f); if (this->timer == 0x1E) { - func_80078884(NA_SE_OC_ABYSS); + Sfx_PlaySfxCentered(NA_SE_OC_ABYSS); Play_TriggerRespawn(play); } } @@ -576,7 +577,7 @@ void EnWallmas_Update(Actor* thisx, PlayState* play) { } if ((this->actionFunc != EnWallmas_ReturnToCeiling) && (this->actionFunc != EnWallmas_TakePlayer)) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } if (this->actionFunc != EnWallmas_Drop) { diff --git a/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c b/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c index e3f19a3ed..80d82f702 100644 --- a/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c +++ b/soh/src/overlays/actors/ovl_En_Weiyer/z_en_weiyer.c @@ -7,6 +7,7 @@ #include "z_en_weiyer.h" #include "objects/object_ei/object_ei.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) @@ -596,9 +597,9 @@ void EnWeiyer_Update(Actor* thisx, PlayState* play) { this->actor.world.rot.x = -this->actor.shape.rot.x; if ((this->actor.world.rot.x == 0) || (this->actionFunc == func_80B333B8)) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } else { - func_8002D97C(&this->actor); + Actor_MoveXYZ(&this->actor); } Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 30.0f, 45.0f, 7); diff --git a/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c b/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c index 2c243e254..91a23dc79 100644 --- a/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c +++ b/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c @@ -9,6 +9,7 @@ #include "overlays/actors/ovl_En_Encount1/z_en_encount1.h" #include "objects/object_wf/object_wf.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -1306,7 +1307,7 @@ void EnWf_Update(Actor* thisx, PlayState* play) { EnWf_UpdateDamage(this, play); if (this->actor.colChkInfo.damageEffect != ENWF_DMGEFF_ICE_MAGIC) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 32.0f, 30.0f, 60.0f, 0x1D); this->actionFunc(this, play); func_80B36F40(this, play); diff --git a/soh/src/overlays/actors/ovl_En_Wonder_Item/z_en_wonder_item.c b/soh/src/overlays/actors/ovl_En_Wonder_Item/z_en_wonder_item.c index 3d09c811d..a18adafcf 100644 --- a/soh/src/overlays/actors/ovl_En_Wonder_Item/z_en_wonder_item.c +++ b/soh/src/overlays/actors/ovl_En_Wonder_Item/z_en_wonder_item.c @@ -75,7 +75,7 @@ void EnWonderItem_DropCollectible(EnWonderItem* this, PlayState* play, s32 autoC s32 i; s32 randomDrop; - func_80078884(NA_SE_SY_GET_ITEM); + Sfx_PlaySfxCentered(NA_SE_SY_GET_ITEM); if (this->dropCount == 0) { this->dropCount++; diff --git a/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c b/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c index 257ed2f86..ffc5062e7 100644 --- a/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c +++ b/soh/src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.c @@ -246,7 +246,7 @@ void func_80B3A4F8(EnWonderTalk2* this, PlayState* play) { osSyncPrintf(VT_FGCOL(PURPLE) " ☆☆ 強制 ☆☆ \n" VT_RST); break; case 4: - // "Gerudo Training Grounds Forced Check Only" + // "Gerudo Training Ground Forced Check Only" osSyncPrintf(VT_FGCOL(RED) " ☆☆ ゲルドの修練場強制チェックのみ ☆☆ \n" VT_RST); break; } diff --git a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c index eb6a77e24..fc25db9af 100644 --- a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c +++ b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c @@ -358,23 +358,21 @@ void EnWood02_Update(Actor* thisx, PlayState* play2) { dropsSpawnPt = this->actor.world.pos; dropsSpawnPt.y += 200.0f; - if ((this->unk_14C >= 0) && (this->unk_14C < 0x64) && (CVarGetInteger(CVAR_ENHANCEMENT("TreesDropSticks"), 0)) && !(INV_CONTENT(ITEM_STICK) == ITEM_NONE)) { - (numDrops = (Rand_ZeroOne() * 4)); - for (i = 0; i < numDrops; ++i) { - Item_DropCollectible(play, &dropsSpawnPt, ITEM00_STICK); - } - } else { - if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) { - Item_DropCollectibleRandom(play, &this->actor, &dropsSpawnPt, this->unk_14C << 4); - } else { - if (this->actor.home.rot.z != 0) { - this->actor.home.rot.z &= 0x1FFF; - this->actor.home.rot.z |= 0xE000; - Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y, - dropsSpawnPt.z, 0, this->actor.world.rot.y, 0, this->actor.home.rot.z, true); - this->actor.home.rot.z = 0; + if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TreesDropSticks"), 0) && INV_CONTENT(ITEM_STICK) != ITEM_NONE) { + numDrops = Rand_ZeroOne() * 4; + for (i = 0; i < numDrops; ++i) { + Item_DropCollectible(play, &dropsSpawnPt, ITEM00_STICK); } + } else { + Item_DropCollectibleRandom(play, &this->actor, &dropsSpawnPt, this->unk_14C << 4); } + } else if (this->actor.home.rot.z != 0) { + this->actor.home.rot.z &= 0x1FFF; + this->actor.home.rot.z |= 0xE000; + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y, + dropsSpawnPt.z, 0, this->actor.world.rot.y, 0, this->actor.home.rot.z, true); + this->actor.home.rot.z = 0; } // Spawn falling leaves @@ -421,7 +419,7 @@ void EnWood02_Update(Actor* thisx, PlayState* play2) { this->unk_14C++; Math_ApproachF(&this->actor.velocity.x, 0.0f, 1.0f, 5 * 0.01f); Math_ApproachF(&this->actor.velocity.z, 0.0f, 1.0f, 5 * 0.01f); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->actor.shape.rot.z = Math_SinS(3000 * this->unk_14C) * 0x4000; this->unk_14E[0]--; diff --git a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c index 512c11766..a5d582db2 100644 --- a/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c +++ b/soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c @@ -13,6 +13,8 @@ #include "scenes/indoors/tokinoma/tokinoma_scene.h" #include "scenes/dungeons/ice_doukutu/ice_doukutu_scene.h" #include "vt.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -415,7 +417,7 @@ void EnXc_SetWalkingSFX(EnXc* this, PlayState* play) { if (this->actor.bgCheckFlags & 1) { sfxId = SFX_FLAG; sfxId += SurfaceType_GetSfx(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId); - func_80078914(&this->actor.projectedPos, sfxId); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, sfxId); } } } @@ -429,11 +431,11 @@ void EnXc_SetNutThrowSFX(EnXc* this, PlayState* play) { if (this->actor.bgCheckFlags & 1) { sfxId = SFX_FLAG; sfxId += SurfaceType_GetSfx(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId); - func_80078914(&this->actor.projectedPos, sfxId); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, sfxId); } } if (Animation_OnFrame(&this->skelAnime, 20.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_SK_SHOUT); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_SK_SHOUT); } } @@ -445,7 +447,7 @@ void EnXc_SetLandingSFX(EnXc* this, PlayState* play) { if (Animation_OnFrame(&this->skelAnime, 11.0f)) { sfxId = SFX_FLAG; sfxId += SurfaceType_GetSfx(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId); - func_80078914(&this->actor.projectedPos, sfxId); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, sfxId); } } } @@ -465,13 +467,13 @@ void EnXc_SetColossusAppearSFX(EnXc* this, PlayState* play) { Vec3f pos = { -611.0f, 728.0f, -2.0f }; SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &pos, &sXyzDist, wDest); - func_80078914(&sXyzDist, NA_SE_EV_JUMP_CONC); + Sfx_PlaySfxAtPos(&sXyzDist, NA_SE_EV_JUMP_CONC); } else if (frameCount == 164) { Vec3f pos = { -1069.0f, 38.0f, 0.0f }; s32 pad; SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &pos, &sXyzDist, wDest); - func_80078914(&sXyzDist, NA_SE_PL_WALK_CONCRETE); + Sfx_PlaySfxAtPos(&sXyzDist, NA_SE_PL_WALK_CONCRETE); } } } @@ -481,7 +483,7 @@ void func_80B3D118(PlayState* play) { s16 sceneNum; if ((gSaveContext.sceneSetupIndex != 4) || (sceneNum = play->sceneNum, sceneNum != SCENE_DESERT_COLOSSUS)) { - func_800788CC(NA_SE_PL_SKIP); + Sfx_PlaySfxCentered2(NA_SE_PL_SKIP); } } @@ -635,11 +637,11 @@ void EnXc_CalcXZAccel(EnXc* this) { *speedXZ = (kREG(2) * 0.01f) + 1.2f; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void func_80B3D644(EnXc* this) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void EnXc_CalcXZSpeed(EnXc* this) { @@ -651,7 +653,7 @@ void EnXc_CalcXZSpeed(EnXc* this) { } else { *speedXZ = 0.0f; } - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void func_80B3D6F0(EnXc* this) { @@ -659,7 +661,7 @@ void func_80B3D6F0(EnXc* this) { } void func_80B3D710(EnXc* this) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } void func_80B3D730(EnXc* this) { @@ -1402,14 +1404,14 @@ void func_80B3F3C8(EnXc* this, PlayState* play) { } void func_80B3F3D8() { - func_800788CC(NA_SE_PL_SKIP); + Sfx_PlaySfxCentered2(NA_SE_PL_SKIP); } void EnXc_PlayDiveSFX(Vec3f* src, PlayState* play) { f32 wDest[2]; SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, src, &D_80B42DA0, wDest); - func_80078914(&D_80B42DA0, NA_SE_EV_DIVE_INTO_WATER); + Sfx_PlaySfxAtPos(&D_80B42DA0, NA_SE_EV_DIVE_INTO_WATER); } void EnXc_LakeHyliaDive(PlayState* play) { @@ -1586,7 +1588,7 @@ void EnXc_PlayTriforceSFX(Actor* thisx, PlayState* play) { void func_80B3FAE0(EnXc* this) { if (Animation_OnFrame(&this->skelAnime, 38.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_SK_SHOUT); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_SK_SHOUT); func_80B3FA2C(); } } @@ -1788,14 +1790,14 @@ void EnXc_SetThrownAroundSFX(EnXc* this) { SkelAnime* skelAnime = &this->skelAnime; if (Animation_OnFrame(skelAnime, 9.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_BOUND_GRASS); - func_80078914(&this->actor.projectedPos, NA_SE_VO_SK_CRASH); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_BOUND_GRASS); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_SK_CRASH); } else if (Animation_OnFrame(skelAnime, 26.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_BOUND_GRASS); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_BOUND_GRASS); } else if (Animation_OnFrame(skelAnime, 28.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_WALK_GRASS); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WALK_GRASS); } else if (Animation_OnFrame(skelAnime, 34.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_WALK_GRASS); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WALK_GRASS); } } @@ -1809,9 +1811,9 @@ void EnXc_SetCrySFX(EnXc* this, PlayState* play) { CutsceneContext* csCtx = &play->csCtx; if (csCtx->frames == 869) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_SK_CRY_0); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_SK_CRY_0); } else if (csCtx->frames == 939) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_SK_CRY_1); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_SK_CRY_1); } } diff --git a/soh/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c b/soh/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c index 20880b496..be77887db 100644 --- a/soh/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c +++ b/soh/src/overlays/actors/ovl_En_Yabusame_Mark/z_en_yabusame_mark.c @@ -177,10 +177,10 @@ void func_80B42F74(EnYabusameMark* this, PlayState* play) { } if (scoreIndex == 1) { Audio_StopSfxById(NA_SE_SY_TRE_BOX_APPEAR); - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } if (scoreIndex == 0) { - func_80078884(NA_SE_SY_DECIDE); + Sfx_PlaySfxCentered(NA_SE_SY_DECIDE); } EffectSsExtra_Spawn(play, &arrowHitPos, &effectVelocity, &effectAccel, 5, scoreIndex); } diff --git a/soh/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c b/soh/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c index c5c066685..96cda6951 100644 --- a/soh/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c +++ b/soh/src/overlays/actors/ovl_En_Yukabyun/z_en_yukabyun.c @@ -131,7 +131,7 @@ void EnYukabyun_Update(Actor* thisx, PlayState* play) { } this->actionfunc(this, play); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (!(this->actionfunc == func_80B43A94 || this->actionfunc == EnYukabyun_Break)) { Actor_UpdateBgCheckInfo(play, &this->actor, 5.0f, 20.0f, 8.0f, 5); diff --git a/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c b/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c index 4ecf2afee..85a878cc6 100644 --- a/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c +++ b/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c @@ -7,6 +7,7 @@ #include "z_en_zf.h" #include "objects/object_zf/object_zf.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED) @@ -2044,7 +2045,7 @@ void EnZf_Update(Actor* thisx, PlayState* play) { } if (!this->unk_3F8) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } Actor_UpdateBgCheckInfo(play, &this->actor, 25.0f, 30.0f, 60.0f, 0x1D); diff --git a/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c b/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c index 1b0b39aa5..672f8a63b 100644 --- a/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c +++ b/soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c @@ -592,34 +592,34 @@ void func_80B4FD90(EnZl2* this, PlayState* play) { void func_80B4FDD4(EnZl2* this) { if (Animation_OnFrame(&this->skelAnime, 14.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_PL_WALK_CONCRETE); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WALK_CONCRETE); } } void func_80B4FE10(PlayState* play) { if ((play->csCtx.frames >= 830) && (play->csCtx.frames < 1081)) { - func_800788CC(NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Sfx_PlaySfxCentered2(NA_SE_EV_EARTHQUAKE - SFX_FLAG); } } void func_80B4FE48(EnZl2* this) { - func_80078914(&this->actor.projectedPos, NA_SE_EV_GOTO_HEAVEN - SFX_FLAG); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_GOTO_HEAVEN - SFX_FLAG); } void func_80B4FE6C(EnZl2* this) { - func_80078914(&this->actor.projectedPos, NA_SE_EN_GANON_LAUGH); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EN_GANON_LAUGH); } void func_80B4FE90(EnZl2* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_Z1_SURPRISE); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_Z1_SURPRISE); } void func_80B4FEB4(EnZl2* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_Z1_PAIN); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_Z1_PAIN); } void func_80B4FED8(EnZl2* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_Z1_CRY_0); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_Z1_CRY_0); } void EnZl2_GiveLightArrows(EnZl2* this, PlayState* play) { @@ -1444,7 +1444,7 @@ void func_80B51D24(EnZl2* this, PlayState* play) { if (this->actor.bgCheckFlags & 1) { sfxId = SFX_FLAG; sfxId += SurfaceType_GetSfx(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId); - func_80078914(&this->actor.projectedPos, sfxId); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, sfxId); } } } diff --git a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c index d07f2de50..125b7351a 100644 --- a/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c +++ b/soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c @@ -11,6 +11,7 @@ #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "objects/object_zl2/object_zl2.h" #include "objects/object_zl2_anime2/object_zl2_anime2.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -776,7 +777,7 @@ void func_80B54EA4(EnZl3* this, PlayState* play) { } void func_80B54EF4(EnZl3* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_Z1_PAIN); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_Z1_PAIN); } void func_80B54F18(EnZl3* this, PlayState* play) { @@ -1012,7 +1013,7 @@ void func_80B55780(EnZl3* this, PlayState* play) { } void func_80B55808(EnZl3* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_Z1_PAIN); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_Z1_PAIN); } void func_80B5582C(EnZl3* this) { @@ -1023,7 +1024,7 @@ void func_80B5585C(EnZl3* this) { SkelAnime* skelAnime = &this->skelAnime; if ((skelAnime->mode == 2) && Animation_OnFrame(skelAnime, 4.0f)) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_Z1_PAIN); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_Z1_PAIN); } } @@ -1534,18 +1535,18 @@ void func_80B56D44(EnZl3* this, PlayState* play) { } void func_80B56DA4(EnZl3* this) { - func_800788CC(NA_SE_EV_ZELDA_POWER); + Sfx_PlaySfxCentered2(NA_SE_EV_ZELDA_POWER); } void func_80B56DC8(EnZl3* this) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_Z1_PAIN); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_Z1_PAIN); } void func_80B56DEC(EnZl3* this) { SkelAnime* skelAnime = &this->skelAnime; if ((skelAnime->mode == 2) && Animation_OnFrame(skelAnime, 9.0f) != 0) { - func_80078914(&this->actor.projectedPos, NA_SE_VO_Z1_OPENDOOR); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_VO_Z1_OPENDOOR); } } @@ -1557,7 +1558,7 @@ void func_80B56E38(EnZl3* this, PlayState* play) { if ((Animation_OnFrame(sp20, 6.0f) || Animation_OnFrame(sp20, 0.0f)) && (this->actor.bgCheckFlags & 1)) { sfxId = 0x800; sfxId += SurfaceType_GetSfx(&play->colCtx, this->actor.floorPoly, this->actor.floorBgId); - func_80078914(&this->actor.projectedPos, sfxId); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, sfxId); } } @@ -2568,7 +2569,7 @@ void func_80B59828(EnZl3* this, PlayState* play) { void func_80B59A80(EnZl3* this, PlayState* play) { if (func_80B59768(this, play)) { - Audio_PlaySoundGeneral(NA_SE_OC_REVENGE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_OC_REVENGE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c index cdb88cc48..a50d64766 100644 --- a/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -7,6 +7,8 @@ #include "z_en_zl4.h" #include "objects/object_zl4/object_zl4.h" #include "scenes/indoors/nakaniwa/nakaniwa_scene.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED) diff --git a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c index 57ac15ecf..bae52cd47 100644 --- a/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c +++ b/soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c @@ -8,6 +8,7 @@ #include "objects/object_zo/object_zo.h" #include "soh/frame_interpolation.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -738,7 +739,7 @@ void EnZo_Update(Actor* thisx, PlayState* play) { EnZo_Blink(this); } - Actor_MoveForward(thisx); + Actor_MoveXZGravity(thisx); Actor_UpdateBgCheckInfo(play, thisx, this->collider.dim.radius, this->collider.dim.height * 0.25f, 0.0f, 5); this->actionFunc(this, play); EnZo_Dialog(this, play); diff --git a/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.c b/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.c index 0601a7f5b..986f60c02 100644 --- a/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.c +++ b/soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.c @@ -290,11 +290,11 @@ void EnfHG_Intro(EnfHG* this, PlayState* play) { bossGnd->work[GND_EYE_STATE] = GND_EYESTATE_BRIGHTEN; } if (this->timers[0] == 35) { - func_80078914(&audioVec, NA_SE_EN_FANTOM_EYE); + Sfx_PlaySfxAtPos(&audioVec, NA_SE_EN_FANTOM_EYE); } if (this->timers[0] == 130) { bossGnd->work[GND_EYE_STATE] = GND_EYESTATE_FADE; - func_80078914(&audioVec, NA_SE_EN_FANTOM_ST_LAUGH); + Sfx_PlaySfxAtPos(&audioVec, NA_SE_EN_FANTOM_ST_LAUGH); } if (this->timers[0] == 20) { Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_BOSS); @@ -468,7 +468,7 @@ void EnfHG_Approach(EnfHG* this, PlayState* play) { this->hoofSfxPos.y = this->actor.projectedPos.y / (this->actor.scale.x * 100.0f); this->hoofSfxPos.z = this->actor.projectedPos.z / (this->actor.scale.x * 100.0f); if ((this->gallopTimer % 8) == 0) { - func_80078914(&this->hoofSfxPos, NA_SE_EV_HORSE_RUN); + Sfx_PlaySfxAtPos(&this->hoofSfxPos, NA_SE_EV_HORSE_RUN); } } SkelAnime_Update(&this->skin.skelAnime); @@ -637,7 +637,7 @@ void EnfHG_Retreat(EnfHG* this, PlayState* play) { this->hoofSfxPos.y = this->actor.projectedPos.y / (this->actor.scale.x * 100.0f); this->hoofSfxPos.z = this->actor.projectedPos.z / (this->actor.scale.x * 100.0f); if ((this->gallopTimer % 8) == 0) { - func_80078914(&this->hoofSfxPos, NA_SE_EV_HORSE_RUN); + Sfx_PlaySfxAtPos(&this->hoofSfxPos, NA_SE_EV_HORSE_RUN); } } SkelAnime_Update(&this->skin.skelAnime); diff --git a/soh/src/overlays/actors/ovl_End_Title/z_end_title.c b/soh/src/overlays/actors/ovl_End_Title/z_end_title.c index af13255a8..3e83e5ae3 100644 --- a/soh/src/overlays/actors/ovl_End_Title/z_end_title.c +++ b/soh/src/overlays/actors/ovl_End_Title/z_end_title.c @@ -84,8 +84,6 @@ void EndTitle_DrawFull(Actor* thisx, PlayState* play) { } OVERLAY_DISP = Gfx_SetupDL_64(OVERLAY_DISP); - if (D_801614B0.a > 0) - gSPGrayscale(OVERLAY_DISP++, false); gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE); gDPSetEnvColor(OVERLAY_DISP++, 255, 120, 30, 0); gDPSetRenderMode(OVERLAY_DISP++, G_RM_PASS, G_RM_XLU_SURF2); @@ -110,8 +108,6 @@ void EndTitle_DrawFull(Actor* thisx, PlayState* play) { G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0); gSPTextureRectangle(OVERLAY_DISP++, 104 << 2, 177 << 2, 216 << 2, 192 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); - if (D_801614B0.a > 0) - gSPGrayscale(OVERLAY_DISP++, true); CLOSE_DISPS(play->state.gfxCtx); } diff --git a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c index 6e003af21..01d63248f 100644 --- a/soh/src/overlays/actors/ovl_Fishing/z_fishing.c +++ b/soh/src/overlays/actors/ovl_Fishing/z_fishing.c @@ -11,6 +11,7 @@ #include "vt.h" #include "soh/frame_interpolation.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -2284,7 +2285,7 @@ void Fishing_UpdateLure(Fishing* this, PlayState* play) { sRodReelingSpeed = 0.5f; D_80B7E118 = Rand_ZeroFloat(1.9f); sFishMouthOffset.y = 500.0f; - func_80078914(&sSoundPos, NA_SE_IT_SWORD_SWING_HARD); + Sfx_PlaySfxAtPos(&sSoundPos, NA_SE_IT_SWORD_SWING_HARD); } } break; @@ -2304,7 +2305,7 @@ void Fishing_UpdateLure(Fishing* this, PlayState* play) { sLurePosDelta.x *= 0.9f; sLurePosDelta.z *= 0.9f; if (!sIsOwnersHatHooked) { - func_80078884(NA_SE_IT_FISHING_REEL_HIGH - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_IT_FISHING_REEL_HIGH - SFX_FLAG); } } @@ -2359,7 +2360,7 @@ void Fishing_UpdateLure(Fishing* this, PlayState* play) { sReelLinePosStep = 0.0; } else { Math_ApproachF(&D_80B7E148, 0.0f, 1.0f, 0.05f); - func_80078914(&sSoundPos, NA_SE_EN_FANTOM_FLOAT - SFX_FLAG); + Sfx_PlaySfxAtPos(&sSoundPos, NA_SE_EN_FANTOM_FLOAT - SFX_FLAG); } } else { spE4 = WATER_SURFACE_Y(play); @@ -2377,7 +2378,7 @@ void Fishing_UpdateLure(Fishing* this, PlayState* play) { if ((sLurePos.y <= spE4) && (spE4 < spE0) && (spE4 == WATER_SURFACE_Y(play))) { D_80B7E114 = 10; - func_80078914(&sSoundPos, NA_SE_EV_BOMB_DROP_WATER); + Sfx_PlaySfxAtPos(&sSoundPos, NA_SE_EV_BOMB_DROP_WATER); sLureCastDelta.y = 0.0f; sLurePosDelta.y *= 0.2f; @@ -2403,7 +2404,7 @@ void Fishing_UpdateLure(Fishing* this, PlayState* play) { } } else { Math_ApproachZeroF(&D_80B7E148, 1.0f, 0.05f); - func_80078914(&sSoundPos, NA_SE_EN_FANTOM_FLOAT - SFX_FLAG); + Sfx_PlaySfxAtPos(&sSoundPos, NA_SE_EN_FANTOM_FLOAT - SFX_FLAG); } } @@ -2536,7 +2537,7 @@ void Fishing_UpdateLure(Fishing* this, PlayState* play) { sLureRot.x = 0.0f; if (CHECK_BTN_ALL(input->press.button, BTN_B)) { sRodLineSpooled += 6.0f; - func_80078914(&sSoundPos, NA_SE_PL_WALK_SAND); + Sfx_PlaySfxAtPos(&sSoundPos, NA_SE_PL_WALK_SAND); } } else { if (sRodLineSpooled > 150.0f) { @@ -2617,11 +2618,11 @@ void Fishing_UpdateLure(Fishing* this, PlayState* play) { if (CHECK_BTN_ALL(input->cur.button, BTN_A)) { if (CHECK_BTN_ALL(input->cur.button, BTN_R)) { sRodLineSpooled += 1.5f; - func_80078884(NA_SE_IT_FISHING_REEL_HIGH - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_IT_FISHING_REEL_HIGH - SFX_FLAG); Math_ApproachF(&sReelLinePosStep, 1000.0f, 1.0f, 2.0f); } else { sRodLineSpooled += sRodReelingSpeed; - func_80078884(NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG); Math_ApproachF(&sReelLinePosStep, 1000.0f, 1.0f, 0.2f); } @@ -2679,7 +2680,7 @@ void Fishing_UpdateLure(Fishing* this, PlayState* play) { } else { sRodLineSpooled += sRodReelingSpeed; } - func_80078884(NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG); } if ((sLureTimer & 0x1F) == 0) { @@ -3608,7 +3609,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { } else if (distToTarget < 10.0f) { if (sLurePos.y > (WATER_SURFACE_Y(play) - 10.0f)) { Audio_PlayActorSound2(&this->actor, NA_SE_EV_JUMP_OUT_WATER); - func_80078884(NA_SE_PL_CATCH_BOOMERANG); + Sfx_PlaySfxCentered(NA_SE_PL_CATCH_BOOMERANG); } Fishing_SplashBySize(this, play, false); @@ -3685,7 +3686,7 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { func_800A9F6C(0.0f, rumbleStrength, 120, 5); sRumbleDelay = 40; sRodHitTimer = 10; - func_80078884(NA_SE_IT_FISHING_HIT); + Sfx_PlaySfxCentered(NA_SE_IT_FISHING_HIT); } } @@ -4147,10 +4148,10 @@ void Fishing_UpdateFish(Actor* thisx, PlayState* play2) { Math_ApproachS(&this->unk_16E, spF6, 3, 0xBB8); } - func_8002D908(&this->actor); + Actor_UpdateVelocityXYZ(&this->actor); } - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->actor.world.pos.y += (this->unk_184 * 1.5f); @@ -5090,16 +5091,14 @@ void Fishing_HandleOwnerDialog(Fishing* this, PlayState* play) { if (sLinkAge == LINK_AGE_CHILD) { // 9 lbs //if we should give the main prize AND it's not rando - if (GameInteractor_Should(VB_SHOULD_GIVE_VANILLA_FISHING_PRIZE, false, &fishData)){ - //((sFishingRecordLength >= 50.0f) && !(HIGH_SCORE(HS_FISHING) & HS_FISH_PRIZE_CHILD)) { + if (GameInteractor_Should(VB_SHOULD_GIVE_VANILLA_FISHING_PRIZE, (sFishingRecordLength >= 50.0f) && !(HIGH_SCORE(HS_FISHING) & HS_FISH_PRIZE_CHILD), &fishData)){ HIGH_SCORE(HS_FISHING) |= HS_FISH_PRIZE_CHILD; getItemId = GI_HEART_PIECE; sSinkingLureLocation = (u8)Rand_ZeroFloat(3.999f) + 1; } } else { // 13 lbs //if we should give the main prize AND it's not rando - if (GameInteractor_Should(VB_SHOULD_GIVE_VANILLA_FISHING_PRIZE, false, &fishData)){ - //(sFishingRecordLength >= 60.0f) && !(HIGH_SCORE(HS_FISHING) & HS_FISH_PRIZE_ADULT)) { + if (GameInteractor_Should(VB_SHOULD_GIVE_VANILLA_FISHING_PRIZE, (sFishingRecordLength >= 60.0f) && !(HIGH_SCORE(HS_FISHING) & HS_FISH_PRIZE_ADULT), &fishData)){ HIGH_SCORE(HS_FISHING) |= HS_FISH_PRIZE_ADULT; getItemId = GI_SCALE_GOLDEN; sSinkingLureLocation = (u8)Rand_ZeroFloat(3.999f) + 1; @@ -5360,7 +5359,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { sSinkingLureLocation = 0; sFishingPlayerCinematicState = 20; func_800A9F6C(0.0f, 150, 10, 10); - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x1400FF); } @@ -5369,7 +5368,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { sLureEquipped = FS_LURE_STOCK; sFishingPlayerCinematicState = 20; func_800A9F6C(0.0f, 150, 10, 10); - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); Audio_QueueSeqCmd(0x1 << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0x1400FF); } @@ -5447,9 +5446,9 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { } if ((sLureCameraZoomLevel == 0) || (sLureCameraZoomLevel == 3)) { - func_80078884(NA_SE_SY_CAMERA_ZOOM_DOWN); + Sfx_PlaySfxCentered(NA_SE_SY_CAMERA_ZOOM_DOWN); } else { - func_80078884(NA_SE_SY_CAMERA_ZOOM_UP); + Sfx_PlaySfxCentered(NA_SE_SY_CAMERA_ZOOM_UP); } } } @@ -5831,7 +5830,7 @@ void Fishing_UpdateOwner(Actor* thisx, PlayState* play2) { SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &sStreamSoundPos, &sStreamSoundProjectedPos, &sProjectedW); - func_80078914(&sStreamSoundProjectedPos, NA_SE_EV_WATER_WALL - SFX_FLAG); + Sfx_PlaySfxAtPos(&sStreamSoundProjectedPos, NA_SE_EV_WATER_WALL - SFX_FLAG); gSaveContext.minigameScore = (SQ((f32)sFishLengthToWeigh) * 0.0036f) + 0.5f; diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index 85a81af85..9d3c9c240 100644 --- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -6,6 +6,7 @@ #include "z_item_b_heart.h" #include "objects/object_gi_hearts/object_gi_hearts.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c index 5aa223290..8088c6262 100644 --- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -6,6 +6,7 @@ #include "z_item_etcetera.h" #include +#include "soh/OTRGlobals.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -166,7 +167,7 @@ void ItemEtcetera_SpawnSparkles(ItemEtcetera* this, PlayState* play) { void ItemEtcetera_MoveFireArrowDown(ItemEtcetera* this, PlayState* play) { Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 10.0f, 0.0f, 5); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (!(this->actor.bgCheckFlags & 1)) { ItemEtcetera_SpawnSparkles(this, play); } diff --git a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c index 7a16f2a71..99cde87d6 100644 --- a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c +++ b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c @@ -6,6 +6,7 @@ #include "z_item_ocarina.h" #include "scenes/overworld/spot00/spot00_scene.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -81,7 +82,7 @@ void ItemOcarina_Destroy(Actor* thisx, PlayState* play) { void ItemOcarina_Fly(ItemOcarina* this, PlayState* play) { Vec3f ripplePos; - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->actor.shape.rot.x += this->spinRotOffset * 2; this->actor.shape.rot.y += this->spinRotOffset * 3; @@ -132,7 +133,7 @@ void ItemOcarina_GetThrown(ItemOcarina* this, PlayState* play) { } void func_80B864EC(ItemOcarina* this, PlayState* play) { - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); this->actor.shape.rot.x += this->spinRotOffset * 2; this->actor.shape.rot.y += this->spinRotOffset * 3; diff --git a/soh/src/overlays/actors/ovl_Item_Shield/z_item_shield.c b/soh/src/overlays/actors/ovl_Item_Shield/z_item_shield.c index beecbf759..8c40e346e 100644 --- a/soh/src/overlays/actors/ovl_Item_Shield/z_item_shield.c +++ b/soh/src/overlays/actors/ovl_Item_Shield/z_item_shield.c @@ -98,7 +98,7 @@ void ItemShield_Destroy(Actor* thisx, PlayState* play) { } void func_80B86AC8(ItemShield* this, PlayState* play) { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); if (Actor_HasParent(&this->actor, play)) { Actor_Kill(&this->actor); return; @@ -148,7 +148,7 @@ void func_80B86CA8(ItemShield* this, PlayState* play) { s32 i; s32 temp; - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 10.0f, 10.0f, 0.0f, 5); this->actor.shape.yOffset = ABS(Math_SinS(this->actor.shape.rot.x)) * 1500.0f; diff --git a/soh/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.c b/soh/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.c index db1ea8208..069e7ddbe 100644 --- a/soh/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.c +++ b/soh/src/overlays/actors/ovl_Magic_Dark/z_magic_dark.c @@ -198,10 +198,14 @@ void MagicDark_DiamondDraw(Actor* thisx, PlayState* play) { MagicDark* this = (MagicDark*)thisx; s32 pad; u16 gameplayFrames = play->gameplayFrames; - Color_RGB8 Spell_env_ori = {0, 100, 255}; - Color_RGB8 Spell_col_ori = {170, 255, 255}; - Color_RGB8 Spell_env = CVarGetColor24(CVAR_COSMETIC("Magic.NayrusSecondary.Value"), Spell_env_ori); - Color_RGB8 Spell_col = CVarGetColor24(CVAR_COSMETIC("Magic.NayrusPrimary.Value"), Spell_col_ori); + Color_RGB8 Spell_env = { 0, 100, 255 }; + Color_RGB8 Spell_col = { 170, 255, 255 }; + if (CVarGetInteger(CVAR_COSMETIC("Magic.NayrusSecondary.Changed"), 0)) { + Spell_env = CVarGetColor24(CVAR_COSMETIC("Magic.NayrusSecondary.Value"), Spell_env); + } + if (CVarGetInteger(CVAR_COSMETIC("Magic.NayrusPrimary.Changed"), 0)) { + Spell_col = CVarGetColor24(CVAR_COSMETIC("Magic.NayrusPrimary.Value"), Spell_col); + } OPEN_DISPS(play->state.gfxCtx); @@ -224,13 +228,8 @@ void MagicDark_DiamondDraw(Actor* thisx, PlayState* play) { Matrix_RotateY(this->actor.shape.rot.y * (M_PI / 0x8000), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - if (CVarGetInteger(CVAR_COSMETIC("UseSpellsColors"),0)) { - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, Spell_col.r, Spell_col.g, Spell_col.b, (s32)(this->primAlpha * 0.6f) & 0xFF); - gDPSetEnvColor(POLY_XLU_DISP++, Spell_env.r, Spell_env.g, Spell_env.b, 128); - } else { - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 170, 255, 255, (s32)(this->primAlpha * 0.6f) & 0xFF); - gDPSetEnvColor(POLY_XLU_DISP++, 0, 100, 255, 128); - } + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, Spell_col.r, Spell_col.g, Spell_col.b, (s32)(this->primAlpha * 0.6f) & 0xFF); + gDPSetEnvColor(POLY_XLU_DISP++, Spell_env.r, Spell_env.g, Spell_env.b, 128); gSPDisplayList(POLY_XLU_DISP++, sDiamondMaterialDL); gSPDisplayList(POLY_XLU_DISP++, Gfx_TwoTexScroll(play->state.gfxCtx, 0, gameplayFrames * 2, gameplayFrames * -4, 32, 32, 1, @@ -271,8 +270,18 @@ void MagicDark_OrbDraw(Actor* thisx, PlayState* play) { OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Xlu(play->state.gfxCtx); - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, 255); - gDPSetEnvColor(POLY_XLU_DISP++, 0, 150, 255, 255); + + Color_RGB8 Spell_env = { 0, 150, 255 }; + Color_RGB8 Spell_col = { 170, 255, 255 }; + if (CVarGetInteger(CVAR_COSMETIC("Magic.NayrusSecondary.Changed"), 0)) { + Spell_env = CVarGetColor24(CVAR_COSMETIC("Magic.NayrusSecondary.Value"), Spell_env); + } + if (CVarGetInteger(CVAR_COSMETIC("Magic.NayrusPrimary.Changed"), 0)) { + Spell_col = CVarGetColor24(CVAR_COSMETIC("Magic.NayrusPrimary.Value"), Spell_col); + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, Spell_col.r, Spell_col.g, Spell_col.b, 255); + gDPSetEnvColor(POLY_XLU_DISP++, Spell_env.r, Spell_env.g, Spell_env.b, 255); Matrix_Translate(pos.x, pos.y, pos.z, MTXMODE_NEW); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY); diff --git a/soh/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.c b/soh/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.c index f785124f4..da0fb02e5 100644 --- a/soh/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.c +++ b/soh/src/overlays/actors/ovl_Magic_Fire/z_magic_fire.c @@ -5,6 +5,7 @@ */ #include "z_magic_fire.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -216,10 +217,14 @@ void MagicFire_Draw(Actor* thisx, PlayState* play) { s32 pad2; s32 i; u8 alpha; - Color_RGB8 Spell_env_ori = {255, 0, 0}; - Color_RGB8 Spell_col_ori = {255, 200, 0}; - Color_RGB8 Spell_env = CVarGetColor24(CVAR_COSMETIC("Magic.DinsSecondary.Value"), Spell_env_ori); - Color_RGB8 Spell_col = CVarGetColor24(CVAR_COSMETIC("Magic.DinsPrimaryary.Value"), Spell_col_ori); + Color_RGB8 Spell_env = { 255, 0, 0 }; + Color_RGB8 Spell_col = { 255, 200, 0 }; + if (CVarGetInteger(CVAR_COSMETIC("Magic.DinsSecondary.Changed"), 0)) { + Spell_env = CVarGetColor24(CVAR_COSMETIC("Magic.DinsSecondary.Value"), Spell_env); + } + if (CVarGetInteger(CVAR_COSMETIC("Magic.DinsPrimaryary.Changed"), 0)) { + Spell_col = CVarGetColor24(CVAR_COSMETIC("Magic.DinsPrimary.Value"), Spell_col); + } if (this->action > 0) { OPEN_DISPS(play->state.gfxCtx); @@ -231,13 +236,8 @@ void MagicFire_Draw(Actor* thisx, PlayState* play) { gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE); gDPFillRectangle(POLY_XLU_DISP++, 0, 0, 319, 239); Gfx_SetupDL_25Xlu(play->state.gfxCtx); - if (CVarGetInteger(CVAR_COSMETIC("UseSpellsColors"),0)) { - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, Spell_col.r, Spell_col.g, Spell_col.b, (u8)(this->alphaMultiplier * 255)); - gDPSetEnvColor(POLY_XLU_DISP++, Spell_env.r, Spell_env.g, Spell_env.b, (u8)(this->alphaMultiplier * 255)); - } else { - gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, Spell_col_ori.r, Spell_col_ori.g, Spell_col_ori.b, (u8)(this->alphaMultiplier * 255)); - gDPSetEnvColor(POLY_XLU_DISP++, Spell_env_ori.r, Spell_env_ori.g, Spell_env_ori.b, (u8)(this->alphaMultiplier * 255)); - } + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, Spell_col.r, Spell_col.g, Spell_col.b, (u8)(this->alphaMultiplier * 255)); + gDPSetEnvColor(POLY_XLU_DISP++, Spell_env.r, Spell_env.g, Spell_env.b, (u8)(this->alphaMultiplier * 255)); Matrix_Scale(0.15f, 0.15f, 0.15f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/soh/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.c b/soh/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.c index ac7a35036..3d8d0cff0 100644 --- a/soh/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.c +++ b/soh/src/overlays/actors/ovl_Magic_Wind/z_magic_wind.c @@ -5,6 +5,7 @@ */ #include "z_magic_wind.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) diff --git a/soh/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c b/soh/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c index c57eb7b1d..968a6a3fc 100644 --- a/soh/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c +++ b/soh/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c @@ -8,6 +8,7 @@ #include "objects/object_mamenoki/object_mamenoki.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "vt.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS ACTOR_FLAG_IGNORE_POINTLIGHTS @@ -701,12 +702,14 @@ void ObjBean_GrowWaterPhase3(ObjBean* this, PlayState* play) { itemDropPos.x = this->dyna.actor.world.pos.x; itemDropPos.y = this->dyna.actor.world.pos.y - 25.0f; itemDropPos.z = this->dyna.actor.world.pos.z; - for (i = 0; i < 3; i++) { - Item_DropCollectible(play, &itemDropPos, ITEM00_FLEXIBLE); + if (GameInteractor_Should(VB_SPAWN_BEAN_STALK_FAIRIES, true, this)) { + for (i = 0; i < 3; i++) { + Item_DropCollectible(play, &itemDropPos, ITEM00_FLEXIBLE); + } } this->stateFlags |= BEAN_STATE_BEEN_WATERED; Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } } else if (this->timer <= 0) { ObjBean_SetupGrowWaterPhase4(this); @@ -752,7 +755,7 @@ void ObjBean_SetupWaitForPlayer(ObjBean* this) { } void ObjBean_WaitForPlayer(ObjBean* this, PlayState* play) { - if (func_8004356C(&this->dyna)) { // Player is standing on + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { // Player is standing on ObjBean_SetupFly(this); if (play->sceneNum == SCENE_LOST_WOODS) { // Lost woods Camera_ChangeSetting(play->cameraPtrs[MAIN_CAM], CAM_SET_BEAN_LOST_WOODS); @@ -786,7 +789,7 @@ void ObjBean_Fly(ObjBean* this, PlayState* play) { Camera_ChangeSetting(camera, CAM_SET_NORMAL0); } - } else if (func_8004356C(&this->dyna) != 0) { // Player is on top + } else if (DynaPolyActor_IsPlayerOnTop(&this->dyna) != 0) { // Player is on top func_8002F974(&this->dyna.actor, NA_SE_PL_PLANT_MOVE - SFX_FLAG); @@ -812,7 +815,7 @@ void ObjBean_SetupWaitForStepOff(ObjBean* this) { } void ObjBean_WaitForStepOff(ObjBean* this, PlayState* play) { - if (!func_80043590(&this->dyna)) { + if (!DynaPolyActor_IsPlayerAbove(&this->dyna)) { ObjBean_SetupWaitForPlayer(this); } ObjBean_UpdatePosition(this); @@ -824,7 +827,7 @@ void func_80B908EC(ObjBean* this) { } void func_80B90918(ObjBean* this, PlayState* play) { - if (!func_8004356C(&this->dyna)) { + if (!DynaPolyActor_IsPlayerOnTop(&this->dyna)) { ObjBean_SetupPathCount(this, play); ObjBean_SetupPath(this, play); ObjBean_Move(this); @@ -904,7 +907,7 @@ void ObjBean_Update(Actor* thisx, PlayState* play) { } Actor_SetFocus(&this->dyna.actor, 6.0f); if (this->stateFlags & BEAN_STATE_DYNAPOLY_SET) { - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { this->stateFlags |= BEAN_STATE_PLAYER_ON_TOP; } else { this->stateFlags &= ~BEAN_STATE_PLAYER_ON_TOP; diff --git a/soh/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c b/soh/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c index dda22c292..cd50df4ba 100644 --- a/soh/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c +++ b/soh/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c @@ -53,9 +53,9 @@ void ObjBlockstop_Update(Actor* thisx, PlayState* play) { if (dynaPolyActor != NULL && dynaPolyActor->actor.id == ACTOR_OBJ_OSHIHIKI) { if ((dynaPolyActor->actor.params & 0x000F) == PUSHBLOCK_HUGE_START_ON || (dynaPolyActor->actor.params & 0x000F) == PUSHBLOCK_HUGE_START_OFF) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } else { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } Flags_SetSwitch(play, this->actor.params); diff --git a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c index b300b6853..602236816 100644 --- a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c +++ b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c @@ -131,7 +131,7 @@ void ObjBombiwa_Update(Actor* thisx, PlayState* play) { Flags_SetSwitch(play, this->actor.params & 0x3F); SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 80, NA_SE_EV_WALL_BROKEN); if (((this->actor.params >> 0xF) & 1) != 0) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); } Actor_Kill(&this->actor); } else { diff --git a/soh/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c b/soh/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c index 694644a80..f62956014 100644 --- a/soh/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c +++ b/soh/src/overlays/actors/ovl_Obj_Elevator/z_obj_elevator.c @@ -86,7 +86,7 @@ void func_80B92C80(ObjElevator* this, PlayState* play) { f32 sub; Actor* thisx = &this->dyna.actor; - if ((this->dyna.unk_160 & 2) && !(this->unk_170 & 2)) { + if ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) && !(this->unk_170 & DYNA_INTERACT_PLAYER_ON_TOP)) { sub = thisx->world.pos.y - thisx->home.pos.y; if (fabsf(sub) < 0.1f) { this->unk_168 = thisx->home.pos.y + ((thisx->params >> 0xC) & 0xF) * 80.0f; @@ -118,7 +118,7 @@ void ObjElevator_Update(Actor* thisx, PlayState* play) { if (this->actionFunc) { this->actionFunc(this, play); } - this->unk_170 = this->dyna.unk_160; + this->unk_170 = this->dyna.interactFlags; } void ObjElevator_Draw(Actor* thisx, PlayState* play) { diff --git a/soh/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c b/soh/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c index 70ae15fd8..eaeaaef07 100644 --- a/soh/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c +++ b/soh/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c @@ -202,7 +202,7 @@ void ObjKibako_Idle(ObjKibako* this, PlayState* play) { ObjKibako_SpawnCollectible(this, play); Actor_Kill(&this->actor); } else { - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 19.0f, 20.0f, 0.0f, 5); if (!(this->collider.base.ocFlags1 & OC1_TYPE_PLAYER) && (this->actor.xzDistToPlayer > 28.0f)) { this->collider.base.ocFlags1 |= OC1_TYPE_PLAYER; @@ -215,7 +215,7 @@ void ObjKibako_Idle(ObjKibako* this, PlayState* play) { } } if (this->actor.xzDistToPlayer < 100.0f) { - func_8002F580(&this->actor, play); + Actor_OfferCarry(&this->actor, play); } } } @@ -236,7 +236,7 @@ void ObjKibako_Held(ObjKibako* this, PlayState* play) { } else { ObjKibako_SetupThrown(this); ObjKibako_ApplyGravity(this); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); } Actor_UpdateBgCheckInfo(play, &this->actor, 19.0f, 20.0f, 0.0f, 5); } @@ -265,7 +265,7 @@ void ObjKibako_Thrown(ObjKibako* this, PlayState* play) { Actor_Kill(&this->actor); } else { ObjKibako_ApplyGravity(this); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 19.0f, 20.0f, 0.0f, 5); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base); diff --git a/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c b/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c index 4fd55a528..166dd4c36 100644 --- a/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c +++ b/soh/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c @@ -138,7 +138,7 @@ void func_80B96560(ObjLift* this, PlayState* play) { s32 pad; s32 quakeIndex; - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { if (this->timer <= 0) { if (((this->dyna.actor.params >> 8) & 7) == 7) { func_80B967C0(this); @@ -192,7 +192,7 @@ void func_80B96840(ObjLift* this, PlayState* play) { s32 bgId; Vec3f sp2C; - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); Math_Vec3f_Copy(&sp2C, &this->dyna.actor.prevPos); sp2C.y += sMaxFallDistances[(this->dyna.actor.params >> 1) & 1]; this->dyna.actor.floorHeight = diff --git a/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c b/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c index 18c898547..59d1b6203 100644 --- a/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c +++ b/soh/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c @@ -8,6 +8,7 @@ #include "vt.h" #include "overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h" #include "objects/object_lightswitch/object_lightswitch.h" +#include "soh/OTRGlobals.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED diff --git a/soh/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c b/soh/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c index f0b6c4c33..133abc310 100644 --- a/soh/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c +++ b/soh/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c @@ -114,7 +114,7 @@ void ObjMakeoshihiki_Draw(Actor* thisx, PlayState* play) { } if (sfxCond1 || sfxCond2) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } } diff --git a/soh/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c b/soh/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c index 5b1eecbd4..2be6ea478 100644 --- a/soh/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c +++ b/soh/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c @@ -5,6 +5,7 @@ */ #include "z_obj_mure2.h" +#include "soh/OTRGlobals.h" #define FLAGS 0 diff --git a/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c b/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c index 026598ac9..c69417461 100644 --- a/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c +++ b/soh/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c @@ -7,6 +7,7 @@ #include "z_obj_oshihiki.h" #include "overlays/actors/ovl_Obj_Switch/z_obj_switch.h" #include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED @@ -50,7 +51,7 @@ static Color_RGB8 sColors[][4] = { { { 232, 210, 176 }, { 232, 210, 176 }, { 232, 210, 176 }, { 232, 210, 176 } }, // spirit temple { { 135, 125, 95 }, { 135, 125, 95 }, { 135, 125, 95 }, { 135, 125, 95 } }, // shadow temple { { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 } }, // ganons castle - { { 232, 210, 176 }, { 232, 210, 176 }, { 232, 210, 176 }, { 232, 210, 176 } }, // gerudo training grounds + { { 232, 210, 176 }, { 232, 210, 176 }, { 232, 210, 176 }, { 232, 210, 176 } }, // Gerudo Training Ground }; static s16 sScenes[] = { @@ -499,7 +500,7 @@ void ObjOshihiki_OnActor(ObjOshihiki* this, PlayState* play) { DynaPolyActor* dynaPolyActor; this->stateFlags |= PUSHBLOCK_ON_ACTOR; - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); if (ObjOshihiki_CheckFloor(this, play)) { bgId = this->floorBgIds[this->highestFloor]; @@ -508,8 +509,8 @@ void ObjOshihiki_OnActor(ObjOshihiki* this, PlayState* play) { } else { dynaPolyActor = DynaPoly_GetActor(&play->colCtx, bgId); if (dynaPolyActor != NULL) { - func_800434A8(dynaPolyActor); - func_80043538(dynaPolyActor); + DynaPolyActor_SetActorOnTop(dynaPolyActor); + DynaPolyActor_SetSwitchPressed(dynaPolyActor); if ((this->timer <= 0) && (fabsf(this->dyna.unk_150) > 0.001f)) { if (ObjOshihiki_StrongEnough(this) && ObjOshihiki_NoSwitchPress(this, dynaPolyActor, play) && @@ -536,9 +537,9 @@ void ObjOshihiki_OnActor(ObjOshihiki* this, PlayState* play) { } else { dynaPolyActor = DynaPoly_GetActor(&play->colCtx, bgId); - if ((dynaPolyActor != NULL) && (dynaPolyActor->unk_15C & 1)) { - func_800434A8(dynaPolyActor); - func_80043538(dynaPolyActor); + if ((dynaPolyActor != NULL) && (dynaPolyActor->transformFlags & 1)) { + DynaPolyActor_SetActorOnTop(dynaPolyActor); + DynaPolyActor_SetSwitchPressed(dynaPolyActor); this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight; } else { ObjOshihiki_SetupFall(this, play); @@ -613,7 +614,7 @@ void ObjOshihiki_Fall(ObjOshihiki* this, PlayState* play) { this->dyna.unk_150 = 0.0f; player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY; } - Actor_MoveForward(&this->dyna.actor); + Actor_MoveXZGravity(&this->dyna.actor); if (ObjOshihiki_CheckGround(this, play)) { if (this->floorBgIds[this->highestFloor] == BGCHECK_SCENE) { ObjOshihiki_SetupOnScene(this, play); diff --git a/soh/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c b/soh/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c index 4da1c3eba..21ec649f9 100644 --- a/soh/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c +++ b/soh/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c @@ -77,11 +77,11 @@ void func_80B9D0B0(ObjRoomtimer* this, PlayState* play) { } Flags_SetClear(play, this->actor.room); Flags_SetSwitch(play, this->switchFlag); - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); Actor_Kill(&this->actor); } else { if ((this->actor.params != 0x3FF) && (gSaveContext.timer1Value == 0)) { - Audio_PlaySoundGeneral(NA_SE_OC_ABYSS, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_OC_ABYSS, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); Play_TriggerVoidOut(play); Actor_Kill(&this->actor); } diff --git a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c index e08291480..05e3577c0 100644 --- a/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c +++ b/soh/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c @@ -390,25 +390,26 @@ void ObjSwitch_FloorUp(ObjSwitch* this, PlayState* play) { } else { switch ((this->dyna.actor.params >> 4 & 7)) { case OBJSWITCH_SUBTYPE_FLOOR_0: - if (func_8004356C(&this->dyna)) { + if (DynaPolyActor_IsPlayerOnTop(&this->dyna)) { ObjSwitch_FloorPressInit(this); ObjSwitch_SetOn(this, play); } break; case OBJSWITCH_SUBTYPE_FLOOR_1: - if ((this->dyna.unk_160 & 2) && !(this->unk_17F & 2)) { + if ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) && + !(this->unk_17F & DYNA_INTERACT_PLAYER_ON_TOP)) { ObjSwitch_FloorPressInit(this); ObjSwitch_SetOn(this, play); } break; case OBJSWITCH_SUBTYPE_FLOOR_2: - if (func_800435B4(&this->dyna)) { + if (DynaPolyActor_IsSwitchPressed(&this->dyna)) { ObjSwitch_FloorPressInit(this); ObjSwitch_SetOn(this, play); } break; case OBJSWITCH_SUBTYPE_FLOOR_3: - if (func_800435B4(&this->dyna)) { + if (DynaPolyActor_IsSwitchPressed(&this->dyna)) { ObjSwitch_FloorPressInit(this); ObjSwitch_SetOff(this, play); } @@ -448,14 +449,15 @@ void ObjSwitch_FloorDown(ObjSwitch* this, PlayState* play) { } break; case OBJSWITCH_SUBTYPE_FLOOR_1: - if ((this->dyna.unk_160 & 2) && !(this->unk_17F & 2)) { + if ((this->dyna.interactFlags & DYNA_INTERACT_PLAYER_ON_TOP) && + !(this->unk_17F & DYNA_INTERACT_PLAYER_ON_TOP)) { ObjSwitch_FloorReleaseInit(this); ObjSwitch_SetOff(this, play); } break; case OBJSWITCH_SUBTYPE_FLOOR_2: case OBJSWITCH_SUBTYPE_FLOOR_3: - if (!func_800435B4(&this->dyna) && !Player_InCsMode(play)) { + if (!DynaPolyActor_IsSwitchPressed(&this->dyna) && !Player_InCsMode(play)) { if (this->releaseTimer <= 0) { ObjSwitch_FloorReleaseInit(this); if ((this->dyna.actor.params >> 4 & 7) == OBJSWITCH_SUBTYPE_FLOOR_2) { @@ -695,7 +697,7 @@ void ObjSwitch_Update(Actor* thisx, PlayState* play) { switch ((this->dyna.actor.params & 7)) { case OBJSWITCH_TYPE_FLOOR: case OBJSWITCH_TYPE_FLOOR_RUSTY: - this->unk_17F = this->dyna.unk_160; + this->unk_17F = this->dyna.interactFlags; break; case OBJSWITCH_TYPE_EYE: this->unk_17F = this->tris.col.base.acFlags; diff --git a/soh/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c b/soh/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c index 1bfb45ed2..bf9300798 100644 --- a/soh/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c +++ b/soh/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c @@ -188,8 +188,8 @@ void ObjSyokudai_Update(Actor* thisx, PlayState* play2) { if (interactionType < 0) { if (player->unk_860 == 0) { player->unk_860 = 210; - Audio_PlaySoundGeneral(NA_SE_EV_FLAME_IGNITION, &this->actor.projectedPos, 4, &D_801333E0, - &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_FLAME_IGNITION, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (player->unk_860 < 200) { player->unk_860 = 200; } @@ -225,8 +225,8 @@ void ObjSyokudai_Update(Actor* thisx, PlayState* play2) { this->litTimer = (litTimeScale * 50) + 110; } } - Audio_PlaySoundGeneral(NA_SE_EV_FLAME_IGNITION, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_FLAME_IGNITION, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } } diff --git a/soh/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c b/soh/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c index cf8c28165..1701eb60d 100644 --- a/soh/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c +++ b/soh/src/overlays/actors/ovl_Obj_Timeblock/z_obj_timeblock.c @@ -148,7 +148,7 @@ void ObjTimeblock_Destroy(Actor* thisx, PlayState* play) { } u8 ObjTimeblock_PlayerIsInRange(ObjTimeblock* this, PlayState* play) { - if (this->isVisible && func_80043590(&this->dyna)) { + if (this->isVisible && DynaPolyActor_IsPlayerAbove(&this->dyna)) { return false; } @@ -156,7 +156,7 @@ u8 ObjTimeblock_PlayerIsInRange(ObjTimeblock* this, PlayState* play) { Vec3f distance; f32 blockSize; - func_8002DBD0(&this->dyna.actor, &distance, &GET_PLAYER(play)->actor.world.pos); + Actor_WorldToActorCoords(&this->dyna.actor, &distance, &GET_PLAYER(play)->actor.world.pos); blockSize = this->dyna.actor.scale.x * 50.0f + 6.0f; // Return true if player's xz position is not inside the block if (blockSize < fabsf(distance.x) || blockSize < fabsf(distance.z)) { @@ -249,7 +249,7 @@ void ObjTimeblock_Normal(ObjTimeblock* this, PlayState* play) { this->isVisible = newIsVisible; if (this->demoEffectTimer == 50) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } } @@ -284,7 +284,7 @@ void ObjTimeblock_AltBehaviorVisible(ObjTimeblock* this, PlayState* play) { func_80BA06AC(this, play); if (this->demoEffectTimer == 50) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } if (!this->isVisible && this->demoEffectTimer <= 0) { diff --git a/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c b/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c index 9be71e91b..4cdc67e44 100644 --- a/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c +++ b/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c @@ -8,6 +8,7 @@ #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" #include "objects/object_tsubo/object_tsubo.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_ALWAYS_THROWN) @@ -86,7 +87,7 @@ static InitChainEntry sInitChain[] = { void ObjTsubo_SpawnCollectible(ObjTsubo* this, PlayState* play) { s16 dropParams = this->actor.params & 0x1F; - if ((dropParams >= ITEM00_RUPEE_GREEN) && (dropParams <= ITEM00_BOMBS_SPECIAL)) { + if (GameInteractor_Should(VB_POT_DROP_ITEM, (dropParams >= ITEM00_RUPEE_GREEN) && (dropParams <= ITEM00_BOMBS_SPECIAL), this)) { Item_DropCollectible(play, &this->actor.world.pos, (dropParams | (((this->actor.params >> 9) & 0x3F) << 8))); } @@ -226,7 +227,9 @@ void ObjTsubo_SetupWaitForObject(ObjTsubo* this) { void ObjTsubo_WaitForObject(ObjTsubo* this, PlayState* play) { if (Object_IsLoaded(&play->objectCtx, this->objTsuboBankIndex)) { - this->actor.draw = ObjTsubo_Draw; + if (GameInteractor_Should(VB_POT_SETUP_DRAW, true, this)) { + this->actor.draw = ObjTsubo_Draw; + } this->actor.objBankIndex = this->objTsuboBankIndex; ObjTsubo_SetupIdle(this); this->actor.flags &= ~ACTOR_FLAG_UPDATE_WHILE_CULLED; @@ -287,7 +290,7 @@ void ObjTsubo_LiftedUp(ObjTsubo* this, PlayState* play) { this->actor.room = play->roomCtx.curRoom.num; ObjTsubo_SetupThrown(this); ObjTsubo_ApplyGravity(this); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Actor_UpdateBgCheckInfo(play, &this->actor, 5.0f, 15.0f, 0.0f, 0x85); } } @@ -318,7 +321,7 @@ void ObjTsubo_Thrown(ObjTsubo* this, PlayState* play) { Actor_Kill(&this->actor); } else { ObjTsubo_ApplyGravity(this); - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Math_StepToS(&D_80BA1B54, D_80BA1B50, 0x64); Math_StepToS(&D_80BA1B5C, D_80BA1B58, 0x64); this->actor.shape.rot.x += D_80BA1B54; diff --git a/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h b/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h index a83d43a47..74dbf6ebb 100644 --- a/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h +++ b/soh/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h @@ -13,6 +13,7 @@ typedef struct ObjTsubo { /* 0x014C */ ObjTsuboActionFunc actionFunc; /* 0x0150 */ ColliderCylinder collider; /* 0x019C */ s8 objTsuboBankIndex; + /* */ PotIdentity potIdentity; } ObjTsubo; // size = 0x01A0 #endif diff --git a/soh/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c b/soh/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c index b67660963..f4c77c73f 100644 --- a/soh/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c +++ b/soh/src/overlays/actors/ovl_Obj_Warp2block/z_obj_warp2block.c @@ -82,7 +82,7 @@ s32 func_80BA1ECC(ObjWarp2block* this, PlayState* play) { Vec3f sp20; f32 temp_f2; - if (func_80043590(&this->dyna)) { + if (DynaPolyActor_IsPlayerAbove(&this->dyna)) { return 0; } @@ -91,14 +91,14 @@ s32 func_80BA1ECC(ObjWarp2block* this, PlayState* play) { if ((this->dyna.actor.xzDistToPlayer <= sDistances[(((this->dyna.actor.params >> 0xB) & 7))]) || (temp_a3->xzDistToPlayer <= sDistances[(((temp_a3->params >> 0xB) & 7))])) { - func_8002DBD0(&this->dyna.actor, &sp20, &player->actor.world.pos); + Actor_WorldToActorCoords(&this->dyna.actor, &sp20, &player->actor.world.pos); temp_f2 = (this->dyna.actor.scale.x * 50.0f) + 6.0f; if (!(temp_f2 < fabsf(sp20.x)) && !(temp_f2 < fabsf(sp20.z))) { return 0; } - func_8002DBD0(temp_a3, &sp20, &player->actor.world.pos); + Actor_WorldToActorCoords(temp_a3, &sp20, &player->actor.world.pos); temp_f2 = (temp_a3->scale.x * 50.0f) + 6.0f; if (!(temp_f2 < fabsf(sp20.x)) && !(temp_f2 < fabsf(sp20.z))) { @@ -290,7 +290,7 @@ void func_80BA2610(ObjWarp2block* this, PlayState* play) { } } if (this->unk_16C == 0x32) { - func_80078884(NA_SE_SY_TRE_BOX_APPEAR); + Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR); } } diff --git a/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c index 2600acd6b..a318cf759 100644 --- a/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c +++ b/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c @@ -208,19 +208,19 @@ void ObjectKankyo_Fairies(ObjectKankyo* this, PlayState* play) { func_800F436C(&sSoundPos, NA_SE_EV_NAVY_FLY - SFX_FLAG, (0.4f * dist) + 0.6f); switch (play->csCtx.frames) { case 473: - func_800788CC(NA_SE_VO_NA_HELLO_3); + Sfx_PlaySfxCentered2(NA_SE_VO_NA_HELLO_3); break; case 583: - func_800F4524(&D_801333D4, NA_SE_VO_NA_HELLO_2, 32); + func_800F4524(&gSfxDefaultPos, NA_SE_VO_NA_HELLO_2, 32); break; case 763: - func_80078884(NA_SE_EV_NAVY_CRASH - SFX_FLAG); + Sfx_PlaySfxCentered(NA_SE_EV_NAVY_CRASH - SFX_FLAG); break; case 771: - func_80078884(NA_SE_VO_RT_THROW); + Sfx_PlaySfxCentered(NA_SE_VO_RT_THROW); break; } } diff --git a/soh/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c b/soh/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c index 3869fa6e4..228e13d21 100644 --- a/soh/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c +++ b/soh/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c @@ -5,6 +5,8 @@ */ #include "z_oceff_storm.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) diff --git a/soh/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c b/soh/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c index dfc236251..052de7f0d 100644 --- a/soh/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c +++ b/soh/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c @@ -6,6 +6,7 @@ #include "z_oceff_wipe.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) diff --git a/soh/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c b/soh/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c index a6b422062..a9eabca24 100644 --- a/soh/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c +++ b/soh/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c @@ -6,6 +6,7 @@ #include "z_oceff_wipe2.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) diff --git a/soh/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c b/soh/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c index 28f02100d..e0ceadeb4 100644 --- a/soh/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c +++ b/soh/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c @@ -6,6 +6,7 @@ #include "z_oceff_wipe3.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) diff --git a/soh/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c b/soh/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c index 6c96e639f..6067ed361 100644 --- a/soh/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c +++ b/soh/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c @@ -6,6 +6,7 @@ #include "z_oceff_wipe4.h" #include "vt.h" +#include "soh/ResourceManagerHelpers.h" #define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA) @@ -107,7 +108,8 @@ void OceffWipe4_Draw(Actor* thisx, PlayState* play) { gSPDisplayList(POLY_XLU_DISP++, sMaterial2DL); gSPDisplayList(POLY_XLU_DISP++, Gfx_TwoTexScroll(play->state.gfxCtx, 0, scroll * 2, scroll * (-2), 32, 64, 1, scroll * (-1), scroll, 32, 32)); - gSPDisplayListOffset(POLY_XLU_DISP++, sMaterial2DL, 11); + // SOH [Port] Index adjust 11 -> 14 (for LUS marker and load texture) to account for our extraction size changes + gSPDisplayListOffset(POLY_XLU_DISP++, sMaterial2DL, 11 + 2 + 1); CLOSE_DISPS(play->state.gfxCtx); } diff --git a/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c b/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c index a0552a027..787975b1d 100644 --- a/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c +++ b/soh/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c @@ -7,6 +7,7 @@ #include "z_shot_sun.h" #include "overlays/actors/ovl_En_Elf/z_en_elf.h" #include "scenes/overworld/spot06/spot06_scene.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "vt.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY) @@ -115,7 +116,7 @@ void ShotSun_TriggerFairy(ShotSun* this, PlayState* play) { Actor_Spawn(&play->actorCtx, play, ACTOR_DEMO_KANKYO, this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, 0, 0, 0, 0x11, true); - func_80078914(&this->actor.projectedPos, NA_SE_EV_TRE_BOX_APPEAR); + Sfx_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_TRE_BOX_APPEAR); } } @@ -160,13 +161,14 @@ void ShotSun_UpdateHyliaSun(ShotSun* this, PlayState* play) { Vec3f spawnPos; if (this->collider.base.acFlags & AC_HIT) { - func_80078884(NA_SE_SY_CORRECT_CHIME); + Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME); osSyncPrintf(VT_FGCOL(CYAN) "SHOT_SUN HIT!!!!!!!\n" VT_RST); - if ((INV_CONTENT(ITEM_ARROW_FIRE) == ITEM_NONE && !IS_RANDO) || - (!Flags_GetTreasure(play, 0x1F) && IS_RANDO)) { + if (GameInteractor_Should(VB_SPAWN_FIRE_ARROW, INV_CONTENT(ITEM_ARROW_FIRE) == ITEM_NONE)) { Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_ETCETERA, 700.0f, -800.0f, 7261.0f, 0, 0, 0, 7, true); - play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gLakeHyliaFireArrowsCS); - gSaveContext.cutsceneTrigger = 1; + if (GameInteractor_Should(VB_PLAY_FIRE_ARROW_CS, true)) { + play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gLakeHyliaFireArrowsCS); + gSaveContext.cutsceneTrigger = 1; + } } else { spawnPos.x = 700.0f; spawnPos.y = -800.0f; diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index f972699e0..8d229178b 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -30,7 +30,8 @@ #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "soh/frame_interpolation.h" -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" #include #include @@ -2678,7 +2679,7 @@ s32 func_8083442C(Player* this, PlayState* play) { if ((this->heldItemAction >= PLAYER_IA_BOW_FIRE) && (this->heldItemAction <= PLAYER_IA_BOW_0E) && (gSaveContext.magicState != MAGIC_STATE_IDLE)) { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } else { Player_SetUpperActionFunc(this, func_808351D4); @@ -3235,7 +3236,11 @@ s32 func_808358F0(Player* this, PlayState* play) { AnimationContext_SetCopyAll(play, this->skelAnime.limbCount, this->upperSkelAnime.jointTable, this->skelAnime.jointTable); } else { - LinkAnimation_Update(play, &this->upperSkelAnime); + // #region SOH [Enhancement] + if (!CVarGetInteger(CVAR_ENHANCEMENT("BoomerangReticle"), 0)) { + // #endregion + LinkAnimation_Update(play, &this->upperSkelAnime); + } } func_80834EB8(this, play); @@ -3441,7 +3446,7 @@ void Player_UseItem(PlayState* play, Player* this, s32 item) { (play->actorCtx.actorLists[ACTORCAT_EXPLOSIVE].length >= 3 && !CVarGetInteger(CVAR_ENHANCEMENT("RemoveExplosiveLimit"), 0))))))) { // Prevent some items from being used if player is out of ammo. // Also prevent explosives from being used if there are 3 or more active (outside of bombchu bowling) - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } else if (itemAction == PLAYER_IA_LENS_OF_TRUTH) { // Handle Lens of Truth if (Magic_RequestChange(play, 0, MAGIC_CONSUME_LENS)) { @@ -3450,16 +3455,16 @@ void Player_UseItem(PlayState* play, Player* this, s32 item) { } else { play->actorCtx.lensActive = true; } - func_80078884((play->actorCtx.lensActive) ? NA_SE_SY_GLASSMODE_ON : NA_SE_SY_GLASSMODE_OFF); + Sfx_PlaySfxCentered((play->actorCtx.lensActive) ? NA_SE_SY_GLASSMODE_ON : NA_SE_SY_GLASSMODE_OFF); } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } else if (itemAction == PLAYER_IA_DEKU_NUT) { // Handle Deku Nuts if (AMMO(ITEM_NUT) != 0) { func_8083C61C(play, this); } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } else if ((temp = Player_ActionToMagicSpell(this, itemAction)) >= 0) { // Handle magic spells @@ -3469,7 +3474,7 @@ void Player_UseItem(PlayState* play, Player* this, s32 item) { this->itemAction = itemAction; this->unk_6AD = 4; } else { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } } else if (itemAction >= PLAYER_IA_MASK_KEATON) { // Handle wearable masks @@ -4757,7 +4762,7 @@ s32 func_808382DC(Player* this, PlayState* play) { Player_PlayVoiceSfx(this, NA_SE_VO_LI_TAKEN_AWAY); play->unk_11DE9 = 1; - func_80078884(NA_SE_OC_ABYSS); + Sfx_PlaySfxCentered(NA_SE_OC_ABYSS); } else if ((this->knockbackType != PLAYER_KNOCKBACK_NONE) && ((this->knockbackType >= PLAYER_KNOCKBACK_LARGE) || (this->invincibilityTimer == 0))) { u8 knockbackResponse[] = { @@ -5031,7 +5036,7 @@ s32 func_80838FB8(PlayState* play, Player* this) { func_80838F5C(play, this); Player_AnimPlayLoop(play, this, &gPlayerAnim_link_normal_landing_wait); Player_PlayVoiceSfx(this, NA_SE_VO_LI_FALL_S); - func_800788CC(NA_SE_OC_SECRET_WARP_IN); + Sfx_PlaySfxCentered2(NA_SE_OC_SECRET_WARP_IN); return 1; } @@ -5053,30 +5058,30 @@ s32 func_80838FB8(PlayState* play, Player* this) { */ static s16 sReturnEntranceGroupData[] = { // ENTR_RETURN_GREAT_FAIRYS_FOUNTAIN_MAGIC - /* 0 */ ENTR_DEATH_MOUNTAIN_TRAIL_4, // from Magic Fairy Fountain - /* 1 */ ENTR_DEATH_MOUNTAIN_CRATER_3, // from Double Magic Fairy Fountain - /* 2 */ ENTR_HYRULE_CASTLE_2, // from Double Defense Fairy Fountain (as adult) + /* 0 */ ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT, // from Magic Fairy Fountain + /* 1 */ ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT, // from Double Magic Fairy Fountain + /* 2 */ ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, // from Double Defense Fairy Fountain (as adult) // ENTR_RETURN_2 - /* 3 */ ENTR_KAKARIKO_VILLAGE_9, // from Potion Shop in Kakariko - /* 4 */ ENTR_MARKET_DAY_5, // from Potion Shop in Market + /* 3 */ ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_FRONT, // from Potion Shop in Kakariko + /* 4 */ ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP, // from Potion Shop in Market // ENTR_RETURN_BAZAAR - /* 5 */ ENTR_KAKARIKO_VILLAGE_3, - /* 6 */ ENTR_MARKET_DAY_6, + /* 5 */ ENTR_KAKARIKO_VILLAGE_OUTSIDE_BAZAAR, + /* 6 */ ENTR_MARKET_DAY_OUTSIDE_BAZAAR, // ENTR_RETURN_4 - /* 7 */ ENTR_KAKARIKO_VILLAGE_11, // from House of Skulltulas - /* 8 */ ENTR_BACK_ALLEY_DAY_2, // from Bombchu Shop + /* 7 */ ENTR_KAKARIKO_VILLAGE_OUTSIDE_SKULKLTULA_HOUSE, // from House of Skulltulas + /* 8 */ ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP, // from Bombchu Shop // ENTR_RETURN_SHOOTING_GALLERY - /* 9 */ ENTR_KAKARIKO_VILLAGE_10, - /* 10 */ ENTR_MARKET_DAY_8, + /* 9 */ ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY, + /* 10 */ ENTR_MARKET_DAY_OUTSIDE_SHOOTING_GALLERY, // ENTR_RETURN_GREAT_FAIRYS_FOUNTAIN_SPELLS - /* 11 */ ENTR_ZORAS_FOUNTAIN_5, // from Farores Wind Fairy Fountain - /* 12 */ ENTR_HYRULE_CASTLE_2, // from Dins Fire Fairy Fountain (as child) - /* 13 */ ENTR_DESERT_COLOSSUS_7, // from Nayrus Love Fairy Fountain + /* 11 */ ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY, // from Farores Wind Fairy Fountain + /* 12 */ ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, // from Dins Fire Fairy Fountain (as child) + /* 13 */ ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT, // from Nayrus Love Fairy Fountain }; /** @@ -5140,9 +5145,9 @@ s32 Player_HandleExitsAndVoids(PlayState* play, Player* this, CollisionPoly* pol Scene_SetTransitionForNextEntrance(play); } else { - // In Entrance rando, if our respawnFlag is set for a grotto return, we don't want the void out to happen - if (SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2 && - (!IS_RANDO || (Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES) && gSaveContext.respawnFlag != 2))) { + if (GameInteractor_Should(VB_SET_VOIDOUT_FROM_SURFACE, + SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2, + play->setupExitList[exitIndex - 1])) { gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = play->nextEntranceIndex; Play_TriggerVoidOut(play); gSaveContext.respawnFlag = -2; @@ -5159,7 +5164,7 @@ s32 Player_HandleExitsAndVoids(PlayState* play, Player* this, CollisionPoly* pol ((sp34 < 100) || (this->actor.bgCheckFlags & 1))) { if (temp == 11) { - func_800788CC(NA_SE_OC_SECRET_HOLE_OUT); + Sfx_PlaySfxCentered2(NA_SE_OC_SECRET_HOLE_OUT); func_800F6964(5); gSaveContext.seqId = (u8)NA_BGM_DISABLED; gSaveContext.natureAmbienceId = NATURE_ID_DISABLED; @@ -5211,7 +5216,7 @@ s32 Player_HandleExitsAndVoids(PlayState* play, Player* this, CollisionPoly* pol Play_TriggerVoidOut(play); } play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; - func_80078884(NA_SE_OC_ABYSS); + Sfx_PlaySfxCentered(NA_SE_OC_ABYSS); } else { func_80838F5C(play, this); this->av2.actionVar2 = 9999; @@ -5822,7 +5827,13 @@ s32 func_8083AD4C(PlayState* play, Player* this) { camMode = shouldUseBowCamera ? CAM_MODE_BOWARROW : CAM_MODE_SLINGSHOT; } else { - camMode = CAM_MODE_BOOMERANG; + // #region SOH [Enhancement] + if (CVarGetInteger(CVAR_ENHANCEMENT("BoomerangFirstPerson"), 0)) { + camMode = CAM_MODE_FIRSTPERSON; + // #endregion + } else { + camMode = CAM_MODE_BOOMERANG; + } } } else { camMode = CAM_MODE_FIRSTPERSON; @@ -6076,12 +6087,12 @@ s32 Player_ActionHandler_13(Player* this, PlayState* play) { func_8083B010(this); } this->stateFlags1 |= PLAYER_STATE1_FIRST_PERSON; - func_80078884(NA_SE_SY_CAMERA_ZOOM_UP); + Sfx_PlaySfxCentered(NA_SE_SY_CAMERA_ZOOM_UP); Player_ZeroSpeedXZ(this); return 1; } else { this->unk_6AD = 0; - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); return 0; } @@ -6208,7 +6219,7 @@ s32 Player_ActionHandler_0(Player* this, PlayState* play) { } else if ((this->naviTextId == 0 || CVarGetInteger(CVAR_ENHANCEMENT("NaviOnL"), 0)) && !Player_CheckHostileLockOn(this) && CHECK_BTN_ALL(sControlInput->press.button, BTN_CUP) && (YREG(15) != 0x10) && (YREG(15) != 0x20) && !func_8083B8F4(this, play)) { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); } return 0; @@ -6545,7 +6556,7 @@ s32 func_8083C6B8(PlayState* play, Player* this) { ? 0 : !(this->actor.bgCheckFlags & 1) || (this->actor.world.pos.z > 1300.0f) || BgCheck_SphVsFirstPoly(&play->colCtx, &rodCheckPos, 20.0f)) { - func_80078884(NA_SE_SY_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_ERROR); return 0; } @@ -7237,7 +7248,7 @@ void func_8083E4C4(PlayState* play, Player* this, GetItemEntry* giEntry) { } else { Item_Give(play, giEntry->itemId); } - func_80078884((this->getItemId < 0 || this->getItemEntry.getItemId < 0) ? NA_SE_SY_GET_BOXITEM : NA_SE_SY_GET_ITEM); + Sfx_PlaySfxCentered((this->getItemId < 0 || this->getItemEntry.getItemId < 0) ? NA_SE_SY_GET_BOXITEM : NA_SE_SY_GET_ITEM); } s32 Player_ActionHandler_2(Player* this, PlayState* play) { @@ -9258,7 +9269,7 @@ void Player_Action_80843188(Player* this, PlayState* play) { f32 sp40; sp54 = sControlInput->rel.stick_y * 100 * (CVarGetInteger(CVAR_SETTING("Controls.InvertShieldAimingYAxis"), 1) ? 1 : -1); - sp50 = sControlInput->rel.stick_x * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? 120 : -120) * (CVarGetInteger(CVAR_SETTING("Controls.InvertShieldAimingYAxis"), 0) ? -1 : 1); + sp50 = sControlInput->rel.stick_x * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? 120 : -120) * (CVarGetInteger(CVAR_SETTING("Controls.InvertShieldAimingXAxis"), 0) ? -1 : 1); sp4E = this->actor.shape.rot.y - Camera_GetInputDirYaw(GET_ACTIVE_CAM(play)); sp40 = Math_CosS(sp4E); @@ -10422,7 +10433,7 @@ void Player_Action_80846120(Player* this, PlayState* play) { this->heldActor = &heavyBlock->dyna.actor; this->actor.child = &heavyBlock->dyna.actor; heavyBlock->dyna.actor.parent = &this->actor; - func_8002DBD0(&heavyBlock->dyna.actor, &heavyBlock->unk_164, &this->leftHandPos); + Actor_WorldToActorCoords(&heavyBlock->dyna.actor, &heavyBlock->unk_164, &this->leftHandPos); return; } @@ -10772,11 +10783,6 @@ void Player_Init(Actor* thisx, PlayState* play2) { s32 respawnFlag; s32 respawnMode; - // In ER, once Link has spawned we know the scene has loaded, so we can sanitize the last known entrance type - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { - Grotto_SanitizeEntranceType(); - } - play->shootingGalleryStatus = play->bombchuBowlingStatus = 0; play->playerInit = Player_InitCommon; @@ -10816,7 +10822,7 @@ void Player_Init(Actor* thisx, PlayState* play2) { if (respawnFlag == -3) { thisx->params = gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams; } else { - if ((respawnFlag == 1) || (respawnFlag == -1)) { + if (GameInteractor_Should(VB_INFLICT_VOID_DAMAGE, (respawnFlag == 1) || (respawnFlag == -1), respawnFlag)) { this->unk_A86 = -2; } @@ -11230,7 +11236,7 @@ void Player_ProcessSceneCollision(PlayState* play, Player* this) { func_80074CE8(play, SurfaceType_GetLightSettingIndex(&play->colCtx, floorPoly, this->actor.floorBgId)); } else { - func_80043508(&play->colCtx, this->actor.floorBgId); + DynaPoly_SetPlayerAbove(&play->colCtx, this->actor.floorBgId); } } @@ -11432,7 +11438,7 @@ void Player_ProcessSceneCollision(PlayState* play, Player* this) { s32 pad3; if (this->actor.floorBgId != BGCHECK_SCENE) { - func_800434C8(&play->colCtx, this->actor.floorBgId); + DynaPoly_SetPlayerOnTop(&play->colCtx, this->actor.floorBgId); } floorPolyNormalX = COLPOLY_GET_NORMAL(floorPoly->normal.x); @@ -11501,7 +11507,19 @@ void Player_UpdateCamAndSeqModes(PlayState* play, Player* this) { } else if (this->stateFlags1 & PLAYER_STATE1_CHARGING_SPIN_ATTACK) { camMode = CAM_MODE_CHARGE; } else if (this->stateFlags1 & PLAYER_STATE1_BOOMERANG_THROWN) { - camMode = CAM_MODE_FOLLOWBOOMERANG; + // #region SOH [Enhancement] + if (CVarGetInteger(CVAR_ENHANCEMENT("BoomerangFirstPerson"), 0)) { + // Avoid camera jumps by switching to normal cam to exit the first person camera, + // before following the boomerang + if (Play_GetCamera(play, 0)->mode == CAM_MODE_FIRSTPERSON) { + camMode = CAM_MODE_NORMAL; + } else { + camMode = CAM_MODE_FOLLOWBOOMERANG; + } + // #endregion + } else { + camMode = CAM_MODE_FOLLOWBOOMERANG; + } Camera_SetParam(Play_GetCamera(play, 0), 8, this->boomerangActor); } else if (this->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE)) { if (Player_FriendlyLockOnOrParallel(this)) { @@ -11781,7 +11799,7 @@ void Player_DetectRumbleSecrets(Player* this) { this->unk_6A0 = 0.0f; if (CVarGetInteger(CVAR_ENHANCEMENT("VisualAgony"), 0) && !this->stateFlags1 && !GameInteractor_NoUIActive()) { // This audio is placed here and not in previous CVar check to prevent ears ra.. :) - Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E0); + Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale); } Player_RequestRumble(this, 120, 20, 10, 0); } @@ -11922,7 +11940,7 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { this->unk_A86++; if (this->unk_A86 == 0) { this->unk_A86 = 1; - func_80078884(NA_SE_OC_REVENGE); + Sfx_PlaySfxCentered(NA_SE_OC_REVENGE); } } @@ -11977,7 +11995,7 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { if (this->stateFlags2 & PLAYER_STATE2_PAUSE_MOST_UPDATING) { if (!(this->actor.bgCheckFlags & 1)) { Player_ZeroSpeedXZ(this); - Actor_MoveForward(&this->actor); + Actor_MoveXZGravity(&this->actor); } Player_ProcessSceneCollision(play, this); @@ -12070,7 +12088,7 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { this->actor.world.rot.y = this->yaw; } - func_8002D868(&this->actor); + Actor_UpdateVelocityXZGravity(&this->actor); if ((this->pushedSpeed != 0.0f) && !Player_InCsMode(play) && !(this->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_CLIMBING_LADDER)) && @@ -12079,7 +12097,7 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) { this->actor.velocity.z += this->pushedSpeed * Math_CosS(this->pushedYaw); } - func_8002D7EC(&this->actor); + Actor_UpdatePos(&this->actor); Player_ProcessSceneCollision(play, this); } else { sFloorType = 0; @@ -12973,7 +12991,7 @@ void Player_Action_8084B1D8(Player* this, PlayState* play) { Player_FriendlyLockOnOrParallel(this) || (!func_8002DD78(this) && !func_808334B4(this)))) || ((this->unk_6AD == 1) && CHECK_BTN_ANY(sControlInput->press.button, buttonsToCheck)))) { func_8083C148(this, play); - func_80078884(NA_SE_SY_CAMERA_ZOOM_UP); + Sfx_PlaySfxCentered(NA_SE_SY_CAMERA_ZOOM_UP); } else if ((DECR(this->av2.actionVar2) == 0) || (this->unk_6AD != 2)) { if (func_8008F128(this)) { this->unk_6AE_rotFlags |= UNK6AE_ROT_FOCUS_X | UNK6AE_ROT_FOCUS_Y | UNK6AE_ROT_UPPER_X; @@ -14193,7 +14211,7 @@ s32 func_8084DFF4(PlayState* play, Player* this) { } else if (((giEntry.itemId >= ITEM_RUPEE_GREEN) && (giEntry.itemId <= ITEM_RUPEE_RED)) || ((giEntry.itemId >= ITEM_RUPEE_PURPLE) && (giEntry.itemId <= ITEM_RUPEE_GOLD)) || (giEntry.itemId == ITEM_HEART)) { - Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { if ((giEntry.itemId == ITEM_HEART_CONTAINER) || ((giEntry.itemId == ITEM_HEART_PIECE_2) && @@ -14246,7 +14264,7 @@ s32 func_8084DFF4(PlayState* play, Player* this) { } else { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) { if (GameInteractor_Should(VB_PLAY_NABOORU_CAPTURED_CS, this->getItemId == GI_GAUNTLETS_SILVER)) { - play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0; + play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_EAST_EXIT; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.nextCutsceneIndex = 0xFFF1; play->transitionType = TRANS_TYPE_SANDSTORM_END; @@ -14321,12 +14339,12 @@ void Player_Action_8084E368(Player* this, PlayState* play) { } static s16 sWarpSongEntrances[] = { - ENTR_SACRED_FOREST_MEADOW_2, - ENTR_DEATH_MOUNTAIN_CRATER_4, - ENTR_LAKE_HYLIA_8, - ENTR_DESERT_COLOSSUS_5, - ENTR_GRAVEYARD_7, - ENTR_TEMPLE_OF_TIME_7, + ENTR_SACRED_FOREST_MEADOW_WARP_PAD, + ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, + ENTR_LAKE_HYLIA_WARP_PAD, + ENTR_DESERT_COLOSSUS_WARP_PAD, + ENTR_GRAVEYARD_WARP_PAD, + ENTR_TEMPLE_OF_TIME_WARP_PAD, }; void Player_Action_8084E3C4(Player* this, PlayState* play) { @@ -15001,7 +15019,7 @@ void Player_Action_8084F88C(Player* this, PlayState* play) { if (this->av1.actionVar1 != 0) { if (play->sceneNum == SCENE_ICE_CAVERN) { Play_TriggerRespawn(play); - play->nextEntranceIndex = ENTR_ICE_CAVERN_0; + play->nextEntranceIndex = ENTR_ICE_CAVERN_ENTRANCE; } else if (this->av1.actionVar1 < 0) { Play_TriggerRespawn(play); // In ER, handle DMT and other special void outs to respawn from last entrance from grotto @@ -15013,7 +15031,7 @@ void Player_Action_8084F88C(Player* this, PlayState* play) { } play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; - func_80078884(NA_SE_OC_ABYSS); + Sfx_PlaySfxCentered(NA_SE_OC_ABYSS); } else { play->transitionType = TRANS_TYPE_FADE_BLACK; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; @@ -15374,7 +15392,7 @@ void Player_Action_8085063C(Player* this, PlayState* play) { if (play->msgCtx.choiceIndex == 1) { //Unsets FW gSaveContext.respawn[RESPAWN_MODE_TOP].data = -respawnData; gSaveContext.fw.set = 0; - func_80078914(&gSaveContext.respawn[RESPAWN_MODE_TOP].pos, NA_SE_PL_MAGIC_WIND_VANISH); + Sfx_PlaySfxAtPos(&gSaveContext.respawn[RESPAWN_MODE_TOP].pos, NA_SE_PL_MAGIC_WIND_VANISH); } func_80853080(this, play); @@ -15394,7 +15412,7 @@ void Player_Action_8085076C(Player* this, PlayState* play) { if (this->av2.actionVar2++ == 20) { gSaveContext.respawn[RESPAWN_MODE_TOP].data = respawnData + 1; - func_80078914(&gSaveContext.respawn[RESPAWN_MODE_TOP].pos, NA_SE_PL_MAGIC_WIND_WARP); + Sfx_PlaySfxAtPos(&gSaveContext.respawn[RESPAWN_MODE_TOP].pos, NA_SE_PL_MAGIC_WIND_WARP); } } diff --git a/soh/src/overlays/effects/ovl_Effect_Ss_Dead_Db/z_eff_ss_dead_db.c b/soh/src/overlays/effects/ovl_Effect_Ss_Dead_Db/z_eff_ss_dead_db.c index c39779f86..78502b25c 100644 --- a/soh/src/overlays/effects/ovl_Effect_Ss_Dead_Db/z_eff_ss_dead_db.c +++ b/soh/src/overlays/effects/ovl_Effect_Ss_Dead_Db/z_eff_ss_dead_db.c @@ -132,6 +132,6 @@ void EffectSsDeadDb_Update(PlayState* play, u32 index, EffectSs* this) { if (this->rPlaySound && (this->rTextIdx == 1)) { SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &this->pos, &this->vec, &w); - Audio_PlaySoundGeneral(NA_SE_EN_EXTINCT, &this->vec, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EN_EXTINCT, &this->vec, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.c b/soh/src/overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.c index b58f22fdf..96b346693 100644 --- a/soh/src/overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.c +++ b/soh/src/overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.c @@ -45,5 +45,5 @@ void EffectSsDeadSound_Update(PlayState* play, u32 index, EffectSs* this) { return; } - Audio_PlaySoundGeneral(this->rSfxId, &this->pos, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(this->rSfxId, &this->pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } diff --git a/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h b/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h index 59d251584..3e3106ef4 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h +++ b/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h @@ -65,7 +65,11 @@ typedef enum { CM_BOSS_RUSH_MENU, CM_START_BOSS_RUSH_MENU, CM_BOSS_RUSH_TO_QUEST, - CM_GENERATE_SEED, + CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU, + CM_RANDOMIZER_SETTINGS_MENU, + CM_START_RANDOMIZER_SETTINGS_MENU, + CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST, + CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU, } ConfigMode; typedef enum { diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 50f846ddc..9b964054e 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -11,17 +11,21 @@ #include #include "textures/message_static/message_static.h" #include "soh/frame_interpolation.h" -#include +#include #include "objects/object_mag/object_mag.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "soh_assets.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/boss-rush/BossRush.h" +#include "soh/Enhancements/FileSelectEnhancements.h" #include "soh/Enhancements/custom-message/CustomMessageTypes.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include #include "z64save.h" +#include "soh/SaveManager.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" typedef struct { s16 left; @@ -981,17 +985,13 @@ void DrawSeedHashSprites(FileChooseContext* this) { // 1. On Name Entry if a rando seed has been generated // 2. On Quest Menu if a spoiler has been dropped and the Randomizer quest option is currently hovered. if ((Randomizer_IsSeedGenerated() || Randomizer_IsSpoilerLoaded()) && - ((this->configMode == CM_NAME_ENTRY && gSaveContext.questId == QUEST_RANDOMIZER) || - (this->configMode == CM_GENERATE_SEED && Randomizer_IsSpoilerLoaded()) || - (this->configMode == CM_QUEST_MENU && this->questType[this->buttonIndex] == QUEST_RANDOMIZER))) { - // Fade top seed icons based on main menu fade and if save supports rando - u8 alpha = - MAX(this->optionButtonAlpha, Save_GetSaveMetaInfo(this->selectedFileIndex)->randoSave == 1 ? 0xFF : 0); - if (alpha >= 200) { - alpha = 0xFF; - } + (((this->configMode == CM_NAME_ENTRY || this->configMode == CM_ROTATE_TO_NAME_ENTRY || + this->configMode == CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU || this->configMode == CM_START_NAME_ENTRY || + this->configMode == CM_START_RANDOMIZER_SETTINGS_MENU) || + this->configMode == CM_RANDOMIZER_SETTINGS_MENU) && + gSaveContext.questId == QUEST_RANDOMIZER)) { - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0xFF, 0xFF, 0xFF, alpha); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF); u16 xStart = 64; for (unsigned int i = 0; i < 5; i++) { SpriteLoad(this, GetSeedTexture(GetSeedIconIndex(i))); @@ -1005,6 +1005,7 @@ void DrawSeedHashSprites(FileChooseContext* this) { } u8 generating; +int retries = 0; bool fileSelectSpoilerFileLoaded = false; void FileChoose_UpdateRandomizer() { @@ -1015,8 +1016,9 @@ void FileChoose_UpdateRandomizer() { } else if (CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0) == 0 && generating) { if (Randomizer_IsSeedGenerated()) { Audio_PlayFanfare(NA_BGM_HORSE_GOAL); + retries = 0; } else { - func_80078884(NA_SE_SY_OCARINA_ERROR); + Sfx_PlaySfxCentered(NA_SE_SY_OCARINA_ERROR); } func_800F5E18(SEQ_PLAYER_BGM_MAIN, NA_BGM_FILE_SELECT, 0, 7, 1); generating = 0; @@ -1068,25 +1070,25 @@ void FileChoose_UpdateMainMenu(GameState* thisx) { if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) { if (this->buttonIndex <= FS_BTN_MAIN_FILE_3) { if (!Save_GetSaveMetaInfo(this->buttonIndex)->valid) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->prevConfigMode = this->configMode; this->configMode = CM_ROTATE_TO_QUEST_MENU; this->logoAlpha = 0; } else if(!FileChoose_IsSaveCompatible(Save_GetSaveMetaInfo(this->buttonIndex))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (this->n64ddFlags[this->buttonIndex] == this->n64ddFlag) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->actionTimer = 8; this->selectMode = SM_FADE_MAIN_TO_SELECT; this->selectedFileIndex = this->buttonIndex; this->menuMode = FS_MENU_MODE_SELECT; this->nextTitleLabel = FS_TITLE_OPEN_FILE; } else if (!this->n64ddFlags[this->buttonIndex]) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else { if (this->warningLabel == FS_WARNING_NONE) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->prevConfigMode = this->configMode; if (this->buttonIndex == FS_BTN_MAIN_COPY) { @@ -1109,12 +1111,12 @@ void FileChoose_UpdateMainMenu(GameState* thisx) { this->actionTimer = 8; } else { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } } else { if ((ABS(this->stickRelY) > 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if ((this->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { this->buttonIndex--; @@ -1238,12 +1240,25 @@ void FileChoose_StartBossRushMenu(GameState* thisx) { this->bossRushUIAlpha = 0; this->bossRushArrowOffset = 0; - if (this->logoAlpha >= 0) { + if (this->logoAlpha <= 0) { this->logoAlpha = 0; this->configMode = CM_BOSS_RUSH_MENU; } } +void FileChoose_StartRandomizerMenu(GameState* thisx) { + FileChooseContext* this = (FileChooseContext*)thisx; + + this->logoAlpha -= 25; + this->randomizerUIAlpha = 0; + this->randomizerArrowOffset = 0; + + if (this->logoAlpha <= 0) { + this->logoAlpha = 0; + this->configMode = CM_RANDOMIZER_SETTINGS_MENU; + } +} + void FileChoose_UpdateQuestMenu(GameState* thisx) { static u8 emptyName[] = { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E }; static u8 linkName[] = { 0x15, 0x2C, 0x31, 0x2E, 0x3E, 0x3E, 0x3E, 0x3E }; @@ -1277,38 +1292,29 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) { this->questType[this->buttonIndex] = MAX_QUEST; } - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); GameInteractor_ExecuteOnUpdateFileQuestSelection(this->questType[this->buttonIndex]); } - if (CHECK_BTN_ALL(input->press.button, BTN_L)) { - if (this->questType[this->buttonIndex] == QUEST_RANDOMIZER) { - Randomizer_SetSpoilerLoaded(false); - this->prevConfigMode = this->configMode; - this->configMode = CM_GENERATE_SEED; - } - } - if (CHECK_BTN_ALL(input->press.button, BTN_A)) { gSaveContext.questId = this->questType[this->buttonIndex]; if (this->questType[this->buttonIndex] == QUEST_BOSSRUSH) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->prevConfigMode = this->configMode; this->configMode = CM_ROTATE_TO_BOSS_RUSH_MENU; return; } else if (this->questType[this->buttonIndex] == QUEST_RANDOMIZER) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->prevConfigMode = this->configMode; - this->configMode = CM_GENERATE_SEED; + this->configMode = CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU; } else { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); osSyncPrintf("Selected Dungeon Quest: %d\n", IS_MASTER_QUEST); this->prevConfigMode = this->configMode; this->configMode = CM_ROTATE_TO_NAME_ENTRY; this->logoAlpha = 0; - CVarSetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 1); this->kbdButton = FS_KBD_BTN_NONE; this->charPage = FS_CHAR_PAGE_ENG; this->kbdX = 0; @@ -1330,38 +1336,6 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) { } } -void FileChoose_GenerateRandoSeed(GameState* thisx) { - FileChooseContext* this = (FileChooseContext*)thisx; - FileChoose_UpdateRandomizer(); - if (Randomizer_IsSeedGenerated() || Randomizer_IsPlandoLoaded()) { - Audio_PlayFanfare(NA_BGM_HORSE_GOAL); - func_800F5E18(SEQ_PLAYER_BGM_MAIN, NA_BGM_FILE_SELECT, 0, 7, 1); - generating = 0; - Randomizer_SetSpoilerLoaded(true); - static u8 emptyName[] = { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E }; - static u8 linkName[] = { 0x15, 0x2C, 0x31, 0x2E, 0x3E, 0x3E, 0x3E, 0x3E }; - this->prevConfigMode = this->configMode; - this->configMode = CM_ROTATE_TO_NAME_ENTRY; - this->logoAlpha = 0; - CVarSetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 1); - this->kbdButton = FS_KBD_BTN_NONE; - this->charPage = FS_CHAR_PAGE_ENG; - this->kbdX = 0; - this->kbdY = 0; - this->charIndex = 0; - this->charBgAlpha = 0; - this->newFileNameCharCount = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? 4 : 0; - this->nameEntryBoxPosX = 120; - this->nameEntryBoxAlpha = 0; - memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, - CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkName : &emptyName, 8); - return; - } - if (!generating) { - Randomizer_GenerateSeed(); - } -} - static s8 sLastBossRushOptionIndex = -1; static s8 sLastBossRushOptionValue = -1; @@ -1412,7 +1386,7 @@ void FileChoose_UpdateBossRushMenu(GameState* thisx) { } } - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } // Cycle through choices for currently selected option. @@ -1433,7 +1407,7 @@ void FileChoose_UpdateBossRushMenu(GameState* thisx) { } } - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } if (sLastBossRushOptionIndex != this->bossRushIndex || @@ -1450,7 +1424,7 @@ void FileChoose_UpdateBossRushMenu(GameState* thisx) { // Load into the game. if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->buttonIndex = 0xFE; this->menuMode = FS_MENU_MODE_SELECT; this->selectMode = SM_FADE_OUT; @@ -1459,6 +1433,84 @@ void FileChoose_UpdateBossRushMenu(GameState* thisx) { } } +void FileChoose_UpdateRandomizerMenu(GameState* thisx) { + FileChoose_UpdateStickDirectionPromptAnim(thisx); + FileChooseContext* this = (FileChooseContext*)thisx; + Input* input = &this->state.input[0]; + bool dpad = CVarGetInteger(CVAR_SETTING("DpadInText"), 0); + + FileChoose_UpdateRandomizer(); + + if (generating) { + return; + } + + // Fade in elements after opening Randomizer options menu + this->randomizerUIAlpha += 25; + if (this->randomizerUIAlpha > 255) { + this->randomizerUIAlpha = 255; + } + + // Move menu selection up or down. + if (ABS(this->stickRelY) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { + // Move down + if (this->stickRelY < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN))) { + // When selecting past the last option, cycle back to the first option. + if ((this->randomizerIndex + 1) > RSM_OPEN_RANDOMIZER_SETTINGS) { + this->randomizerIndex = RSM_START_RANDOMIZER; + } else { + this->randomizerIndex++; + } + } else if (this->stickRelY > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DUP))) { + // When selecting past the first option, cycle back to the last option and offset the list to view it properly. + if ((this->randomizerIndex - 1) < RSM_START_RANDOMIZER) { + this->randomizerIndex = RSM_OPEN_RANDOMIZER_SETTINGS; + } else { + this->randomizerIndex--; + } + } + + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + + if (CHECK_BTN_ALL(input->press.button, BTN_B)) { + this->configMode = CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST; + return; + } + + if (CHECK_BTN_ALL(input->press.button, BTN_A)) { + if (this->randomizerIndex == RSM_START_RANDOMIZER) { + if (Randomizer_IsSeedGenerated() || Randomizer_IsSpoilerLoaded()) { + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + static u8 emptyName[] = { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E }; + static u8 linkName[] = { 0x15, 0x2C, 0x31, 0x2E, 0x3E, 0x3E, 0x3E, 0x3E }; + this->prevConfigMode = this->configMode; + this->configMode = CM_ROTATE_TO_NAME_ENTRY; + this->logoAlpha = 0; + CVarSetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 1); + this->kbdButton = FS_KBD_BTN_NONE; + this->charPage = FS_CHAR_PAGE_ENG; + this->kbdX = 0; + this->kbdY = 0; + this->charIndex = 0; + this->charBgAlpha = 0; + this->newFileNameCharCount = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? 4 : 0; + this->nameEntryBoxPosX = 120; + this->nameEntryBoxAlpha = 0; + memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, + CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkName : &emptyName, 8); + } else { + Sfx_PlaySfxCentered(NA_SE_SY_OCARINA_ERROR); + } + } else if (this->randomizerIndex == RSM_GENERATE_RANDOMIZER) { + Randomizer_GenerateRandomizer(); + } else if (this->randomizerIndex == RSM_OPEN_RANDOMIZER_SETTINGS) { + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Randomizer_ShowRandomizerMenu(); + } + } +} + /** * Update function for `CM_UNUSED_31` */ @@ -1491,9 +1543,16 @@ void FileChoose_RotateToNameEntry(GameState* thisx) { this->windowRot += VREG(16); - if (this->windowRot >= 628.0f) { - this->windowRot = 628.0f; - this->configMode = CM_START_NAME_ENTRY; + if (this->prevConfigMode == CM_RANDOMIZER_SETTINGS_MENU) { + if (this->windowRot >= 942.0f) { + this->windowRot = 628.0f; + this->configMode = CM_START_NAME_ENTRY; + } + } else { + if (this->windowRot >= 628.0f) { + this->windowRot = 628.0f; + this->configMode = CM_START_NAME_ENTRY; + } } } @@ -1540,7 +1599,8 @@ void FileChoose_RotateToMain(GameState* thisx) { void FileChoose_RotateToQuest(GameState* thisx) { FileChooseContext* this = (FileChooseContext*)thisx; - if (this->configMode == CM_NAME_ENTRY_TO_QUEST_MENU || this->configMode == CM_BOSS_RUSH_TO_QUEST) { + if (this->configMode == CM_NAME_ENTRY_TO_QUEST_MENU || this->configMode == CM_BOSS_RUSH_TO_QUEST || + this->configMode == CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST) { this->windowRot -= VREG(16); if (this->windowRot <= 314.0f) { @@ -1568,6 +1628,26 @@ void FileChoose_RotateToBossRush(GameState* thisx) { } } +void FileChoose_RotateToRandomizer(GameState* thisx) { + FileChooseContext* this = (FileChooseContext*)thisx; + + if (this->configMode == CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU) { + this->windowRot -= VREG(16); + + if (this->windowRot <= 314.0f) { + this->windowRot = 628.0f; + this->configMode = CM_START_RANDOMIZER_SETTINGS_MENU; + } + } else { + this->windowRot += VREG(16); + + if (this->windowRot >= 628.0f) { + this->windowRot = 628.0f; + this->configMode = CM_START_RANDOMIZER_SETTINGS_MENU; + } + } +} + static void (*gConfigModeUpdateFuncs[])(GameState*) = { FileChoose_StartFadeIn, FileChoose_FinishFadeIn, FileChoose_UpdateMainMenu, FileChoose_SetupCopySource, @@ -1594,7 +1674,9 @@ static void (*gConfigModeUpdateFuncs[])(GameState*) = { FileChoose_RotateToMain, FileChoose_RotateToQuest, FileChoose_RotateToBossRush, FileChoose_UpdateBossRushMenu, FileChoose_StartBossRushMenu, FileChoose_RotateToQuest, - FileChoose_GenerateRandoSeed, + FileChoose_RotateToRandomizer, FileChoose_UpdateRandomizerMenu, + FileChoose_StartRandomizerMenu,FileChoose_RotateToQuest, + FileChoose_RotateToRandomizer }; /** @@ -2161,7 +2243,7 @@ const char* FileChoose_GetQuestChooseTitleTexName(Language lang) { } } -const char* FileChoose_GetBossRushOptionsTitleTexName(Language lang) { +const char* FileChoose_GetSohOptionsTitleTexName(Language lang) { switch (lang) { case LANGUAGE_ENG: default: @@ -2187,20 +2269,24 @@ void FileChoose_DrawWindowContents(GameState* thisx) { s16 pad; char* tex; - switch (this->configMode) { + switch (this->configMode) { case CM_QUEST_MENU: case CM_ROTATE_TO_NAME_ENTRY: case CM_START_QUEST_MENU: case CM_QUEST_TO_MAIN: case CM_NAME_ENTRY_TO_QUEST_MENU: case CM_ROTATE_TO_BOSS_RUSH_MENU: - case CM_GENERATE_SEED: + case CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU: tex = FileChoose_GetQuestChooseTitleTexName(gSaveContext.language); break; case CM_BOSS_RUSH_MENU: case CM_START_BOSS_RUSH_MENU: case CM_BOSS_RUSH_TO_QUEST: - tex = FileChoose_GetBossRushOptionsTitleTexName(gSaveContext.language); + case CM_RANDOMIZER_SETTINGS_MENU: + case CM_START_RANDOMIZER_SETTINGS_MENU: + case CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST: + case CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU: + tex = FileChoose_GetSohOptionsTitleTexName(gSaveContext.language); break; default: tex = sTitleLabels[gSaveContext.language][this->titleLabel]; @@ -2224,34 +2310,32 @@ void FileChoose_DrawWindowContents(GameState* thisx) { // draw next title label if ((this->configMode == CM_QUEST_MENU) || (this->configMode == CM_START_QUEST_MENU) || - this->configMode == CM_NAME_ENTRY_TO_QUEST_MENU || this->configMode == CM_GENERATE_SEED) { + this->configMode == CM_NAME_ENTRY_TO_QUEST_MENU || this->configMode == CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU) { // draw control stick prompts. - if (this->configMode != CM_GENERATE_SEED) { - Gfx_SetupDL_39Opa(this->state.gfxCtx); - gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); - gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOLOD); - FileChoose_DrawTextRec(this->state.gfxCtx, this->stickLeftPrompt.arrowColorR, - this->stickLeftPrompt.arrowColorG, this->stickLeftPrompt.arrowColorB, - this->stickLeftPrompt.arrowColorA, this->stickLeftPrompt.arrowTexX, - this->stickLeftPrompt.arrowTexY, this->stickLeftPrompt.z, 0, 0, -1.0f, 1.0f); - FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.arrowColorR, - this->stickRightPrompt.arrowColorG, this->stickRightPrompt.arrowColorB, - this->stickRightPrompt.arrowColorA, this->stickRightPrompt.arrowTexX, - this->stickRightPrompt.arrowTexY, this->stickRightPrompt.z, 0, 0, 1.0f, 1.0f); - gDPLoadTextureBlock(POLY_OPA_DISP++, gControlStickTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, - G_TX_NOLOD); - FileChoose_DrawTextRec(this->state.gfxCtx, this->stickLeftPrompt.stickColorR, - this->stickLeftPrompt.stickColorG, this->stickLeftPrompt.stickColorB, - this->stickLeftPrompt.stickColorA, this->stickLeftPrompt.stickTexX, - this->stickLeftPrompt.stickTexY, this->stickLeftPrompt.z, 0, 0, -1.0f, 1.0f); - FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.stickColorR, - this->stickRightPrompt.stickColorG, this->stickRightPrompt.stickColorB, - this->stickRightPrompt.stickColorA, this->stickRightPrompt.stickTexX, - this->stickRightPrompt.stickTexY, this->stickRightPrompt.z, 0, 0, 1.0f, 1.0f); - } + Gfx_SetupDL_39Opa(this->state.gfxCtx); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + FileChoose_DrawTextRec(this->state.gfxCtx, this->stickLeftPrompt.arrowColorR, + this->stickLeftPrompt.arrowColorG, this->stickLeftPrompt.arrowColorB, + this->stickLeftPrompt.arrowColorA, this->stickLeftPrompt.arrowTexX, + this->stickLeftPrompt.arrowTexY, this->stickLeftPrompt.z, 0, 0, -1.0f, 1.0f); + FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.arrowColorR, + this->stickRightPrompt.arrowColorG, this->stickRightPrompt.arrowColorB, + this->stickRightPrompt.arrowColorA, this->stickRightPrompt.arrowTexX, + this->stickRightPrompt.arrowTexY, this->stickRightPrompt.z, 0, 0, 1.0f, 1.0f); + gDPLoadTextureBlock(POLY_OPA_DISP++, gControlStickTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + FileChoose_DrawTextRec(this->state.gfxCtx, this->stickLeftPrompt.stickColorR, + this->stickLeftPrompt.stickColorG, this->stickLeftPrompt.stickColorB, + this->stickLeftPrompt.stickColorA, this->stickLeftPrompt.stickTexX, + this->stickLeftPrompt.stickTexY, this->stickLeftPrompt.z, 0, 0, -1.0f, 1.0f); + FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.stickColorR, + this->stickRightPrompt.stickColorG, this->stickRightPrompt.stickColorB, + this->stickRightPrompt.stickColorA, this->stickRightPrompt.stickTexX, + this->stickRightPrompt.stickTexY, this->stickRightPrompt.z, 0, 0, 1.0f, 1.0f); switch (this->questType[this->buttonIndex]) { case QUEST_NORMAL: default: @@ -2270,11 +2354,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) { break; case QUEST_RANDOMIZER: - if (this->configMode == CM_GENERATE_SEED) { - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->logoAlpha / 2); - } else { - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->logoAlpha); - } + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->logoAlpha); FileChoose_DrawTextureI8(this->state.gfxCtx, gTitleTheLegendOfTextTex, 72, 8, 156, 108, 72, 8, 1024, 1024); FileChoose_DrawTextureI8(this->state.gfxCtx, gTitleOcarinaOfTimeTMTextTex, 96, 8, 154, 163, 96, 8, 1024, 1024); FileChoose_DrawImageRGBA32(this->state.gfxCtx, 160, 135, ResourceMgr_GameHasOriginal() ? gTitleZeldaShieldLogoTex : gTitleZeldaShieldLogoMQTex, 160, 160); @@ -2348,9 +2428,57 @@ void FileChoose_DrawWindowContents(GameState* thisx) { (92 + textYOffset), 0.42f, 0, 0, 1.0f, 1.0f); } } + } else if (this->configMode == CM_RANDOMIZER_SETTINGS_MENU) { + uint8_t textAlpha = this->randomizerUIAlpha; + + for (uint8_t index = 0; index <= RSM_OPEN_RANDOMIZER_SETTINGS; index++) { + uint8_t textColorR = 255; + uint8_t textColorG = 255; + uint8_t textColorB = 255; + + // If current index is the selected one, make the text yellow. + if (this->randomizerIndex == index) { + textColorB = 80; + } + + // If no randomizer is loaded and text is "start randomizer" or when a seed is generating, make all options gray. + if ((index == RSM_START_RANDOMIZER && !Randomizer_IsSeedGenerated() && !Randomizer_IsSpoilerLoaded()) || generating) { + textColorR = textColorG = textColorB = 100; + } + + Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetSettingText(index, gSaveContext.language), 70, + (80 + (index * 16)), textColorR, textColorG, textColorB, textAlpha, 0.8f, true); + } + + // Show text to indicate randomizer is being generated. + if (generating) { + Interface_DrawTextLine(this->state.gfxCtx, + SohFileSelect_GetSettingText(RSM_GENERATING, gSaveContext.language), 70, + (80 + 64), 255, 255, 255, textAlpha, 0.8f, true); + } + + // If no randomizer is generated and "start randomizer" is selected, show text to explain why user can't start the randomizer. + if (!Randomizer_IsSeedGenerated() && !Randomizer_IsSpoilerLoaded() && this->randomizerIndex == RSM_START_RANDOMIZER) { + Interface_DrawTextLine(this->state.gfxCtx, + SohFileSelect_GetSettingText(RSM_NO_RANDOMIZER_GENERATED, gSaveContext.language), 70, + (80 + 64), + 240, 80, 80, textAlpha, 0.8f, true); + } + + uint16_t textOffset = 16 * this->randomizerIndex; + Gfx_SetupDL_39Opa(this->state.gfxCtx); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.arrowColorR, + this->stickRightPrompt.arrowColorG, this->stickRightPrompt.arrowColorB, textAlpha, + 62, (85 + textOffset), 0.42f, 0, 0, 1.0f, 1.0f); } else if (this->configMode != CM_ROTATE_TO_NAME_ENTRY && this->configMode != CM_START_BOSS_RUSH_MENU && - this->configMode != CM_ROTATE_TO_BOSS_RUSH_MENU && this->configMode != CM_BOSS_RUSH_TO_QUEST) { + this->configMode != CM_ROTATE_TO_BOSS_RUSH_MENU && this->configMode != CM_BOSS_RUSH_TO_QUEST && + this->configMode != CM_START_RANDOMIZER_SETTINGS_MENU && this->configMode != CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU && + this->configMode != CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST && this->configMode != CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU) { gDPPipeSync(POLY_OPA_DISP++); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->titleAlpha[1]); gDPLoadTextureBlock(POLY_OPA_DISP++, sTitleLabels[gSaveContext.language][this->nextTitleLabel], G_IM_FMT_IA, @@ -2596,8 +2724,9 @@ void FileChoose_ConfigModeDraw(GameState* thisx) { FrameInterpolation_RecordOpenChild(this, this->configMode); - if ((this->configMode != CM_NAME_ENTRY) && (this->configMode != CM_START_NAME_ENTRY) && - (this->configMode != CM_QUEST_MENU) && this->configMode != CM_NAME_ENTRY_TO_QUEST_MENU) { + if (this->configMode != CM_NAME_ENTRY && this->configMode != CM_START_NAME_ENTRY && + this->configMode != CM_QUEST_MENU && this->configMode != CM_NAME_ENTRY_TO_QUEST_MENU && + this->configMode != CM_RANDOMIZER_SETTINGS_MENU && this->configMode != CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU) { gDPPipeSync(POLY_OPA_DISP++); gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->windowColor[0], this->windowColor[1], this->windowColor[2], @@ -2608,9 +2737,8 @@ void FileChoose_ConfigModeDraw(GameState* thisx) { Matrix_Scale(0.78f, 0.78f, 0.78f, MTXMODE_APPLY); if (this->windowRot != 0) { - if (this->configMode == CM_ROTATE_TO_QUEST_MENU || - (this->configMode >= CM_MAIN_TO_OPTIONS && this->configMode <= CM_OPTIONS_TO_MAIN) || - this->configMode == CM_QUEST_TO_MAIN) { + if ((this->configMode >= CM_MAIN_TO_OPTIONS && this->configMode <= CM_OPTIONS_TO_MAIN) || + this->configMode == CM_ROTATE_TO_QUEST_MENU || this->configMode == CM_QUEST_TO_MAIN) { Matrix_RotateX(this->windowRot / 100.0f, MTXMODE_APPLY); } else { Matrix_RotateX((this->windowRot - 942.0f) / 100.0f, MTXMODE_APPLY); @@ -2644,7 +2772,13 @@ void FileChoose_ConfigModeDraw(GameState* thisx) { Matrix_Translate(0.0f, 0.0f, -93.6f, MTXMODE_NEW); Matrix_Scale(0.78f, 0.78f, 0.78f, MTXMODE_APPLY); - Matrix_RotateX((this->windowRot - 628.0f) / 100.0f, MTXMODE_APPLY); + // Invert name select when switching from randomizer settings menu to name entry, otherwise + // it'll show on the backside while rotating to the menu. + if (this->configMode == CM_ROTATE_TO_NAME_ENTRY && this->prevConfigMode == CM_RANDOMIZER_SETTINGS_MENU) { + Matrix_RotateX((this->windowRot - 314.0f) / 100.0f, MTXMODE_APPLY); + } else { + Matrix_RotateX((this->windowRot - 628.0f) / 100.0f, MTXMODE_APPLY); + } gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(this->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -2692,10 +2826,10 @@ void FileChoose_ConfigModeDraw(GameState* thisx) { } // draw quest menu - if ((this->configMode == CM_QUEST_MENU) || (this->configMode == CM_ROTATE_TO_QUEST_MENU) || - (this->configMode == CM_ROTATE_TO_NAME_ENTRY) || this->configMode == CM_QUEST_TO_MAIN || + if (this->configMode == CM_QUEST_MENU || (this->configMode == CM_ROTATE_TO_QUEST_MENU) || + this->configMode == CM_ROTATE_TO_NAME_ENTRY || this->configMode == CM_QUEST_TO_MAIN || this->configMode == CM_NAME_ENTRY_TO_QUEST_MENU || this->configMode == CM_ROTATE_TO_BOSS_RUSH_MENU || - this->configMode == CM_GENERATE_SEED) { + this->configMode == CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU || this->configMode == CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU) { // window gDPPipeSync(POLY_OPA_DISP++); gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); @@ -2724,9 +2858,11 @@ void FileChoose_ConfigModeDraw(GameState* thisx) { FileChoose_DrawWindowContents(&this->state); } - // Draw Boss Rush Options Menu + // Draw Boss Rush / Randomizer Options Menu if (this->configMode == CM_BOSS_RUSH_MENU || this->configMode == CM_ROTATE_TO_BOSS_RUSH_MENU || - this->configMode == CM_START_BOSS_RUSH_MENU || this->configMode == CM_BOSS_RUSH_TO_QUEST) { + this->configMode == CM_START_BOSS_RUSH_MENU || this->configMode == CM_BOSS_RUSH_TO_QUEST || + this->configMode == CM_RANDOMIZER_SETTINGS_MENU || this->configMode == CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU || + this->configMode == CM_START_RANDOMIZER_SETTINGS_MENU || this->configMode == CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST) { // window gDPPipeSync(POLY_OPA_DISP++); gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); @@ -2855,18 +2991,18 @@ void FileChoose_ConfirmFile(GameState* thisx) { if (CHECK_BTN_ALL(input->press.button, BTN_START) || (CHECK_BTN_ALL(input->press.button, BTN_A))) { if (this->confirmButtonIndex == FS_BTN_CONFIRM_YES) { func_800AA000(300.0f, 180, 20, 100); - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->selectMode = SM_FADE_OUT; func_800F6964(0xF); } else { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->selectMode++; } } else if (CHECK_BTN_ALL(input->press.button, BTN_B)) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->selectMode++; } else if ((ABS(this->stickRelY) >= 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->confirmButtonIndex ^= 1; } @@ -2975,7 +3111,7 @@ void FileChoose_LoadGame(GameState* thisx) { u16 swordEquipValue; s32 pad; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); gSaveContext.fileNum = this->buttonIndex; gSaveContext.gameMode = 0; @@ -3108,8 +3244,6 @@ void FileChoose_SelectModeDraw(GameState* thisx) { gDPPipeSync(POLY_OPA_DISP++); FileChoose_SetView(this, 0.0f, 0.0f, 64.0f); - DrawSeedHashSprites(this); - CLOSE_DISPS(this->state.gfxCtx); } @@ -3179,77 +3313,6 @@ void FileChoose_DrawRandoSaveVersionWarning(GameState* thisx) { CLOSE_DISPS(this->state.gfxCtx); } -static const char* noRandoGeneratedText[] = { - // English - "No Randomizer seed currently available.\nGenerate one in the Randomizer Settings" -#if defined(__WIIU__) || defined(__SWITCH__) - ".", -#else - ",\nor drop a spoiler log on the game window.", -#endif - // German - "No Randomizer seed currently available.\nGenerate one in the Randomizer Settings" -#if defined(__WIIU__) || defined(__SWITCH__) - ".", -#else - ",\nor drop a spoiler log on the game window.", -#endif - // French - "Aucune Seed de Randomizer actuellement disponible.\nGénérez-en une dans les \"Randomizer Settings\"" -#if (defined(__WIIU__) || defined(__SWITCH__)) - "." -#else - "\nou glissez un spoilerlog sur la fenêtre du jeu." -#endif -}; - -void FileChoose_DrawNoRandoGeneratedWarning(GameState* thisx) { - FileChooseContext* this = (FileChooseContext*)thisx; - - OPEN_DISPS(this->state.gfxCtx); - - // Draw rando seed warning when build version doesn't match for Major or Minor number - if (this->configMode == CM_QUEST_MENU && this->questType[this->buttonIndex] == QUEST_RANDOMIZER && !(Randomizer_IsSeedGenerated() || Randomizer_IsSpoilerLoaded())) { - uint8_t textAlpha = 225; - uint8_t textboxAlpha = 170; - float textboxScale = 0.7f; - - // float math to get a S5.10 number that will squish the texture - float texCoordinateHeightF = 512 / textboxScale; - uint16_t texCoordinateHeightScale = texCoordinateHeightF + 0.5f; - float texCoordinateWidthF = 512 / textboxScale; - uint16_t texCoordinateWidthScale = texCoordinateWidthF + 0.5f; - uint16_t textboxWidth = 256 * textboxScale; - uint16_t textboxHeight = 64 * textboxScale; - uint8_t leftOffset = 72; - uint8_t bottomOffset = 84; - uint8_t textVerticalOffset; -#if defined(__WIIU__) || defined(__SWITCH__) - textVerticalOffset = 127; // 2 lines -#else - textVerticalOffset = 122; // 3 lines -#endif - - Gfx_SetupDL_39Opa(this->state.gfxCtx); - gDPSetAlphaDither(POLY_OPA_DISP++, G_AD_DISABLE); - gSPClearGeometryMode(POLY_OPA_DISP++, G_SHADE); - gDPSetCombineLERP(POLY_OPA_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, - 0, PRIMITIVE, 0); - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, textboxAlpha); - gDPLoadTextureBlock_4b(POLY_OPA_DISP++, gDefaultMessageBackgroundTex, G_IM_FMT_I, 128, 64, 0, G_TX_MIRROR, - G_TX_MIRROR, 7, 0, G_TX_NOLOD, G_TX_NOLOD); - - gSPTextureRectangle(POLY_OPA_DISP++, leftOffset << 2, (SCREEN_HEIGHT - bottomOffset - textboxHeight) << 2, - (textboxWidth + leftOffset) << 2, (SCREEN_HEIGHT - bottomOffset) << 2, G_TX_RENDERTILE, 0, 0, - texCoordinateWidthScale << 1, texCoordinateHeightScale << 1); - - Interface_DrawTextLine(this->state.gfxCtx, noRandoGeneratedText[gSaveContext.language], 80, textVerticalOffset, - 255, 255, 255, textAlpha, 0.6f, 1); - } - - CLOSE_DISPS(this->state.gfxCtx); -} - void FileChoose_Main(GameState* thisx) { static void* controlsTextures[] = { gFileSelControlsENGTex, @@ -3444,8 +3507,6 @@ void FileChoose_Main(GameState* thisx) { // Draw rando save version warning over the controls text, but before the screen fill fade out FileChoose_DrawRandoSaveVersionWarning(&this->state); - FileChoose_DrawNoRandoGeneratedWarning(&this->state); - gDPPipeSync(POLY_OPA_DISP++); gSPDisplayList(POLY_OPA_DISP++, sScreenFillSetupDL); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, sScreenFillAlpha); @@ -3617,6 +3678,7 @@ void FileChoose_InitContext(GameState* thisx) { this->bossRushIndex = 0; this->bossRushOffset = 0; + this->randomizerIndex = 0; ShrinkWindow_SetVal(0); diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c index 3080eb14f..89092e77c 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c @@ -1,5 +1,6 @@ #include "file_choose.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/SaveManager.h" // when choosing a file to copy or erase, the 6 main menu buttons are placed at these offsets static s16 sChooseFileYOffsets[] = { -48, -48, -48, -24, -24, 0 }; @@ -73,20 +74,20 @@ void FileChoose_SelectCopySource(GameState* thisx) { this->nextTitleLabel = FS_TITLE_SELECT_FILE; this->configMode = CM_COPY_RETURN_MAIN; this->warningLabel = FS_WARNING_NONE; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) { if (Save_GetSaveMetaInfo(this->buttonIndex)->valid) { this->actionTimer = 8; this->selectedFileIndex = this->buttonIndex; this->configMode = CM_SETUP_COPY_DEST_1; this->nextTitleLabel = FS_TITLE_COPY_TO; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else { if ((ABS(this->stickRelY) >= 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if ((this->stickRelY >= 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { this->buttonIndex--; @@ -189,21 +190,21 @@ void FileChoose_SelectCopyDest(GameState* thisx) { this->nextTitleLabel = FS_TITLE_COPY_FROM; this->actionTimer = 8; this->configMode = CM_EXIT_TO_COPY_SOURCE_1; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) { if (!Save_GetSaveMetaInfo(this->buttonIndex)->valid) { this->copyDestFileIndex = this->buttonIndex; this->nextTitleLabel = FS_TITLE_COPY_CONFIRM; this->actionTimer = 8; this->configMode = CM_SETUP_COPY_CONFIRM_1; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else { if ((ABS(this->stickRelY) >= 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if ((this->stickRelY >= 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { this->buttonIndex--; @@ -377,7 +378,7 @@ void FileChoose_CopyConfirm(GameState* thisx) { this->actionTimer = 8; this->nextTitleLabel = FS_TITLE_COPY_TO; this->configMode = CM_RETURN_TO_COPY_DEST; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) { dayTime = gSaveContext.dayTime; Save_CopyFile(this->selectedFileIndex, this->copyDestFileIndex); @@ -387,9 +388,9 @@ void FileChoose_CopyConfirm(GameState* thisx) { this->actionTimer = 8; this->configMode = CM_COPY_ANIM_1; func_800AA000(300.0f, 0xB4, 0x14, 0x64); - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if ((ABS(this->stickRelY) >= 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->buttonIndex ^= 1; } @@ -504,7 +505,7 @@ void FileChoose_CopyAnim3(GameState* thisx) { if (this->actionTimer == 75) { this->connectorAlpha[this->copyDestFileIndex] = 255; - Audio_PlaySoundGeneral(NA_SE_EV_DIAMOND_SWITCH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_DIAMOND_SWITCH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } this->actionTimer--; @@ -514,7 +515,7 @@ void FileChoose_CopyAnim3(GameState* thisx) { this->actionTimer = 8; this->nextTitleLabel = FS_TITLE_SELECT_FILE; this->configMode++; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } } @@ -704,20 +705,20 @@ void FileChoose_EraseSelect(GameState* thisx) { this->nextTitleLabel = FS_TITLE_SELECT_FILE; this->configMode = CM_EXIT_ERASE_TO_MAIN; this->warningLabel = FS_WARNING_NONE; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) { if (Save_GetSaveMetaInfo(this->buttonIndex)->valid) { this->actionTimer = 8; this->selectedFileIndex = this->buttonIndex; this->configMode = CM_SETUP_ERASE_CONFIRM_1; this->nextTitleLabel = FS_TITLE_ERASE_CONFIRM; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else { if ((ABS(this->stickRelY) >= 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if ((this->stickRelY >= 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { this->buttonIndex--; @@ -845,17 +846,17 @@ void FileChoose_EraseConfirm(GameState* thisx) { this->nextTitleLabel = FS_TITLE_ERASE_FILE; this->configMode = CM_EXIT_TO_ERASE_SELECT_1; this->actionTimer = 8; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if (CHECK_BTN_ANY(input->press.button, BTN_A | BTN_START)) { this->connectorAlpha[this->selectedFileIndex] = 0; - Audio_PlaySoundGeneral(NA_SE_EV_DIAMOND_SWITCH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_DIAMOND_SWITCH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->actionTimer = 8; this->configMode = CM_ERASE_ANIM_1; this->nextTitleLabel = FS_TITLE_ERASE_COMPLETE; func_800AA000(200.0f, 0xFF, 0x14, 0x96); sEraseDelayTimer = 15; } else if ((ABS(this->stickRelY) >= 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->buttonIndex ^= 1; } @@ -971,7 +972,7 @@ void FileChoose_EraseAnim1(GameState* thisx) { sEraseDelayTimer--; if (sEraseDelayTimer == 0) { - Audio_PlaySoundGeneral(NA_SE_OC_ABYSS, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_OC_ABYSS, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } } @@ -989,7 +990,7 @@ void FileChoose_EraseAnim2(GameState* thisx) { this->actionTimer = 8; this->nextTitleLabel = FS_TITLE_SELECT_FILE; this->configMode++; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c index 6463bdbab..8f10e9837 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c @@ -3,6 +3,9 @@ #include "assets/overlays/ovl_File_Choose/ovl_file_choose.h" #include "assets/soh_assets.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/SaveManager.h" static s16 D_808124C0[] = { @@ -356,7 +359,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) { if (this->configMode == CM_NAME_ENTRY) { if (CHECK_BTN_ALL(input->press.button, BTN_START)) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); // place cursor on END button this->kbdY = 5; this->kbdX = 4; @@ -367,15 +370,16 @@ void FileChoose_DrawNameEntry(GameState* thisx) { } filename[i] = 0x3E; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { this->newFileNameCharCount--; if (this->newFileNameCharCount < 0) { this->newFileNameCharCount = 0; - if (this->prevConfigMode == CM_QUEST_MENU || this->prevConfigMode == CM_GENERATE_SEED) { + if (this->prevConfigMode == CM_QUEST_MENU) { this->configMode = CM_NAME_ENTRY_TO_QUEST_MENU; - Randomizer_SetSeedGenerated(false); + } else if (this->prevConfigMode == CM_RANDOMIZER_SETTINGS_MENU) { + this->configMode = CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU; } else { this->configMode = CM_NAME_ENTRY_TO_MAIN; } @@ -388,8 +392,8 @@ void FileChoose_DrawNameEntry(GameState* thisx) { } filename[i] = 0x3E; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } } else { @@ -403,8 +407,8 @@ void FileChoose_DrawNameEntry(GameState* thisx) { font->fontBuf + D_808123F0[this->charIndex] * FONT_CHAR_TEX_SIZE, 0); if (CHECK_BTN_ALL(input->press.button, BTN_A)) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); filename[this->newFileNameCharCount] = D_808123F0[this->charIndex]; this->newFileNameCharCount++; @@ -420,8 +424,8 @@ void FileChoose_DrawNameEntry(GameState* thisx) { } filename[i] = 0x3E; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } else { this->newFileNameCharCount--; @@ -434,8 +438,8 @@ void FileChoose_DrawNameEntry(GameState* thisx) { } filename[i] = 0x3E; - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_S, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } else if (this->kbdButton == FS_KBD_BTN_END) { validName = false; @@ -448,8 +452,8 @@ void FileChoose_DrawNameEntry(GameState* thisx) { } if (validName) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); gSaveContext.fileNum = this->buttonIndex; dayTime = ((void)0, gSaveContext.dayTime); Sram_InitSave(this); @@ -457,26 +461,25 @@ void FileChoose_DrawNameEntry(GameState* thisx) { this->prevConfigMode = CM_MAIN_MENU; this->configMode = CM_NAME_ENTRY_TO_MAIN; CVarSetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0); - Randomizer_SetSeedGenerated(false); this->nameBoxAlpha[this->buttonIndex] = this->nameAlpha[this->buttonIndex] = 200; this->connectorAlpha[this->buttonIndex] = 255; func_800AA000(300.0f, 0xB4, 0x14, 0x64); } else { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } } if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT)) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->newFileNameCharCount++; if (this->newFileNameCharCount > 7) { this->newFileNameCharCount = 7; } } else if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT)) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->newFileNameCharCount--; if (this->newFileNameCharCount < 0) { @@ -535,7 +538,7 @@ void FileChoose_UpdateKeyboardCursor(GameState* thisx) { if (this->kbdY != 5) { if ((this->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->charIndex--; this->kbdX--; if (this->kbdX < 0) { @@ -543,7 +546,7 @@ void FileChoose_UpdateKeyboardCursor(GameState* thisx) { this->charIndex = (this->kbdY * 13) + this->kbdX; } } else if ((this->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->charIndex++; this->kbdX++; if (this->kbdX > 12) { @@ -553,13 +556,13 @@ void FileChoose_UpdateKeyboardCursor(GameState* thisx) { } } else { if ((this->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->kbdX--; if (this->kbdX < 3) { this->kbdX = 4; } } else if ((this->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->kbdX++; if (this->kbdX > 4) { this->kbdX = 3; @@ -568,7 +571,7 @@ void FileChoose_UpdateKeyboardCursor(GameState* thisx) { } if ((this->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->kbdY--; if (this->kbdY < 0) { @@ -599,7 +602,7 @@ void FileChoose_UpdateKeyboardCursor(GameState* thisx) { } } } else if ((this->stickRelY < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->kbdY++; if (this->kbdY > 5) { @@ -688,7 +691,7 @@ void FileChoose_UpdateOptionsMenu(GameState* thisx) { bool dpad = CVarGetInteger(CVAR_SETTING("DpadInText"), 0); if (CHECK_BTN_ALL(input->press.button, BTN_B)) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->prevConfigMode = this->configMode; this->configMode = CM_OPTIONS_TO_MAIN; sLastOptionButtonIndex = -1; @@ -711,7 +714,7 @@ void FileChoose_UpdateOptionsMenu(GameState* thisx) { ResourceMgr_GetGamePlatform(versionIndex) == GAME_PLATFORM_N64; if ((this->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (sSelectedSetting == FS_SETTING_AUDIO) { gSaveContext.audioSetting--; @@ -732,7 +735,7 @@ void FileChoose_UpdateOptionsMenu(GameState* thisx) { gSaveContext.zTargetSetting ^= 1; } } else if ((this->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (sSelectedSetting == FS_SETTING_AUDIO) { gSaveContext.audioSetting++; @@ -762,24 +765,24 @@ void FileChoose_UpdateOptionsMenu(GameState* thisx) { // NTSC and GC only has two rows and can just flip the setting bit // Otherwise for PAL 64, handle the additional change language setting if (!isPalN64 && ((ABS(this->stickRelY) > 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP)))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sSelectedSetting ^= 1; } else if (isPalN64 && ((this->stickRelY > 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DUP)))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sSelectedSetting--; if (sSelectedSetting > 0xF0) { sSelectedSetting = FS_SETTING_LANGUAGE; } } else if (isPalN64 && ((this->stickRelY < -30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN)))) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sSelectedSetting++; if (sSelectedSetting > FS_SETTING_LANGUAGE) { sSelectedSetting = FS_SETTING_AUDIO; } } else if (CHECK_BTN_ALL(input->press.button, BTN_A)) { - Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (isPalN64) { sSelectedSetting++; diff --git a/soh/src/overlays/gamestates/ovl_select/z_select.c b/soh/src/overlays/gamestates/ovl_select/z_select.c index 6d89521f9..f1899d27c 100644 --- a/soh/src/overlays/gamestates/ovl_select/z_select.c +++ b/soh/src/overlays/gamestates/ovl_select/z_select.c @@ -11,6 +11,8 @@ #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" #include "soh/Enhancements/randomizer/randomizer_grotto.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" void Select_SwitchBetterWarpMode(SelectContext* this, u8 isBetterWarpMode); void Sram_InitDebugSave(void); @@ -128,52 +130,52 @@ void Select_Grotto_LoadGame(SelectContext* this, s32 grottoIndex) { } static SceneSelectEntry sScenes[] = { - { " 1:SPOT00", " 1:Hyrule Field", " 1:Hylianische Steppe", " 1:Plaine d'Hyrule", Select_LoadGame, ENTR_HYRULE_FIELD_0 }, - { " 2:SPOT01", " 2:Kakariko Village", " 2:Kakariko", " 2:Village Cocorico", Select_LoadGame, ENTR_KAKARIKO_VILLAGE_0 }, - { " 3:SPOT02", " 3:Graveyard", " 3:Friedhof", " 3:Cimetiere", Select_LoadGame, ENTR_GRAVEYARD_0 }, - { " 4:SPOT03", " 4:Zora's River", " 4:Zora-Fluss", " 4:Riviere Zora", Select_LoadGame, ENTR_ZORAS_RIVER_0 }, + { " 1:SPOT00", " 1:Hyrule Field", " 1:Hylianische Steppe", " 1:Plaine d'Hyrule", Select_LoadGame, ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN }, + { " 2:SPOT01", " 2:Kakariko Village", " 2:Kakariko", " 2:Village Cocorico", Select_LoadGame, ENTR_KAKARIKO_VILLAGE_FRONT_GATE }, + { " 3:SPOT02", " 3:Graveyard", " 3:Friedhof", " 3:Cimetiere", Select_LoadGame, ENTR_GRAVEYARD_ENTRANCE }, + { " 4:SPOT03", " 4:Zora's River", " 4:Zora-Fluss", " 4:Riviere Zora", Select_LoadGame, ENTR_ZORAS_RIVER_WEST_EXIT }, { " 5:SPOT04", " 5:Kokiri Forest", " 5:Kokiri-Wald", " 5:Foret Kokiri", Select_LoadGame, ENTR_KOKIRI_FOREST_0 }, - { " 6:SPOT05", " 6:Sacred Forest Meadow", " 6:Heilige Lichtung", " 6:Bosquet Sacre", Select_LoadGame, ENTR_SACRED_FOREST_MEADOW_0 }, - { " 7:SPOT06", " 7:Lake Hylia", " 7:Hylia-See", " 7:Lac Hylia", Select_LoadGame, ENTR_LAKE_HYLIA_0 }, - { " 8:SPOT07", " 8:Zora's Domain", " 8:Zoras Reich", " 8:Domaine Zora", Select_LoadGame, ENTR_ZORAS_DOMAIN_0 }, - { " 9:SPOT08", " 9:Zora's Fountain", " 9:Zoras Quelle", " 9:Fontaine Zora", Select_LoadGame, ENTR_ZORAS_FOUNTAIN_0 }, - { "10:SPOT09", "10:Gerudo Valley", "10:Gerudotal", "10:Vallee Gerudo", Select_LoadGame, ENTR_GERUDO_VALLEY_0 }, - { "11:SPOT10", "11:Lost Woods", "11:Verlorene Waelder", "11:Bois Perdus", Select_LoadGame, ENTR_LOST_WOODS_0 }, - { "12:SPOT11", "12:Desert Colossus", "12:Wuestenkoloss", "12:Colosse du Desert", Select_LoadGame, ENTR_DESERT_COLOSSUS_0 }, - { "13:SPOT12", "13:Gerudo's Fortress", "13:Gerudo-Festung", "13:Forteresse Gerudo", Select_LoadGame, ENTR_GERUDOS_FORTRESS_0 }, - { "14:SPOT13", "14:Haunted Wasteland", "14:Gespensterwueste", "14:Desert Hante", Select_LoadGame, ENTR_HAUNTED_WASTELAND_0 }, - { "15:SPOT15", "15:Hyrule Castle", "15:Schloss Hyrule", "15:Chateau d'Hyrule", Select_LoadGame, ENTR_HYRULE_CASTLE_0 }, - { "16:SPOT16", "16:Death Mountain Trail", "16:Pfad zum Todesberg", "16:Chemin du Peril", Select_LoadGame, ENTR_DEATH_MOUNTAIN_TRAIL_0 }, - { "17:SPOT17", "17:Death Mountain Crater", "17:Todeskrater", "17:Cratere du Peril", Select_LoadGame, ENTR_DEATH_MOUNTAIN_CRATER_0 }, - { "18:SPOT18", "18:Goron City", "18:Goronia", "18:Village Goron", Select_LoadGame, ENTR_GORON_CITY_0 }, - { "19:SPOT20", "19:Lon Lon Ranch", "19:Lon Lon-Farm", "19:Ranch Lon Lon", Select_LoadGame, ENTR_LON_LON_RANCH_0 }, - { "20:" GFXP_HIRAGANA "トキノマ", "20:Temple Of Time", "20:Zitadelle der Zeit", "20:Temple du Temps", Select_LoadGame, ENTR_TEMPLE_OF_TIME_0 }, + { " 6:SPOT05", " 6:Sacred Forest Meadow", " 6:Heilige Lichtung", " 6:Bosquet Sacre", Select_LoadGame, ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT }, + { " 7:SPOT06", " 7:Lake Hylia", " 7:Hylia-See", " 7:Lac Hylia", Select_LoadGame, ENTR_LAKE_HYLIA_NORTH_EXIT }, + { " 8:SPOT07", " 8:Zora's Domain", " 8:Zoras Reich", " 8:Domaine Zora", Select_LoadGame, ENTR_ZORAS_DOMAIN_ENTRANCE }, + { " 9:SPOT08", " 9:Zora's Fountain", " 9:Zoras Quelle", " 9:Fontaine Zora", Select_LoadGame, ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP }, + { "10:SPOT09", "10:Gerudo Valley", "10:Gerudotal", "10:Vallee Gerudo", Select_LoadGame, ENTR_GERUDO_VALLEY_EAST_EXIT }, + { "11:SPOT10", "11:Lost Woods", "11:Verlorene Waelder", "11:Bois Perdus", Select_LoadGame, ENTR_LOST_WOODS_SOUTH_EXIT }, + { "12:SPOT11", "12:Desert Colossus", "12:Wuestenkoloss", "12:Colosse du Desert", Select_LoadGame, ENTR_DESERT_COLOSSUS_EAST_EXIT }, + { "13:SPOT12", "13:Gerudo's Fortress", "13:Gerudo-Festung", "13:Forteresse Gerudo", Select_LoadGame, ENTR_GERUDOS_FORTRESS_EAST_EXIT }, + { "14:SPOT13", "14:Haunted Wasteland", "14:Gespensterwueste", "14:Desert Hante", Select_LoadGame, ENTR_HAUNTED_WASTELAND_EAST_EXIT }, + { "15:SPOT15", "15:Hyrule Castle", "15:Schloss Hyrule", "15:Chateau d'Hyrule", Select_LoadGame, ENTR_CASTLE_GROUNDS_SOUTH_EXIT }, + { "16:SPOT16", "16:Death Mountain Trail", "16:Pfad zum Todesberg", "16:Chemin du Peril", Select_LoadGame, ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT }, + { "17:SPOT17", "17:Death Mountain Crater", "17:Todeskrater", "17:Cratere du Peril", Select_LoadGame, ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT }, + { "18:SPOT18", "18:Goron City", "18:Goronia", "18:Village Goron", Select_LoadGame, ENTR_GORON_CITY_UPPER_EXIT }, + { "19:SPOT20", "19:Lon Lon Ranch", "19:Lon Lon-Farm", "19:Ranch Lon Lon", Select_LoadGame, ENTR_LON_LON_RANCH_ENTRANCE }, + { "20:" GFXP_HIRAGANA "トキノマ", "20:Temple Of Time", "20:Zitadelle der Zeit", "20:Temple du Temps", Select_LoadGame, ENTR_TEMPLE_OF_TIME_ENTRANCE }, { "21:" GFXP_HIRAGANA "ケンジャノマ", "21:Chamber of Sages", "21:Halle der Weisen", "21:Sanctuaire des Sages", Select_LoadGame, ENTR_CHAMBER_OF_THE_SAGES_0 }, { "22:" GFXP_HIRAGANA "シャテキジョウ", "22:Shooting Gallery", "22:Schiessbude", "22:Jeu d'adresse", Select_LoadGame, ENTR_SHOOTING_GALLERY_0 }, { "23:" GFXP_KATAKANA "ハイラル" GFXP_HIRAGANA "ニワ" GFXP_KATAKANA "ゲーム", "23:Castle Courtyard Game", "23:Burghof - Wachen", "23:Cour du Chateau (Infilration)", Select_LoadGame, ENTR_CASTLE_COURTYARD_GUARDS_DAY_0 }, { "24:" GFXP_HIRAGANA "ハカシタトビコミアナ", "24:Grave 1", "24:Grab 1", "24:Tombe 1", Select_LoadGame, ENTR_REDEAD_GRAVE_0 }, { "25:" GFXP_HIRAGANA "ハカシタトビコミアナ 2", "25:Grave 2", "25:Grab 2", "25:Tombe 2", Select_LoadGame, ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0 }, { "26:" GFXP_HIRAGANA "オウケ ノ ハカアナ", "26:Royal Family's Tomb", "26:Koenigsgrab", "26:Tombe Royale", Select_LoadGame, ENTR_ROYAL_FAMILYS_TOMB_0 }, - { "27:" GFXP_HIRAGANA "ダイヨウセイノイズミ", "27:Great Fairy's Fountain (Upgrades)", "27:Feen-Quelle (Upgrades)", "27:Fontaine Royale des Fees (Amel.)", Select_LoadGame, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0 }, + { "27:" GFXP_HIRAGANA "ダイヨウセイノイズミ", "27:Great Fairy's Fountain (Upgrades)", "27:Feen-Quelle (Upgrades)", "27:Fontaine Royale des Fees (Amel.)", Select_LoadGame, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT }, { "28:" GFXP_HIRAGANA "トビコミ ヨウセイ アナ", "28:Fairy's Fountain (Grotto)", "28:Feen-Brunnen (Grotte)", "28:Fontaines des Fees (Grotte)", Select_LoadGame, ENTR_FAIRYS_FOUNTAIN_0 }, - { "29:" GFXP_HIRAGANA "マホウセキ ヨウセイノイズミ", "29:Great Fairy's Fountain (Magic)", "29:Feen-Quelle (Magie)", "29:Fontaine Royale des Fees (Magie)", Select_LoadGame, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0 }, + { "29:" GFXP_HIRAGANA "マホウセキ ヨウセイノイズミ", "29:Great Fairy's Fountain (Magic)", "29:Feen-Quelle (Magie)", "29:Fontaine Royale des Fees (Magie)", Select_LoadGame, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF }, { "30:" GFXP_KATAKANA "ガノン" GFXP_HIRAGANA "サイシュウセン", "30:Ganon's Tower - Collapsing", "30:Ganons Turm - Einsturz", "30:Tour de Ganon - Effondrement", Select_LoadGame, ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0 }, { "31:" GFXP_KATAKANA "ハイラル" GFXP_HIRAGANA "ナカニワ", "31:Castle Courtyard", "31:Burghof - Zelda", "31:Cour du Chateau", Select_LoadGame, ENTR_CASTLE_COURTYARD_ZELDA_0 }, { "32:" GFXP_HIRAGANA "ツリボリ", "32:Fishing Pond", "32:Fischweiher", "32:Etang", Select_LoadGame, ENTR_FISHING_POND_0 }, { "33:" GFXP_KATAKANA "ボムチュウボーリング", "33:Bombchu Bowling Alley", "33:Minenbowlingbahn", "33:Bowling Teigneux", Select_LoadGame, ENTR_BOMBCHU_BOWLING_ALLEY_0 }, - { "34:" GFXP_KATAKANA "ロンロン" GFXP_HIRAGANA "ボクジョウ ソウコ 1", "34:Lon Lon Ranch House", "34:Lon Lon-Farm Haus", "34:Maison du Ranch Lon Lon", Select_LoadGame, ENTR_LON_LON_BUILDINGS_0 }, - { "35:" GFXP_KATAKANA "ロンロン" GFXP_HIRAGANA "ボクジョウ ソウコ 2", "35:Lon Lon Ranch Silo", "35:Lon Lon-Farm Silo", "35:Silo du Ranch Lon Lon", Select_LoadGame, ENTR_LON_LON_BUILDINGS_1 }, + { "34:" GFXP_KATAKANA "ロンロン" GFXP_HIRAGANA "ボクジョウ ソウコ 1", "34:Lon Lon Ranch House", "34:Lon Lon-Farm Haus", "34:Maison du Ranch Lon Lon", Select_LoadGame, ENTR_LON_LON_BUILDINGS_TALONS_HOUSE }, + { "35:" GFXP_KATAKANA "ロンロン" GFXP_HIRAGANA "ボクジョウ ソウコ 2", "35:Lon Lon Ranch Silo", "35:Lon Lon-Farm Silo", "35:Silo du Ranch Lon Lon", Select_LoadGame, ENTR_LON_LON_BUILDINGS_TOWER }, { "36:" GFXP_HIRAGANA "ミハリ ゴヤ", "36:Guard House", "36:Wachposten", "36:Maison de Garde", Select_LoadGame, ENTR_MARKET_GUARD_HOUSE_0 }, { "37:" GFXP_HIRAGANA "マホウ ノ クスリヤ", "37:Potion Shop", "37:Magie-Laden", "37:Apothicaire", Select_LoadGame, ENTR_POTION_SHOP_GRANNY_0 }, { "38:" GFXP_HIRAGANA "タカラバコヤ", "38:Treasure Chest Game", "38:Truhenlotterie", "38:Chasse aux Tresors", Select_LoadGame, ENTR_TREASURE_BOX_SHOP_0 }, { "39:" GFXP_HIRAGANA "キン " GFXP_KATAKANA "スタルチュラ ハウス", "39:House Of Skulltula", "39:Skulltulas Haus", "39:Maison des Skulltulas", Select_LoadGame, ENTR_HOUSE_OF_SKULLTULA_0 }, - { "40:" GFXP_HIRAGANA "ジョウカマチ イリグチ", "40:Entrance to Market", "40:Eingang zum Marktplatz", "40:Entree de la Place du Marche", Select_LoadGame, ENTR_MARKET_ENTRANCE_DAY_0 }, - { "41:" GFXP_HIRAGANA "ジョウカマチ", "41:Market", "41:Marktplatz", "41:Place du Marche", Select_LoadGame, ENTR_MARKET_DAY_0 }, + { "40:" GFXP_HIRAGANA "ジョウカマチ イリグチ", "40:Entrance to Market", "40:Eingang zum Marktplatz", "40:Entree de la Place du Marche", Select_LoadGame, ENTR_MARKET_ENTRANCE_NORTH_EXIT }, + { "41:" GFXP_HIRAGANA "ジョウカマチ", "41:Market", "41:Marktplatz", "41:Place du Marche", Select_LoadGame, ENTR_MARKET_SOUTH_EXIT }, { "42:" GFXP_HIRAGANA "ウラロジ", "42:Back Alley", "42:Seitenstrasse", "42:Ruelle", Select_LoadGame, ENTR_BACK_ALLEY_DAY_0 }, - { "43:" GFXP_HIRAGANA "トキノシンデン マエ", "43:Temple of Time Exterior", "43:Vor der Zitadelle der Zeit", "43:Exterieur du Temple du Temps", Select_LoadGame, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_0 }, - { "44:" GFXP_HIRAGANA "リンクノイエ", "44:Link's House", "44:Links Haus", "44:Cabane de Link", Select_LoadGame, ENTR_LINKS_HOUSE_0 }, + { "43:" GFXP_HIRAGANA "トキノシンデン マエ", "43:Temple of Time Exterior", "43:Vor der Zitadelle der Zeit", "43:Exterieur du Temple du Temps", Select_LoadGame, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT }, + { "44:" GFXP_HIRAGANA "リンクノイエ", "44:Link's House", "44:Links Haus", "44:Cabane de Link", Select_LoadGame, ENTR_LINKS_HOUSE_CHILD_SPAWN }, { "45:" GFXP_KATAKANA "カカリコ" GFXP_HIRAGANA "ムラノナガヤ", "45:Kakariko House 1", "45:Kakariko Haus 1", "45:Maison du Village Cocorico 1", Select_LoadGame, ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0 }, - { "46:" GFXP_HIRAGANA "ウラロジノ イエ", "46:Back Alley House 1", "46:Seitenstrasse Haus 1", "46:Maison de la Ruelle 1", Select_LoadGame, ENTR_BACK_ALLEY_HOUSE_0 }, + { "46:" GFXP_HIRAGANA "ウラロジノ イエ", "46:Back Alley House 1", "46:Seitenstrasse Haus 1", "46:Maison de la Ruelle 1", Select_LoadGame, ENTR_BACK_ALLEY_MAN_IN_GREEN_HOUSE }, { "47:" GFXP_HIRAGANA "コキリノムラ モノシリキョウダイノイエ", "47:House of the Know-it-All Brothers", "47:Haus der Allwissenden Brueder", "47:Cabane des Freres Je-Sais-Tout", Select_LoadGame, ENTR_KNOW_IT_ALL_BROS_HOUSE_0 }, { "48:" GFXP_HIRAGANA "コキリノムラ フタゴノイエ", "48:House of Twins", "48:Haus der Zwillinge", "48:Cabane des Jumeaux", Select_LoadGame, ENTR_TWINS_HOUSE_0 }, { "49:" GFXP_HIRAGANA "コキリノムラ " GFXP_KATAKANA "ミド" GFXP_HIRAGANA "ノイエ", "49:Mido's House", "49:Midos Haus", "49:Cabane du Grand Mido", Select_LoadGame, ENTR_MIDOS_HOUSE_0 }, @@ -181,41 +183,41 @@ static SceneSelectEntry sScenes[] = { { "51:" GFXP_HIRAGANA "ウマゴヤ", "51:Stable", "51:Stall", "51:Etable", Select_LoadGame, ENTR_STABLE_0 }, { "52:" GFXP_HIRAGANA "ハカモリノイエ", "52:Grave Keeper's Hut", "52:Huette des Totengraebers", "52:Cabane du Fossoyeur", Select_LoadGame, ENTR_GRAVEKEEPERS_HUT_0 }, { "53:" GFXP_HIRAGANA "ウラロジ イヌオバサンノイエ", "53:Dog Lady's House", "53:Haus der Hunde-Dame", "53:Maison de la Dame du Chien", Select_LoadGame, ENTR_DOG_LADY_HOUSE_0 }, - { "54:" GFXP_HIRAGANA "カカリコムラ " GFXP_KATAKANA "インパ" GFXP_HIRAGANA "ノイエ", "54:Impa's House", "54:Impas Haus", "54:Maison d'Impa", Select_LoadGame, ENTR_IMPAS_HOUSE_0 }, + { "54:" GFXP_HIRAGANA "カカリコムラ " GFXP_KATAKANA "インパ" GFXP_HIRAGANA "ノイエ", "54:Impa's House", "54:Impas Haus", "54:Maison d'Impa", Select_LoadGame, ENTR_IMPAS_HOUSE_FRONT }, { "55:" GFXP_KATAKANA "ハイリア" GFXP_HIRAGANA " ケンキュウジョ", "55:Lakeside Laboratory", "55:Hylia-See Laboratorium", "55:Laboratoire du Lac", Select_LoadGame, ENTR_LAKESIDE_LABORATORY_0 }, { "56:" GFXP_KATAKANA "テント", "56:Running Man's Tent", "56:Zelt des Rennlaeufers", "56:Tente du Marathonien", Select_LoadGame, ENTR_CARPENTERS_TENT_0 }, { "57:" GFXP_HIRAGANA "タテノミセ", "57:Bazaar", "57:Basar", "57:Bazar", Select_LoadGame, ENTR_BAZAAR_0 }, { "58:" GFXP_HIRAGANA "コキリゾクノミセ", "58:Kokiri Shop", "58:Kokiri-Laden", "58:Boutique Kokiri", Select_LoadGame, ENTR_KOKIRI_SHOP_0 }, { "59:" GFXP_KATAKANA "ゴロン" GFXP_HIRAGANA "ノミセ", "59:Goron Shop", "59:Goronen-Laden", "59:Boutique Goron", Select_LoadGame, ENTR_GORON_SHOP_0 }, { "60:" GFXP_KATAKANA "ゾーラ" GFXP_HIRAGANA "ノミセ", "60:Zora Shop", "60:Zora-Laden", "60:Boutique Zora", Select_LoadGame, ENTR_ZORA_SHOP_0 }, - { "61:" GFXP_KATAKANA "カカリコ" GFXP_HIRAGANA "ムラ クスリヤ", "61:Closed Shop", "61:Geschlossener Laden", "61:Boutique Fermee", Select_LoadGame, ENTR_POTION_SHOP_KAKARIKO_0 }, + { "61:" GFXP_KATAKANA "カカリコ" GFXP_HIRAGANA "ムラ クスリヤ", "61:Closed Shop", "61:Geschlossener Laden", "61:Boutique Fermee", Select_LoadGame, ENTR_POTION_SHOP_KAKARIKO_FRONT }, { "62:" GFXP_HIRAGANA "ジョウカマチ クスリヤ", "62:Potion Shop", "62:Magie-Laden", "62:Apothicaire (Boutique)", Select_LoadGame, ENTR_POTION_SHOP_MARKET_0 }, { "63:" GFXP_HIRAGANA "ウラロジ ヨルノミセ", "63:Bombchu Shop", "63:Krabbelminen-Laden", "63:Boutique de Missiles Teigneux", Select_LoadGame, ENTR_BOMBCHU_SHOP_0 }, { "64:" GFXP_HIRAGANA "オメンヤ", "64:Happy Mask Shop", "64:Maskenhaendler", "64:Foire aux Masques", Select_LoadGame, ENTR_HAPPY_MASK_SHOP_0 }, - { "65:" GFXP_KATAKANA "ゲルド" GFXP_HIRAGANA "ノシュウレンジョウ", "65:Gerudo Training Ground", "65:Gerudo-Trainingsarena", "65:Gymnase Gerudo", Select_LoadGame, ENTR_GERUDO_TRAINING_GROUND_0 }, - { "66:" GFXP_HIRAGANA "ヨウセイノキノ " GFXP_KATAKANA "ダンジョン", "66:Inside the Deku Tree", "66:Im Deku-Baum", "66:Arbre Mojo", Select_LoadGame, ENTR_DEKU_TREE_0 }, - { "67:" GFXP_HIRAGANA "ヨウセイノキノ " GFXP_KATAKANA "ダンジョン ボス", "67:Gohma's Lair", "67:Gohmas Verlies", "67:Repaire de Gohma", Select_LoadGame, ENTR_DEKU_TREE_BOSS_0 }, - { "68:" GFXP_KATAKANA "ドドンゴ ダンジョン", "68:Dodongo's Cavern", "68:Dodongos Hoehle", "68:Caverne Dodongo", Select_LoadGame, ENTR_DODONGOS_CAVERN_0 }, - { "69:" GFXP_KATAKANA "ドドンゴ ダンジョン ボス", "69:King Dodongo's Lair", "69:Koenig Dodongos Verlies", "69:Repaire du Roi Dodongo", Select_LoadGame, ENTR_DODONGOS_CAVERN_BOSS_0 }, - { "70:" GFXP_HIRAGANA "キョダイギョ " GFXP_KATAKANA "ダンジョン", "70:Inside Jabu-Jabu's Belly", "70:Jabu-Jabus Bauch", "70:Ventre de Jabu-Jabu", Select_LoadGame, ENTR_JABU_JABU_0 }, - { "71:" GFXP_HIRAGANA "キョダイギョ " GFXP_KATAKANA "ダンジョン ボス", "71:Barinade's Lair", "71:Barinades Verlies", "71:Repaire de Barinade", Select_LoadGame, ENTR_JABU_JABU_BOSS_0 }, - { "72:" GFXP_HIRAGANA "モリノシンデン", "72:Forest Temple", "72:Waldtempel", "72:Temple de la Foret", Select_LoadGame, ENTR_FOREST_TEMPLE_0 }, - { "73:" GFXP_HIRAGANA "モリノシンデン " GFXP_KATAKANA "ボス", "73:Phantom Ganon's Lair", "73:Phantom-Ganons Verlies", "73:Repaire de Ganon Spectral", Select_LoadGame, ENTR_FOREST_TEMPLE_BOSS_0 }, - { "74:" GFXP_HIRAGANA "イドシタ " GFXP_KATAKANA "ダンジョン", "74:Bottom of the Well", "74:Grund des Brunnens", "74:Puits", Select_LoadGame, ENTR_BOTTOM_OF_THE_WELL_0 }, - { "75:" GFXP_HIRAGANA "ハカシタ " GFXP_KATAKANA "ダンジョン", "75:Shadow Temple", "75:Schattentempel", "75:Temple de l'Ombre", Select_LoadGame, ENTR_SHADOW_TEMPLE_0 }, - { "76:" GFXP_HIRAGANA "ハカシタ " GFXP_KATAKANA "ダンジョン ボス", "76:Bongo Bongo's Lair", "76:Bongo Bongos Verlies", "76:Repaire de Bongo Bongo", Select_LoadGame, ENTR_SHADOW_TEMPLE_BOSS_0 }, - { "77:" GFXP_HIRAGANA "ヒノシンデン", "77:Fire Temple", "77:Feuertempel", "77:Temple du Feu", Select_LoadGame, ENTR_FIRE_TEMPLE_0 }, - { "78:" GFXP_HIRAGANA "ヒノシンデン " GFXP_KATAKANA "ボス", "78:Volvagia's Lair", "78:Volvagias Verlies", "78:Repaire de Volcania", Select_LoadGame, ENTR_FIRE_TEMPLE_BOSS_0 }, - { "79:" GFXP_HIRAGANA "ミズノシンデン", "79:Water Temple", "79:Wassertempel", "79:Temple de l'Eau", Select_LoadGame, ENTR_WATER_TEMPLE_0 }, - { "80:" GFXP_HIRAGANA "ミズノシンデン " GFXP_KATAKANA "ボス", "80:Morpha's Lair", "80:Morphas Verlies", "80:Repaire de Morpha", Select_LoadGame, ENTR_WATER_TEMPLE_BOSS_0 }, - { "81:" GFXP_HIRAGANA "ジャシンゾウ " GFXP_KATAKANA "ダンジョン", "81:Spirit Temple", "81:Geistertempel", "81:Temple de l'Esprit", Select_LoadGame, ENTR_SPIRIT_TEMPLE_0 }, - { "82:" GFXP_HIRAGANA "ジャシンゾウ " GFXP_KATAKANA "ダンジョン アイアンナック", "82:Iron Knuckle's Lair", "82:Eisenprinz' Verlies", "82:Repaire du Hache Viande", Select_LoadGame, ENTR_SPIRIT_TEMPLE_BOSS_0 }, + { "65:" GFXP_KATAKANA "ゲルド" GFXP_HIRAGANA "ノシュウレンジョウ", "65:Gerudo Training Ground", "65:Gerudo-Trainingsarena", "65:Gymnase Gerudo", Select_LoadGame, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE }, + { "66:" GFXP_HIRAGANA "ヨウセイノキノ " GFXP_KATAKANA "ダンジョン", "66:Inside the Deku Tree", "66:Im Deku-Baum", "66:Arbre Mojo", Select_LoadGame, ENTR_DEKU_TREE_ENTRANCE }, + { "67:" GFXP_HIRAGANA "ヨウセイノキノ " GFXP_KATAKANA "ダンジョン ボス", "67:Gohma's Lair", "67:Gohmas Verlies", "67:Repaire de Gohma", Select_LoadGame, ENTR_DEKU_TREE_BOSS_ENTRANCE }, + { "68:" GFXP_KATAKANA "ドドンゴ ダンジョン", "68:Dodongo's Cavern", "68:Dodongos Hoehle", "68:Caverne Dodongo", Select_LoadGame, ENTR_DODONGOS_CAVERN_ENTRANCE }, + { "69:" GFXP_KATAKANA "ドドンゴ ダンジョン ボス", "69:King Dodongo's Lair", "69:Koenig Dodongos Verlies", "69:Repaire du Roi Dodongo", Select_LoadGame, ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE }, + { "70:" GFXP_HIRAGANA "キョダイギョ " GFXP_KATAKANA "ダンジョン", "70:Inside Jabu-Jabu's Belly", "70:Jabu-Jabus Bauch", "70:Ventre de Jabu-Jabu", Select_LoadGame, ENTR_JABU_JABU_ENTRANCE }, + { "71:" GFXP_HIRAGANA "キョダイギョ " GFXP_KATAKANA "ダンジョン ボス", "71:Barinade's Lair", "71:Barinades Verlies", "71:Repaire de Barinade", Select_LoadGame, ENTR_JABU_JABU_BOSS_ENTRANCE }, + { "72:" GFXP_HIRAGANA "モリノシンデン", "72:Forest Temple", "72:Waldtempel", "72:Temple de la Foret", Select_LoadGame, ENTR_FOREST_TEMPLE_ENTRANCE }, + { "73:" GFXP_HIRAGANA "モリノシンデン " GFXP_KATAKANA "ボス", "73:Phantom Ganon's Lair", "73:Phantom-Ganons Verlies", "73:Repaire de Ganon Spectral", Select_LoadGame, ENTR_FOREST_TEMPLE_BOSS_ENTRANCE }, + { "74:" GFXP_HIRAGANA "イドシタ " GFXP_KATAKANA "ダンジョン", "74:Bottom of the Well", "74:Grund des Brunnens", "74:Puits", Select_LoadGame, ENTR_BOTTOM_OF_THE_WELL_ENTRANCE }, + { "75:" GFXP_HIRAGANA "ハカシタ " GFXP_KATAKANA "ダンジョン", "75:Shadow Temple", "75:Schattentempel", "75:Temple de l'Ombre", Select_LoadGame, ENTR_SHADOW_TEMPLE_ENTRANCE }, + { "76:" GFXP_HIRAGANA "ハカシタ " GFXP_KATAKANA "ダンジョン ボス", "76:Bongo Bongo's Lair", "76:Bongo Bongos Verlies", "76:Repaire de Bongo Bongo", Select_LoadGame, ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE }, + { "77:" GFXP_HIRAGANA "ヒノシンデン", "77:Fire Temple", "77:Feuertempel", "77:Temple du Feu", Select_LoadGame, ENTR_FIRE_TEMPLE_ENTRANCE }, + { "78:" GFXP_HIRAGANA "ヒノシンデン " GFXP_KATAKANA "ボス", "78:Volvagia's Lair", "78:Volvagias Verlies", "78:Repaire de Volcania", Select_LoadGame, ENTR_FIRE_TEMPLE_BOSS_ENTRANCE }, + { "79:" GFXP_HIRAGANA "ミズノシンデン", "79:Water Temple", "79:Wassertempel", "79:Temple de l'Eau", Select_LoadGame, ENTR_WATER_TEMPLE_ENTRANCE }, + { "80:" GFXP_HIRAGANA "ミズノシンデン " GFXP_KATAKANA "ボス", "80:Morpha's Lair", "80:Morphas Verlies", "80:Repaire de Morpha", Select_LoadGame, ENTR_WATER_TEMPLE_BOSS_ENTRANCE }, + { "81:" GFXP_HIRAGANA "ジャシンゾウ " GFXP_KATAKANA "ダンジョン", "81:Spirit Temple", "81:Geistertempel", "81:Temple de l'Esprit", Select_LoadGame, ENTR_SPIRIT_TEMPLE_ENTRANCE }, + { "82:" GFXP_HIRAGANA "ジャシンゾウ " GFXP_KATAKANA "ダンジョン アイアンナック", "82:Iron Knuckle's Lair", "82:Eisenprinz' Verlies", "82:Repaire du Hache Viande", Select_LoadGame, ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE }, { "83:" GFXP_HIRAGANA "ジャシンゾウ " GFXP_KATAKANA "ダンジョン ボス", "83:Twinrova's Lair", "83:Killa Ohmaz' Verlies", "83:Repaire du Duo Malefique", Select_LoadGame, ENTR_SPIRIT_TEMPLE_BOSS_2 }, { "84:" GFXP_KATAKANA "ガノン" GFXP_HIRAGANA "ノトウ", "84:Stairs to Ganondorf's Lair", "84:Treppen zu Ganondorfs Verlies", "84:Repaire de Ganondorf (Escaliers)", Select_LoadGame, ENTR_GANONS_TOWER_0 }, { "85:" GFXP_KATAKANA "ガノン" GFXP_HIRAGANA "ノトウ" GFXP_KATAKANA "ボス", "85:Ganondorf's Lair", "85:Ganondorfs Verlies", "85:Repaire de Ganondorf", Select_LoadGame, ENTR_GANONDORF_BOSS_0 }, - { "86:" GFXP_HIRAGANA "コオリノドウクツ", "86:Ice Cavern", "86:Eishoehle", "86:Caverne Polaire", Select_LoadGame, ENTR_ICE_CAVERN_0 }, - { "87:" GFXP_HIRAGANA "ハカシタ" GFXP_KATAKANA "リレー", "87:Dampe Grave Relay Game", "87:Boris' Grab Staffellauf", "87:Tombe d'Igor", Select_LoadGame, ENTR_WINDMILL_AND_DAMPES_GRAVE_0 }, - { "88:" GFXP_KATAKANA "ガノン" GFXP_HIRAGANA "チカ " GFXP_KATAKANA "ダンジョン", "88:Inside Ganon's Castle", "88:In Ganons Schloss", "88:Tour de Ganon", Select_LoadGame, ENTR_INSIDE_GANONS_CASTLE_0 }, + { "86:" GFXP_HIRAGANA "コオリノドウクツ", "86:Ice Cavern", "86:Eishoehle", "86:Caverne Polaire", Select_LoadGame, ENTR_ICE_CAVERN_ENTRANCE }, + { "87:" GFXP_HIRAGANA "ハカシタ" GFXP_KATAKANA "リレー", "87:Dampe Grave Relay Game", "87:Boris' Grab Staffellauf", "87:Tombe d'Igor", Select_LoadGame, ENTR_WINDMILL_AND_DAMPES_GRAVE_GRAVE }, + { "88:" GFXP_KATAKANA "ガノン" GFXP_HIRAGANA "チカ " GFXP_KATAKANA "ダンジョン", "88:Inside Ganon's Castle", "88:In Ganons Schloss", "88:Tour de Ganon", Select_LoadGame, ENTR_INSIDE_GANONS_CASTLE_ENTRANCE }, { "89:" GFXP_KATAKANA "ガノン" GFXP_HIRAGANA "サイシュウセン " GFXP_KATAKANA "デモ & バトル", "89:Ganon's Lair", "89:Ganons Verlies", "89:Repaire de Ganon", Select_LoadGame, ENTR_GANON_BOSS_0 }, { "90:" GFXP_KATAKANA "ガノン" GFXP_HIRAGANA "ノトウ ソノゴ 1", "90:Escaping Ganon's Castle 1", "90:Flucht aus Ganons Schloss 1", "90:Fuite du Chateau de Ganon 1", Select_LoadGame, ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_0 }, { "91:" GFXP_KATAKANA "ガノン" GFXP_HIRAGANA "ノトウ ソノゴ 2", "91:Escaping Ganon's Castle 2", "91:Flucht aus Ganons Schloss 2", "91:Fuite du Chateau de Ganon 2", Select_LoadGame, ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_2 }, @@ -259,28 +261,28 @@ static SceneSelectEntry sScenes[] = { static BetterSceneSelectEntry sBetterScenes[] = { { " 1:Hyrule Field", " 1:Hylianische Steppe", " 1:Plaine d'Hyrule", Select_LoadGame, 8, { - { "Near Drawbridge", "Nahe der Zugbruecke", "Pres du Pont-levis", ENTR_HYRULE_FIELD_0, 0 }, - { "From Drawbridge", "Von der Zugbruecke", "Depuis le Pont-levis", ENTR_HYRULE_FIELD_7, 0 }, - { "From Kakariko Village", "Von Kakariko", "Depuis le Village Cocorico", ENTR_HYRULE_FIELD_1, 0 }, - { "From Zora River", "Vom Zora-Fluss", "Depuis la Riviere Zora", ENTR_HYRULE_FIELD_2, 0 }, - { "From Lost Woods", "Von den verlorenen Waeldern", "Depuis les Bois Perdus", ENTR_HYRULE_FIELD_3, 0 }, - { "From Lake Hylia", "Vom Hylia-See", "Depuis le Lac Hylia", ENTR_HYRULE_FIELD_4, 0 }, - { "From Gerudo Valley", "Vom Gerudotal", "Depuis la Vallee Gerudo", ENTR_HYRULE_FIELD_5, 0 }, - { "From Lon Lon Ranch", "Von der Lon Lon-Farm", "Depuis le Ranch Lon Lon", ENTR_HYRULE_FIELD_6, 0 }, + { "Near Drawbridge", "Nahe der Zugbruecke", "Pres du Pont-levis", ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN, 0 }, + { "From Drawbridge", "Von der Zugbruecke", "Depuis le Pont-levis", ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN, 0 }, + { "From Kakariko Village", "Von Kakariko", "Depuis le Village Cocorico", ENTR_HYRULE_FIELD_STAIRS_EXIT, 0 }, + { "From Zora River", "Vom Zora-Fluss", "Depuis la Riviere Zora", ENTR_HYRULE_FIELD_RIVER_EXIT, 0 }, + { "From Lost Woods", "Von den verlorenen Waeldern", "Depuis les Bois Perdus", ENTR_HYRULE_FIELD_WOODED_EXIT, 0 }, + { "From Lake Hylia", "Vom Hylia-See", "Depuis le Lac Hylia", ENTR_HYRULE_FIELD_FENCE_EXIT, 0 }, + { "From Gerudo Valley", "Vom Gerudotal", "Depuis la Vallee Gerudo", ENTR_HYRULE_FIELD_ROCKY_PATH, 0 }, + { "From Lon Lon Ranch", "Von der Lon Lon-Farm", "Depuis le Ranch Lon Lon", ENTR_HYRULE_FIELD_CENTER_EXIT, 0 }, }}, { " 2:Kokiri Forest", " 2:Kokiri-Wald", " 2:Foret Kokiri", Select_LoadGame, 9, { - { "From Links House", "Von Links Haus", "Depuis la Cabane de Link", ENTR_KOKIRI_FOREST_3, 0 }, - { "From Bridge", "Von der Bruecke", "Depuis le Pont", ENTR_KOKIRI_FOREST_2, 0 }, - { "From Lost Woods", "Von den verlorenen Waeldern", "Depuis les Bois Perdus", ENTR_KOKIRI_FOREST_6, 0 }, - { "From Deku Tree", "Vom Deku-Baum", "Depuis l'Arbre Mojo", ENTR_KOKIRI_FOREST_1, 0 }, - { "From Kokiri Shop", "Vom Kokiri-Laden", "Depuis la Boutique Kokiri", ENTR_KOKIRI_FOREST_4, 0 }, - { "From Know-It-All Brothers House", "Vom Haus der Allwissenden Brueder", "Depuis la Cabane des Freres Je-Sais-Tout", ENTR_KOKIRI_FOREST_5, 0 }, - { "From Twins House", "Vom Haus der Zwillinge", "Depuis la Cabane des Jumeaux", ENTR_KOKIRI_FOREST_8, 0 }, - { "From Midos House", "Von Midos Haus", "Depuis la Cabane du Grand Mido", ENTR_KOKIRI_FOREST_9, 0 }, - { "From Sarias House", "Von Salias Haus", "Depuis la Cabane de Saria", ENTR_KOKIRI_FOREST_10, 0 }, + { "From Links House", "Von Links Haus", "Depuis la Cabane de Link", ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE, 0 }, + { "From Bridge", "Von der Bruecke", "Depuis le Pont", ENTR_KOKIRI_FOREST_LOWER_EXIT, 0 }, + { "From Lost Woods", "Von den verlorenen Waeldern", "Depuis les Bois Perdus", ENTR_KOKIRI_FOREST_UPPER_EXIT, 0 }, + { "From Deku Tree", "Vom Deku-Baum", "Depuis l'Arbre Mojo", ENTR_KOKIRI_FOREST_OUTSIDE_DEKU_TREE, 0 }, + { "From Kokiri Shop", "Vom Kokiri-Laden", "Depuis la Boutique Kokiri", ENTR_KOKIRI_FOREST_OUTSIDE_SHOP, 0 }, + { "From Know-It-All Brothers House", "Vom Haus der Allwissenden Brueder", "Depuis la Cabane des Freres Je-Sais-Tout", ENTR_KOKIRI_FOREST_OUTSIDE_KNOW_IT_ALL_HOUSE, 0 }, + { "From Twins House", "Vom Haus der Zwillinge", "Depuis la Cabane des Jumeaux", ENTR_KOKIRI_FOREST_OUTSIDE_TWINS_HOUSE, 0 }, + { "From Midos House", "Von Midos Haus", "Depuis la Cabane du Grand Mido", ENTR_KOKIRI_FOREST_OUTSIDE_MIDOS_HOUSE, 0 }, + { "From Sarias House", "Von Salias Haus", "Depuis la Cabane de Saria", ENTR_KOKIRI_FOREST_OUTSIDE_SARIAS_HOUSE, 0 }, }}, { " 3:Kokiri Buildings", " 3:Kokiri Gebaeude", " 3:Cabanes des Kokiris", Select_LoadGame, 6, { - { "Links Bed", "Links Bett", "Lit de Link", ENTR_LINKS_HOUSE_0, 0 }, + { "Links Bed", "Links Bett", "Lit de Link", ENTR_LINKS_HOUSE_CHILD_SPAWN, 0 }, { "Kokiri Shop", "Kokiri-Laden", "Boutique Kokiri", ENTR_KOKIRI_SHOP_0, 0 }, { "Twins House", "Haus der Zwillinge", "Cabane des Jumeaux", ENTR_TWINS_HOUSE_0, 0 }, { "Know-It-All Brothers House", "Haus der Allwissenden Brueder", "Cabane des Freres Je-Sais-Tout", ENTR_KNOW_IT_ALL_BROS_HOUSE_0, 0 }, @@ -288,41 +290,41 @@ static BetterSceneSelectEntry sBetterScenes[] = { { "Sarias House", "Salias Haus", "Cabane de Sara", ENTR_SARIAS_HOUSE_0, 0 }, }}, { " 4:Lost Woods", " 4:Verlorene Waelder", " 4:Bois Perdus", Select_LoadGame, 5, { - { "From Kokiri Forest", "Vom Kokiri-Wald", "Depuis la Foret Kokiri", ENTR_LOST_WOODS_0, 0 }, - { "From Sacred Meadow", "Von der Waldlichtung", "Depuis le Bosquet Sacre", ENTR_LOST_WOODS_1, 0 }, - { "From Goron City", "Vom Goronia", "Depuis le Village Goron", ENTR_LOST_WOODS_6, 0 }, - { "From Zora River", "Vom Zora-Fluss", "Depuis la Riviere Zora", ENTR_LOST_WOODS_7, 0 }, - { "Bridge", "Bruecke", "Pont", ENTR_LOST_WOODS_9, 0 }, + { "From Kokiri Forest", "Vom Kokiri-Wald", "Depuis la Foret Kokiri", ENTR_LOST_WOODS_SOUTH_EXIT, 0 }, + { "From Sacred Meadow", "Von der Waldlichtung", "Depuis le Bosquet Sacre", ENTR_LOST_WOODS_NORTH_EXIT, 0 }, + { "From Goron City", "Vom Goronia", "Depuis le Village Goron", ENTR_LOST_WOODS_TUNNEL_SHORTCUT, 0 }, + { "From Zora River", "Vom Zora-Fluss", "Depuis la Riviere Zora", ENTR_LOST_WOODS_UNDERWATER_SHORTCUT, 0 }, + { "Bridge", "Bruecke", "Pont", ENTR_LOST_WOODS_BRIDGE_EAST_EXIT, 0 }, }}, { " 5:Sacred Forest Meadow", " 5:Waldlichtung", " 5:Bosquet Sacre", Select_LoadGame, 3, { - { "From Lost Woods", "Von den Verlorenen Waeldern", "Depuis les Bois Perdus", ENTR_SACRED_FOREST_MEADOW_0, 0 }, - { "From Forest Temple", "Vom Waldtempel", "Depuis le Temple de la Foret", ENTR_SACRED_FOREST_MEADOW_1, 0 }, - { "Minuet of Forest Warp", "Menuett des Waldes Teleport", "Teleporteur du Menuet des Bois", ENTR_SACRED_FOREST_MEADOW_2, 0 }, + { "From Lost Woods", "Von den Verlorenen Waeldern", "Depuis les Bois Perdus", ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT, 0 }, + { "From Forest Temple", "Vom Waldtempel", "Depuis le Temple de la Foret", ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE, 0 }, + { "Minuet of Forest Warp", "Menuett des Waldes Teleport", "Teleporteur du Menuet des Bois", ENTR_SACRED_FOREST_MEADOW_WARP_PAD, 0 }, }}, { " 6:Castle Town Entrance", " 6:Eingang zum Marktplatz", " 6:Entree du Bourg d'Hyrule", Select_LoadGame, 3, { - { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_MARKET_ENTRANCE_DAY_1, 0 }, - { "From Market", "Vom Marktplatz", "Depuis la Place du Marche", ENTR_MARKET_ENTRANCE_DAY_0, 0 }, - { "From Pot House", "Vom Wachposten", "Depuis la Maison des Jarres", ENTR_MARKET_ENTRANCE_DAY_2, 0 }, + { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT, 0 }, + { "From Market", "Vom Marktplatz", "Depuis la Place du Marche", ENTR_MARKET_ENTRANCE_NORTH_EXIT, 0 }, + { "From Pot House", "Vom Wachposten", "Depuis la Maison des Jarres", ENTR_MARKET_ENTRANCE_OUTSIDE_GUARD_HOUSE, 0 }, }}, { " 7:Market", " 7:Marktplatz", " 7:Place du Marche", Select_LoadGame, 11, { - { "From Castle Town Entrance", "Vom Eingang zum Marktplatz", "Depuis l'Entree du Bourg d'Hyrule", ENTR_MARKET_DAY_0, 0 }, - { "From Shooting Gallery", "Von der Schiessbude", "Depuis le Jeu d'adresse", ENTR_MARKET_DAY_8, 0 }, - { "From Happy Mask Shop", "Vom Maskenhaendler", "Depuis la Foire aux Masques", ENTR_MARKET_DAY_9, 0 }, - { "From Treasure Box Minigame", "Von der Truhenlotterie", "Depuis le Bowling Teigneux", ENTR_MARKET_DAY_10, 0 }, - { "From Castle", "Vom Schloss", "Depuis le Chateau d'Hyrule", ENTR_MARKET_DAY_1, 0 }, - { "From Temple of Time", "Von der Zitadelle der Zeit", "Depuis le Temple du Temps", ENTR_MARKET_DAY_2, 0 }, + { "From Castle Town Entrance", "Vom Eingang zum Marktplatz", "Depuis l'Entree du Bourg d'Hyrule", ENTR_MARKET_SOUTH_EXIT, 0 }, + { "From Shooting Gallery", "Von der Schiessbude", "Depuis le Jeu d'adresse", ENTR_MARKET_DAY_OUTSIDE_SHOOTING_GALLERY, 0 }, + { "From Happy Mask Shop", "Vom Maskenhaendler", "Depuis la Foire aux Masques", ENTR_MARKET_DAY_OUTSIDE_HAPPY_MASK_SHOP, 0 }, + { "From Treasure Box Minigame", "Von der Truhenlotterie", "Depuis le Bowling Teigneux", ENTR_MARKET_DAY_OUTSIDE_TREASURE_BOX_SHOP, 0 }, + { "From Castle", "Vom Schloss", "Depuis le Chateau d'Hyrule", ENTR_MARKET_DAY_CASTLE_EXIT, 0 }, + { "From Temple of Time", "Von der Zitadelle der Zeit", "Depuis le Temple du Temps", ENTR_MARKET_DAY_TEMPLE_EXIT, 0 }, { "From Back Alley (Right)", "Von der Seitenstrasse (Rechts)", "Depuis la Ruelle (Droite)", ENTR_MARKET_DAY_3, 0 }, { "From Back Alley (Left)", "Von der Seitenstrasse (Links)", "Depuis la Ruelle (Gauche)", ENTR_MARKET_DAY_4, 0 }, - { "From Potion Shop", "Vom Magie-Laden", "Depuis l'Apothicaire", ENTR_MARKET_DAY_5, 0 }, - { "From Bazaar Shop", "Vom Basar", "Depuis le Bazar", ENTR_MARKET_DAY_6, 0 }, - { "From Bomchu Bowling Minigame", "Von der Minenbowlingbahn", "Depuis le Bowling Teigneux", ENTR_MARKET_DAY_7, 0 }, + { "From Potion Shop", "Vom Magie-Laden", "Depuis l'Apothicaire", ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP, 0 }, + { "From Bazaar Shop", "Vom Basar", "Depuis le Bazar", ENTR_MARKET_DAY_OUTSIDE_BAZAAR, 0 }, + { "From Bomchu Bowling Minigame", "Von der Minenbowlingbahn", "Depuis le Bowling Teigneux", ENTR_MARKET_DAY_OUTSIDE_BOMBCHU_BOWLING, 0 }, }}, { " 8:Castle Town Alley", " 8:Seitenstrasse", " 8:Ruelle du Bourg d'Hyrule", Select_LoadGame, 5, { { "From Market (Right)", "Vom Marktplatz (Rechts)", "Depuis la Place du Marche (Droite)", ENTR_BACK_ALLEY_DAY_0, 0 }, { "From Market (Left)", "Vom Marktplatz (Links)", "Depuis la Place du Marche (Gauche)", ENTR_BACK_ALLEY_DAY_1, 0 }, - { "From Alley House", "Vom Seitenstrassenhaus", "Depuis la Maison de la Ruelle", ENTR_BACK_ALLEY_DAY_3, 0 }, + { "From Alley House", "Vom Seitenstrassenhaus", "Depuis la Maison de la Ruelle", ENTR_BACK_ALLEY_DAY_OUTSIDE_MAN_IN_GREEN_HOUSE, 0 }, { "From Dog House", "Vom Haus der Hunde-Dame", "Depuis la Maison du Chien", ENTR_BACK_ALLEY_DAY_4, 0 }, - { "From Bombchu Shop", "Vom Krabbelminen-Laden", "Depuis le Magasin de Missiles", ENTR_BACK_ALLEY_DAY_2, 0 }, + { "From Bombchu Shop", "Vom Krabbelminen-Laden", "Depuis le Magasin de Missiles", ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP, 0 }, }}, { " 9:Castle Town Buildings", " 9:Marktplatz Gebaeude", " 9:Batiments du Bourg d'Hyrule", Select_LoadGame, 10, { { "Pot House", "Wachposten", "Maison des Jarres", ENTR_MARKET_GUARD_HOUSE_0, 0 }, @@ -334,21 +336,21 @@ static BetterSceneSelectEntry sBetterScenes[] = { { "Happy Mask Shop", "Maskenhaendler", "Foire aux Masques", ENTR_HAPPY_MASK_SHOP_0, 0 }, { "Bombchu Shop", "Krabbelminen-Laden", "Boutique de Missiles", ENTR_BOMBCHU_SHOP_1, 0 }, { "Dog House", "Haus der Hunde-Dame", "Maison du Chien", ENTR_DOG_LADY_HOUSE_0, 0 }, - { "Alley House", "Seitenstrassenhaus", "Maison de la Ruelle", ENTR_BACK_ALLEY_HOUSE_0, 0 }, + { "Alley House", "Seitenstrassenhaus", "Maison de la Ruelle", ENTR_BACK_ALLEY_MAN_IN_GREEN_HOUSE, 0 }, }}, { "10:Temple of Time", "10:Zitadelle der Zeit", "10:Temple du Temps", Select_LoadGame, 5, { - { "From Outside", "Von draussen", "Depuis l'Entree", ENTR_TEMPLE_OF_TIME_0, 0 }, + { "From Outside", "Von draussen", "Depuis l'Entree", ENTR_TEMPLE_OF_TIME_ENTRANCE, 0 }, { "From Master Sword Pedestal", "Vom Podest des Master-Schwerts", "Depuis le Piedestal de l'Epee de Legende", ENTR_TEMPLE_OF_TIME_2, 0 }, - { "Prelude of Light Warp", "Kantate des Lichts Teleport", "Teleporteur du Prelude de la Lumiere", ENTR_TEMPLE_OF_TIME_7, 0 }, - { "Outside Temple of Time - From Market", "Vor der Zitadelle der Zeit - Vom Marktplatz", "Exterieur du Temple - Depuis la Place du Marche", ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_0, 0 }, - { "Outside Temple of Time - From Temple of Time", "Vor der Zitadelle der Zeit - Von der Zitadelle der Zeit", "Exterieur du Temple - Depuis le Temple", ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_1, 0 }, + { "Prelude of Light Warp", "Kantate des Lichts Teleport", "Teleporteur du Prelude de la Lumiere", ENTR_TEMPLE_OF_TIME_WARP_PAD, 0 }, + { "Outside Temple of Time - From Market", "Vor der Zitadelle der Zeit - Vom Marktplatz", "Exterieur du Temple - Depuis la Place du Marche", ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT, 0 }, + { "Outside Temple of Time - From Temple of Time", "Vor der Zitadelle der Zeit - Von der Zitadelle der Zeit", "Exterieur du Temple - Depuis le Temple", ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE, 0 }, }}, { "11:Hyrule Castle", "11:Schloss Hyrule", "11:Chateau d'Hyrule", Select_LoadGame, 5, { - { "From Market", "Vom Marktplatz", "Depuis la Place du Marche", ENTR_HYRULE_CASTLE_0, 0 }, - { "From Castle Courtyard", "Vom Burghof", "Depuis la Cour du Chateau", ENTR_HYRULE_CASTLE_1, 0 }, - { "From Great Fairy", "Von der Feen-Quelle", "Depuis la Grande Fee", ENTR_HYRULE_CASTLE_2, 0 }, + { "From Market", "Vom Marktplatz", "Depuis la Place du Marche", ENTR_CASTLE_GROUNDS_SOUTH_EXIT, 0 }, + { "From Castle Courtyard", "Vom Burghof", "Depuis la Cour du Chateau", ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT, 0 }, + { "From Great Fairy", "Von der Feen-Quelle", "Depuis la Grande Fee", ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT, 0 }, { "From Courtyard Guard Capture", "Von der Wachen-Festnahme", "Depuis la capture d'un Garde de la Cour", ENTR_HYRULE_CASTLE_3, 0 }, - { "Great Fairy", "Feen-Quelle", "Grande Fee", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2, 0 }, + { "Great Fairy", "Feen-Quelle", "Grande Fee", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC, 0 }, }}, { "12:Hyrule Castle Courtyard", "12:Burghof", "12:Cour du Chateau", Select_LoadGame, 3, { { "From Crawlspace", "Vom Kriechtunnel", "Depuis l'Entree", ENTR_CASTLE_COURTYARD_GUARDS_DAY_0, 0 }, @@ -356,129 +358,129 @@ static BetterSceneSelectEntry sBetterScenes[] = { { "Zeldas Courtyard", "Zeldas Burghof", "Depuis la Cour de Zelda", ENTR_CASTLE_COURTYARD_ZELDA_0, 0 }, }}, { "13:Lon Lon Ranch", "13:Lon Lon-Farm", "13:Ranch Lon Lon", Select_LoadGame, 5, { - { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_LON_LON_RANCH_0, 0 }, - { "From Ranch House", "Vom Farmhaus", "Depuis la Maison du Ranch", ENTR_LON_LON_RANCH_4, 0 }, - { "From Stables", "Vom Stall", "Depuis l'Etable", ENTR_LON_LON_RANCH_5, 0 }, - { "From Back Tower", "Vom Silo", "Depuis Silo du Ranch", ENTR_LON_LON_RANCH_10, 0 }, + { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_LON_LON_RANCH_ENTRANCE, 0 }, + { "From Ranch House", "Vom Farmhaus", "Depuis la Maison du Ranch", ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE, 0 }, + { "From Stables", "Vom Stall", "Depuis l'Etable", ENTR_LON_LON_RANCH_OUTSIDE_STABLES, 0 }, + { "From Back Tower", "Vom Silo", "Depuis Silo du Ranch", ENTR_LON_LON_RANCH_OUTSIDE_TOWER, 0 }, { "Epona Song Cutscene", "Eponas Song Sequenz", "Cinematique du Chant d'Epona", ENTR_LON_LON_RANCH_1, 0 }, }}, { "14:Lon Lon Ranch Buildings", "14:Lon Lon-Farm Gebaeude", "14:Batiments du Ranch Lon Lon", Select_LoadGame, 3, { - { "Ranch House", "Farmhaus", "Maison du Ranch", ENTR_LON_LON_BUILDINGS_0, 0 }, + { "Ranch House", "Farmhaus", "Maison du Ranch", ENTR_LON_LON_BUILDINGS_TALONS_HOUSE, 0 }, { "Stables", "Stall", "Etable du Ranch", ENTR_STABLE_0, 0 }, - { "Back Tower", "Silo", "Silo du Ranch", ENTR_LON_LON_BUILDINGS_1, 0 }, + { "Back Tower", "Silo", "Silo du Ranch", ENTR_LON_LON_BUILDINGS_TOWER, 0 }, }}, { "15:Kakariko Village", "15:Kakariko", "15:Village Cocorico", Select_LoadGame, 15, { - { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_KAKARIKO_VILLAGE_0, 0 }, - { "From Death Mountain", "Vom Todesberg", "Depuis le Mont du Peril", ENTR_KAKARIKO_VILLAGE_1, 0 }, - { "From Graveyard", "Vom Friedhof", "Depuis le Cimetiere", ENTR_KAKARIKO_VILLAGE_2, 0 }, - { "From Bazaar", "Vom Basar", "Depuis le Bazar", ENTR_KAKARIKO_VILLAGE_3, 0 }, - { "From Bottom of Well", "Vom Grund des Brunnens", "Depuis le Puits", ENTR_KAKARIKO_VILLAGE_4, 0 }, - { "From Boss House", "Vom Haus des Bosses", "Depuis la Maison du Boss", ENTR_KAKARIKO_VILLAGE_6, 0 }, - { "From Potion Shop", "Vom Magie-Laden", "Depuis l'Apothicaire", ENTR_KAKARIKO_VILLAGE_9, 0 }, - { "From Potion Shop (Back Entrance)", "Vom Magie-Laden (Hintereingang)", "Depuis l'Apothicaire (Entree Arriere)", ENTR_KAKARIKO_VILLAGE_12, 0 }, - { "From Grannys Potion Shop", "Von Omas Magie-Laden", "Depuis l'Apothicaire (Vieille Femme)", ENTR_KAKARIKO_VILLAGE_7, 0 }, - { "From Impas House", "Von Impas Haus", "Depuis la Maison d'Impa", ENTR_KAKARIKO_VILLAGE_5, 0 }, - { "From Impas House (Cow)", "Von Impas Haus (Kuh)", "Depuis la Maison d'Impa (Vache)", ENTR_KAKARIKO_VILLAGE_15, 0 }, - { "From Windmill", "Von der Windmuehle", "Depuis le Moulin", ENTR_KAKARIKO_VILLAGE_8, 0 }, - { "From Shooting Gallery", "Von der Schiessbude", "Depuis le Jeu d'adresse", ENTR_KAKARIKO_VILLAGE_10, 0 }, - { "From Skulltula House", "Vom Haus der Skulltulas", "Depuis la Maison des Skulltulas", ENTR_KAKARIKO_VILLAGE_11, 0 }, - { "Owl Drop Spot from Death Mountain", "Eulen-Absetzpunkt vom Todesberg", "Point de chute du Hibou depuis le Mont du Peril", ENTR_KAKARIKO_VILLAGE_14, 0 }, + { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_KAKARIKO_VILLAGE_FRONT_GATE, 0 }, + { "From Death Mountain", "Vom Todesberg", "Depuis le Mont du Peril", ENTR_KAKARIKO_VILLAGE_GUARD_GATE, 0 }, + { "From Graveyard", "Vom Friedhof", "Depuis le Cimetiere", ENTR_KAKARIKO_VILLAGE_SOUTHEAST_EXIT, 0 }, + { "From Bazaar", "Vom Basar", "Depuis le Bazar", ENTR_KAKARIKO_VILLAGE_OUTSIDE_BAZAAR, 0 }, + { "From Bottom of Well", "Vom Grund des Brunnens", "Depuis le Puits", ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL, 0 }, + { "From Boss House", "Vom Haus des Bosses", "Depuis la Maison du Boss", ENTR_KAKARIKO_VILLAGE_OUTSIDE_CENTER_GUEST_HOUSE, 0 }, + { "From Potion Shop", "Vom Magie-Laden", "Depuis l'Apothicaire", ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_FRONT, 0 }, + { "From Potion Shop (Back Entrance)", "Vom Magie-Laden (Hintereingang)", "Depuis l'Apothicaire (Entree Arriere)", ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_BACK, 0 }, + { "From Grannys Potion Shop", "Von Omas Magie-Laden", "Depuis l'Apothicaire (Vieille Femme)", ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOP_GRANNY, 0 }, + { "From Impas House", "Von Impas Haus", "Depuis la Maison d'Impa", ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_FRONT, 0 }, + { "From Impas House (Cow)", "Von Impas Haus (Kuh)", "Depuis la Maison d'Impa (Vache)", ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_BACK, 0 }, + { "From Windmill", "Von der Windmuehle", "Depuis le Moulin", ENTR_KAKARIKO_VILLAGE_OUTSIDE_WINDMILL, 0 }, + { "From Shooting Gallery", "Von der Schiessbude", "Depuis le Jeu d'adresse", ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY, 0 }, + { "From Skulltula House", "Vom Haus der Skulltulas", "Depuis la Maison des Skulltulas", ENTR_KAKARIKO_VILLAGE_OUTSIDE_SKULKLTULA_HOUSE, 0 }, + { "Owl Drop Spot from Death Mountain", "Eulen-Absetzpunkt vom Todesberg", "Point de chute du Hibou depuis le Mont du Peril", ENTR_KAKARIKO_VILLAGE_OWL_DROP, 0 }, }}, { "16:Kakariko Buildings", "16:Kakariko Gebaeude", "16:Batiments du Village Cocorico", Select_LoadGame, 9, { { "Shooting Gallery Minigame", "Schiessbude", "Jeu d'adresse", ENTR_SHOOTING_GALLERY_0, 0 }, { "Grannys Potion Shop", "Omas Magie-Laden", "Apothicaire (Vieille Femme)", ENTR_POTION_SHOP_GRANNY_0, 0 }, { "Bazaar Shop", "Basar", "Bazar", ENTR_BAZAAR_0, 0 }, - { "Potion Shop", "Magie-Laden", "Apothicaire", ENTR_POTION_SHOP_KAKARIKO_0, 0 }, - { "Impas House", "Impas Haus", "Maison d'Impa", ENTR_IMPAS_HOUSE_0, 0 }, - { "Impas House (Near Cow)", "Impas Haus (Kuh)", "Maison d'Impa (Vache)", ENTR_IMPAS_HOUSE_1, 0 }, + { "Potion Shop", "Magie-Laden", "Apothicaire", ENTR_POTION_SHOP_KAKARIKO_FRONT, 0 }, + { "Impas House", "Impas Haus", "Maison d'Impa", ENTR_IMPAS_HOUSE_FRONT, 0 }, + { "Impas House (Near Cow)", "Impas Haus (Kuh)", "Maison d'Impa (Vache)", ENTR_IMPAS_HOUSE_BACK, 0 }, { "Boss House", "Haus des Bosses", "Maison du Boss", ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0, 0 }, - { "Windmill", "Windmuehle", "Moulin", ENTR_WINDMILL_AND_DAMPES_GRAVE_1, 0 }, + { "Windmill", "Windmuehle", "Moulin", ENTR_WINDMILL_AND_DAMPES_GRAVE_WINDMILL, 0 }, { "Skulltula House", "Haus der Skulltulas", "Maison des Skulltulas", ENTR_HOUSE_OF_SKULLTULA_0, 0 }, }}, { "17:Graveyard", "17:Friedhof", "17:Cimetiere", Select_LoadGame, 9, { - { "From Kakariko", "Von Kakariko", "Depuis l'Apothicaire", ENTR_GRAVEYARD_0, 0 }, - { "From Shadow Temple", "Vom Schattentempel", "Depuis le Temple de l'Ombre", ENTR_GRAVEYARD_1, 0 }, - { "From Gravekeepers Hut", "Von der Huette des Totengraebers", "Depuis la Cabane du Fossoyeur", ENTR_GRAVEYARD_2, 0 }, - { "From Dampes Grave", "Von Boris' Grab", "Depuis la Tombe d'Igor", ENTR_GRAVEYARD_3, 0 }, - { "From Shield Grave", "Vom Schild-Grab", "Depuis la Tombe au Bouclier", ENTR_GRAVEYARD_4, 0 }, - { "From Redead Grave", "Vom Zombie-Grab", "Depuis la Tombe au Effrois", ENTR_GRAVEYARD_5, 0 }, - { "From Royal Familys Tomb", "Vom Koenigsgrab", "Depuis la Tombe Royale", ENTR_GRAVEYARD_6, 0 }, + { "From Kakariko", "Von Kakariko", "Depuis l'Apothicaire", ENTR_GRAVEYARD_ENTRANCE, 0 }, + { "From Shadow Temple", "Vom Schattentempel", "Depuis le Temple de l'Ombre", ENTR_GRAVEYARD_OUTSIDE_TEMPLE, 0 }, + { "From Gravekeepers Hut", "Von der Huette des Totengraebers", "Depuis la Cabane du Fossoyeur", ENTR_GRAVEYARD_OUTSIDE_DAMPES_HUT, 0 }, + { "From Dampes Grave", "Von Boris' Grab", "Depuis la Tombe d'Igor", ENTR_GRAVEYARD_DAMPES_GRAVE_EXIT, 0 }, + { "From Shield Grave", "Vom Schild-Grab", "Depuis la Tombe au Bouclier", ENTR_GRAVEYARD_SHIELD_GRAVE_EXIT, 0 }, + { "From Redead Grave", "Vom Zombie-Grab", "Depuis la Tombe au Effrois", ENTR_GRAVEYARD_HEART_PIECE_GRAVE_EXIT, 0 }, + { "From Royal Familys Tomb", "Vom Koenigsgrab", "Depuis la Tombe Royale", ENTR_GRAVEYARD_ROYAL_TOMB_EXIT, 0 }, { "Inside Dampe's Hut", "Huette des Totengraebers", "A l'interieur de la Cabane du Fossoyeur", ENTR_GRAVEKEEPERS_HUT_0, 0 }, - { "Nocturne of Shadow Warp", "Nocturne des Schattens Teleport", "Teleporteur du Nocturne de l'Ombre", ENTR_GRAVEYARD_7, 0 }, + { "Nocturne of Shadow Warp", "Nocturne des Schattens Teleport", "Teleporteur du Nocturne de l'Ombre", ENTR_GRAVEYARD_WARP_PAD, 0 }, }}, { "18:Graves", "18:Graeber", "18:Tombes", Select_LoadGame, 5, { - { "Dampes Grave Minigame", "Boris' Grab-Minispiel", "Tour du Cimetiere d'Igor", ENTR_WINDMILL_AND_DAMPES_GRAVE_0, 0 }, + { "Dampes Grave Minigame", "Boris' Grab-Minispiel", "Tour du Cimetiere d'Igor", ENTR_WINDMILL_AND_DAMPES_GRAVE_GRAVE, 0 }, { "Royal Familys Tomb", "Koenigsgrab", "Tombe Royale", ENTR_ROYAL_FAMILYS_TOMB_0, 0 }, { "Royal Familys Tomb, Suns Song Cutscene", "Koenigsgrab, Hymne der Sonne Sequenz", "Tombe Royale, Cinematique du Chant du Soleil", ENTR_ROYAL_FAMILYS_TOMB_1, 0 }, { "Treasure Chest Grave", "Schatzkisten Grab", "Tombe au Coffre", ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0, 0 }, { "ReDead Grave", "Zombie Grab", "Tombe au Effrois", ENTR_REDEAD_GRAVE_0, 0 }, }}, { "19:Death Mountain Trail", "19:Gebirgspfad", "19:Mont du Peril", Select_LoadGame, 6, { - { "From Kakariko Village", "Von Kakariko", "Depuis le Village Cocorico", ENTR_DEATH_MOUNTAIN_TRAIL_0, 0 }, - { "From Goron City", "Von Goronia", "Depuis le Village Goron", ENTR_DEATH_MOUNTAIN_TRAIL_1, 0 }, - { "From Death Mountain Crater", "Vom Todeskrater", "Depuis le Cratere du Peril", ENTR_DEATH_MOUNTAIN_TRAIL_2, 0 }, - { "From Dodongos Cavern", "Von Dodongos Hoehle", "Depuis la Caverne Dodongo", ENTR_DEATH_MOUNTAIN_TRAIL_3, 0 }, - { "From Great Fairy", "Von der Feen-Quelle", "Depuis la Grande Fee", ENTR_DEATH_MOUNTAIN_TRAIL_4, 0 }, - { "Great Fairy", "Feen-Quelle", "Grande Fee", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0, 0 }, + { "From Kakariko Village", "Von Kakariko", "Depuis le Village Cocorico", ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT, 0 }, + { "From Goron City", "Von Goronia", "Depuis le Village Goron", ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT, 0 }, + { "From Death Mountain Crater", "Vom Todeskrater", "Depuis le Cratere du Peril", ENTR_DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT, 0 }, + { "From Dodongos Cavern", "Von Dodongos Hoehle", "Depuis la Caverne Dodongo", ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN, 0 }, + { "From Great Fairy", "Von der Feen-Quelle", "Depuis la Grande Fee", ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT, 0 }, + { "Great Fairy", "Feen-Quelle", "Grande Fee", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT, 0 }, }}, { "20:Goron City", "20:Goronia", "20:Village Goron", Select_LoadGame, 5, { - { "From Death Mountain Trail", "Vom Gebirgspfad", "Depuis le Mont du Peril", ENTR_GORON_CITY_0, 0 }, - { "From Death Mountain Crater", "Vom Todeskrater", "Depuis le Cratere du Peril", ENTR_GORON_CITY_1, 0 }, - { "From Goron City Shop", "Vom Goronen-Laden", "Depuis la Boutique Goron", ENTR_GORON_CITY_2, 0 }, - { "From Lost Woods", "Von den Verlorenen Waeldern", "Depuis les Bois Perdus", ENTR_GORON_CITY_3, 0 }, + { "From Death Mountain Trail", "Vom Gebirgspfad", "Depuis le Mont du Peril", ENTR_GORON_CITY_UPPER_EXIT, 0 }, + { "From Death Mountain Crater", "Vom Todeskrater", "Depuis le Cratere du Peril", ENTR_GORON_CITY_DARUNIA_ROOM_EXIT, 0 }, + { "From Goron City Shop", "Vom Goronen-Laden", "Depuis la Boutique Goron", ENTR_GORON_CITY_OUTSIDE_SHOP, 0 }, + { "From Lost Woods", "Von den Verlorenen Waeldern", "Depuis les Bois Perdus", ENTR_GORON_CITY_TUNNEL_SHORTCUT, 0 }, { "Goron City Shop", "Goronen-Laden", "Boutique Goron", ENTR_GORON_SHOP_0, 0 }, }}, { "21:Death Mountain Crater", "21:Todeskrater", "21:Cratere du Peril", Select_LoadGame, 6, { - { "From Death Mountain Trail", "Vom Gebirgspfad", "Depuis le Mont du Peril", ENTR_DEATH_MOUNTAIN_CRATER_0, 0 }, - { "From Goron City", "Von Goronia", "Depuis le Village Goron", ENTR_DEATH_MOUNTAIN_CRATER_1, 0 }, - { "From Fire Temple", "Vom Feuertempel", "Depuis le Temple du Feu", ENTR_DEATH_MOUNTAIN_CRATER_2, 0 }, - { "From Fairy Fountain", "Von der Feen-Quelle", "Depuis la Fontaine des Fees", ENTR_DEATH_MOUNTAIN_CRATER_3, 0 }, - { "Great Fairy", "Feen-Quelle", "Depuis la Grande Fee", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1, 0 }, - { "Bolero of Fire Warp", "Bolero des Feuers Teleport", "Teleporteur du Bolero du Feu", ENTR_DEATH_MOUNTAIN_CRATER_4, 0 }, + { "From Death Mountain Trail", "Vom Gebirgspfad", "Depuis le Mont du Peril", ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT, 0 }, + { "From Goron City", "Von Goronia", "Depuis le Village Goron", ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT, 0 }, + { "From Fire Temple", "Vom Feuertempel", "Depuis le Temple du Feu", ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE, 0 }, + { "From Fairy Fountain", "Von der Feen-Quelle", "Depuis la Fontaine des Fees", ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT, 0 }, + { "Great Fairy", "Feen-Quelle", "Depuis la Grande Fee", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC, 0 }, + { "Bolero of Fire Warp", "Bolero des Feuers Teleport", "Teleporteur du Bolero du Feu", ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, 0 }, }}, { "22:Zora River", "22:Zora-Fluss", "22:Riviere Zora", Select_LoadGame, 3, { - { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_ZORAS_RIVER_0, 0 }, - { "From Zoras Domain", "Von Zoras Reich", "Depuis le Domaine Zora", ENTR_ZORAS_RIVER_2, 0 }, - { "From Lost Woods", "Von den Verlorenen Waeldern", "Depuis les Bois Perdus", ENTR_ZORAS_RIVER_4, 0 }, + { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_ZORAS_RIVER_WEST_EXIT, 0 }, + { "From Zoras Domain", "Von Zoras Reich", "Depuis le Domaine Zora", ENTR_ZORAS_RIVER_WATERFALL_EXIT, 0 }, + { "From Lost Woods", "Von den Verlorenen Waeldern", "Depuis les Bois Perdus", ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT, 0 }, }}, { "23:Zoras Domain", "23:Zoras Reich", "23:Domaine Zora", Select_LoadGame, 5, { - { "From Zora River", "Vom Zora-Fluss", "Depuis la Riviere Zora", ENTR_ZORAS_DOMAIN_0, 0 }, - { "From Zoras Fountain", "Von Zoras Quelle", "Depuis la Fontaine Zora", ENTR_ZORAS_DOMAIN_1, 0 }, - { "From Lake Hylia", "Vom Hylia-See", "Depuis le Lac Hylia", ENTR_ZORAS_DOMAIN_4, 0 }, - { "From Zora Shop", "Vom Zora-Laden", "Depuis la Boutique Zora", ENTR_ZORAS_DOMAIN_2, 0 }, + { "From Zora River", "Vom Zora-Fluss", "Depuis la Riviere Zora", ENTR_ZORAS_DOMAIN_ENTRANCE, 0 }, + { "From Zoras Fountain", "Von Zoras Quelle", "Depuis la Fontaine Zora", ENTR_ZORAS_DOMAIN_KING_ZORA_EXIT, 0 }, + { "From Lake Hylia", "Vom Hylia-See", "Depuis le Lac Hylia", ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT, 0 }, + { "From Zora Shop", "Vom Zora-Laden", "Depuis la Boutique Zora", ENTR_ZORAS_DOMAIN_OUTSIDE_SHOP, 0 }, { "Zora Shop", "Zora-Laden", "Boutique Zora", ENTR_ZORA_SHOP_0, 0 }, }}, { "24:Zoras Fountain", "24:Zoras Quelle", "24:Fontaine Zora", Select_LoadGame, 5, { - { "From Zoras Domain", "Von Zoras Reich", "Depuis le Domaine Zora", ENTR_ZORAS_FOUNTAIN_2, 0 }, - { "From Jabu Jabu", "Von Jabu-Jabu", "Depuis Jabu-Jabu", ENTR_ZORAS_FOUNTAIN_1, 0 }, - { "From Ice Cavern", "Von der Eishoehle", "Depuis la Caverne Polaire", ENTR_ZORAS_FOUNTAIN_3, 0 }, - { "From Fairy Fountain", "Von der Feen-Quelle", "Depuis la Fontaine des Fees", ENTR_ZORAS_FOUNTAIN_5, 0 }, - { "Great Fairy", "Feen-Quelle", "Grande Fee", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0, 0 }, + { "From Zoras Domain", "Von Zoras Reich", "Depuis le Domaine Zora", ENTR_ZORAS_FOUNTAIN_TUNNEL_EXIT, 0 }, + { "From Jabu Jabu", "Von Jabu-Jabu", "Depuis Jabu-Jabu", ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU, 0 }, + { "From Ice Cavern", "Von der Eishoehle", "Depuis la Caverne Polaire", ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN, 0 }, + { "From Fairy Fountain", "Von der Feen-Quelle", "Depuis la Fontaine des Fees", ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY, 0 }, + { "Great Fairy", "Feen-Quelle", "Grande Fee", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF, 0 }, }}, { "25:Lake Hylia", "25:Hylia-See", "25:Lac Hylia", Select_LoadGame, 7, { - { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_LAKE_HYLIA_0, 0 }, - { "From Gerudo Valley", "Vom Gerudotal", "Depuis la Vallee Gerudo", ENTR_LAKE_HYLIA_1, 0 }, - { "From Water Temple", "Vom Wassertempel", "Depuis le Temple de l'Eau", ENTR_LAKE_HYLIA_2, 0 }, - { "From Fishing Pond", "Vom Fischweiher", "Depuis l'Etang", ENTR_LAKE_HYLIA_6, 0 }, - { "From Laboratory", "Vom Laboratorium", "Depuis le Laboratoire du Lac", ENTR_LAKE_HYLIA_4, 0 }, - { "From Zoras Domain", "Von Zoras Reich", "Depuis le Domaine Zora", ENTR_LAKE_HYLIA_7, 0 }, - { "Serenade Of Water Warp", "Serenade des Wassers Teleport", "Teleporteur de la Serenade de l'Eau", ENTR_LAKE_HYLIA_8, 0 }, + { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_LAKE_HYLIA_NORTH_EXIT, 0 }, + { "From Gerudo Valley", "Vom Gerudotal", "Depuis la Vallee Gerudo", ENTR_LAKE_HYLIA_RIVER_EXIT, 0 }, + { "From Water Temple", "Vom Wassertempel", "Depuis le Temple de l'Eau", ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE, 0 }, + { "From Fishing Pond", "Vom Fischweiher", "Depuis l'Etang", ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND, 0 }, + { "From Laboratory", "Vom Laboratorium", "Depuis le Laboratoire du Lac", ENTR_LAKE_HYLIA_OUTSIDE_LAB, 0 }, + { "From Zoras Domain", "Von Zoras Reich", "Depuis le Domaine Zora", ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT, 0 }, + { "Serenade Of Water Warp", "Serenade des Wassers Teleport", "Teleporteur de la Serenade de l'Eau", ENTR_LAKE_HYLIA_WARP_PAD, 0 }, }}, { "26:Lake Hylia Buildings", "26:Hylia-See Gebaeude", "26:Batiments du Lac Hylia", Select_LoadGame, 2, { { "Laboratory", "Laboratorium", "Laboratoire du Lac", ENTR_LAKESIDE_LABORATORY_0, 0 }, { "Fishing Pond Minigame", "Fischweiher", "Etang", ENTR_FISHING_POND_0, 0 }, }}, { "27:Gerudo Valley", "27:Gerudotal", "27:Vallee Gerudo", Select_LoadGame, 5, { - { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_GERUDO_VALLEY_0, 0 }, - { "From Gerudo Fortress", "Von der Gerudo-Festung", "Depuis la Forteresse Gerudo", ENTR_GERUDO_VALLEY_3, 0 }, - { "From Carpenter's Tent", "Vom Zelt der Zimmerleute", "Depuis la Tente du Charpentier", ENTR_GERUDO_VALLEY_4, 0 }, + { "From Hyrule Field", "Von der Hylianischen Steppe", "Depuis la Plaine d'Hyrule", ENTR_GERUDO_VALLEY_EAST_EXIT, 0 }, + { "From Gerudo Fortress", "Von der Gerudo-Festung", "Depuis la Forteresse Gerudo", ENTR_GERUDO_VALLEY_WEST_EXIT, 0 }, + { "From Carpenter's Tent", "Vom Zelt der Zimmerleute", "Depuis la Tente du Charpentier", ENTR_GERUDO_VALLEY_OUTSIDE_TENT, 0 }, { "Carpenter's Tent/ Running Man Minigame", "Zelt der Zimmerleute/ Rennlaeufer Minispiel", "Tente du Charpentier/ Marathonien", ENTR_CARPENTERS_TENT_0, 0 }, { "Thrown out of Fortress", "Aus der Festung geworfen", "Expulse de la Forteresse", ENTR_GERUDO_VALLEY_1, 0 }, }}, { "28:Gerudo Fortress", "28:Gerudo-Festung", "28:Forteresse Gerudo", Select_LoadGame, 18, { - { "From Gerudo Valley", "Vom Gerudotal", "Depuis la Vallee Gerudo", ENTR_GERUDOS_FORTRESS_0, 0 }, - { "From Gerudo Training Grounds", "Von der Gerudo-Trainingsarena", "Depuis le Gymnase Gerudo", ENTR_GERUDOS_FORTRESS_14, 0 }, - { "From Haunted Wasteland", "Von der Gespensterwueste", "Depuis le Desert Hante", ENTR_GERUDOS_FORTRESS_15, 0 }, + { "From Gerudo Valley", "Vom Gerudotal", "Depuis la Vallee Gerudo", ENTR_GERUDOS_FORTRESS_EAST_EXIT, 0 }, + { "From Gerudo Training Ground", "Von der Gerudo-Trainingsarena", "Depuis le Gymnase Gerudo", ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND, 0 }, + { "From Haunted Wasteland", "Von der Gespensterwueste", "Depuis le Desert Hante", ENTR_GERUDOS_FORTRESS_GATE_EXIT, 0 }, { "Horseback Riding Minigame", "Bogen zu Pferde Minispiel", "Archerie Montee", ENTR_GERUDOS_FORTRESS_16, 0 }, { "Gerudo Fortress Jail", "Gerudo-Festung Gefaengnis", "Prison de la Forteresse Gerudo", ENTR_GERUDOS_FORTRESS_17, 0 }, { "From Thieves Hideout (1)", "Vom Diebesversteck (1)", "Depuis le Repaire des Voleurs (1)", ENTR_GERUDOS_FORTRESS_1, 0 }, @@ -511,62 +513,62 @@ static BetterSceneSelectEntry sBetterScenes[] = { { "From Gerudo Fortress (13)", "Von der Gerudo-Festung (13)", "Depuis la Forteresse Gerudo (13)", ENTR_THIEVES_HIDEOUT_12, 0 }, }}, { "30:Haunted Wasteland", "30:Geisterwueste", "30:Desert Hante", Select_LoadGame, 2, { - { "From Gerudo Fortress", "Von der Gerudo-Festung", "Depuis la Forteresse Gerudo", ENTR_HAUNTED_WASTELAND_0, 0 }, - { "From Desert Colossus", "Vom Wuestenkoloss", "Depuis le Colosse du Desert", ENTR_HAUNTED_WASTELAND_1, 0 }, + { "From Gerudo Fortress", "Von der Gerudo-Festung", "Depuis la Forteresse Gerudo", ENTR_HAUNTED_WASTELAND_EAST_EXIT, 0 }, + { "From Desert Colossus", "Vom Wuestenkoloss", "Depuis le Colosse du Desert", ENTR_HAUNTED_WASTELAND_WEST_EXIT, 0 }, }}, { "31:Desert Colossus", "31:Wuestenkoloss", "31:Colosse du Desert", Select_LoadGame, 7, { - { "From Haunted Wasteland", "Von der Geisterwueste", "Depuis le Desert Hante", ENTR_DESERT_COLOSSUS_0, 0 }, - { "From Spirit Temple", "Vom Geistertempel", "Depuis le Temple de l'Esprit", ENTR_DESERT_COLOSSUS_1, 0 }, + { "From Haunted Wasteland", "Von der Geisterwueste", "Depuis le Desert Hante", ENTR_DESERT_COLOSSUS_EAST_EXIT, 0 }, + { "From Spirit Temple", "Vom Geistertempel", "Depuis le Temple de l'Esprit", ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, 0 }, { "From Spirit Temple (Left Hand)", "Vom Geistertempel (Linke Hand)", "Depuis le Temple de l'Esprit (Main Gauche)", ENTR_DESERT_COLOSSUS_2, 0 }, { "From Spirit Temple (Right Hand)", "Vom Geistertempel (Rechte Hand)", "Depuis le Temple de l'Esprit (Main Droite)", ENTR_DESERT_COLOSSUS_3, 0 }, - { "From Fairy Fountain", "Von der Feen-Quelle", "Depuis la Fontaine des Fees", ENTR_DESERT_COLOSSUS_7, 0 }, - { "Great Fairy", "Feen-Quelle", "Grande Fee", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2, 0 }, - { "Requiem of Spirit Warp", "Requiem der Geister Teleport", "Teleporteur du Requiem de l'Esprit", ENTR_DESERT_COLOSSUS_5, 0 }, + { "From Fairy Fountain", "Von der Feen-Quelle", "Depuis la Fontaine des Fees", ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT, 0 }, + { "Great Fairy", "Feen-Quelle", "Grande Fee", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_NAYRUS_COLOSSUS, 0 }, + { "Requiem of Spirit Warp", "Requiem der Geister Teleport", "Teleporteur du Requiem de l'Esprit", ENTR_DESERT_COLOSSUS_WARP_PAD, 0 }, }}, { "32:Deku Tree", "32:Deku-Baum", "32:Arbre Mojo", Select_LoadGame, 3, { - { "Entrance", "Eingang", "Entree", ENTR_DEKU_TREE_0, 1 }, - { "From Gohma's Lair", "Von Gohmas Kampf", "Depuis le Repaire de Gohma", ENTR_DEKU_TREE_1, 1 }, - { "Gohma's Lair", "Gohmas Kampf", "Repaire de Gohma", ENTR_DEKU_TREE_BOSS_0, 0 }, + { "Entrance", "Eingang", "Entree", ENTR_DEKU_TREE_ENTRANCE, 1 }, + { "From Gohma's Lair", "Von Gohmas Kampf", "Depuis le Repaire de Gohma", ENTR_DEKU_TREE_BOSS_DOOR, 1 }, + { "Gohma's Lair", "Gohmas Kampf", "Repaire de Gohma", ENTR_DEKU_TREE_BOSS_ENTRANCE, 0 }, }}, { "33:Dodongos Cavern", "33:Dodongos Hoehle", "33:Caverne Dodongo", Select_LoadGame, 3, { - { "Entrance", "Eingang", "Entree", ENTR_DODONGOS_CAVERN_0, 1 }, - { "From King Dodongo", "Von Koenig Dodongo", "Depuis le Repaire du Roi Dodongo", ENTR_DODONGOS_CAVERN_1, 1 }, - { "King Dodongo's Lair", "Koenig Dodongos Kampf", "Repaire du Roi Dodongo", ENTR_DODONGOS_CAVERN_BOSS_0, 0 }, + { "Entrance", "Eingang", "Entree", ENTR_DODONGOS_CAVERN_ENTRANCE, 1 }, + { "From King Dodongo", "Von Koenig Dodongo", "Depuis le Repaire du Roi Dodongo", ENTR_DODONGOS_CAVERN_BOSS_DOOR, 1 }, + { "King Dodongo's Lair", "Koenig Dodongos Kampf", "Repaire du Roi Dodongo", ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE, 0 }, }}, { "34:Jabu Jabu", "34:Jabu-Jabu", "34:Jabu-Jabu", Select_LoadGame, 2, { - { "Entrance", "Eingang", "Entree", ENTR_JABU_JABU_0, 1 }, - { "Barinade's Lair", "Barinades Kampf", "Repaire de Barinade", ENTR_JABU_JABU_BOSS_0, 0 }, + { "Entrance", "Eingang", "Entree", ENTR_JABU_JABU_ENTRANCE, 1 }, + { "Barinade's Lair", "Barinades Kampf", "Repaire de Barinade", ENTR_JABU_JABU_BOSS_ENTRANCE, 0 }, }}, { "35:Forest Temple", "35:Waldtempel", "35:Temple de la Foret", Select_LoadGame, 4, { - { "Entrance", "Eingang", "Entree", ENTR_FOREST_TEMPLE_0, 1 }, + { "Entrance", "Eingang", "Entree", ENTR_FOREST_TEMPLE_ENTRANCE, 1 }, { "Crushing Room", "Der Fallende Decke Raum", "Salle de Broyage", ENTR_FOREST_TEMPLE_2, 1 }, - { "Before Phantom Ganon", "Vor Phantom-Ganon", "Avant Ganon Spectral", ENTR_FOREST_TEMPLE_1, 1 }, - { "Phantom Ganon's Lair", "Phantom-Ganons Kampf", "Repaire de Ganon Spectral", ENTR_FOREST_TEMPLE_BOSS_0, 0 }, + { "Before Phantom Ganon", "Vor Phantom-Ganon", "Avant Ganon Spectral", ENTR_FOREST_TEMPLE_BOSS_DOOR, 1 }, + { "Phantom Ganon's Lair", "Phantom-Ganons Kampf", "Repaire de Ganon Spectral", ENTR_FOREST_TEMPLE_BOSS_ENTRANCE, 0 }, }}, { "36:Fire Temple", "36:Feuertempel", "36:Temple du Feu", Select_LoadGame, 3, { - { "Entrance", "Eingang", "Entrance", ENTR_FIRE_TEMPLE_0, 1 }, - { "Before Volvagia", "Vor Volvagia", "Avant Volvagia", ENTR_FIRE_TEMPLE_1, 1 }, - { "Volvagia's Lair", "Volvagias Kampf", "Repaire de Volcania", ENTR_FIRE_TEMPLE_BOSS_0, 0 }, + { "Entrance", "Eingang", "Entrance", ENTR_FIRE_TEMPLE_ENTRANCE, 1 }, + { "Before Volvagia", "Vor Volvagia", "Avant Volvagia", ENTR_FIRE_TEMPLE_BOSS_DOOR, 1 }, + { "Volvagia's Lair", "Volvagias Kampf", "Repaire de Volcania", ENTR_FIRE_TEMPLE_BOSS_ENTRANCE, 0 }, }}, { "37:Water Temple", "37:Wassertempel", "37:Temple de l'Eau", Select_LoadGame, 2, { - { "Entrance", "Eingang", "Entree", ENTR_WATER_TEMPLE_0, 1 }, - { "Morpha's Lair", "Morphas Kampf", "Repaire de Morpha", ENTR_WATER_TEMPLE_BOSS_0, 0 }, + { "Entrance", "Eingang", "Entree", ENTR_WATER_TEMPLE_ENTRANCE, 1 }, + { "Morpha's Lair", "Morphas Kampf", "Repaire de Morpha", ENTR_WATER_TEMPLE_BOSS_ENTRANCE, 0 }, }}, { "38:Shadow Temple", "38:Schattentempel", "38:Temple de l'Ombre", Select_LoadGame, 3, { - { "Entrance", "Eingang", "Entree", ENTR_SHADOW_TEMPLE_0, 1 }, - { "Outside Bongo Bongo", "Vor Bongo Bongo", "Avant Bongo Bongo", ENTR_SHADOW_TEMPLE_1, 1 }, - { "Bongo Bongo's Lair", "Bongo Bongos Kampf", "Repaire de Bongo Bongo", ENTR_SHADOW_TEMPLE_BOSS_0, 1 }, + { "Entrance", "Eingang", "Entree", ENTR_SHADOW_TEMPLE_ENTRANCE, 1 }, + { "Outside Bongo Bongo", "Vor Bongo Bongo", "Avant Bongo Bongo", ENTR_SHADOW_TEMPLE_BOSS_DOOR, 1 }, + { "Bongo Bongo's Lair", "Bongo Bongos Kampf", "Repaire de Bongo Bongo", ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE, 1 }, }}, { "39:Spirit Temple", "39:Geistertempel", "39:Temple de l'Esprit", Select_LoadGame, 6, { - { "Entrance", "Eingang", "Entree", ENTR_SPIRIT_TEMPLE_0, 1 }, + { "Entrance", "Eingang", "Entree", ENTR_SPIRIT_TEMPLE_ENTRANCE, 1 }, { "From Left Hand", "Von der linken Hand", "Depuis la Main Gauche", ENTR_SPIRIT_TEMPLE_2, 1 }, { "From Right Hand", "Von der rechten Hand", "Depuis la Main Droite", ENTR_SPIRIT_TEMPLE_3, 1 }, - { "Before Twinrova", "Vor den Killa Ohmaz", "Avant le Duo Malefique", ENTR_SPIRIT_TEMPLE_1, 1 }, - { "Nabooru Fight", "Naborus Kampf", "Combat contre Nabooru", ENTR_SPIRIT_TEMPLE_BOSS_0, 0 }, + { "Before Twinrova", "Vor den Killa Ohmaz", "Avant le Duo Malefique", ENTR_SPIRIT_TEMPLE_BOSS_DOOR, 1 }, + { "Nabooru Fight", "Naborus Kampf", "Combat contre Nabooru", ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE, 0 }, { "Twinrova's Lair", "Killa Ohmaz' Kampf", "Repaire du Duo Malefique", ENTR_SPIRIT_TEMPLE_BOSS_2, 0 }, }}, { "40:Ganons Castle", "40:Ganons Schloss", "40:Chateau de Ganon", Select_LoadGame, 9, { - { "Entrance", "Eingang", "Entree", ENTR_INSIDE_GANONS_CASTLE_0, 1 }, + { "Entrance", "Eingang", "Entree", ENTR_INSIDE_GANONS_CASTLE_ENTRANCE, 1 }, { "From Tower", "Vom Tower", "Depuis la Tour", ENTR_INSIDE_GANONS_CASTLE_1, 1 }, { "Stairs to Lair - From Castle", "Stufen zum Verlies - Vom Schloss", "Escaliers vers Repaire - Depuis le Chateau", ENTR_GANONS_TOWER_0, 0 }, { "Stairs to Lair - From Ganondorf's Lair", "Stufen zum Verlies - Von Ganondorfs Verlies", "Escaliers vers Repaire - Depuis le Repaire de Ganondorf", ENTR_GANONS_TOWER_1, 0 }, @@ -577,21 +579,21 @@ static BetterSceneSelectEntry sBetterScenes[] = { { "Ganon Death Cutscene", "Ganons Todessequenz", "Cinematique de la Mort de Ganon", ENTR_GANONS_TOWER_COLLAPSE_EXTERIOR_0, 0 }, }}, { "41:Bottom of the Well", "41:Grund des Brunnens", "41:Puits", Select_LoadGame, 1, { - { "Entrance", "Eingang", "Entree", ENTR_BOTTOM_OF_THE_WELL_0, 1 }, + { "Entrance", "Eingang", "Entree", ENTR_BOTTOM_OF_THE_WELL_ENTRANCE, 1 }, }}, { "42:Ice Cavern", "42:Eishoehle", "42:Caverne Polaire", Select_LoadGame, 1, { - { "Entrance", "Eingang", "Entree", ENTR_ICE_CAVERN_0, 1 }, + { "Entrance", "Eingang", "Entree", ENTR_ICE_CAVERN_ENTRANCE, 1 }, }}, - { "43:Gerudo Training Grounds", "43:Gerudo-Trainingsarena", "43:Gymnase Gerudo", Select_LoadGame, 1, { - { "Entrance", "Eingang", "Entree", ENTR_GERUDO_TRAINING_GROUND_0, 1 }, + { "43:Gerudo Training Ground", "43:Gerudo-Trainingsarena", "43:Gymnase Gerudo", Select_LoadGame, 1, { + { "Entrance", "Eingang", "Entree", ENTR_GERUDO_TRAINING_GROUND_ENTRANCE, 1 }, }}, { "44:Warps", "44:Teleportpunkte", "44:Teleporteurs", Select_LoadGame, 6, { - { "Prelude of Light Warp", "Kantate des Lichts Teleport", "Teleporteur du Prelude de la Lumiere", ENTR_TEMPLE_OF_TIME_7, 0 }, - { "Minuet of Forest Warp", "Menuett des Waldes Teleport", "Teleporteur du Menuet des Bois", ENTR_SACRED_FOREST_MEADOW_2, 0 }, - { "Bolero of Fire Warp", "Bolero des Feuers Teleport", "Teleporteur du Bolero du Feu", ENTR_DEATH_MOUNTAIN_CRATER_4, 0 }, - { "Serenade Of Water Warp", "Serenade des Wassers Teleport", "Teleporteur de la Serenade de l'Eau", ENTR_LAKE_HYLIA_8, 0 }, - { "Nocturne of Shadow Warp", "Nocturne des Schattens Teleport", "Teleporteur du Nocturne de l'Ombre", ENTR_GRAVEYARD_7, 0 }, - { "Requiem of Spirit Warp", "Requiem der Geister Teleport", "Teleporteur du Requiem de l'Esprit", ENTR_DESERT_COLOSSUS_5, 0 }, + { "Prelude of Light Warp", "Kantate des Lichts Teleport", "Teleporteur du Prelude de la Lumiere", ENTR_TEMPLE_OF_TIME_WARP_PAD, 0 }, + { "Minuet of Forest Warp", "Menuett des Waldes Teleport", "Teleporteur du Menuet des Bois", ENTR_SACRED_FOREST_MEADOW_WARP_PAD, 0 }, + { "Bolero of Fire Warp", "Bolero des Feuers Teleport", "Teleporteur du Bolero du Feu", ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, 0 }, + { "Serenade Of Water Warp", "Serenade des Wassers Teleport", "Teleporteur de la Serenade de l'Eau", ENTR_LAKE_HYLIA_WARP_PAD, 0 }, + { "Nocturne of Shadow Warp", "Nocturne des Schattens Teleport", "Teleporteur du Nocturne de l'Ombre", ENTR_GRAVEYARD_WARP_PAD, 0 }, + { "Requiem of Spirit Warp", "Requiem der Geister Teleport", "Teleporteur du Requiem de l'Esprit", ENTR_DESERT_COLOSSUS_WARP_PAD, 0 }, }}, { "45:Shops", "45:Laeden", "45:Boutiques", Select_LoadGame, 9, { { "Kokiri Shop", "Kokiri-Laden", "Boutique Kokiri", ENTR_KOKIRI_SHOP_0 }, @@ -600,17 +602,17 @@ static BetterSceneSelectEntry sBetterScenes[] = { { "Happy Mask Shop", "Maskenhaendler", "Foire aux Masques", ENTR_HAPPY_MASK_SHOP_0, 0 }, { "Bombchu Shop", "Krabbelminen-Laden", "Boutique de Missiles", ENTR_BOMBCHU_SHOP_1, 0 }, { "Bazaar Shop (Kakariko)", "Basar (Kakariko)", "Bazar (Village Cocorico)", ENTR_BAZAAR_0, 0 }, - { "Potion Shop (Kakariko)", "Magie-Laden (Kakariko)", "Apothicaire (Village Cocorico)", ENTR_POTION_SHOP_KAKARIKO_0, 0 }, + { "Potion Shop (Kakariko)", "Magie-Laden (Kakariko)", "Apothicaire (Village Cocorico)", ENTR_POTION_SHOP_KAKARIKO_FRONT, 0 }, { "Goron City Shop", "Goronen-Laden", "Boutique Goron", ENTR_GORON_SHOP_0, 0 }, { "Zora Shop", "Zora-Laden", "Boutique Zora", ENTR_ZORA_SHOP_0, 0 }, }}, { "46:Great Fairies", "46:Feen-Quellen", "46:Grandes Fees", Select_LoadGame, 6, { - { "Hyrule Castle (Child)", "Schloss Hyrule (Kind)", "Chateau d'Hyrule (Enfant)", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_1, 0 }, - { "Hyrule Castle (Adult)", "Schloss Hyrule (Erwachsener)", "Chateau d'Hyrule (Adult)", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_2, 0 }, - { "Death Mountain Trail", "Gebirgspfad", "Mont du Peril", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_0, 0 }, - { "Death Mountain Crater", "Todeskrater", "Cratere du Peril", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_1, 0 }, - { "Zoras Fountain", "Zoras Quelle", "Fontaine Zora", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_0, 0 }, - { "Desert Colossus", "Wuestenkoloss", "Colosse du Desert", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_2, 0 }, + { "Hyrule Castle (Child)", "Schloss Hyrule (Kind)", "Chateau d'Hyrule (Enfant)", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC, 0 }, + { "Hyrule Castle (Adult)", "Schloss Hyrule (Erwachsener)", "Chateau d'Hyrule (Adult)", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD, 0 }, + { "Death Mountain Trail", "Gebirgspfad", "Mont du Peril", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT, 0 }, + { "Death Mountain Crater", "Todeskrater", "Cratere du Peril", ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC, 0 }, + { "Zoras Fountain", "Zoras Quelle", "Fontaine Zora", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF, 0 }, + { "Desert Colossus", "Wuestenkoloss", "Colosse du Desert", ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_NAYRUS_COLOSSUS, 0 }, }}, { "47:Chest Grottos", "47:Truhengrotten", "47:Grottes a Coffres", Select_Grotto_LoadGame, 11, { { "Kokiri Forest (Song of Storms)", "Kokiri-Wald (Hymne des Sturms)", "Foret Kokiri (Chant des Tempetes)", 0x00, 0 }, @@ -662,33 +664,33 @@ static BetterSceneSelectEntry sBetterScenes[] = { static BetterSceneSelectGrottoData sBetterGrottos[] = { { ENTR_GROTTOS_0, ENTR_KOKIRI_FOREST_0, 0, 0x2C, SCENE_KOKIRI_FOREST, { -504.0, 380.0, -1224.0 }}, // Kokiri Forest -> KF Storms Grotto - { ENTR_GROTTOS_0, ENTR_LOST_WOODS_6, 2, 0x14, SCENE_LOST_WOODS, { 922.0, 0.0, -933.0 }}, // Lost Woods -> LW Near Shortcuts Grotto - { ENTR_GROTTOS_8, ENTR_SACRED_FOREST_MEADOW_0, 0, 0xED, SCENE_SACRED_FOREST_MEADOW, { -201.0, 0.0, 1906.0 }}, // SFM Entryway -> SFM Wolfos Grotto - { ENTR_GROTTOS_0, ENTR_HYRULE_FIELD_0, 0, 0x00, SCENE_HYRULE_FIELD, { -1428.0, 0.0, 790.0 }}, // Hyrule Field -> HF Near Market Grotto - { ENTR_GROTTOS_0, ENTR_HYRULE_FIELD_4, 0, 0x03, SCENE_HYRULE_FIELD, { -4026.0, -700.0, 13858.0 }}, // Hyrule Field -> HF Open Grotto - { ENTR_GROTTOS_0, ENTR_HYRULE_FIELD_4, 0, 0x22, SCENE_HYRULE_FIELD, { -259.0, -500.0, 12356.0 }}, // Hyrule Field -> HF Southeast Grotto - { ENTR_GROTTOS_0, ENTR_KAKARIKO_VILLAGE_7, 0, 0x28, SCENE_KAKARIKO_VILLAGE, { 861.0, 80.0, -253.0 }}, // Kak Backyard -> Kak Open Grotto - { ENTR_GROTTOS_3, ENTR_KAKARIKO_VILLAGE_7, 0, 0xE7, SCENE_KAKARIKO_VILLAGE, { -400.0, 0.0, 408.0 }}, // Kakariko Village -> Kak Redead Grotto - { ENTR_GROTTOS_0, ENTR_DEATH_MOUNTAIN_TRAIL_1, 0, 0x57, SCENE_DEATH_MOUNTAIN_TRAIL, { -389.0, 1386.0, -1202.0 }}, // Death Mountain -> DMT Storms Grotto - { ENTR_GROTTOS_0, ENTR_DEATH_MOUNTAIN_CRATER_0, 1, 0x7A, SCENE_DEATH_MOUNTAIN_CRATER, { 50.0, 1233.0, 1776.0 }}, // DMC Upper Nearby -> DMC Upper Grotto - { ENTR_GROTTOS_0, ENTR_ZORAS_RIVER_2, 0, 0x29, SCENE_ZORAS_RIVER, { 369.0, 570.0, 128.0 }}, // Zora River -> ZR Open Grotto - { ENTR_GROTTOS_2, ENTR_HYRULE_FIELD_4, 0, 0xE6, SCENE_HYRULE_FIELD, { -5002.0, -700.0, 13823.0 }}, // Hyrule Field -> HF Inside Fence Grotto - { ENTR_GROTTOS_4, ENTR_DEATH_MOUNTAIN_CRATER_1, 1, 0xF9, SCENE_DEATH_MOUNTAIN_CRATER, { -1703.0, 722.0, -481.0 }}, // DMC Lower Nearby -> DMC Hammer Grotto - { ENTR_GROTTOS_4, ENTR_GORON_CITY_0, 3, 0xFB, SCENE_GORON_CITY, { 1091.0, 580.0, -1192.0 }}, // GC Grotto Platform -> GC Grotto - { ENTR_GROTTOS_4, ENTR_LON_LON_RANCH_10, 0, 0xFC, SCENE_LON_LON_RANCH, { 1798.0, 0.0, 1498.0 }}, // Lon Lon Ranch -> LLR Grotto - { ENTR_GROTTOS_4, ENTR_LAKE_HYLIA_2, 0, 0xEF, SCENE_LAKE_HYLIA, { -3044.0, -1033.0, 6070.0 }}, // Lake Hylia -> LH Grotto - { ENTR_GROTTOS_7, ENTR_LOST_WOODS_1, 8, 0xF5, SCENE_LOST_WOODS, { 677.0, 0.0, -2515.0 }}, // LW Beyond Mido -> LW Scrubs Grotto - { ENTR_GROTTOS_10, ENTR_ZORAS_RIVER_0, 0, 0xEB, SCENE_ZORAS_RIVER, { -1632.0, 100.0, -123.0 }}, // Zora River -> ZR Storms Grotto - { ENTR_GROTTOS_10, ENTR_SACRED_FOREST_MEADOW_1, 0, 0xEE, SCENE_SACRED_FOREST_MEADOW, { 317.0, 480.0, -2303.0 }}, // Sacred Forest Meadow -> SFM Storms Grotto - { ENTR_GROTTOS_10, ENTR_GERUDO_VALLEY_4, 0, 0xF0, SCENE_GERUDO_VALLEY, { -1321.0, 15.0, -968.0 }}, // GV Fortress Side -> GV Storms Grotto - { ENTR_GROTTOS_10, ENTR_DESERT_COLOSSUS_5, 0, 0xFD, SCENE_DESERT_COLOSSUS, { 71.0, -32.0, -1303.0 }}, // Desert Colossus -> Colossus Grotto - { ENTR_GROTTOS_12, ENTR_LOST_WOODS_6, 6, 0xF3, SCENE_LOST_WOODS, { 75.0, -20.0, -1596.0 }}, // LW Beyond Mido -> Deku Theater - { ENTR_GROTTOS_1, ENTR_HYRULE_FIELD_1, 0, 0xE5, SCENE_HYRULE_FIELD, { 2059.0, 20.0, -174.0 }}, // Hyrule Field -> HF Near Kak Grotto - { ENTR_GROTTOS_9, ENTR_HYRULE_CASTLE_1, 0, 0xF6, SCENE_HYRULE_CASTLE, { 986.0, 1571.0, 837.0 }}, // Hyrule Castle Grounds -> HC Storms Grotto - { ENTR_GROTTOS_5, ENTR_HYRULE_FIELD_5, 0, 0xE4, SCENE_HYRULE_FIELD, { -7873.0, -300.0, 6916.0 }}, // Hyrule Field -> HF Cow Grotto - { ENTR_GROTTOS_13, ENTR_DEATH_MOUNTAIN_TRAIL_1, 0, 0xF8, SCENE_DEATH_MOUNTAIN_TRAIL, { -678.0, 1946.0, -284.0 }}, // Death Mountain Summit -> DMT Cow Grotto - { ENTR_GROTTOS_6, ENTR_GERUDO_VALLEY_0, 0, 0xF2, SCENE_GERUDO_VALLEY, { 271.0, -555.0, 1465.0 }}, // GV Grotto Ledge -> GV Octorok Grotto - { ENTR_GROTTOS_11, ENTR_HYRULE_FIELD_0, 0, 0xE1, SCENE_HYRULE_FIELD, { -4945.0, -300.0, 2841.0 }}, // Hyrule Field -> HF Tektite Grotto + { ENTR_GROTTOS_0, ENTR_LOST_WOODS_TUNNEL_SHORTCUT, 2, 0x14, SCENE_LOST_WOODS, { 922.0, 0.0, -933.0 }}, // Lost Woods -> LW Near Shortcuts Grotto + { ENTR_GROTTOS_8, ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT, 0, 0xED, SCENE_SACRED_FOREST_MEADOW, { -201.0, 0.0, 1906.0 }}, // SFM Entryway -> SFM Wolfos Grotto + { ENTR_GROTTOS_0, ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN, 0, 0x00, SCENE_HYRULE_FIELD, { -1428.0, 0.0, 790.0 }}, // Hyrule Field -> HF Near Market Grotto + { ENTR_GROTTOS_0, ENTR_HYRULE_FIELD_FENCE_EXIT, 0, 0x03, SCENE_HYRULE_FIELD, { -4026.0, -700.0, 13858.0 }}, // Hyrule Field -> HF Open Grotto + { ENTR_GROTTOS_0, ENTR_HYRULE_FIELD_FENCE_EXIT, 0, 0x22, SCENE_HYRULE_FIELD, { -259.0, -500.0, 12356.0 }}, // Hyrule Field -> HF Southeast Grotto + { ENTR_GROTTOS_0, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOP_GRANNY, 0, 0x28, SCENE_KAKARIKO_VILLAGE, { 861.0, 80.0, -253.0 }}, // Kak Backyard -> Kak Open Grotto + { ENTR_GROTTOS_3, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOP_GRANNY, 0, 0xE7, SCENE_KAKARIKO_VILLAGE, { -400.0, 0.0, 408.0 }}, // Kakariko Village -> Kak Redead Grotto + { ENTR_GROTTOS_0, ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT, 0, 0x57, SCENE_DEATH_MOUNTAIN_TRAIL, { -389.0, 1386.0, -1202.0 }}, // Death Mountain -> DMT Storms Grotto + { ENTR_GROTTOS_0, ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT, 1, 0x7A, SCENE_DEATH_MOUNTAIN_CRATER, { 50.0, 1233.0, 1776.0 }}, // DMC Upper Nearby -> DMC Upper Grotto + { ENTR_GROTTOS_0, ENTR_ZORAS_RIVER_WATERFALL_EXIT, 0, 0x29, SCENE_ZORAS_RIVER, { 369.0, 570.0, 128.0 }}, // Zora River -> ZR Open Grotto + { ENTR_GROTTOS_2, ENTR_HYRULE_FIELD_FENCE_EXIT, 0, 0xE6, SCENE_HYRULE_FIELD, { -5002.0, -700.0, 13823.0 }}, // Hyrule Field -> HF Inside Fence Grotto + { ENTR_GROTTOS_4, ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT, 1, 0xF9, SCENE_DEATH_MOUNTAIN_CRATER, { -1703.0, 722.0, -481.0 }}, // DMC Lower Nearby -> DMC Hammer Grotto + { ENTR_GROTTOS_4, ENTR_GORON_CITY_UPPER_EXIT, 3, 0xFB, SCENE_GORON_CITY, { 1091.0, 580.0, -1192.0 }}, // GC Grotto Platform -> GC Grotto + { ENTR_GROTTOS_4, ENTR_LON_LON_RANCH_OUTSIDE_TOWER, 0, 0xFC, SCENE_LON_LON_RANCH, { 1798.0, 0.0, 1498.0 }}, // Lon Lon Ranch -> LLR Grotto + { ENTR_GROTTOS_4, ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE, 0, 0xEF, SCENE_LAKE_HYLIA, { -3044.0, -1033.0, 6070.0 }}, // Lake Hylia -> LH Grotto + { ENTR_GROTTOS_7, ENTR_LOST_WOODS_NORTH_EXIT, 8, 0xF5, SCENE_LOST_WOODS, { 677.0, 0.0, -2515.0 }}, // LW Beyond Mido -> LW Scrubs Grotto + { ENTR_GROTTOS_10, ENTR_ZORAS_RIVER_WEST_EXIT, 0, 0xEB, SCENE_ZORAS_RIVER, { -1632.0, 100.0, -123.0 }}, // Zora River -> ZR Storms Grotto + { ENTR_GROTTOS_10, ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE, 0, 0xEE, SCENE_SACRED_FOREST_MEADOW, { 317.0, 480.0, -2303.0 }}, // Sacred Forest Meadow -> SFM Storms Grotto + { ENTR_GROTTOS_10, ENTR_GERUDO_VALLEY_OUTSIDE_TENT, 0, 0xF0, SCENE_GERUDO_VALLEY, { -1321.0, 15.0, -968.0 }}, // GV Fortress Side -> GV Storms Grotto + { ENTR_GROTTOS_10, ENTR_DESERT_COLOSSUS_WARP_PAD, 0, 0xFD, SCENE_DESERT_COLOSSUS, { 71.0, -32.0, -1303.0 }}, // Desert Colossus -> Colossus Grotto + { ENTR_GROTTOS_12, ENTR_LOST_WOODS_TUNNEL_SHORTCUT, 6, 0xF3, SCENE_LOST_WOODS, { 75.0, -20.0, -1596.0 }}, // LW Beyond Mido -> Deku Theater + { ENTR_GROTTOS_1, ENTR_HYRULE_FIELD_STAIRS_EXIT, 0, 0xE5, SCENE_HYRULE_FIELD, { 2059.0, 20.0, -174.0 }}, // Hyrule Field -> HF Near Kak Grotto + { ENTR_GROTTOS_9, ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT, 0, 0xF6, SCENE_HYRULE_CASTLE, { 986.0, 1571.0, 837.0 }}, // Hyrule Castle Grounds -> HC Storms Grotto + { ENTR_GROTTOS_5, ENTR_HYRULE_FIELD_ROCKY_PATH, 0, 0xE4, SCENE_HYRULE_FIELD, { -7873.0, -300.0, 6916.0 }}, // Hyrule Field -> HF Cow Grotto + { ENTR_GROTTOS_13, ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT, 0, 0xF8, SCENE_DEATH_MOUNTAIN_TRAIL, { -678.0, 1946.0, -284.0 }}, // Death Mountain Summit -> DMT Cow Grotto + { ENTR_GROTTOS_6, ENTR_GERUDO_VALLEY_EAST_EXIT, 0, 0xF2, SCENE_GERUDO_VALLEY, { 271.0, -555.0, 1465.0 }}, // GV Grotto Ledge -> GV Octorok Grotto + { ENTR_GROTTOS_11, ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN, 0, 0xE1, SCENE_HYRULE_FIELD, { -4945.0, -300.0, 2841.0 }}, // Hyrule Field -> HF Tektite Grotto }; void Select_UpdateMenu(SelectContext* this) { @@ -790,13 +792,13 @@ void Select_UpdateMenu(SelectContext* this) { if (this->timerUp == 0) { this->timerUp = 20; this->lockUp = true; - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->verticalInput = R_UPDATE_RATE; } } if (CHECK_BTN_ALL(input->cur.button, BTN_DUP) && this->timerUp == 0) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->verticalInput = R_UPDATE_RATE * 3; } @@ -807,23 +809,23 @@ void Select_UpdateMenu(SelectContext* this) { if (this->timerDown == 0) { this->timerDown = 20; this->lockDown = true; - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->verticalInput = -R_UPDATE_RATE; } } if (CHECK_BTN_ALL(input->cur.button, BTN_DDOWN) && (this->timerDown == 0)) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->verticalInput = -R_UPDATE_RATE * 3; } if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT) || CHECK_BTN_ALL(input->cur.button, BTN_DLEFT)) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->verticalInput = R_UPDATE_RATE; } if (CHECK_BTN_ALL(input->press.button, BTN_DRIGHT) || CHECK_BTN_ALL(input->cur.button, BTN_DRIGHT)) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->verticalInput = -R_UPDATE_RATE; } } @@ -909,10 +911,10 @@ void Better_Select_UpdateMenu(SelectContext* this) { if (CHECK_BTN_ALL(input->press.button, BTN_B)) { if (LINK_AGE_IN_YEARS == YEARS_ADULT) { gSaveContext.linkAge = 1; - Audio_PlaySoundGeneral(NA_SE_VO_LI_SWORD_N_KID, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_VO_LI_SWORD_N_KID, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { gSaveContext.linkAge = 0; - Audio_PlaySoundGeneral(NA_SE_VO_LI_SWORD_N, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_VO_LI_SWORD_N, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -920,11 +922,11 @@ void Better_Select_UpdateMenu(SelectContext* this) { if (gSaveContext.dayTime > 0xC000 || gSaveContext.dayTime < 0x4555) { gSaveContext.nightFlag = 0; gSaveContext.dayTime = 0x8000; - Audio_PlaySoundGeneral(NA_SE_EV_CHICKEN_CRY_M, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_CHICKEN_CRY_M, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { gSaveContext.nightFlag = 1; gSaveContext.dayTime = 0x0000; - Audio_PlaySoundGeneral(NA_SE_EV_DOG_CRY_EVENING, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_EV_DOG_CRY_EVENING, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -934,23 +936,23 @@ void Better_Select_UpdateMenu(SelectContext* this) { this->betterScenes[this->currentScene].entrancePairs[this->pageDownIndex].canBeMQ) { this->opt = this->opt ? 0 : 1; if (this->opt) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_PICKOUT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_PICKOUT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_PUTAWAY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_PUTAWAY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } } if (CHECK_BTN_ALL(input->press.button, BTN_CLEFT) || CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) { this->pageDownIndex--; - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (this->pageDownIndex < 0) { this->pageDownIndex = this->betterScenes[this->currentScene].entranceCount - 1; } } if (CHECK_BTN_ALL(input->press.button, BTN_CRIGHT) || CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) { this->pageDownIndex++; - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_SWING, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (this->pageDownIndex > this->betterScenes[this->currentScene].entranceCount - 1) { this->pageDownIndex = 0; } @@ -963,13 +965,13 @@ void Better_Select_UpdateMenu(SelectContext* this) { if (this->timerUp == 0) { this->timerUp = 20; this->lockUp = true; - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->verticalInput = R_UPDATE_RATE; } } if ((CHECK_BTN_ALL(input->cur.button, BTN_DUP) || CHECK_BTN_ALL(input->cur.button, BTN_CUP)) && this->timerUp == 0) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->verticalInput = R_UPDATE_RATE * 3; } @@ -980,13 +982,13 @@ void Better_Select_UpdateMenu(SelectContext* this) { if (this->timerDown == 0) { this->timerDown = 20; this->lockDown = true; - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->verticalInput = -R_UPDATE_RATE; } } if ((CHECK_BTN_ALL(input->cur.button, BTN_DDOWN) || CHECK_BTN_ALL(input->cur.button, BTN_CDOWN)) && (this->timerDown == 0)) { - Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->verticalInput = -R_UPDATE_RATE * 3; } } diff --git a/soh/src/overlays/gamestates/ovl_title/z_title.c b/soh/src/overlays/gamestates/ovl_title/z_title.c index 8893d9d5f..f8561166f 100644 --- a/soh/src/overlays/gamestates/ovl_title/z_title.c +++ b/soh/src/overlays/gamestates/ovl_title/z_title.c @@ -11,8 +11,9 @@ #include "textures/nintendo_rogo_static/nintendo_rogo_static.h" #include "assets/objects/gameplay_keep/gameplay_keep.h" #include -#include +#include #include +#include "soh/ResourceManagerHelpers.h" #include #include "time.h" @@ -293,8 +294,6 @@ void Title_Init(GameState* thisx) { //ResourceMgr_LoadDirectory("nintendo_rogo_static*"); - // Disable vismono - D_801614B0.a = 0; R_UPDATE_RATE = 1; Matrix_Init(&this->state); View_Init(&this->view, this->state.gfxCtx); diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c index b91696fad..e4f2e65ef 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c @@ -127,97 +127,101 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { OPEN_DISPS(gfxCtx); - if ((!pauseCtx->unk_1E4 || (pauseCtx->unk_1E4 == 5) || (pauseCtx->unk_1E4 == 8)) && + if (((pauseCtx->unk_1E4 == 0) || (pauseCtx->unk_1E4 == 5) || (pauseCtx->unk_1E4 == 8)) && (pauseCtx->pageIndex == PAUSE_QUEST)) { pauseCtx->cursorColorSet = 0; if (pauseCtx->cursorSpecialPos == 0) { pauseCtx->nameColorSet = 0; - sp216 = pauseCtx->cursorSlot[PAUSE_QUEST]; - phi_s3 = pauseCtx->cursorPoint[PAUSE_QUEST]; - - if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { - phi_s0 = D_8082A1AC[phi_s3][2]; - if (phi_s0 == -3) { - KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_LEFT); - pauseCtx->unk_1E4 = 0; - } else { - while (phi_s0 >= 0) { - if ((s16)KaleidoScope_UpdateQuestStatusPoint(pauseCtx, phi_s0) != 0) { - break; - } - phi_s0 = D_8082A1AC[phi_s0][2]; - } - } - } else if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { - phi_s0 = D_8082A1AC[phi_s3][3]; - if (phi_s0 == -2) { - KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT); - pauseCtx->unk_1E4 = 0; - } else { - while (phi_s0 >= 0) { - if ((s16)KaleidoScope_UpdateQuestStatusPoint(pauseCtx, phi_s0) != 0) { - break; - } - phi_s0 = D_8082A1AC[phi_s0][3]; - } - } - } - - if ((pauseCtx->stickRelY < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) { - phi_s0 = D_8082A1AC[phi_s3][1]; - while (phi_s0 >= 0) { - if ((s16)KaleidoScope_UpdateQuestStatusPoint(pauseCtx, phi_s0) != 0) { - break; - } - phi_s0 = D_8082A1AC[phi_s0][1]; - } - } else if ((pauseCtx->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { - phi_s0 = D_8082A1AC[phi_s3][0]; - while (phi_s0 >= 0) { - if ((s16)KaleidoScope_UpdateQuestStatusPoint(pauseCtx, phi_s0) != 0) { - break; - } - phi_s0 = D_8082A1AC[phi_s0][0]; - } - } - - if (phi_s3 != pauseCtx->cursorPoint[PAUSE_QUEST]) { - pauseCtx->unk_1E4 = 0; - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - } - - if (pauseCtx->cursorPoint[PAUSE_QUEST] != 0x18) { - if (CHECK_QUEST_ITEM(pauseCtx->cursorPoint[PAUSE_QUEST])) { - if (pauseCtx->cursorPoint[PAUSE_QUEST] < 6) { - phi_s0_2 = pauseCtx->cursorPoint[PAUSE_QUEST] + 0x66; - osSyncPrintf("000 ccc=%d\n", phi_s0_2); - } else if (pauseCtx->cursorPoint[PAUSE_QUEST] < 0x12) { - phi_s0_2 = pauseCtx->cursorPoint[PAUSE_QUEST] + 0x54; - osSyncPrintf("111 ccc=%d\n", phi_s0_2); - } else { - phi_s0_2 = pauseCtx->cursorPoint[PAUSE_QUEST] + 0x5A; - osSyncPrintf("222 ccc=%d (%d, %d, %d)\n", phi_s0_2, pauseCtx->cursorPoint[PAUSE_QUEST], - 0x12, 0x6C); - } - } else { - phi_s0_2 = PAUSE_ITEM_NONE; - osSyncPrintf("999 ccc=%d (%d, %d)\n", PAUSE_ITEM_NONE, pauseCtx->cursorPoint[PAUSE_QUEST], - 0x18); - } + if ((pauseCtx->state != 6) || ((pauseCtx->stickRelX == 0) && (pauseCtx->stickRelY == 0))) { + // No cursor movement + sp216 = pauseCtx->cursorSlot[PAUSE_QUEST]; } else { - if ((gSaveContext.inventory.questItems & 0xF0000000) != 0) { - phi_s0_2 = 0x72; - } else { - phi_s0_2 = PAUSE_ITEM_NONE; - } - osSyncPrintf("888 ccc=%d (%d, %d, %x)\n", phi_s0_2, pauseCtx->cursorPoint[PAUSE_QUEST], 0x72, - gSaveContext.inventory.questItems & 0xF0000000); - } + phi_s3 = pauseCtx->cursorPoint[PAUSE_QUEST]; - sp216 = pauseCtx->cursorPoint[PAUSE_QUEST]; - pauseCtx->cursorItem[pauseCtx->pageIndex] = phi_s0_2; - pauseCtx->cursorSlot[pauseCtx->pageIndex] = sp216; + if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { + phi_s0 = D_8082A1AC[phi_s3][2]; + if (phi_s0 == -3) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_LEFT); + pauseCtx->unk_1E4 = 0; + } else { + while (phi_s0 >= 0) { + if ((s16)KaleidoScope_UpdateQuestStatusPoint(pauseCtx, phi_s0) != 0) { + break; + } + phi_s0 = D_8082A1AC[phi_s0][2]; + } + } + } else if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { + phi_s0 = D_8082A1AC[phi_s3][3]; + if (phi_s0 == -2) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT); + pauseCtx->unk_1E4 = 0; + } else { + while (phi_s0 >= 0) { + if ((s16)KaleidoScope_UpdateQuestStatusPoint(pauseCtx, phi_s0) != 0) { + break; + } + phi_s0 = D_8082A1AC[phi_s0][3]; + } + } + } + + if ((pauseCtx->stickRelY < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) { + phi_s0 = D_8082A1AC[phi_s3][1]; + while (phi_s0 >= 0) { + if ((s16)KaleidoScope_UpdateQuestStatusPoint(pauseCtx, phi_s0) != 0) { + break; + } + phi_s0 = D_8082A1AC[phi_s0][1]; + } + } else if ((pauseCtx->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { + phi_s0 = D_8082A1AC[phi_s3][0]; + while (phi_s0 >= 0) { + if ((s16)KaleidoScope_UpdateQuestStatusPoint(pauseCtx, phi_s0) != 0) { + break; + } + phi_s0 = D_8082A1AC[phi_s0][0]; + } + } + + if (phi_s3 != pauseCtx->cursorPoint[PAUSE_QUEST]) { + pauseCtx->unk_1E4 = 0; + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + + if (pauseCtx->cursorPoint[PAUSE_QUEST] != 0x18) { + if (CHECK_QUEST_ITEM(pauseCtx->cursorPoint[PAUSE_QUEST])) { + if (pauseCtx->cursorPoint[PAUSE_QUEST] < 6) { + phi_s0_2 = pauseCtx->cursorPoint[PAUSE_QUEST] + 0x66; + osSyncPrintf("000 ccc=%d\n", phi_s0_2); + } else if (pauseCtx->cursorPoint[PAUSE_QUEST] < 0x12) { + phi_s0_2 = pauseCtx->cursorPoint[PAUSE_QUEST] + 0x54; + osSyncPrintf("111 ccc=%d\n", phi_s0_2); + } else { + phi_s0_2 = pauseCtx->cursorPoint[PAUSE_QUEST] + 0x5A; + osSyncPrintf("222 ccc=%d (%d, %d, %d)\n", phi_s0_2, pauseCtx->cursorPoint[PAUSE_QUEST], + 0x12, 0x6C); + } + } else { + phi_s0_2 = PAUSE_ITEM_NONE; + osSyncPrintf("999 ccc=%d (%d, %d)\n", PAUSE_ITEM_NONE, pauseCtx->cursorPoint[PAUSE_QUEST], + 0x18); + } + } else { + if ((gSaveContext.inventory.questItems & 0xF0000000) != 0) { + phi_s0_2 = 0x72; + } else { + phi_s0_2 = PAUSE_ITEM_NONE; + } + osSyncPrintf("888 ccc=%d (%d, %d, %x)\n", phi_s0_2, pauseCtx->cursorPoint[PAUSE_QUEST], 0x72, + gSaveContext.inventory.questItems & 0xF0000000); + } + + sp216 = pauseCtx->cursorPoint[PAUSE_QUEST]; + pauseCtx->cursorItem[pauseCtx->pageIndex] = phi_s0_2; + pauseCtx->cursorSlot[pauseCtx->pageIndex] = sp216; + } KaleidoScope_SetCursorVtx(pauseCtx, sp216 * 4, pauseCtx->questVtx); @@ -267,7 +271,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { pauseCtx->cursorSpecialPos = 0; sp216 = pauseCtx->cursorPoint[PAUSE_QUEST]; KaleidoScope_SetCursorVtx(pauseCtx, sp216 * 4, pauseCtx->questVtx); - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (CHECK_QUEST_ITEM(pauseCtx->cursorPoint[PAUSE_QUEST])) { phi_s0_2 = pauseCtx->cursorPoint[PAUSE_QUEST] + 0x5A; } else { @@ -284,7 +288,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) { pauseCtx->cursorSpecialPos = 0; sp216 = pauseCtx->cursorPoint[PAUSE_QUEST]; KaleidoScope_SetCursorVtx(pauseCtx, sp216 * 4, pauseCtx->questVtx); - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (CHECK_QUEST_ITEM(pauseCtx->cursorPoint[PAUSE_QUEST])) { if (pauseCtx->cursorPoint[PAUSE_QUEST] < 6) { phi_s0_2 = pauseCtx->cursorPoint[PAUSE_QUEST] + 0x66; diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c index 73c965176..bef08b08a 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c @@ -385,7 +385,7 @@ void KaleidoScope_DrawEquipment(PlayState* play) { pauseCtx->nameDisplayTimer = 0; pauseCtx->cursorSpecialPos = 0; - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); cursorPoint = cursorX = cursorY = 0; while (true) { @@ -431,7 +431,7 @@ void KaleidoScope_DrawEquipment(PlayState* play) { if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { pauseCtx->nameDisplayTimer = 0; pauseCtx->cursorSpecialPos = 0; - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); cursorPoint = cursorX = 3; cursorY = 0; @@ -545,7 +545,7 @@ void KaleidoScope_DrawEquipment(PlayState* play) { (pauseCtx->cursorX[PAUSE_EQUIP] == 0) && (pauseCtx->cursorY[PAUSE_EQUIP] == 2) && CVarGetInteger(CVAR_ENHANCEMENT("ToggleStrength"), 0)) { CVarSetInteger(CVAR_ENHANCEMENT("StrengthDisabled"), !CVarGetInteger(CVAR_ENHANCEMENT("StrengthDisabled"), 0)); // Equip success sound - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); // Wait 10 frames before accepting input again pauseCtx->unk_1E4 = 7; sEquipTimer = 10; @@ -637,7 +637,7 @@ void KaleidoScope_DrawEquipment(PlayState* play) { Interface_LoadItemIcon1(play, 0); } - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); pauseCtx->unk_1E4 = 7; sEquipTimer = 10; } else if (CVarGetInteger(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 0) != 0) { @@ -671,23 +671,23 @@ void KaleidoScope_DrawEquipment(PlayState* play) { pauseCtx->equipVtx[cursorSlot * 4].v.ob[0] * 10, pauseCtx->equipVtx[cursorSlot * 4].v.ob[1] * 10); } else { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } } } else { EQUIP_FAIL: if (CHECK_BTN_ALL(input->press.button, BTN_A)) { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else if ((CVarGetInteger(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 0) != 0) && (pauseCtx->cursorY[PAUSE_EQUIP] > 1)) { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } } if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_EQUIP]) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else if ((pauseCtx->unk_1E4 == 7) && (pauseCtx->pageIndex == PAUSE_EQUIP)) { KaleidoScope_SetCursorVtx(pauseCtx, pauseCtx->cursorSlot[PAUSE_EQUIP] * 4, pauseCtx->equipVtx); diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c index 6023282c7..91051f5f3 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c @@ -5,6 +5,7 @@ #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" +#include "soh/OTRGlobals.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" @@ -270,14 +271,14 @@ void KaleidoScope_HandleItemCycleExtras(PlayState* play, u8 slot, bool canCycle, CHECK_BTN_ALL(input->press.button, BTN_A) && (hasLeftItem || hasRightItem) ) { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); gCurrentItemCyclingSlot = gCurrentItemCyclingSlot == slot ? -1 : slot; } if (gCurrentItemCyclingSlot == slot) { pauseCtx->cursorColorSet = 8; if ((pauseCtx->stickRelX > 30 || pauseCtx->stickRelY > 30) || dpad && CHECK_BTN_ANY(input->press.button, BTN_DRIGHT | BTN_DUP)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (replaceCButtons) { for (int i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) { if (gSaveContext.equips.buttonItems[i] == gSaveContext.inventory.items[slot]) { @@ -294,7 +295,7 @@ void KaleidoScope_HandleItemCycleExtras(PlayState* play, u8 slot, bool canCycle, gSaveContext.inventory.items[slot] = rightItem; } else if ((pauseCtx->stickRelX < -30 || pauseCtx->stickRelY < -30) || dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DDOWN)) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (replaceCButtons) { for (int i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) { if (gSaveContext.equips.buttonItems[i] == gSaveContext.inventory.items[slot]) { @@ -541,7 +542,7 @@ void KaleidoScope_DrawItemSelect(PlayState* play) { pauseCtx->nameDisplayTimer = 0; pauseCtx->cursorSpecialPos = 0; - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); cursorPoint = cursorX = cursorY = 0; while (true) { @@ -575,7 +576,7 @@ void KaleidoScope_DrawItemSelect(PlayState* play) { pauseCtx->nameDisplayTimer = 0; pauseCtx->cursorSpecialPos = 0; - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); cursorPoint = cursorX = 5; cursorY = 0; @@ -687,8 +688,8 @@ void KaleidoScope_DrawItemSelect(PlayState* play) { pauseCtx->itemVtx[index].v.ob[0] * 10, pauseCtx->itemVtx[index].v.ob[1] * 10); } else { - Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); } } } @@ -704,7 +705,7 @@ void KaleidoScope_DrawItemSelect(PlayState* play) { } if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_ITEM]) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else if ((pauseCtx->unk_1E4 == 3) && (pauseCtx->pageIndex == PAUSE_ITEM)) { KaleidoScope_SetCursorVtx(pauseCtx, cursorSlot * 4, pauseCtx->itemVtx); @@ -835,7 +836,7 @@ void KaleidoScope_SetupItemEquip(PlayState* play, u16 item, u16 slot, s16 animX, if ((pauseCtx->equipTargetItem == ITEM_ARROW_FIRE) || (pauseCtx->equipTargetItem == ITEM_ARROW_ICE) || (pauseCtx->equipTargetItem == ITEM_ARROW_LIGHT)) { if (CVarGetInteger(CVAR_ENHANCEMENT("SkipArrowAnimation"), 0)) { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } else { u16 index = 0; if (pauseCtx->equipTargetItem == ITEM_ARROW_ICE) { @@ -844,14 +845,14 @@ void KaleidoScope_SetupItemEquip(PlayState* play, u16 item, u16 slot, s16 animX, if (pauseCtx->equipTargetItem == ITEM_ARROW_LIGHT) { index = 2; } - Audio_PlaySoundGeneral(NA_SE_SY_SET_FIRE_ARROW + index, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_SET_FIRE_ARROW + index, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); pauseCtx->equipTargetItem = 0xBF + index; sEquipState = 0; pauseCtx->equipAnimAlpha = 0; sEquipMoveTimer = 6; } } else { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -1052,7 +1053,7 @@ void KaleidoScope_UpdateItemEquip(PlayState* play) { WREG(90) = 320; WREG(87) = WREG(91); sEquipState++; - Audio_PlaySoundGeneral(NA_SE_SY_SYNTH_MAGIC_ARROW, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_SYNTH_MAGIC_ARROW, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } return; } diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c index 8aba85040..0730f6b12 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c @@ -157,7 +157,7 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) { pauseCtx->cursorX[PAUSE_MAP] = 0; j = 72 + (pauseCtx->cursorSlot[PAUSE_MAP] * 4); KaleidoScope_SetCursorVtx(pauseCtx, j, pauseCtx->mapPageVtx); - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } else { if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { @@ -187,12 +187,12 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) { osSyncPrintf("kscope->cursor_point====%d\n", pauseCtx->cursorPoint[PAUSE_MAP]); j = 72 + (pauseCtx->cursorSlot[PAUSE_MAP] * 4); KaleidoScope_SetCursorVtx(pauseCtx, j, pauseCtx->mapPageVtx); - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_MAP]) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } @@ -506,7 +506,7 @@ void KaleidoScope_DrawWorldMap(PlayState* play, GraphicsContext* gfxCtx) { pauseCtx->cursorItem[PAUSE_MAP] = pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; pauseCtx->cursorSlot[PAUSE_MAP] = pauseCtx->cursorPoint[PAUSE_WORLD_MAP] + 0x1F; KaleidoScope_SetCursorVtx(pauseCtx, pauseCtx->cursorSlot[PAUSE_MAP] * 4, pauseCtx->mapPageVtx); - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); D_8082A6D4 = 0; } } else { @@ -528,7 +528,7 @@ void KaleidoScope_DrawWorldMap(PlayState* play, GraphicsContext* gfxCtx) { pauseCtx->cursorItem[PAUSE_MAP] = pauseCtx->cursorPoint[PAUSE_WORLD_MAP]; pauseCtx->cursorSlot[PAUSE_MAP] = pauseCtx->cursorPoint[PAUSE_WORLD_MAP] + 0x1F; KaleidoScope_SetCursorVtx(pauseCtx, pauseCtx->cursorSlot[PAUSE_MAP] * 4, pauseCtx->mapPageVtx); - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); D_8082A6D4 = 0; } } @@ -539,7 +539,7 @@ void KaleidoScope_DrawWorldMap(PlayState* play, GraphicsContext* gfxCtx) { } if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_WORLD_MAP]) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } } diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_prompt.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_prompt.c index 80ab3da9e..902519667 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_prompt.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_prompt.c @@ -11,10 +11,10 @@ void KaleidoScope_UpdatePrompt(PlayState* play) { if (((pauseCtx->state == 7) && (pauseCtx->unk_1EC == 1)) || (pauseCtx->state == 0xE) || (pauseCtx->state == 0x10)) { if ((pauseCtx->promptChoice == 0) && ((relStickX >= 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)))) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); pauseCtx->promptChoice = 4; } else if ((pauseCtx->promptChoice != 0) && ((relStickX <= -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT)))) { - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); pauseCtx->promptChoice = 0; } diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index baf1eb533..217ec24e3 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -16,10 +16,11 @@ #include "soh/frame_interpolation.h" #include "soh/Enhancements/game-interactor/GameInteractor.h" -#include "soh/Enhancements/randomizer/randomizer_entrance.h" -#include "soh/Enhancements/randomizer/randomizer_grotto.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" #include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/OTRGlobals.h" +#include "soh/ResourceManagerHelpers.h" +#include "soh/SaveManager.h" #include "soh/Enhancements/kaleido.h" @@ -990,7 +991,7 @@ void KaleidoScope_MoveCursorToSpecialPos(PlayState* play, u16 specialPos) { pauseCtx->cursorSpecialPos = specialPos; pauseCtx->pageSwitchTimer = 0; - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } void KaleidoScope_DrawQuadTextureRGBA32(GraphicsContext* gfxCtx, void* texture, u16 width, u16 height, u16 point) { @@ -1045,11 +1046,11 @@ void KaleidoScope_SwitchPage(PauseContext* pauseCtx, u8 pt) { if (!pt) { pauseCtx->mode = pauseCtx->pageIndex * 2 + 1; - Audio_PlaySoundGeneral(NA_SE_SY_WIN_SCROLL_LEFT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WIN_SCROLL_LEFT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); pauseCtx->cursorSpecialPos = PAUSE_CURSOR_PAGE_RIGHT; } else { pauseCtx->mode = pauseCtx->pageIndex * 2; - Audio_PlaySoundGeneral(NA_SE_SY_WIN_SCROLL_RIGHT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_WIN_SCROLL_RIGHT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); pauseCtx->cursorSpecialPos = PAUSE_CURSOR_PAGE_LEFT; } @@ -4002,7 +4003,7 @@ void KaleidoScope_Update(PlayState* play) } else if (CHECK_BTN_ALL(input->press.button, BTN_B)) { pauseCtx->mode = 0; pauseCtx->promptChoice = 0; - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] = gSaveContext.buttonStatus[3] = BTN_DISABLED; gSaveContext.buttonStatus[4] = BTN_ENABLED; @@ -4013,7 +4014,7 @@ void KaleidoScope_Update(PlayState* play) pauseCtx->unk_1EC = 0; pauseCtx->state = 7; } else if (CHECK_BTN_ALL(input->press.button, BTN_CUP) && pauseCtx->pageIndex == PAUSE_QUEST) { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); pauseCtx->randoQuestMode ^= 1; } break; @@ -4053,7 +4054,7 @@ void KaleidoScope_Update(PlayState* play) pauseCtx->unk_1E4 = 0; pauseCtx->mode = 0; pauseCtx->promptChoice = 0; - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] = gSaveContext.buttonStatus[3] = BTN_DISABLED; gSaveContext.buttonStatus[4] = BTN_ENABLED; @@ -4064,14 +4065,14 @@ void KaleidoScope_Update(PlayState* play) pauseCtx->unk_1EC = 0; pauseCtx->state = 7; } else if (pauseCtx->ocarinaStaff->state == pauseCtx->ocarinaSongIdx) { - Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); D_8082B258 = 0; D_8082B25C = 30; pauseCtx->unk_1E4 = 6; } else if (pauseCtx->ocarinaStaff->state == 0xFF) { - Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); D_8082B258 = 4; D_8082B25C = 20; pauseCtx->unk_1E4 = 6; @@ -4104,7 +4105,7 @@ void KaleidoScope_Update(PlayState* play) pauseCtx->unk_1E4 = 0; pauseCtx->mode = 0; pauseCtx->promptChoice = 0; - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] = gSaveContext.buttonStatus[3] = BTN_DISABLED; gSaveContext.buttonStatus[4] = BTN_ENABLED; @@ -4153,8 +4154,8 @@ void KaleidoScope_Update(PlayState* play) YREG(8) = pauseCtx->unk_204; func_800F64E0(0); } else { - Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); Play_PerformSave(play); pauseCtx->unk_1EC = 4; D_8082B25C = CVarGetInteger(CVAR_ENHANCEMENT("SkipSaveConfirmation"), 0) ? 3 /* 0.1 sec */ : 90 /* 3 secs */; @@ -4392,12 +4393,12 @@ void KaleidoScope_Update(PlayState* play) if (CHECK_BTN_ALL(input->press.button, BTN_A)) { if (pauseCtx->promptChoice != 0) { pauseCtx->promptChoice = 0; - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); pauseCtx->state = 0x10; gameOverCtx->state++; } else { - Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); pauseCtx->promptChoice = 0; Play_SaveSceneFlags(play); gSaveContext.savedSceneNum = play->sceneNum; @@ -4424,62 +4425,57 @@ void KaleidoScope_Update(PlayState* play) case 0x10: if (CHECK_BTN_ALL(input->press.button, BTN_A) || CHECK_BTN_ALL(input->press.button, BTN_START)) { if (pauseCtx->promptChoice == 0 && GameInteractor_Should(VB_BE_ABLE_TO_SAVE, true)) { - Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, - &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultReverb); Play_SaveSceneFlags(play); switch (gSaveContext.entranceIndex) { - case ENTR_DEKU_TREE_0: - case ENTR_DODONGOS_CAVERN_0: - case ENTR_JABU_JABU_0: - case ENTR_FOREST_TEMPLE_0: - case ENTR_FIRE_TEMPLE_0: - case ENTR_WATER_TEMPLE_0: - case ENTR_SPIRIT_TEMPLE_0: - case ENTR_SHADOW_TEMPLE_0: + case ENTR_DEKU_TREE_ENTRANCE: + case ENTR_DODONGOS_CAVERN_ENTRANCE: + case ENTR_JABU_JABU_ENTRANCE: + case ENTR_FOREST_TEMPLE_ENTRANCE: + case ENTR_FIRE_TEMPLE_ENTRANCE: + case ENTR_WATER_TEMPLE_ENTRANCE: + case ENTR_SPIRIT_TEMPLE_ENTRANCE: + case ENTR_SHADOW_TEMPLE_ENTRANCE: case ENTR_GANONS_TOWER_0: - case ENTR_GERUDO_TRAINING_GROUND_0: - case ENTR_ICE_CAVERN_0: + case ENTR_GERUDO_TRAINING_GROUND_ENTRANCE: + case ENTR_ICE_CAVERN_ENTRANCE: case ENTR_THIEVES_HIDEOUT_0: - case ENTR_BOTTOM_OF_THE_WELL_0: - case ENTR_INSIDE_GANONS_CASTLE_0: + case ENTR_BOTTOM_OF_THE_WELL_ENTRANCE: + case ENTR_INSIDE_GANONS_CASTLE_ENTRANCE: case ENTR_GANONS_TOWER_COLLAPSE_INTERIOR_0: break; - case ENTR_DEKU_TREE_BOSS_0: - gSaveContext.entranceIndex = ENTR_DEKU_TREE_0; + case ENTR_DEKU_TREE_BOSS_ENTRANCE: + gSaveContext.entranceIndex = ENTR_DEKU_TREE_ENTRANCE; break; - case ENTR_DODONGOS_CAVERN_BOSS_0: - gSaveContext.entranceIndex = ENTR_DODONGOS_CAVERN_0; + case ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE: + gSaveContext.entranceIndex = ENTR_DODONGOS_CAVERN_ENTRANCE; break; - case ENTR_JABU_JABU_BOSS_0: - gSaveContext.entranceIndex = ENTR_JABU_JABU_0; + case ENTR_JABU_JABU_BOSS_ENTRANCE: + gSaveContext.entranceIndex = ENTR_JABU_JABU_ENTRANCE; break; - case ENTR_FOREST_TEMPLE_BOSS_0: - gSaveContext.entranceIndex = ENTR_FOREST_TEMPLE_0; + case ENTR_FOREST_TEMPLE_BOSS_ENTRANCE: + gSaveContext.entranceIndex = ENTR_FOREST_TEMPLE_ENTRANCE; break; - case ENTR_FIRE_TEMPLE_BOSS_0: - gSaveContext.entranceIndex = ENTR_FIRE_TEMPLE_0; + case ENTR_FIRE_TEMPLE_BOSS_ENTRANCE: + gSaveContext.entranceIndex = ENTR_FIRE_TEMPLE_ENTRANCE; break; - case ENTR_WATER_TEMPLE_BOSS_0: - gSaveContext.entranceIndex = ENTR_WATER_TEMPLE_0; + case ENTR_WATER_TEMPLE_BOSS_ENTRANCE: + gSaveContext.entranceIndex = ENTR_WATER_TEMPLE_ENTRANCE; break; - case ENTR_SPIRIT_TEMPLE_BOSS_0: - gSaveContext.entranceIndex = ENTR_SPIRIT_TEMPLE_0; + case ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE: + gSaveContext.entranceIndex = ENTR_SPIRIT_TEMPLE_ENTRANCE; break; - case ENTR_SHADOW_TEMPLE_BOSS_0: - gSaveContext.entranceIndex = ENTR_SHADOW_TEMPLE_0; + case ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE: + gSaveContext.entranceIndex = ENTR_SHADOW_TEMPLE_ENTRANCE; break; case ENTR_GANONDORF_BOSS_0: gSaveContext.entranceIndex = ENTR_GANONS_TOWER_0; break; } - - // In ER, handle overriding the game over respawn entrance - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { - Entrance_SetGameOverEntrance(); - } } else { - Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } pauseCtx->state = 0x11; @@ -4499,10 +4495,6 @@ void KaleidoScope_Update(PlayState* play) if (pauseCtx->promptChoice == 0 && GameInteractor_Should(VB_BE_ABLE_TO_SAVE, true)) { Play_TriggerRespawn(play); gSaveContext.respawnFlag = -2; - // In ER, handle death warp to last entrance from grottos - if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) { - Grotto_ForceGrottoReturn(); - } // Reset frame counter to prevent autosave on respawn play->gameplayFrames = 0; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK; diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_lmap_mark.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_lmap_mark.c index 0de1d117a..d4b3da6a9 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_lmap_mark.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_lmap_mark.c @@ -1,5 +1,6 @@ #include "z_kaleido_scope.h" #include "textures/parameter_static/parameter_static.h" +#include "soh/ResourceManagerHelpers.h" typedef struct { /* 0x00 */ void* texture; @@ -36,8 +37,6 @@ extern PauseMapMarksData gPauseMapMarkDataTable[]; extern PauseMapMarksData gPauseMapMarkDataTableMasterQuest[]; void PauseMapMark_Init(PlayState* play) { - gBossMarkState = 0; - gBossMarkScale = 1.0f; if(ResourceMgr_IsGameMasterQuest()) { gLoadedPauseMarkDataTable = gPauseMapMarkDataTableMasterQuest; } else { @@ -171,6 +170,20 @@ void PauseMapMark_Draw(PlayState* play) { case SCENE_ICE_CAVERN: PauseMapMark_DrawForDungeon(play); break; + case SCENE_DEKU_TREE_BOSS: + case SCENE_DODONGOS_CAVERN_BOSS: + case SCENE_JABU_JABU_BOSS: + case SCENE_FOREST_TEMPLE_BOSS: + case SCENE_FIRE_TEMPLE_BOSS: + case SCENE_WATER_TEMPLE_BOSS: + case SCENE_SPIRIT_TEMPLE_BOSS: + case SCENE_SHADOW_TEMPLE_BOSS: + case SCENE_GANONDORF_BOSS: + case SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR: + if (CVarGetInteger(CVAR_ENHANCEMENT("PulsateBossIcon"), 0) != 0) { + PauseMapMark_DrawForDungeon(play); + } + break; } PauseMapMark_Clear(play);