Merge branch 'develop' into aManchipelago

This commit is contained in:
aMannus
2025-10-15 09:37:51 +02:00
273 changed files with 6101 additions and 3191 deletions
+8
View File
@@ -6,9 +6,16 @@
# OPUSFILE_LIBRARY - Path to the opusfile library
# OPUSFILE_LIBRARIES - Full list of libraries to link (opusfile, opus, ogg)
# Use pkg-config to find opusfile if available
find_package(PkgConf)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_OPUSFILE QUIET opusfile)
endif()
# Search for the OpusFile header
find_path(OPUSFILE_INCLUDE_DIR
NAMES opusfile.h
HINTS ${PC_OPUSFILE_INCLUDE_DIRS}
PATHS /usr/include/opus /usr/local/include/opus /opt/local/include/opus /opt/homebrew/include/opus
DOC "Directory where opusfile.h is located"
)
@@ -16,6 +23,7 @@ find_path(OPUSFILE_INCLUDE_DIR
# Search for the OpusFile library
find_library(OPUSFILE_LIBRARY
NAMES opusfile
HINTS ${PC_OPUSFILE_LIBRARY_DIRS}
DOC "Path to the libopusfile library"
)
+6 -2
View File
@@ -155,6 +155,9 @@ set(GFX_DEBUG_DISASSEMBLER ON)
set(GBI_UCODE F3DEX_GBI_2)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")
# Enable MPQ and OTR support
set(INCLUDE_MPQ_SUPPORT ON)
################################################################################
# Set CONTROLLERBUTTONS_T
################################################################################
@@ -165,6 +168,7 @@ add_compile_definitions(CONTROLLERBUTTONS_T=uint32_t)
################################################################################
add_subdirectory(libultraship ${CMAKE_BINARY_DIR}/libultraship)
target_compile_options(libultraship PRIVATE "${WARNING_OVERRIDE}")
target_compile_definitions(libultraship PUBLIC INCLUDE_MPQ_SUPPORT)
add_subdirectory(ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD)
add_subdirectory(OTRExporter)
add_subdirectory(soh)
@@ -194,7 +198,7 @@ add_custom_target(
# copy LUS default shaders into assets/custom
COMMAND ${CMAKE_COMMAND} -E rm -r -f ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/libultraship/src/graphic/Fast3D/shaders/ ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/libultraship/src/fast/shaders/ ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$<TARGET_FILE:ZAPD>" --non-interactive --xml-root assets/xml --custom-otr-file soh.o2r "--custom-assets-path" ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom --port-ver "${CMAKE_PROJECT_VERSION}"
COMMAND ${CMAKE_COMMAND} -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DTARGET_DIR="$<TARGET_FILE_DIR:ZAPD>" -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DBINARY_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/copy-existing-otrs.cmake
@@ -220,7 +224,7 @@ add_custom_target(
# copy LUS default shaders into assets/custom
COMMAND ${CMAKE_COMMAND} -E rm -r -f ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/libultraship/src/graphic/Fast3D/shaders/ ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/libultraship/src/fast/shaders/ ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom/shaders/
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/OTRExporter/extract_assets.py -z "$<TARGET_FILE:ZAPD>" --norom --custom-otr-file soh.o2r "--custom-assets-path" ${CMAKE_CURRENT_SOURCE_DIR}/soh/assets/custom --port-ver "${CMAKE_PROJECT_VERSION}"
COMMAND ${CMAKE_COMMAND} -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DTARGET_DIR="$<TARGET_FILE_DIR:ZAPD>" -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR} -DBINARY_DIR=${CMAKE_BINARY_DIR} -DONLYSOHOTR=On -P ${CMAKE_CURRENT_SOURCE_DIR}/copy-existing-otrs.cmake
+69 -3
View File
@@ -119,6 +119,72 @@ zypper in gcc gcc-c++ git cmake ninja SDL2-devel libpng16-devel libzip-devel lib
# or using clang
zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools nlohmann_json-devel tinyxml2-devel spdlog-devel
```
#### Nix
You can use a `flake.nix` file to instantly setup a development environment using [Nix](https://nixos.org/). Write this `flake.nix` file in the root directory:
```nix
{
description = "Shipwright development environment";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
# Build tools
clang
git
cmake
ninja
lsb-release
pkg-config
# SDL2 libraries
SDL2
SDL2.dev
SDL2_net
# Other libraries
libpng
libzip
nlohmann_json
tinyxml-2
spdlog
libGL
libGL.dev
bzip2
# X11 libraries
xorg.libX11
# Audio libraries
libogg
libogg.dev
libvorbis
libvorbis.dev
libopus
libopus.dev
opusfile
opusfile.dev
];
shellHook = ''
echo "Shipwright development environment loaded"
echo "Available tools: clang, git, cmake, ninja"
'';
};
});
}
```
Now type `nix develop` and you will be dropped into a shell with all dependencies, ensuring that all build commands work.
### Build
@@ -231,7 +297,7 @@ cmake --build build-cmake --target ExtractAssetHeaders
## Switch
1. Requires that your build machine is setup with the tools necessary for your platform above
2. Requires that you have the switch build tools installed
2. Requires that you have the switch build tools installed
3. Clone the Ship of Harkinian repository
4. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice
@@ -252,7 +318,7 @@ cmake --build build-switch --target soh_nro
## Wii U
1. Requires that your build machine is setup with the tools necessary for your platform above
2. Requires that you have the Wii U build tools installed
2. Requires that you have the Wii U build tools installed
3. Clone the Ship of Harkinian repository
4. Place one or more [compatible](#compatible-roms) roms in the `OTRExporter` directory with namings of your choice
@@ -265,7 +331,7 @@ cmake --build build-cmake --target ExtractAssets
# Setup cmake project for building for Wii U
cmake -H. -Bbuild-wiiu -GNinja -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/WiiU.cmake # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging)
# Build project and generate rpx
cmake --build build-wiiu --target soh # --target soh_wuhb (for building .wuhb)
cmake --build build-wiiu --target soh # --target soh_wuhb (for building .wuhb)
# Now you can run the executable in ./build-wiiu/soh/soh.rpx or the Wii U Homebrew Bundle in ./build-wiiu/soh/soh.wuhb
# To develop the project open the repository in VSCode (or your preferred editor)
+30 -30
View File
@@ -1,38 +1,38 @@
# SDL GameControllerDB
The Ship of Harkinian utilizes a text file with SDL controller mappings for extended controller hardware support.
This file is pulled from https://github.com/gabomdq/SDL_GameControllerDB during the build process as [a part of CMakeLists.txt](https://github.com/HarbourMasters/Shipwright/blob/bb643661f62865dfc757c185d0daaebb32f2d53d/soh/CMakeLists.txt#L760).
This file is pulled from https://github.com/mdqinc/SDL_GameControllerDB during the build process as [a part of CMakeLists.txt](https://github.com/HarbourMasters/Shipwright/blob/bb643661f62865dfc757c185d0daaebb32f2d53d/soh/CMakeLists.txt#L760).
## Released versions
| Release | sha | diff |
| - | - | - |
| Zhora Alfa 4.0.0 | [967daa8](https://github.com/gabomdq/SDL_GameControllerDB/tree/967daa8f89c48b01ed0f9c6a86ac849930442fc6) | |
| Zhora Bravo 4.0.1 | [ccac7cd](https://github.com/gabomdq/SDL_GameControllerDB/tree/ccac7cd97f445955d4437e21c5f82123d9b4349b) | [+1](https://github.com/gabomdq/SDL_GameControllerDB/compare/967daa8...ccac7cd) |
| Zhora Charlie 4.0.2 | [ff26eb0](https://github.com/gabomdq/SDL_GameControllerDB/tree/ff26eb04d0fe18356985d968119429d6012e7d75) | [+8/-3](https://github.com/gabomdq/SDL_GameControllerDB/compare/ccac7cd...ff26eb0) |
| Zhora Delta 4.0.3 | [ad02da5](https://github.com/gabomdq/SDL_GameControllerDB/tree/ad02da5a95ca8005f2c1facc11a5a52f8522f0ee) | [+4/-5](https://github.com/gabomdq/SDL_GameControllerDB/compare/ff26eb0...ad02da5) |
| Zohra Echo 4.0.4 | [c203690](https://github.com/gabomdq/SDL_GameControllerDB/tree/c203690b1e13980699802918d362cd9dadf89bd0) | [+8/-4](https://github.com/gabomdq/SDL_GameControllerDB/compare/ad02da5...c203690) |
| Zhora Foxtrot 4.0.5 | [9db8101](https://github.com/gabomdq/SDL_GameControllerDB/tree/9db8101a5780d1b0721bf6de385e6ffe0d07dfc7) | [+6](https://github.com/gabomdq/SDL_GameControllerDB/compare/c203690...9db8101) |
| Flynn Alfa 5.0.0 | [163cc5d](https://github.com/gabomdq/SDL_GameControllerDB/tree/163cc5d45e9fc2f1bb2b95ea7eee4bbc9a57955c) | [+29/-8](https://github.com/gabomdq/SDL_GameControllerDB/compare/9db8101...163cc5d) |
| Flynn Bravo 5.0.1 | [7efce7d](https://github.com/gabomdq/SDL_GameControllerDB/tree/7efce7d3f309ec1fa409b1af09153f9eb77fbedf) | [-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/163cc5d...7efce7d) |
| Flynn Charlie 5.0.2 | [e607703](https://github.com/gabomdq/SDL_GameControllerDB/tree/e607703392145343e8aca42be052121c0b7bd1c9) | [+40/-17](https://github.com/gabomdq/SDL_GameControllerDB/compare/7efce7d...e607703) |
| Bradley Alfa 5.1.0 | [2ba9676](https://github.com/gabomdq/SDL_GameControllerDB/tree/2ba96761af795c15e916cc97790b51e09dc0cd54) | [+1/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/e607703...2ba9676) |
| Bradley Charlie 5.1.2 | [4f5d1d4](https://github.com/gabomdq/SDL_GameControllerDB/tree/4f5d1d497985b75f4a83a5de46f596dc4d7f002e) | [+5/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/2ba9676...4f5d1d4) |
| Bradley Delta 5.1.3 | [9b73049](https://github.com/gabomdq/SDL_GameControllerDB/tree/9b73049ee62a2cc862d6ad94c2c777f2e8363a48) | [+4/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/4f5d1d4...9b73049) |
| Bradley Echo 5.1.4 | [6d3801f](https://github.com/gabomdq/SDL_GameControllerDB/tree/6d3801fcfe74b1989de96403b7b560eba72a175c) | [+56/-21](https://github.com/gabomdq/SDL_GameControllerDB/compare/9b73049...6d3801f) |
| Gibbs Alfa 6.0.0 | [0562b00](https://github.com/gabomdq/SDL_GameControllerDB/tree/0562b00eaf5c0308c49d329b79263d2dae1c3a85) | [+8/-2](https://github.com/gabomdq/SDL_GameControllerDB/compare/6d3801f...0562b00) |
| Khan Alfa 6.1.0 | [436c7e3](https://github.com/gabomdq/SDL_GameControllerDB/tree/436c7e3d54a57189ea0ab44d05f36b7cc7ea496c) | [+31/-16](https://github.com/gabomdq/SDL_GameControllerDB/compare/0562b00...436c7e3) |
| Khan Bravo 6.1.1 | [01cca2e](https://github.com/gabomdq/SDL_GameControllerDB/tree/01cca2e77f9bf9f1432be04f876f287eb78297fe) | [+23/-6](https://github.com/gabomdq/SDL_GameControllerDB/compare/436c7e3...01cca2e) |
| Khan Charlie 6.1.2 | [6852946](https://github.com/gabomdq/SDL_GameControllerDB/tree/6852946487534c69b7d228fd4eb8c87cf6966475) | [+25/-15](https://github.com/gabomdq/SDL_GameControllerDB/compare/01cca2e...6852946) |
| Spock Alfa 7.0.0 | [38bda81](https://github.com/gabomdq/SDL_GameControllerDB/tree/38bda816dc786f18493876f7bc30bc12dfd2636a) | [+15/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/6852946...38bda81) |
| Spock Bravo 7.0.1 | [228d980](https://github.com/gabomdq/SDL_GameControllerDB/tree/228d980d3d791e9df3b096472f6b97459f8709fe) | [+7/-3](https://github.com/gabomdq/SDL_GameControllerDB/compare/38bda81...228d980) |
| Spock Charlie 7.0.2 | [c5b4df0](https://github.com/gabomdq/SDL_GameControllerDB/tree/c5b4df0e1061175cb11e3ebbf8045178339864a5) | [+3](https://github.com/gabomdq/SDL_GameControllerDB/compare/228d980...c5b4df0) |
| Sulu Alfa 7.1.0 | [a2cf171](https://github.com/gabomdq/SDL_GameControllerDB/tree/a2cf1711b4ebc646a3814705d2fb6aac5707bcae) | [+4/-1](https://github.com/gabomdq/SDL_GameControllerDB/compare/c5b4df0...a2cf171) |
| Sulu Bravo 7.1.1 | [cc9f777](https://github.com/gabomdq/SDL_GameControllerDB/tree/cc9f777721f0cb30058d9eef52a295130b734a4a) | [+29/-9](https://github.com/gabomdq/SDL_GameControllerDB/compare/a2cf171...cc9f777) |
| MacReady Alfa 8.0.0 | [c56329f](https://github.com/gabomdq/SDL_GameControllerDB/tree/c56329f4df93fc7a780bdbeae47a9c91447b629c) | [+67/-23](https://github.com/gabomdq/SDL_GameControllerDB/compare/cc9f777...c56329f) |
| MacReady Bravo 8.0.1 | [721b575](https://github.com/gabomdq/SDL_GameControllerDB/tree/721b575d3053b21d6d30419bf74afb5b1d0fa7a4) | [+5/-5](https://github.com/gabomdq/SDL_GameControllerDB/compare/c56329f...721b575) |
| MacReady Charlie 8.0.2 | [721b575](https://github.com/gabomdq/SDL_GameControllerDB/tree/721b575d3053b21d6d30419bf74afb5b1d0fa7a4) | [+0/-0](https://github.com/gabomdq/SDL_GameControllerDB/compare/721b575...721b575) |
| MacReady Delta 8.0.3 | [d4ab609](https://github.com/gabomdq/SDL_GameControllerDB/tree/d4ab609121ee6e687bc3d3a7e80244b3b26d1164) | [+5/-3](https://github.com/gabomdq/SDL_GameControllerDB/compare/721b575...d4ab609) |
| MacReady Echo 8.0.4 | [6555d47](https://github.com/gabomdq/SDL_GameControllerDB/tree/6555d47ecb5d9eebac0e3d8cd19a545e9d946c40) | [+2/-0](https://github.com/gabomdq/SDL_GameControllerDB/compare/d4ab609...6555d47) |
| MacReady Foxtrot 8.0.5 | [037d6a1](https://github.com/gabomdq/SDL_GameControllerDB/tree/037d6a1533ed94fbc6a8c71e6f1f9aff1e46208a) | [+47/-14](https://github.com/gabomdq/SDL_GameControllerDB/compare/6555d47...037d6a1) |
| MacReady Golf 8.0.6 | [075c154](https://github.com/gabomdq/SDL_GameControllerDB/tree/075c1549075ef89a397fd7e0663d21e53a2485fd) | [+340/-301](https://github.com/gabomdq/SDL_GameControllerDB/compare/037d6a1...075c154) |
| Zhora Alfa 4.0.0 | [967daa8](https://github.com/mdqinc/SDL_GameControllerDB/tree/967daa8f89c48b01ed0f9c6a86ac849930442fc6) | |
| Zhora Bravo 4.0.1 | [ccac7cd](https://github.com/mdqinc/SDL_GameControllerDB/tree/ccac7cd97f445955d4437e21c5f82123d9b4349b) | [+1](https://github.com/mdqinc/SDL_GameControllerDB/compare/967daa8...ccac7cd) |
| Zhora Charlie 4.0.2 | [ff26eb0](https://github.com/mdqinc/SDL_GameControllerDB/tree/ff26eb04d0fe18356985d968119429d6012e7d75) | [+8/-3](https://github.com/mdqinc/SDL_GameControllerDB/compare/ccac7cd...ff26eb0) |
| Zhora Delta 4.0.3 | [ad02da5](https://github.com/mdqinc/SDL_GameControllerDB/tree/ad02da5a95ca8005f2c1facc11a5a52f8522f0ee) | [+4/-5](https://github.com/mdqinc/SDL_GameControllerDB/compare/ff26eb0...ad02da5) |
| Zohra Echo 4.0.4 | [c203690](https://github.com/mdqinc/SDL_GameControllerDB/tree/c203690b1e13980699802918d362cd9dadf89bd0) | [+8/-4](https://github.com/mdqinc/SDL_GameControllerDB/compare/ad02da5...c203690) |
| Zhora Foxtrot 4.0.5 | [9db8101](https://github.com/mdqinc/SDL_GameControllerDB/tree/9db8101a5780d1b0721bf6de385e6ffe0d07dfc7) | [+6](https://github.com/mdqinc/SDL_GameControllerDB/compare/c203690...9db8101) |
| Flynn Alfa 5.0.0 | [163cc5d](https://github.com/mdqinc/SDL_GameControllerDB/tree/163cc5d45e9fc2f1bb2b95ea7eee4bbc9a57955c) | [+29/-8](https://github.com/mdqinc/SDL_GameControllerDB/compare/9db8101...163cc5d) |
| Flynn Bravo 5.0.1 | [7efce7d](https://github.com/mdqinc/SDL_GameControllerDB/tree/7efce7d3f309ec1fa409b1af09153f9eb77fbedf) | [-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/163cc5d...7efce7d) |
| Flynn Charlie 5.0.2 | [e607703](https://github.com/mdqinc/SDL_GameControllerDB/tree/e607703392145343e8aca42be052121c0b7bd1c9) | [+40/-17](https://github.com/mdqinc/SDL_GameControllerDB/compare/7efce7d...e607703) |
| Bradley Alfa 5.1.0 | [2ba9676](https://github.com/mdqinc/SDL_GameControllerDB/tree/2ba96761af795c15e916cc97790b51e09dc0cd54) | [+1/-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/e607703...2ba9676) |
| Bradley Charlie 5.1.2 | [4f5d1d4](https://github.com/mdqinc/SDL_GameControllerDB/tree/4f5d1d497985b75f4a83a5de46f596dc4d7f002e) | [+5/-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/2ba9676...4f5d1d4) |
| Bradley Delta 5.1.3 | [9b73049](https://github.com/mdqinc/SDL_GameControllerDB/tree/9b73049ee62a2cc862d6ad94c2c777f2e8363a48) | [+4/-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/4f5d1d4...9b73049) |
| Bradley Echo 5.1.4 | [6d3801f](https://github.com/mdqinc/SDL_GameControllerDB/tree/6d3801fcfe74b1989de96403b7b560eba72a175c) | [+56/-21](https://github.com/mdqinc/SDL_GameControllerDB/compare/9b73049...6d3801f) |
| Gibbs Alfa 6.0.0 | [0562b00](https://github.com/mdqinc/SDL_GameControllerDB/tree/0562b00eaf5c0308c49d329b79263d2dae1c3a85) | [+8/-2](https://github.com/mdqinc/SDL_GameControllerDB/compare/6d3801f...0562b00) |
| Khan Alfa 6.1.0 | [436c7e3](https://github.com/mdqinc/SDL_GameControllerDB/tree/436c7e3d54a57189ea0ab44d05f36b7cc7ea496c) | [+31/-16](https://github.com/mdqinc/SDL_GameControllerDB/compare/0562b00...436c7e3) |
| Khan Bravo 6.1.1 | [01cca2e](https://github.com/mdqinc/SDL_GameControllerDB/tree/01cca2e77f9bf9f1432be04f876f287eb78297fe) | [+23/-6](https://github.com/mdqinc/SDL_GameControllerDB/compare/436c7e3...01cca2e) |
| Khan Charlie 6.1.2 | [6852946](https://github.com/mdqinc/SDL_GameControllerDB/tree/6852946487534c69b7d228fd4eb8c87cf6966475) | [+25/-15](https://github.com/mdqinc/SDL_GameControllerDB/compare/01cca2e...6852946) |
| Spock Alfa 7.0.0 | [38bda81](https://github.com/mdqinc/SDL_GameControllerDB/tree/38bda816dc786f18493876f7bc30bc12dfd2636a) | [+15/-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/6852946...38bda81) |
| Spock Bravo 7.0.1 | [228d980](https://github.com/mdqinc/SDL_GameControllerDB/tree/228d980d3d791e9df3b096472f6b97459f8709fe) | [+7/-3](https://github.com/mdqinc/SDL_GameControllerDB/compare/38bda81...228d980) |
| Spock Charlie 7.0.2 | [c5b4df0](https://github.com/mdqinc/SDL_GameControllerDB/tree/c5b4df0e1061175cb11e3ebbf8045178339864a5) | [+3](https://github.com/mdqinc/SDL_GameControllerDB/compare/228d980...c5b4df0) |
| Sulu Alfa 7.1.0 | [a2cf171](https://github.com/mdqinc/SDL_GameControllerDB/tree/a2cf1711b4ebc646a3814705d2fb6aac5707bcae) | [+4/-1](https://github.com/mdqinc/SDL_GameControllerDB/compare/c5b4df0...a2cf171) |
| Sulu Bravo 7.1.1 | [cc9f777](https://github.com/mdqinc/SDL_GameControllerDB/tree/cc9f777721f0cb30058d9eef52a295130b734a4a) | [+29/-9](https://github.com/mdqinc/SDL_GameControllerDB/compare/a2cf171...cc9f777) |
| MacReady Alfa 8.0.0 | [c56329f](https://github.com/mdqinc/SDL_GameControllerDB/tree/c56329f4df93fc7a780bdbeae47a9c91447b629c) | [+67/-23](https://github.com/mdqinc/SDL_GameControllerDB/compare/cc9f777...c56329f) |
| MacReady Bravo 8.0.1 | [721b575](https://github.com/mdqinc/SDL_GameControllerDB/tree/721b575d3053b21d6d30419bf74afb5b1d0fa7a4) | [+5/-5](https://github.com/mdqinc/SDL_GameControllerDB/compare/c56329f...721b575) |
| MacReady Charlie 8.0.2 | [721b575](https://github.com/mdqinc/SDL_GameControllerDB/tree/721b575d3053b21d6d30419bf74afb5b1d0fa7a4) | [+0/-0](https://github.com/mdqinc/SDL_GameControllerDB/compare/721b575...721b575) |
| MacReady Delta 8.0.3 | [d4ab609](https://github.com/mdqinc/SDL_GameControllerDB/tree/d4ab609121ee6e687bc3d3a7e80244b3b26d1164) | [+5/-3](https://github.com/mdqinc/SDL_GameControllerDB/compare/721b575...d4ab609) |
| MacReady Echo 8.0.4 | [6555d47](https://github.com/mdqinc/SDL_GameControllerDB/tree/6555d47ecb5d9eebac0e3d8cd19a545e9d946c40) | [+2/-0](https://github.com/mdqinc/SDL_GameControllerDB/compare/d4ab609...6555d47) |
| MacReady Foxtrot 8.0.5 | [037d6a1](https://github.com/mdqinc/SDL_GameControllerDB/tree/037d6a1533ed94fbc6a8c71e6f1f9aff1e46208a) | [+47/-14](https://github.com/mdqinc/SDL_GameControllerDB/compare/6555d47...037d6a1) |
| MacReady Golf 8.0.6 | [075c154](https://github.com/mdqinc/SDL_GameControllerDB/tree/075c1549075ef89a397fd7e0663d21e53a2485fd) | [+340/-301](https://github.com/mdqinc/SDL_GameControllerDB/compare/037d6a1...075c154) |
+4 -25
View File
@@ -413,31 +413,7 @@ endif()
target_include_directories(${PROJECT_NAME} PRIVATE assets
${CMAKE_CURRENT_SOURCE_DIR}/include/
${CMAKE_CURRENT_SOURCE_DIR}/src/
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/include
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/log
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/debug
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/menu
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/utils
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/utils/binarytools
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/config
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/resource
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/resource/type
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/resource/factory
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/audio
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/window
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/window/gui
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/config
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/public
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/public/libultra
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/public/bridge
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/extern
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/extern/tinyxml2
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/libjpeg/include/
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/graphic/Fast3D/U64/PR
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/graphic
${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD/resource/type
${SDL2-INCLUDE}
${SDL2-NET-INCLUDE}
@@ -597,6 +573,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
target_compile_options(${PROJECT_NAME} PRIVATE
-Wall -Wextra -Wno-error
-Wformat-security
-Wno-return-type
-Wno-unused-parameter
-Wno-unused-function
@@ -624,6 +601,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
elseif (CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
target_compile_options(${PROJECT_NAME} PRIVATE
-Wall -Wextra -Wno-error
-Wformat-security
-Wno-return-type
-Wno-unused-parameter
-Wno-unused-function
@@ -674,6 +652,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
target_compile_options(${PROJECT_NAME} PRIVATE
-Wall -Wextra -Wno-error
-Wformat-security
-Wno-unused-parameter
-Wno-unused-function
-Wno-unused-variable
@@ -839,7 +818,7 @@ INSTALL(FILES ${CMAKE_BINARY_DIR}/soh/soh.o2r DESTINATION . COMPONENT ship)
endif()
find_program(CURL NAMES curl DOC "Path to the curl program. Used to download files.")
execute_process(COMMAND ${CURL} -sSfL https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt -o ${CMAKE_BINARY_DIR}/gamecontrollerdb.txt OUTPUT_VARIABLE RESULT)
execute_process(COMMAND ${CURL} -sSfL https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/master/gamecontrollerdb.txt -o ${CMAKE_BINARY_DIR}/gamecontrollerdb.txt OUTPUT_VARIABLE RESULT)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/macosx/Info.plist.in ${CMAKE_BINARY_DIR}/macosx/Info.plist @ONLY)
+1 -1
View File
@@ -1,6 +1,6 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#include <ship/resource/Resource.h>
#include "properties.h"
#define APSTUDIO_READONLY_SYMBOLS
@@ -25,5 +25,5 @@
"quest_sel_vanilla": "Quest - Original",
"quest_sel_mq": "Quest - Master Quest",
"quest_sel_randomizer": "Quest - Randomizer",
"quest_sel_boss_rush": "Quest - Bosse Rush"
}
"quest_sel_boss_rush": "Quest - Boss Rush"
}
@@ -47,7 +47,7 @@
"28": "Blaues Feuer",
"29": "Käfer",
"30": "Nachtschwärmer",
"31": "Milch (1/2)",
"31": "Milch (Halbe Füllung)",
"32": "Irrlicht",
"33": "Seltsames Ei",
"34": "Huhn",
@@ -67,7 +67,7 @@
"48": "Schimmelpilz",
"49": "Modertrank",
"50": "Säge",
"51": "Goronen-Schwert (zerbrochen)",
"51": "Zerbr. Goronen-Schwert",
"52": "Rezept",
"53": "Glotzfrosch",
"54": "Augentropfen",
@@ -78,7 +78,7 @@
"59": "Kokiri-Schwert",
"60": "Master-Schwert",
"61": "Langschwert",
"62": "Deku-schild",
"62": "Deku-Schild",
"63": "Hylia-Schild",
"64": "Spiegel-Schild",
"65": "Kokiri-Rüstung",
@@ -99,13 +99,13 @@
"80": "Goronen-Armband",
"81": "Krafthandschuh",
"82": "Titanhandschuh",
"83": "Silberschuppe",
"84": "Goldschuppe",
"85": "Langschwert (gebrochen)",
"83": "Silberne Schuppe",
"84": "Goldene Schuppe",
"85": "Zerbr. Langschwert",
"86": "Große Börse",
"87": "Riesenbörse",
"88": "Deku-Kerne",
"89": "Angel",
"89": "Angelrute",
"90": "Menuett des Waldes",
"91": "Bolero des Feuers",
"92": "Serenade des Wassers",
@@ -117,7 +117,7 @@
"98": "Salias Lied",
"99": "Hymne der Sonne",
"100": "Hymne der Zeit",
"101": "Song of Storms",
"101": "Hymne des Sturms",
"102": "Amulett des Waldes",
"103": "Amulett des Feuers",
"104": "Amulett des Wassers",
@@ -125,7 +125,7 @@
"106": "Amulett des Schattens",
"107": "Amulett des Lichts",
"108": "Kokiri-Smaragd",
"109": "Goronen-Opal",
"109": "Goronen-Rubin",
"110": "Zora-Saphir",
"111": "Stein des Wissens",
"112": "Gerudo-Paß",
@@ -136,8 +136,8 @@
"117": "Kompaß",
"118": "Labyrinth-Karte",
"119": "Kleiner Schlüssel",
"120": "MAGIE KLEIN",
"121": "MAGIE GROß",
"120": "Kleine Magieflasche",
"121": "Große Magieflasche",
"122": "Biggoron-Schwert",
"123": "UNGÜLTIG 1",
"124": "UNGÜLTIG 2",
@@ -154,24 +154,24 @@
"135": "50 Rubine",
"136": "200 Rubine",
"137": "UNGÜLTIG 8",
"138": "STÄBE 5",
"139": "STÄBE 10",
"140": "NÜSSE 5",
"141": "NÜSSE 10",
"138": "DEKU-STÄBE 5",
"139": "DEKU-STÄBE 10",
"140": "DEKU-NÜSSE 5",
"141": "DEKU-NÜSSE 10",
"142": "BOMBEN 5",
"143": "BOMBEN 10",
"144": "BOMBEN 20",
"145": "BOMBEN 30",
"146": "PFEILE KLEIN",
"147": "PFEILE MITTEL",
"148": "PFEILE GROß",
"149": "KERNE 30",
"146": "PFEILE 5",
"147": "PFEILE 10",
"148": "PFEILE 30",
"149": "DEKU-KERNE 30",
"150": "KRABBELMINEN 5",
"151": "KRABBELMINEN 20",
"152": "STAB UPGRADE 20",
"153": "STAB UPGRADE 30",
"154": "NUß UPGRADE 30",
"155": "NUß UPGRADE 40",
"152": "DEKU-STAB-KAPAZITÄT 20",
"153": "DEKU-STAB-KAPAZITÄT 30",
"154": "DEKU-NUẞ-KAPAZITÄT 30",
"155": "DEKU-NUẞ-KAPAZITÄT 40",
"255": "",
"256": "Gespensterwüste",
"257": "Gerudo-Festung",
@@ -9,7 +9,7 @@
"7": "Schattentempel",
"8": "Grund des Brunnens",
"9": "Eishöhle",
"10": "", // Treppe zu Ganondorfs Verließ (Keine Title-Card)
"10": "", // Treppe zu Ganondorfs Verlies (Keine Title-Card)
"11": "Gerudo-Arena",
"12": "Diebesversteck",
"13": "Ganons Schloß",
@@ -22,7 +22,7 @@
"20": "Reitendes Unheil - Phantom-Ganon",
"21": "Subterraner Lavadrachoid - Volvagia",
"22": "Aquamöbes Wassertentakel - Morpha",
"23": "Höllische Hexenarmada - Killa Ohmaz",
"23": "Höllische Hexenarmada - Twinrova",
"24": "Bestialische Schattenmonstrosität - Bongo Bongo",
"25": "Großmeister des Bösen - Ganondorf",
"26": "",
@@ -109,4 +109,4 @@
"107": "",
"108": "", // Debug: SRD Raum (Keine Title-Card)
"109": "" // Debug: Schatzkisten Teleport (Keine Title-Card)
}
}
@@ -16,6 +16,7 @@
"EnemySpawnsOverWaterboxes": 1,
"FasterRupeeAccumulator": 1,
"FixBrokenGiantsKnife": 1,
"FixDampeGoingBackwards": 1,
"FixDaruniaDanceSpeed": 1,
"FixDungeonMinimapIcon": 1,
"FixEyesOpenWhileSleeping": 1,
@@ -45,6 +45,7 @@
"FishNeverEscape": 1,
"FixBrokenGiantsKnife": 1,
"FixDaruniaDanceSpeed": 1,
"FixDampeGoingBackwards": 1,
"FixDungeonMinimapIcon": 1,
"FixFloorSwitches": 1,
"FixHammerHand": 1,
@@ -17,6 +17,7 @@
"FasterRupeeAccumulator": 1,
"FixBrokenGiantsKnife": 1,
"FixDaruniaDanceSpeed": 1,
"FixDampeGoingBackwards": 1,
"FixDungeonMinimapIcon": 1,
"FixEyesOpenWhileSleeping": 1,
"FixFloorSwitches": 1,
@@ -34,6 +34,7 @@
"ShopsanityPrices": 2,
"Shuffle100GSReward": 1,
"ShuffleAdultTrade": 1,
"ShuffleBeanFairies": 1,
"ShuffleBeehives": 1,
"ShuffleBossEntrances": 2,
"ShuffleBossSouls": 2,
@@ -43,8 +44,9 @@
"ShuffleDekuNutBag": 1,
"ShuffleDekuStickBag": 1,
"ShuffleDungeonsEntrances": 2,
"ShuffleFairies": 1,
"ShuffleFairySpots": 1,
"ShuffleFishingPole": 1,
"ShuffleFountainFairies": 1,
"ShuffleFreestanding": 3,
"ShuffleFrogSongRupees": 1,
"ShuffleGanonBossKey": 9,
@@ -63,6 +65,7 @@
"ShufflePots": 3,
"ShuffleScrubs": 2,
"ShuffleSongs": 2,
"ShuffleStoneFairies": 1,
"ShuffleSwim": 1,
"ShuffleTokens": 3,
"ShuffleWarpSongs": 1,
+1 -1
View File
@@ -10,7 +10,7 @@ extern "C"
{
#endif
#include "luslog.h"
#include <libultraship/log/luslog.h>
#include <soh/Enhancements/item-tables/ItemTableTypes.h>
#if defined(INCLUDE_GAME_PRINTF) && defined(_DEBUG)
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef MACROS_H
#define MACROS_H
#include <endianness.h>
#include <ship/utils/binarytools/endianness.h>
// Upstream TODO: Document reasoning for change
// #ifndef __GNUC__
+1 -1
View File
@@ -1522,7 +1522,7 @@ typedef struct {
/* 0x34 */ s32 isEnabled;
} StickDirectionPrompt;
typedef struct {
typedef struct FileChooseContext {
/* 0x00000 */ GameState state;
/* 0x000A4 */ Vtx* windowVtx;
/* 0x000A8 */ u8* staticSegment;
+1 -1
View File
@@ -5,7 +5,7 @@
extern "C" {
#endif
#include <endianness.h>
#include <ship/utils/binarytools/endianness.h>
#define MK_CMD(b0,b1,b2,b3) ((((b0) & 0xFF) << 0x18) | (((b1) & 0xFF) << 0x10) | (((b2) & 0xFF) << 0x8) | (((b3) & 0xFF) << 0))
+1 -1
View File
@@ -7,7 +7,7 @@
#include "soh/Enhancements/randomizer/randomizerTypes.h"
#include "soh/Enhancements/gameplaystats.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
#include "soh/Enhancements/boss-rush/BossRush.h"
typedef enum {
/* 0x0 */ MAGIC_STATE_IDLE, // Regular gameplay
+1 -1
View File
@@ -19,7 +19,7 @@ static std::array<const char*, ACTORCAT_MAX> sCatToStrArray{
"SWITCH", "BG", "PLAYER", "EXPLOSIVE", "NPC", "ENEMY", "PROP", "ITEMACTION", "MISC", "BOSS", "DOOR", "CHEST",
};
#define DEFINE_SCENE(_1, _2, enumName, _4, _5, _6) #enumName
#define DEFINE_SCENE(_1, _2, enumName, _4, _5, _6) #enumName,
static std::array<const char*, SCENE_ID_MAX> sSceneIdToStrArray{
#include "tables/scene_table.h"
+51
View File
@@ -0,0 +1,51 @@
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "./enhancementTypes.h"
extern "C" {
#include "functions.h"
#include "macros.h"
extern PlayState* gPlayState;
extern SaveContext gSaveContext;
}
void RegisterBonkDamage() {
COND_HOOK(OnPlayerBonk, CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE) != BONK_DAMAGE_NONE,
[] {
uint16_t bonkDamage = 0;
switch (CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE)) {
case BONK_DAMAGE_NONE:
return;
case BONK_DAMAGE_OHKO:
gSaveContext.health = 0;
return;
case BONK_DAMAGE_QUARTER_HEART:
bonkDamage = 4;
break;
case BONK_DAMAGE_HALF_HEART:
bonkDamage = 8;
break;
case BONK_DAMAGE_1_HEART:
bonkDamage = 16;
break;
case BONK_DAMAGE_2_HEARTS:
bonkDamage = 32;
break;
case BONK_DAMAGE_4_HEARTS:
bonkDamage = 64;
break;
case BONK_DAMAGE_8_HEARTS:
bonkDamage = 128;
break;
default:
break;
}
Health_ChangeBy(gPlayState, -bonkDamage);
// Set invincibility to make Link flash red as a visual damage indicator.
Player* player = GET_PLAYER(gPlayState);
player->invincibilityTimer = 28;
});
}
static RegisterShipInitFunc initFunc(RegisterBonkDamage, { CVAR_ENHANCEMENT("BonkDamageMult") });
@@ -42,6 +42,5 @@ void RegisterBootToDebugWarpScreen() {
OnZTitleUpdateBootToDebugWarpScreen);
}
static RegisterShipInitFunc initFunc_BootToDebugWarpScreen(RegisterBootToDebugWarpScreen,
{ CVAR_DEBUG_ENABLED_NAME,
CVAR_BOOT_TO_DEBUG_WARP_SCREEN_NAME });
static RegisterShipInitFunc initFunc(RegisterBootToDebugWarpScreen,
{ CVAR_DEBUG_ENABLED_NAME, CVAR_BOOT_TO_DEBUG_WARP_SCREEN_NAME });
@@ -20,4 +20,4 @@ void RegisterNoKeeseGuayTarget() {
COND_VB_SHOULD(VB_GUAY_FORCE_FLY_AWAY, CVAR_NOKEESEGUAYTARGET_VALUE, { *should = true; });
}
static RegisterShipInitFunc initFunc_NoKeeseGuayTarget(RegisterNoKeeseGuayTarget, { CVAR_NOKEESEGUAYTARGET_NAME });
static RegisterShipInitFunc initFunc(RegisterNoKeeseGuayTarget, { CVAR_NOKEESEGUAYTARGET_NAME });
@@ -14,4 +14,4 @@ void RegisterNoRedeadFreeze() {
COND_VB_SHOULD(VB_REDEAD_GIBDO_FREEZE_LINK, CVAR_NOREDEADFREEZE_VALUE, { *should = false; });
}
static RegisterShipInitFunc initFunc_NoRedeadFreeze(RegisterNoRedeadFreeze, { CVAR_NOREDEADFREEZE_NAME });
static RegisterShipInitFunc initFunc(RegisterNoRedeadFreeze, { CVAR_NOREDEADFREEZE_NAME });
+16
View File
@@ -0,0 +1,16 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/ShipInit.hpp"
extern "C" PlayState* gPlayState;
void DisableSandstormAfterTransition(int16_t sceneNum) {
if (sceneNum == SCENE_HAUNTED_WASTELAND) {
gPlayState->envCtx.sandstormState = SANDSTORM_OFF;
}
}
void RegisterDisableSandstorm() {
COND_HOOK(OnTransitionEnd, CVarGetInteger(CVAR_CHEAT("DisableSandstorm"), 0), DisableSandstormAfterTransition);
}
static RegisterShipInitFunc initFunc(RegisterDisableSandstorm, { CVAR_CHEAT("DisableSandstorm") });
@@ -40,4 +40,4 @@ void RegisterRupeeDash() {
COND_HOOK(OnPlayerUpdate, CVAR_RUPEE_DASH_VALUE, UpdateRupeeDash);
}
static RegisterShipInitFunc initFunc_RupeeDash(RegisterRupeeDash, { CVAR_RUPEE_DASH_NAME });
static RegisterShipInitFunc initFunc(RegisterRupeeDash, { CVAR_RUPEE_DASH_NAME });
@@ -47,4 +47,4 @@ void RegisterShadowTag() {
COND_HOOK(OnSceneInit, true, [](int16_t) { ResetShadowTagSpawnTimer(); });
}
static RegisterShipInitFunc initFunc_ShadowTag(RegisterShadowTag, { CVAR_SHADOW_TAG_NAME });
static RegisterShipInitFunc initFunc(RegisterShadowTag, { CVAR_SHADOW_TAG_NAME });
@@ -0,0 +1,161 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/enhancementTypes.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
extern "C" {
extern SaveContext gSaveContext;
extern PlayState* gPlayState;
#include "macros.h"
#include "variables.h"
}
#define CVAR_NAME CVAR_ENHANCEMENT("3DSceneRender")
#define CVAR_VALUE CVarGetInteger(CVAR_NAME, 0)
std::vector<SceneID> fogControlList = {
SCENE_MARKET_ENTRANCE_DAY,
SCENE_MARKET_ENTRANCE_NIGHT,
SCENE_MARKET_ENTRANCE_RUINS,
SCENE_BACK_ALLEY_DAY,
SCENE_BACK_ALLEY_NIGHT,
SCENE_MARKET_DAY,
SCENE_MARKET_NIGHT,
SCENE_MARKET_RUINS,
SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY,
SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT,
SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS,
SCENE_KNOW_IT_ALL_BROS_HOUSE,
SCENE_TWINS_HOUSE,
SCENE_MIDOS_HOUSE,
SCENE_SARIAS_HOUSE,
SCENE_BACK_ALLEY_HOUSE,
SCENE_BAZAAR,
SCENE_KOKIRI_SHOP,
SCENE_GORON_SHOP,
SCENE_ZORA_SHOP,
SCENE_POTION_SHOP_KAKARIKO,
SCENE_POTION_SHOP_MARKET,
SCENE_BOMBCHU_SHOP,
SCENE_HAPPY_MASK_SHOP,
SCENE_LINKS_HOUSE,
SCENE_DOG_LADY_HOUSE,
SCENE_STABLE,
SCENE_IMPAS_HOUSE,
SCENE_CARPENTERS_TENT,
SCENE_GRAVEKEEPERS_HUT,
};
std::vector<SceneID> skyboxSceneControlList = {
SCENE_MARKET_ENTRANCE_DAY,
SCENE_MARKET_ENTRANCE_NIGHT,
SCENE_MARKET_ENTRANCE_RUINS,
SCENE_BACK_ALLEY_DAY,
SCENE_BACK_ALLEY_NIGHT,
SCENE_MARKET_DAY,
SCENE_MARKET_NIGHT,
SCENE_MARKET_RUINS,
SCENE_CASTLE_COURTYARD_ZELDA,
SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY,
SCENE_TEMPLE_OF_TIME_EXTERIOR_NIGHT,
SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS,
SCENE_FOREST_TEMPLE,
};
std::vector<SkyboxId> skyboxIdControlList = {
SKYBOX_BAZAAR,
SKYBOX_HOUSE_LINK,
SKYBOX_MARKET_ADULT,
SKYBOX_MARKET_CHILD_DAY,
SKYBOX_MARKET_CHILD_NIGHT,
SKYBOX_HAPPY_MASK_SHOP,
SKYBOX_HOUSE_KNOW_IT_ALL_BROTHERS,
SKYBOX_HOUSE_OF_TWINS,
SKYBOX_STABLES,
SKYBOX_HOUSE_KAKARIKO,
SKYBOX_KOKIRI_SHOP,
SKYBOX_GORON_SHOP,
SKYBOX_ZORA_SHOP,
SKYBOX_POTION_SHOP_KAKARIKO,
SKYBOX_POTION_SHOP_MARKET,
SKYBOX_HOUSE_RICHARD,
SKYBOX_HOUSE_IMPA,
SKYBOX_TENT,
SKYBOX_HOUSE_MIDO,
SKYBOX_HOUSE_SARIA,
SKYBOX_HOUSE_ALLEY,
};
void Register3DPreRenderedScenes() {
COND_HOOK(AfterSceneCommands, CVAR_VALUE, [](int16_t sceneNum) {
// Check if this scene is in the skyboxControlList
bool shouldControlSkybox = false;
for (const auto& scene : skyboxSceneControlList) {
if (sceneNum == scene) {
shouldControlSkybox = true;
break;
}
}
if (shouldControlSkybox) {
// Add a skybox on scenes from skyboxSceneControlList
gPlayState->envCtx.skyboxDisabled = false;
// Replace skybox with normal sky
gPlayState->skyboxId = SKYBOX_NORMAL_SKY;
// Apply the always cloudy skybox as an adult for Temple of Time and the Market
if (sceneNum == SCENE_TEMPLE_OF_TIME_EXTERIOR_RUINS || sceneNum == SCENE_MARKET_RUINS ||
sceneNum == SCENE_MARKET_ENTRANCE_RUINS) {
gWeatherMode = 3;
}
}
});
COND_HOOK(OnPlayDrawBegin, CVAR_VALUE, []() {
if (!CVarGetInteger(CVAR_ENHANCEMENT("3DSceneRender"), 0)) {
return;
}
for (auto& scene : fogControlList) {
if (scene == gPlayState->sceneNum) {
if ((HREG(80) != 10) || (HREG(82) != 0)) {
// Furthest possible fog and zFar
gPlayState->view.zFar = 12800;
gPlayState->lightCtx.fogNear = 996; // Set to 1000 to complete disable fog entirely
gPlayState->lightCtx.fogFar = 12800;
// General gray fog color
gPlayState->lightCtx.fogColor[0] = 100;
gPlayState->lightCtx.fogColor[1] = 100;
gPlayState->lightCtx.fogColor[2] = 100;
}
break;
}
}
});
REGISTER_VB_SHOULD(VB_DRAW_2D_BACKGROUND, {
if (CVAR_VALUE) {
*should = false;
return;
}
});
REGISTER_VB_SHOULD(VB_LOAD_SKYBOX, {
if (!gPlayState) {
return;
}
if (!CVAR_VALUE) {
return;
}
for (auto& skybox : skyboxIdControlList) {
if (gPlayState->skyboxCtx.skyboxId == skybox) {
gPlayState->skyboxCtx.unk_140 = 0;
*should = false;
return;
}
}
});
}
static RegisterShipInitFunc initFunc(Register3DPreRenderedScenes, { CVAR_NAME });
+7 -5
View File
@@ -2,11 +2,11 @@
#include <variant>
#include <string>
#include <fstream>
#include <config/Config.h>
#include <ship/config/Config.h>
#include <libultraship/classes.h>
#include <nlohmann/json.hpp>
#include <libultraship/libultraship.h>
#include <Json.h>
#include <ship/resource/type/Json.h>
#include "soh/OTRGlobals.h"
#include "soh/SohGui/MenuTypes.h"
#include "soh/SohGui/SohMenu.h"
@@ -395,7 +395,7 @@ void PresetsCustomWidget(WidgetInfo& info) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::AlignTextToFramePadding();
ImGui::Text(name.c_str());
ImGui::Text("%s", name.c_str());
for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) {
ImGui::TableNextColumn();
DrawSectionCheck(name, !info.presetValues["blocks"].contains(blockInfo[i].names[1]), &info.apply[i],
@@ -437,10 +437,12 @@ void PresetsCustomWidget(WidgetInfo& info) {
void RegisterPresetsWidgets() {
SohGui::mSohMenu->AddSidebarEntry("Settings", "Presets", 1);
WidgetPath path = { "Settings", "Presets", SECTION_COLUMN_1 };
SohGui::mSohMenu->AddWidget(path, "PresetsWidget", WIDGET_CUSTOM).CustomFunction(PresetsCustomWidget);
SohGui::mSohMenu->AddWidget(path, "PresetsWidget", WIDGET_CUSTOM)
.CustomFunction(PresetsCustomWidget)
.HideInSearch(true);
presetFolder = Ship::Context::GetInstance()->GetPathRelativeToAppDirectory("presets");
std::fill_n(saveSection, PRESET_SECTION_MAX, true);
LoadPresets();
}
static RegisterMenuInitFunc initFunc(RegisterPresetsWidgets);
static RegisterMenuInitFunc menuInitFunc(RegisterPresetsWidgets);
+1 -1
View File
@@ -66,4 +66,4 @@ void RegisterDaytimeGoldSkultullas() {
COND_HOOK(OnSceneSpawnActors, CVAR_DAYTIME_GS_VALUE, OnSpawnNighttimeGoldSkulltula);
}
static RegisterShipInitFunc initFunc_DaytimeGoldSkulltulas(RegisterDaytimeGoldSkultullas, { CVAR_DAYTIME_GS_NAME });
static RegisterShipInitFunc initFunc(RegisterDaytimeGoldSkultullas, { CVAR_DAYTIME_GS_NAME });
@@ -0,0 +1,72 @@
#include <libultraship/bridge/consolevariablebridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "functions.h"
#include "soh/Enhancements/enhancementTypes.h"
#include "soh/resource/type/Scene.h"
#include "soh/resource/type/scenecommand/SceneCommand.h"
#include "soh/resource/type/scenecommand/SetCollisionHeader.h"
#define CVAR_GRAVE_HOLE_NAME CVAR_ENHANCEMENT("GraveHoles")
#define GRAVE_HOLES_DEFAULT 0
#define CVAR_GRAVE_HOLE_VALUE CVarGetInteger(CVAR_GRAVE_HOLE_NAME, GRAVE_HOLES_DEFAULT)
#define GRAVEYARD_SCENE_FILEPATH "scenes/shared/spot02_scene/spot02_scene"
#define CUSTOM_SURFACE_TYPE 32
const static std::array<std::pair<std::pair<u16, u16>, std::pair<u16, u16>>, 6> graveyardGeometryPatches = { {
// { { startPolygon, endPolygon }, { originalSurfaceType, patchedSurfaceType } }
{ { 487, 509 }, { 20, CUSTOM_SURFACE_TYPE } }, // Floor around graves
{ { 651, 658 }, { 20, CUSTOM_SURFACE_TYPE } }, // Floor around Royal Family Tomb
{ { 613, 620 }, { 0, 15 } }, // Grave ledges (Hylian Shield)
{ { 623, 630 }, { 0, 15 } }, // Grave ledges (Redead)
{ { 633, 640 }, { 0, 15 } }, // Grave ledges (Dampe)
{ { 643, 650 }, { 0, 15 } }, // Grave ledges (Royal Family)
} };
CollisionHeader* getGraveyardCollisionHeader() {
/*
* Load the graveyard collision header manually. Since its position varies between versions, we cannot directly use
* dspot02_sceneCollisionHeader_003C54. We have to scroll through the scene cmds to get the header the same way the
* game does.
*/
SOH::Scene* scene =
(SOH::Scene*)Ship::Context::GetInstance()->GetResourceManager()->LoadResource(GRAVEYARD_SCENE_FILEPATH).get();
SOH::ISceneCommand* sceneCmd = nullptr;
for (int i = 0; i < scene->commands.size(); i++) {
auto cmd = scene->commands[i];
if (cmd->cmdId == SOH::SceneCommandID::SetCollisionHeader) {
sceneCmd = cmd.get();
break;
}
}
CollisionHeader* graveyardColHeader = (CollisionHeader*)((SOH::SetCollisionHeader*)sceneCmd)->GetRawPointer();
/*
* Copy the surface type list and give ourselves some extra space to create another surface type for Link to fall
* into graves. NTSC 1.0's graveyard has 31 surface types, while later versions have 32. The contents of the lists
* are shifted somewhat between versions, so to be safe we just create an extra slot that is not in any version.
*/
static SurfaceType newSurfaceTypes[33];
memcpy(newSurfaceTypes, graveyardColHeader->surfaceTypeList, sizeof(SurfaceType) * 33);
newSurfaceTypes[CUSTOM_SURFACE_TYPE].data[0] = 0x24000004;
newSurfaceTypes[CUSTOM_SURFACE_TYPE].data[1] = 0xFC8;
graveyardColHeader->surfaceTypeList = newSurfaceTypes;
return graveyardColHeader;
}
void ApplyGraveyardGeometryPatches() {
static CollisionHeader* graveyardColHeader = getGraveyardCollisionHeader();
for (auto& mappingPatch : graveyardGeometryPatches) {
for (int i = mappingPatch.first.first; i <= mappingPatch.first.second; i++) {
CollisionPoly* poly = &graveyardColHeader->polyList[i];
poly->type = CVAR_GRAVE_HOLE_VALUE ? mappingPatch.second.first : mappingPatch.second.second;
}
}
}
void RegisterGraveHoleJumps() {
ApplyGraveyardGeometryPatches();
}
static RegisterShipInitFunc initFunc(RegisterGraveHoleJumps, { CVAR_GRAVE_HOLE_NAME });
@@ -1,4 +1,4 @@
#include "public/bridge/consolevariablebridge.h"
#include <libultraship/bridge/consolevariablebridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/ShipInit.hpp"
@@ -1,7 +1,7 @@
#include "WeirdAnimation.h"
#include "resource/ResourceManager.h"
#include "Context.h"
#include <ship/resource/ResourceManager.h>
#include <ship/Context.h>
#include <cassert>
#include <cstring>
@@ -0,0 +1,30 @@
#include <libultraship/bridge/consolevariablebridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
}
#define CVAR_WIDE_SHUTTER_DOOR_RANGE CVAR_ENHANCEMENT("WideShutterDoorRange")
#define WIDE_SHUTTER_DOOR_RANGE_DEFAULT 0
#define CVAR_WIDE_SHUTTER_DOOR_RANGE_VALUE CVarGetInteger(CVAR_WIDE_SHUTTER_DOOR_RANGE, WIDE_SHUTTER_DOOR_RANGE_DEFAULT)
// The X range is 70 on NTSC 1.0 and 50 in later versions. The Y range is 15 in any version.
// https://github.com/zeldaret/oot/blob/6ecb84097c1a9a8426f3815c84aa6a5d49ad5804/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c#L248-L259
#define SHUTTER_DOOR_RANGE_X 70
#define SHUTTER_DOOR_RANGE_Y 15
void RegisterWideShutterDoorRange() {
COND_VB_SHOULD(VB_BE_NEAR_DOOR_SHUTTER, CVAR_WIDE_SHUTTER_DOOR_RANGE_VALUE, {
DoorShutter* doorShutter = va_arg(args, DoorShutter*);
Vec3f relPlayerPos = *va_arg(args, Vec3f*);
// Jabu-Jabu door, Phantom Ganon bars, Gohma door, or boss door
if (doorShutter->unk_16C == 3 || doorShutter->unk_16C == 4 || doorShutter->unk_16C == 5 ||
doorShutter->unk_16C == 7) {
*should = (SHUTTER_DOOR_RANGE_X < fabsf(relPlayerPos.x) || SHUTTER_DOOR_RANGE_Y < fabsf(relPlayerPos.y));
}
});
}
static RegisterShipInitFunc initFunc(RegisterWideShutterDoorRange, { CVAR_WIDE_SHUTTER_DOOR_RANGE });
+13 -3
View File
@@ -1,4 +1,5 @@
#include <libultraship/bridge.h>
#include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "global.h"
@@ -102,9 +103,18 @@ void CrawlSpeed_Register() {
COND_VB_SHOULD(VB_CRAWL_SPEED_INCREASE, shouldRegister, {
Player* player = GET_PLAYER(gPlayState);
IncreaseCrawlSpeed(player, gPlayState);
*should = false;
bool isMQ = ResourceMgr_IsGameMasterQuest();
bool boulderExists = !Flags_GetSwitch(gPlayState, 5);
bool excludeSpiritMQBoulder =
(gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE && player->actor.world.pos.z < -545.0f &&
player->actor.world.pos.z > -630.0f && isMQ && boulderExists);
if (excludeSpiritMQBoulder) {
*should = true;
} else {
IncreaseCrawlSpeed(player, gPlayState);
*should = false;
}
});
}
static RegisterShipInitFunc initSpeed(CrawlSpeed_Register, { CVAR_CRAWL_SPEED_NAME });
static RegisterShipInitFunc initFunc(CrawlSpeed_Register, { CVAR_CRAWL_SPEED_NAME });
@@ -2,6 +2,7 @@
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/Enhancements/randomizer/context.h"
#include "soh/ShipInit.hpp"
#include "soh/Enhancements/timesaver_hook_handlers.h"
extern "C" {
#include "macros.h"
@@ -10,7 +11,9 @@ extern "C" {
#include "functions.h"
#include "variables.h"
}
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
extern "C" PlayState* gPlayState;
static bool sEnteredBlueWarp = false;
// Todo: Move item queueing here
@@ -64,7 +67,16 @@ void RegisterSkipBlueWarp() {
* to the player instead.
*/
COND_VB_SHOULD(VB_GIVE_ITEM_FROM_BLUE_WARP,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), { *should = false; });
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), {
if (IS_VANILLA) {
if (gPlayState->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) {
TimeSaverQueueItem(RG_SHADOW_MEDALLION);
} else if (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) {
TimeSaverQueueItem(RG_SPIRIT_MEDALLION);
}
}
*should = false;
});
}
void RegisterShouldPlayBlueWarp() {
@@ -156,8 +168,9 @@ void RegisterShouldPlayBlueWarp() {
}
// This is outside the above condition because we want to handle both first and following visits to the blue
// warp
if (sEnteredBlueWarp && overrideBlueWarpDestinations) {
// warp. Jabu's blue warp doesn't call VB_PLAY_BLUE_WARP_CS without Ruto
if ((sEnteredBlueWarp || gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP) &&
overrideBlueWarpDestinations) {
Entrance_OverrideBlueWarp();
}
}
+10 -1
View File
@@ -2,8 +2,9 @@
#include "sequence.h"
#include "sfx.h"
#include "soh/cvar_prefixes.h"
#include "soh/Notification/Notification.h"
#include <vector>
#include <utils/StringHelper.h>
#include <ship/utils/StringHelper.h>
#include <libultraship/bridge.h>
#include <libultraship/classes.h>
#include <soh/OTRGlobals.h>
@@ -458,3 +459,11 @@ extern "C" bool AudioCollection_HasSequenceNum(uint16_t seqId) {
extern "C" size_t AudioCollection_SequenceMapSize() {
return AudioCollection::Instance->SequenceMapSize();
}
extern "C" void AudioCollection_EmitSongNameNotification(s32 seqId) {
const char* sequenceName = AudioCollection_GetSequenceName(seqId);
if (sequenceName != NULL) {
Notification::Emit({ .message = "Currently playing: " + std::string(sequenceName),
.remainingTime = (float)CVarGetInteger(CVAR_AUDIO("SeqNameOverlayDuration"), 5) });
}
}
@@ -73,4 +73,5 @@ void AudioCollection_AddToCollection(char* otrPath, uint16_t seqNum);
const char* AudioCollection_GetSequenceName(uint16_t seqId);
bool AudioCollection_HasSequenceNum(uint16_t seqId);
size_t AudioCollection_SequenceMapSize();
void AudioCollection_EmitSongNameNotification(s32 seqId);
#endif
+120 -59
View File
@@ -10,8 +10,8 @@
#include "../randomizer/3drando/random.hpp"
#include "soh/OTRGlobals.h"
#include "soh/cvar_prefixes.h"
#include <utils/StringHelper.h>
#include "soh/SohGui/UIWidgets.hpp"
#include <ship/utils/StringHelper.h>
#include "soh/SohGui/SohMenu.h"
#include "soh/SohGui/SohGui.hpp"
#include "AudioCollection.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
@@ -25,6 +25,23 @@ Vec3f pos = { 0.0f, 0.0f, 0.0f };
f32 freqScale = 1.0f;
s8 reverbAdd = 0;
using namespace UIWidgets;
static WidgetInfo lowHpAlarm;
static WidgetInfo naviCall;
static WidgetInfo enemyProx;
static WidgetInfo leadingMusic;
static WidgetInfo displaySeqName;
static WidgetInfo ovlDuration;
static WidgetInfo voicePitch;
static WidgetInfo randoMusicOnSceneChange;
static WidgetInfo randomAudioOnSeedGen;
static WidgetInfo lowerOctaves;
namespace SohGui {
extern std::shared_ptr<SohMenu> mSohMenu;
}
// Authentic sequence counts
// used to ensure we have enough to shuffle
#define SEQ_COUNT_BGM_WORLD 30
@@ -468,8 +485,17 @@ void AudioEditorRegisterOnSceneInitHook() {
});
}
void AudioEditorRegisterOnGenerationCompletionHook() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGenerationCompletion>([]() {
if (CVarGetInteger(CVAR_AUDIO("RandomizeAllOnRandoGen"), 0)) {
AudioEditor_RandomizeAll();
}
});
}
void AudioEditor::InitElement() {
AudioEditorRegisterOnSceneInitHook();
AudioEditorRegisterOnGenerationCompletionHook();
}
void AudioEditor::DrawElement() {
@@ -518,69 +544,22 @@ void AudioEditor::DrawElement() {
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginChild("SfxOptions", ImVec2(0, -8))) {
UIWidgets::CVarCheckbox(
"Mute Low HP Alarm", CVAR_AUDIO("LowHpAlarm"),
UIWidgets::CheckboxOptions().Color(THEME_COLOR).Tooltip("Disable the low HP beeping sound."));
UIWidgets::CVarCheckbox("Disable Navi Call Audio", CVAR_AUDIO("DisableNaviCallAudio"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Disables the voice audio when Navi calls you."));
UIWidgets::CVarCheckbox(
"Disable Enemy Proximity Music", CVAR_AUDIO("EnemyBGMDisable"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Disables the music change when getting close to enemies. Useful for hearing "
"your custom music for each scene more often."));
UIWidgets::CVarCheckbox(
"Disable Leading Music in Lost Woods", CVAR_AUDIO("LostWoodsConsistentVolume"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Disables the volume shifting in the Lost Woods. Useful for hearing "
"your custom music in the Lost Woods if you don't need the navigation assitance "
"the volume changing provides. If toggling this while in the Lost Woods, reload "
"the area for the effect to kick in."));
UIWidgets::CVarCheckbox(
"Display Sequence Name on Overlay", CVAR_AUDIO("SeqNameOverlay"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Displays the name of the current sequence in the corner of the screen whenever a new "
"sequence "
"is loaded to the main sequence player (does not apply to fanfares or enemy BGM)."));
UIWidgets::CVarSliderInt("Overlay Duration: %d seconds", CVAR_AUDIO("SeqNameOverlayDuration"),
UIWidgets::IntSliderOptions()
.Min(1)
.Max(10)
.DefaultValue(5)
.Size(ImVec2(300.0f, 0.0f))
.Color(THEME_COLOR));
UIWidgets::CVarSliderFloat("Link's voice pitch multiplier", CVAR_AUDIO("LinkVoiceFreqMultiplier"),
UIWidgets::FloatSliderOptions()
.IsPercentage()
.Min(0.4f)
.Max(2.5f)
.DefaultValue(1.0f)
.Size(ImVec2(300.0f, 0.0f))
.Color(THEME_COLOR));
SohGui::mSohMenu->MenuDrawItem(lowHpAlarm, ImGui::GetContentRegionAvail().x, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(naviCall, ImGui::GetContentRegionAvail().x, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(enemyProx, ImGui::GetContentRegionAvail().x, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(leadingMusic, ImGui::GetContentRegionAvail().x, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(displaySeqName, ImGui::GetContentRegionAvail().x, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(ovlDuration, ImGui::GetContentRegionAvail().x, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(voicePitch, ImGui::GetContentRegionAvail().x, THEME_COLOR);
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetCursorPos().y + 40.f);
if (UIWidgets::Button("Reset##linkVoiceFreqMultiplier",
UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) {
CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f);
}
UIWidgets::CVarCheckbox(
"Randomize All Music and Sound Effects on New Scene", CVAR_AUDIO("RandomizeAllOnNewScene"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip(
"Enables randomizing all unlocked music and sound effects when you enter a new scene."));
UIWidgets::CVarCheckbox(
"Lower Octaves of Unplayable High Notes", CVAR_AUDIO("ExperimentalOctaveDrop"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Some custom sequences may have notes that are too high for the game's audio "
"engine to play. Enabling this checkbox will cause these notes to drop a "
"couple of octaves so they can still harmonize with the other notes of the "
"sequence."));
SohGui::mSohMenu->MenuDrawItem(randoMusicOnSceneChange, ImGui::GetContentRegionAvail().x, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(randomAudioOnSeedGen, ImGui::GetContentRegionAvail().x, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(lowerOctaves, ImGui::GetContentRegionAvail().x, THEME_COLOR);
}
ImGui::EndChild();
ImGui::EndTable();
@@ -834,3 +813,85 @@ void AudioEditor_UnlockAll() {
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
}
void RegisterAudioWidgets() {
lowHpAlarm = { .name = "Mute Low HP Alarm", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
lowHpAlarm.CVar(CVAR_AUDIO("LowHpAlarm"))
.Options(CheckboxOptions().Color(THEME_COLOR).Tooltip("Disable the low HP beeping sound."));
SohGui::mSohMenu->AddSearchWidget({ lowHpAlarm, "Enhancements", "Audio Editor", "Audio Options" });
naviCall = { .name = "Disable Navi Call Audio", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
naviCall.CVar(CVAR_AUDIO("DisableNaviCallAudio"))
.Options(CheckboxOptions().Color(THEME_COLOR).Tooltip("Disables the voice audio when Navi calls you."));
SohGui::mSohMenu->AddSearchWidget({ naviCall, "Enhancements", "Audio Editor", "Audio Options" });
enemyProx = { .name = "Disable Enemy Proximity Music", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
enemyProx.CVar(CVAR_AUDIO("EnemyBGMDisable"))
.Options(CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Disables the music change when getting close to enemies. Useful for hearing "
"your custom music for each scene more often."));
leadingMusic = { .name = "Disable Leading Music in Lost Woods", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
leadingMusic.CVar(CVAR_AUDIO("LostWoodsConsistentVolume"))
.Options(CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Disables the volume shifting in the Lost Woods. Useful for hearing "
"your custom music in the Lost Woods if you don't need the navigation assitance "
"the volume changing provides. If toggling this while in the Lost Woods, reload "
"the area for the effect to kick in."));
SohGui::mSohMenu->AddSearchWidget({ leadingMusic, "Enhancements", "Audio Editor", "Audio Options" });
displaySeqName = { .name = "Display Sequence Name in Notifications", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
displaySeqName.CVar(CVAR_AUDIO("SeqNameNotification"))
.Options(CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Emits a notification with the current song name whenever it changes. "
"(does not apply to fanfares or enemy BGM)."));
SohGui::mSohMenu->AddSearchWidget({ displaySeqName, "Enhancements", "Audio Editor", "Audio Options" });
ovlDuration = { .name = "Sequence Notification Duration: %d seconds", .type = WidgetType::WIDGET_CVAR_SLIDER_INT };
ovlDuration.CVar(CVAR_AUDIO("SeqNameNotificationDuration"))
.Options(IntSliderOptions().Color(THEME_COLOR).Min(1).Max(20).DefaultValue(10).Size(ImVec2(300.0f, 0.0f)));
SohGui::mSohMenu->AddSearchWidget({ ovlDuration, "Enhancements", "Audio Editor", "Audio Options" });
voicePitch = { .name = "Link's Voice Pitch Multiplier", .type = WidgetType::WIDGET_CVAR_SLIDER_FLOAT };
voicePitch.CVar(CVAR_AUDIO("LinkVoiceFreqMultiplier"))
.Options(FloatSliderOptions()
.Color(THEME_COLOR)
.IsPercentage()
.Min(0.4f)
.Max(2.5f)
.DefaultValue(1.0f)
.Size(ImVec2(300.0f, 0.0f)));
SohGui::mSohMenu->AddSearchWidget({ voicePitch, "Enhancements", "Audio Editor", "Audio Options" });
randoMusicOnSceneChange = { .name = "Randomize All Music and Sound Effects on New Scene",
.type = WidgetType::WIDGET_CVAR_CHECKBOX };
randoMusicOnSceneChange.CVar(CVAR_AUDIO("RandomizeAllOnNewScene"))
.Options(CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Enables randomizing all unlocked music and sound effects when you enter a new scene."));
SohGui::mSohMenu->AddSearchWidget({ randoMusicOnSceneChange, "Enhancements", "Audio Editor", "Audio Options" });
randomAudioOnSeedGen = { .name = "Randomize All Music and Sound Effects on Randomizer Generation",
.type = WidgetType::WIDGET_CVAR_CHECKBOX };
randomAudioOnSeedGen.CVar(CVAR_AUDIO("RandomizeAllOnRandoGen"))
.Options(CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Enables randomizing all unlocked music and sound effects when you generate a new "
"randomizer. Respects locks already in place."));
SohGui::mSohMenu->AddSearchWidget({ randomAudioOnSeedGen, "Enhancements", "Audio Editor", "Audio Options" });
lowerOctaves = { .name = "Lower Octaves of Unplayable High Notes", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
lowerOctaves.CVar(CVAR_AUDIO("ExperimentalOctaveDrop"))
.Options(CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Some custom sequences may have notes that are too high for the game's audio "
"engine to play. Enabling this checkbox will cause these notes to drop a "
"couple of octaves so they can still harmonize with the other notes of the "
"sequence."));
SohGui::mSohMenu->AddSearchWidget({ lowerOctaves, "Enhancements", "Audio Editor", "Audio Options" });
}
static RegisterMenuInitFunc menuInitFunc(RegisterAudioWidgets);
+43
View File
@@ -0,0 +1,43 @@
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "AudioCollection.h"
#include <soh/Notification/Notification.h>
#include <soh/SohGui/ImGuiUtils.h>
extern "C" {
#include "variables.h"
extern PlayState* gPlayState;
}
#define CVAR_SEQOVERLAY_NAME CVAR_AUDIO("SeqNameNotification")
#define CVAR_SEQOVERLAY_DEFAULT 0
#define CVAR_SEQOVERLAY_VALUE CVarGetInteger(CVAR_SEQOVERLAY_NAME, CVAR_SEQOVERLAY_DEFAULT)
void NotifySequenceName(int32_t playerIdx, int32_t seqId) {
// Keep track of the previous sequence/scene so we don't repeat notifications
static uint16_t previousSeqId = UINT16_MAX;
static int16_t previousSceneNum = INT16_MAX;
if (playerIdx == SEQ_PLAYER_BGM_MAIN &&
(seqId != previousSeqId || (gPlayState != NULL && gPlayState->sceneNum != previousSceneNum))) {
previousSeqId = seqId;
if (gPlayState != NULL) {
previousSceneNum = gPlayState->sceneNum;
}
const char* sequenceName = AudioCollection::Instance->GetSequenceName(seqId);
if (sequenceName != NULL) {
Notification::Emit({
.message = ICON_FA_MUSIC " " + std::string(sequenceName),
.remainingTime = static_cast<float>(CVarGetInteger(CVAR_AUDIO("SeqNameNotificationDuration"), 10)),
.mute = true,
});
}
}
}
void RegisterAudioNotificationHooks() {
COND_HOOK(OnSeqPlayerInit, CVAR_SEQOVERLAY_VALUE, NotifySequenceName);
}
static RegisterShipInitFunc initFunc(RegisterAudioNotificationHooks, { CVAR_SEQOVERLAY_NAME });
+291 -52
View File
@@ -2,6 +2,8 @@
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh_assets.h"
#include "soh/frame_interpolation.h"
#include <array>
#include <string>
@@ -14,14 +16,87 @@ extern "C" {
#include "src/overlays/actors/ovl_Boss_Goma/z_boss_goma.h"
#include "src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h"
#include "src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
extern PlayState* gPlayState;
Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point);
#include "src/overlays/gamestates/ovl_file_choose/file_choose.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "textures/icon_item_nes_static/icon_item_nes_static.h"
#include "textures/icon_item_ger_static/icon_item_ger_static.h"
#include "textures/icon_item_fra_static/icon_item_fra_static.h"
extern PlayState* gPlayState;
Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point);
void FileChoose_UpdateStickDirectionPromptAnim(GameState* thisx);
void FileChoose_DrawTextRec(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a, f32 x, f32 y, f32 z, s32 s, s32 t,
f32 dx, f32 dy);
}
typedef enum {
BR_CHOICE_BOSSES_ALL,
BR_CHOICE_BOSSES_CHILD,
BR_CHOICE_BOSSES_ADULT,
BR_CHOICE_BOSSES_GANONDORF_GANON
} BossRushBossesChoices;
typedef enum {
BR_CHOICE_HEARTS_10,
BR_CHOICE_HEARTS_15,
BR_CHOICE_HEARTS_20,
BR_CHOICE_HEARTS_3,
BR_CHOICE_HEARTS_5,
BR_CHOICE_HEARTS_7
} BossRushHeartsChoices;
typedef enum {
BR_CHOICE_AMMO_LIMITED,
BR_CHOICE_AMMO_FULL,
BR_CHOICE_AMMO_MAXED,
} BossRushAmmoChoices;
typedef enum {
BR_CHOICE_HEAL_GANONDORF,
BR_CHOICE_HEAL_EVERYBOSS,
BR_CHOICE_HEAL_NEVER,
} BossRushHealChoices;
typedef enum {
BR_CHOICE_MAGIC_SINGLE,
BR_CHOICE_MAGIC_DOUBLE,
} BossRushMagicChoices;
typedef enum {
BR_CHOICE_BGS_NO,
BR_CHOICE_BGS_YES,
} BossRushBgsChoices;
typedef enum {
BR_CHOICE_BOTTLE_NO,
BR_CHOICE_BOTTLE_EMPTY,
BR_CHOICE_BOTTLE_FAIRY,
BR_CHOICE_BOTTLE_REDPOTION,
BR_CHOICE_BOTTLE_GREENPOTION,
BR_CHOICE_BOTTLE_BLUEPOTION
} BossRushBottleChoices;
typedef enum {
BR_CHOICE_LONGSHOT_NO,
BR_CHOICE_LONGSHOT_YES,
} BossRushLongshotChoices;
typedef enum {
BR_CHOICE_HOVERBOOTS_NO,
BR_CHOICE_HOVERBOOTS_YES,
} BossRushHoverBootsChoices;
typedef enum {
BR_CHOICE_BUNNYHOOD_NO,
BR_CHOICE_BUNNYHOOD_YES,
} BossRushBunnyHoodChoices;
typedef enum {
BR_CHOICE_TIMER_YES,
BR_CHOICE_TIMER_NO,
} BossRushTimerChoices;
typedef struct BossRushSetting {
std::array<std::string, LANGUAGE_MAX> name;
std::vector<std::array<std::string, LANGUAGE_MAX>> choices;
@@ -114,6 +189,180 @@ u8 BossRush_GetSettingOptionsAmount(u8 optionIndex) {
return static_cast<u8>(BossRushOptions[optionIndex].choices.size());
}
void FileChoose_UpdateBossRushMenu(GameState* gameState) {
static s8 sLastBossRushOptionIndex = -1;
static s8 sLastBossRushOptionValue = -1;
FileChoose_UpdateStickDirectionPromptAnim(gameState);
FileChooseContext* fileChooseContext = (FileChooseContext*)gameState;
Input* input = &fileChooseContext->state.input[0];
bool dpad = CVarGetInteger(CVAR_SETTING("DpadInText"), 0);
// Fade in elements after opening Boss Rush options menu
fileChooseContext->bossRushUIAlpha += 25;
if (fileChooseContext->bossRushUIAlpha > 255) {
fileChooseContext->bossRushUIAlpha = 255;
}
// Animate up/down arrows.
fileChooseContext->bossRushArrowOffset += 1;
if (fileChooseContext->bossRushArrowOffset >= 30) {
fileChooseContext->bossRushArrowOffset = 0;
}
// Move menu selection up or down.
if (ABS(fileChooseContext->stickRelY) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) {
// Move down
if (fileChooseContext->stickRelY < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN))) {
// When selecting past the last option, cycle back to the first option.
if ((fileChooseContext->bossRushIndex + 1) > BR_OPTIONS_MAX - 1) {
fileChooseContext->bossRushIndex = 0;
fileChooseContext->bossRushOffset = 0;
} else {
fileChooseContext->bossRushIndex++;
// When last visible option is selected when moving down, offset the list down by one.
if (fileChooseContext->bossRushIndex - fileChooseContext->bossRushOffset >
BOSSRUSH_MAX_OPTIONS_ON_SCREEN - 1) {
fileChooseContext->bossRushOffset++;
}
}
} else if (fileChooseContext->stickRelY > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DUP))) {
// When selecting past the first option, cycle back to the last option and offset the list to view it
// properly.
if ((fileChooseContext->bossRushIndex - 1) < 0) {
fileChooseContext->bossRushIndex = BR_OPTIONS_MAX - 1;
fileChooseContext->bossRushOffset =
fileChooseContext->bossRushIndex - BOSSRUSH_MAX_OPTIONS_ON_SCREEN + 1;
} else {
// When first visible option is selected when moving up, offset the list up by one.
if (fileChooseContext->bossRushIndex - fileChooseContext->bossRushOffset == 0) {
fileChooseContext->bossRushOffset--;
}
fileChooseContext->bossRushIndex--;
}
}
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
}
// Cycle through choices for currently selected option.
if (ABS(fileChooseContext->stickRelX) > 30 ||
(dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DRIGHT))) {
if (fileChooseContext->stickRelX > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DRIGHT))) {
// If exceeding the amount of choices for the selected option, cycle back to the first.
if ((gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] + 1) ==
BossRush_GetSettingOptionsAmount(fileChooseContext->bossRushIndex)) {
gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] = 0;
} else {
gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]++;
}
} else if (fileChooseContext->stickRelX < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT))) {
// If cycling back when already at the first choice for the selected option, cycle back to the last choice.
if ((gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] - 1) < 0) {
gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex] =
BossRush_GetSettingOptionsAmount(fileChooseContext->bossRushIndex) - 1;
} else {
gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]--;
}
}
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
}
if (sLastBossRushOptionIndex != fileChooseContext->bossRushIndex ||
sLastBossRushOptionValue != gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]) {
GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection(
fileChooseContext->bossRushIndex,
gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex]);
sLastBossRushOptionIndex = fileChooseContext->bossRushIndex;
sLastBossRushOptionValue = gSaveContext.ship.quest.data.bossRush.options[fileChooseContext->bossRushIndex];
}
if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
fileChooseContext->configMode = CM_BOSS_RUSH_TO_QUEST;
return;
}
// Load into the game.
if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
fileChooseContext->buttonIndex = 0xFE;
fileChooseContext->menuMode = FS_MENU_MODE_SELECT;
fileChooseContext->selectMode = SM_FADE_OUT;
fileChooseContext->prevConfigMode = fileChooseContext->configMode;
return;
}
}
void FileChoose_DrawBossRushMenuWindowContents(FileChooseContext* fileChooseContext) {
OPEN_DISPS(fileChooseContext->state.gfxCtx);
uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language;
uint8_t listOffset = fileChooseContext->bossRushOffset;
uint8_t textAlpha = fileChooseContext->bossRushUIAlpha;
// Draw arrows to indicate that the list can scroll up or down.
// Arrow up
if (listOffset > 0) {
uint16_t arrowUpX = 140;
uint16_t arrowUpY = 76 - (fileChooseContext->bossRushArrowOffset / 10);
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowUpTex, G_IM_FMT_IA, G_IM_SIZ_16b, 16, 16, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
gSPWideTextureRectangle(POLY_OPA_DISP++, arrowUpX << 2, arrowUpY << 2, (arrowUpX + 8) << 2, (arrowUpY + 8) << 2,
G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11));
}
// Arrow down
if (BR_OPTIONS_MAX - listOffset > BOSSRUSH_MAX_OPTIONS_ON_SCREEN) {
uint16_t arrowDownX = 140;
uint16_t arrowDownY = 181 + (fileChooseContext->bossRushArrowOffset / 10);
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowDownTex, G_IM_FMT_IA, G_IM_SIZ_16b, 16, 16, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
gSPWideTextureRectangle(POLY_OPA_DISP++, arrowDownX << 2, arrowDownY << 2, (arrowDownX + 8) << 2,
(arrowDownY + 8) << 2, G_TX_RENDERTILE, 0, 0, (1 << 11), (1 << 11));
}
// Draw options. There's more options than what fits on the screen, so the visible options
// depend on the current offset of the list. Currently selected option pulses in
// color and has arrows surrounding the option.
for (uint8_t i = listOffset; i - listOffset < BOSSRUSH_MAX_OPTIONS_ON_SCREEN; i++) {
uint16_t textYOffset = (i - listOffset) * 16;
// Option name.
Interface_DrawTextLine(fileChooseContext->state.gfxCtx, (char*)BossRush_GetSettingName(i, language), 65,
(87 + textYOffset), 255, 255, 80, textAlpha, 0.8f, true);
// Selected choice for option.
uint16_t finalKerning = Interface_DrawTextLine(
fileChooseContext->state.gfxCtx,
(char*)BossRush_GetSettingChoiceName(i, gSaveContext.ship.quest.data.bossRush.options[i], language), 165,
(87 + textYOffset), 255, 255, 255, textAlpha, 0.8f, true);
// Draw arrows around selected option.
if (fileChooseContext->bossRushIndex == i) {
Gfx_SetupDL_39Opa(fileChooseContext->state.gfxCtx);
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
FileChoose_DrawTextRec(fileChooseContext->state.gfxCtx, fileChooseContext->stickLeftPrompt.arrowColorR,
fileChooseContext->stickLeftPrompt.arrowColorG,
fileChooseContext->stickLeftPrompt.arrowColorB, textAlpha, 160, (92 + textYOffset),
0.42f, 0, 0, -1.0f, 1.0f);
FileChoose_DrawTextRec(fileChooseContext->state.gfxCtx, fileChooseContext->stickRightPrompt.arrowColorR,
fileChooseContext->stickRightPrompt.arrowColorG,
fileChooseContext->stickRightPrompt.arrowColorB, textAlpha, (171 + finalKerning),
(92 + textYOffset), 0.42f, 0, 0, 1.0f, 1.0f);
}
}
CLOSE_DISPS(fileChooseContext->state.gfxCtx);
}
void BossRush_SpawnBlueWarps(PlayState* play) {
// Spawn blue warps in Chamber of Sages based on what bosses have been defeated.
@@ -316,7 +565,7 @@ void BossRush_HandleCompleteBoss(PlayState* play) {
}
}
void BossRush_InitSave() {
extern "C" void BossRush_InitSave() {
// Set player name to Lonk for the few textboxes that show up during Boss Rush. Player can't input their own name.
std::array<char, 8> brPlayerName = { 21, 50, 49, 46, 62, 62, 62, 62 };
@@ -502,6 +751,10 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
}
break;
}
case VB_PLAY_BLUE_WARP_CS: {
*should = false;
break;
}
// Spawn clean blue warps (no ruto, adult animation, etc)
case VB_SPAWN_BLUE_WARP: {
switch (gPlayState->sceneNum) {
@@ -609,6 +862,17 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
*should = false;
break;
}
// Handle the heal on blue warp
case VB_BLUE_WARP_CONSIDER_ADULT_IN_RANGE: {
if (*should) {
BossRush_HandleBlueWarpHeal(gPlayState);
}
break;
}
case VB_SHOW_GAMEPLAY_TIMER: {
*should |= gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_TIMER] == BR_CHOICE_TIMER_YES;
break;
}
// Prevent saving
case VB_BE_ABLE_TO_SAVE:
// Disable doors so the player can't leave the boss rooms backwards.
@@ -629,25 +893,6 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
va_end(args);
}
void BossRush_OnActorInitHandler(void* actorRef) {
Actor* actor = static_cast<Actor*>(actorRef);
if (actor->id == ACTOR_DEMO_SA && gPlayState->sceneNum == SCENE_CHAMBER_OF_THE_SAGES) {
BossRush_SpawnBlueWarps(gPlayState);
Actor_Kill(actor);
GET_PLAYER(gPlayState)->actor.world.rot.y = GET_PLAYER(gPlayState)->actor.shape.rot.y = 27306;
return;
}
// Remove chests, mainly for the chest in King Dodongo's boss room.
// Remove bushes, used in Gohma's arena.
// Remove pots, used in Barinade's and Ganondorf's arenas.
if (actor->id == ACTOR_EN_KUSA || actor->id == ACTOR_OBJ_TSUBO || actor->id == ACTOR_EN_BOX) {
Actor_Kill(actor);
return;
}
}
void BossRush_OnSceneInitHandler(s16 sceneNum) {
// Unpause the timer when the scene loaded isn't the Chamber of Sages.
if (sceneNum != SCENE_CHAMBER_OF_THE_SAGES) {
@@ -667,38 +912,32 @@ void BossRush_OnBlueWarpUpdate(void* actor) {
}
}
void BossRush_RegisterHooks() {
static u32 onVanillaBehaviorHook = 0;
static u32 onSceneInitHook = 0;
static u32 onActorInitHook = 0;
static u32 onBossDefeatHook = 0;
static u32 onActorUpdate = 0;
void RegisterBossRush() {
COND_HOOK(OnLoadGame, true, [](int32_t fileNum) {
COND_ID_HOOK(OnActorInit, ACTOR_DEMO_SA, IS_BOSS_RUSH, [](void* actorPtr) {
BossRush_SpawnBlueWarps(gPlayState);
Actor_Kill((Actor*)actorPtr);
GET_PLAYER(gPlayState)->actor.world.rot.y = 27306;
GET_PLAYER(gPlayState)->actor.shape.rot.y = 27306;
});
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) {
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnVanillaBehavior>(onVanillaBehaviorHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(onSceneInitHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorInit>(onActorInitHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnBossDefeat>(onBossDefeatHook);
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnActorUpdate>(onActorUpdate);
// Remove bushes, used in Gohma's arena
COND_ID_HOOK(OnActorInit, ACTOR_EN_KUSA, IS_BOSS_RUSH, [](void* actorPtr) { Actor_Kill((Actor*)actorPtr); });
onVanillaBehaviorHook = 0;
onSceneInitHook = 0;
onActorInitHook = 0;
onBossDefeatHook = 0;
onActorUpdate = 0;
// Remove pots, used in Barinade's and Ganondorf's arenas
COND_ID_HOOK(OnActorInit, ACTOR_OBJ_TSUBO, IS_BOSS_RUSH, [](void* actorPtr) { Actor_Kill((Actor*)actorPtr); });
if (!IS_BOSS_RUSH)
return;
// Remove chests, mainly for the chest in King Dodongo's boss room
COND_ID_HOOK(OnActorInit, ACTOR_EN_BOX, IS_BOSS_RUSH, [](void* actorPtr) { Actor_Kill((Actor*)actorPtr); });
onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(
BossRush_OnVanillaBehaviorHandler);
onSceneInitHook =
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>(BossRush_OnSceneInitHandler);
onActorInitHook =
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>(BossRush_OnActorInitHandler);
onBossDefeatHook =
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnBossDefeat>(BossRush_OnBossDefeatHandler);
onActorUpdate = GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorUpdate>(
ACTOR_DOOR_WARP1, BossRush_OnBlueWarpUpdate);
COND_HOOK(OnVanillaBehavior, IS_BOSS_RUSH, BossRush_OnVanillaBehaviorHandler);
COND_HOOK(OnSceneInit, IS_BOSS_RUSH, BossRush_OnSceneInitHandler);
COND_HOOK(OnBossDefeat, IS_BOSS_RUSH, BossRush_OnBossDefeatHandler);
COND_ID_HOOK(OnActorUpdate, ACTOR_DOOR_WARP1, IS_BOSS_RUSH, BossRush_OnBlueWarpUpdate);
});
}
static RegisterShipInitFunc initFunc(RegisterBossRush);
+29 -4
View File
@@ -1,16 +1,41 @@
#pragma once
#include "z64.h"
#include <libultraship/libultra/types.h>
#ifdef __cplusplus
extern "C" {
#endif
void BossRush_HandleBlueWarpHeal(PlayState* play);
void BossRush_InitSave();
struct GameState;
struct FileChooseContext;
void FileChoose_UpdateBossRushMenu(struct GameState* gameState);
void FileChoose_DrawBossRushMenuWindowContents(struct FileChooseContext* fileChooseContext);
const char* BossRush_GetSettingName(u8 optionIndex, u8 language);
const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 language);
u8 BossRush_GetSettingOptionsAmount(u8 optionIndex);
void BossRush_RegisterHooks();
#ifdef __cplusplus
};
#endif
#define BOSSRUSH_MAX_OPTIONS_ON_SCREEN 6
typedef enum {
BR_OPTIONS_BOSSES,
BR_OPTIONS_HEARTS,
BR_OPTIONS_AMMO,
BR_OPTIONS_HEAL,
BR_OPTIONS_HYPERBOSSES,
BR_OPTIONS_MAGIC,
BR_OPTIONS_BGS,
BR_OPTIONS_BOTTLE,
BR_OPTIONS_LONGSHOT,
BR_OPTIONS_HOVERBOOTS,
BR_OPTIONS_BUNNYHOOD,
BR_OPTIONS_TIMER,
BR_OPTIONS_MAX,
} BossRushOptionEnums;
typedef enum {
BR_CHOICE_HYPERBOSSES_NO,
BR_CHOICE_HYPERBOSSES_YES,
} BossRushHyperBossesChoices;
@@ -1,91 +0,0 @@
#pragma once
#define BOSSRUSH_MAX_OPTIONS_ON_SCREEN 6
typedef enum {
BR_OPTIONS_BOSSES,
BR_OPTIONS_HEARTS,
BR_OPTIONS_AMMO,
BR_OPTIONS_HEAL,
BR_OPTIONS_HYPERBOSSES,
BR_OPTIONS_MAGIC,
BR_OPTIONS_BGS,
BR_OPTIONS_BOTTLE,
BR_OPTIONS_LONGSHOT,
BR_OPTIONS_HOVERBOOTS,
BR_OPTIONS_BUNNYHOOD,
BR_OPTIONS_TIMER,
BR_OPTIONS_MAX,
} BossRushOptionEnums;
typedef enum {
BR_CHOICE_BOSSES_ALL,
BR_CHOICE_BOSSES_CHILD,
BR_CHOICE_BOSSES_ADULT,
BR_CHOICE_BOSSES_GANONDORF_GANON
} BossRushBossesChoices;
typedef enum {
BR_CHOICE_HEARTS_10,
BR_CHOICE_HEARTS_15,
BR_CHOICE_HEARTS_20,
BR_CHOICE_HEARTS_3,
BR_CHOICE_HEARTS_5,
BR_CHOICE_HEARTS_7
} BossRushHeartsChoices;
typedef enum {
BR_CHOICE_AMMO_LIMITED,
BR_CHOICE_AMMO_FULL,
BR_CHOICE_AMMO_MAXED,
} BossRushAmmoChoices;
typedef enum {
BR_CHOICE_HEAL_GANONDORF,
BR_CHOICE_HEAL_EVERYBOSS,
BR_CHOICE_HEAL_NEVER,
} BossRushHealChoices;
typedef enum {
BR_CHOICE_HYPERBOSSES_NO,
BR_CHOICE_HYPERBOSSES_YES,
} BossRushHyperBossesChoices;
typedef enum {
BR_CHOICE_MAGIC_SINGLE,
BR_CHOICE_MAGIC_DOUBLE,
} BossRushMagicChoices;
typedef enum {
BR_CHOICE_BGS_NO,
BR_CHOICE_BGS_YES,
} BossRushBgsChoices;
typedef enum {
BR_CHOICE_BOTTLE_NO,
BR_CHOICE_BOTTLE_EMPTY,
BR_CHOICE_BOTTLE_FAIRY,
BR_CHOICE_BOTTLE_REDPOTION,
BR_CHOICE_BOTTLE_GREENPOTION,
BR_CHOICE_BOTTLE_BLUEPOTION
} BossRushBottleChoices;
typedef enum {
BR_CHOICE_LONGSHOT_NO,
BR_CHOICE_LONGSHOT_YES,
} BossRushLongshotChoices;
typedef enum {
BR_CHOICE_HOVERBOOTS_NO,
BR_CHOICE_HOVERBOOTS_YES,
} BossRushHoverBootsChoices;
typedef enum {
BR_CHOICE_BUNNYHOOD_NO,
BR_CHOICE_BUNNYHOOD_YES,
} BossRushBunnyHoodChoices;
typedef enum {
BR_CHOICE_TIMER_YES,
BR_CHOICE_TIMER_NO,
} BossRushTimerChoices;
@@ -1,8 +1,9 @@
#include "InputViewer.h"
#include "public/bridge/consolevariablebridge.h"
#include <libultraship/bridge/consolevariablebridge.h>
#include "libultraship/libultra/controller.h"
#include "Context.h"
#include <ship/Context.h>
#include <libultraship/controller/controldeck/ControlDeck.h>
#include "soh/OTRGlobals.h"
#include "soh/cvar_prefixes.h"
#include <imgui.h>
+6 -6
View File
@@ -2,7 +2,7 @@
#include "soh/OTRGlobals.h"
#include "z64player.h"
#include "global.h"
#include <Window.h>
#include <ship/window/Window.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
@@ -148,9 +148,9 @@ void Mouse_RegisterHandleQuickspin() {
REGISTER_VB_SHOULD(VB_SHOULD_QUICKSPIN, { Mouse_HandleQuickspin(should, va_arg(args, s8*), va_arg(args, s8*)); });
}
static RegisterShipInitFunc initFunc_shieldRecenter(Mouse_RegisterRecenterCursorOnShield, { CVAR_ENABLE_MOUSE_NAME });
static RegisterShipInitFunc initFunc_firstPerson(Mouse_RegisterHandleFirstPerson, { CVAR_ENABLE_MOUSE_NAME });
static RegisterShipInitFunc initFunc_quickspinCount(Mouse_RegisterUpdateQuickspinCount, { CVAR_ENABLE_MOUSE_NAME });
static RegisterShipInitFunc initFunc_quickspin(Mouse_RegisterHandleQuickspin, { CVAR_ENABLE_MOUSE_NAME });
static RegisterShipInitFunc initFunc_shieldMove(Mouse_RegisterHandleShield, { CVAR_ENABLE_MOUSE_NAME });
static RegisterShipInitFunc registerShieldRecenter(Mouse_RegisterRecenterCursorOnShield, { CVAR_ENABLE_MOUSE_NAME });
static RegisterShipInitFunc registerFirstPerson(Mouse_RegisterHandleFirstPerson, { CVAR_ENABLE_MOUSE_NAME });
static RegisterShipInitFunc registerQuickspinCount(Mouse_RegisterUpdateQuickspinCount, { CVAR_ENABLE_MOUSE_NAME });
static RegisterShipInitFunc registerQuickspin(Mouse_RegisterHandleQuickspin, { CVAR_ENABLE_MOUSE_NAME });
static RegisterShipInitFunc registerShieldMove(Mouse_RegisterHandleShield, { CVAR_ENABLE_MOUSE_NAME });
} // extern "C"
@@ -1,18 +1,31 @@
#include "SohInputEditorWindow.h"
#include <utils/StringHelper.h>
#include <ship/utils/StringHelper.h>
#include <fast/Fast3dWindow.h>
#include "soh/OTRGlobals.h"
#include "soh/SohGui/UIWidgets.hpp"
#include "soh/SohGui/SohMenu.h"
#include "soh/SohGui/SohGui.hpp"
#include "z64.h"
#include "soh/cvar_prefixes.h"
#ifndef __WIIU__
#include "controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.h"
#include <ship/controller/controldevice/controller/mapping/sdl/SDLAxisDirectionToButtonMapping.h>
#endif
#define SCALE_IMGUI_SIZE(value) ((value / 13.0f) * ImGui::GetFontSize())
using namespace UIWidgets;
static WidgetInfo freeLook;
static WidgetInfo mouseControl;
static WidgetInfo mouseAutoCapture;
static WidgetInfo rightStickOcarina;
static WidgetInfo dpadOcarina;
static WidgetInfo dpadPause;
static WidgetInfo dpadText;
namespace SohGui {
extern std::shared_ptr<SohMenu> mSohMenu;
}
SohInputEditorWindow::~SohInputEditorWindow() {
}
@@ -1321,8 +1334,8 @@ void SohInputEditorWindow::DrawOcarinaControlPanel() {
ImGui::SetCursorPos(ImVec2(cursor.x, cursor.y + 5));
CheckboxOptions checkOpt = CheckboxOptions().Color(THEME_COLOR);
CVarCheckbox("Dpad Ocarina Playback", CVAR_SETTING("CustomOcarina.Dpad"), checkOpt);
CVarCheckbox("Right Stick Ocarina Playback", CVAR_SETTING("CustomOcarina.RightStick"), checkOpt);
SohGui::mSohMenu->MenuDrawItem(dpadOcarina, ImGui::GetContentRegionAvail().x, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(rightStickOcarina, ImGui::GetContentRegionAvail().x, THEME_COLOR);
CVarCheckbox("Customize Ocarina Controls", CVAR_SETTING("CustomOcarina.Enabled"), checkOpt);
if (!CVarGetInteger(CVAR_SETTING("CustomOcarina.Enabled"), 0)) {
@@ -1354,12 +1367,11 @@ void SohInputEditorWindow::DrawOcarinaControlPanel() {
void SohInputEditorWindow::DrawCameraControlPanel() {
ImVec2 cursor = ImGui::GetCursorPos();
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
CVarCheckbox(
"Enable Mouse Controls", CVAR_SETTING("EnableMouse"),
CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Allows for using the mouse to control the camera (must enable Free Look), "
"aim with the shield, and perform quickspin attacks (quickly rotate the mouse then press B)"));
SohGui::mSohMenu->MenuDrawItem(mouseControl, ImGui::GetContentRegionAvail().x, THEME_COLOR);
cursor = ImGui::GetCursorPos();
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
SohGui::mSohMenu->MenuDrawItem(mouseAutoCapture, ImGui::GetContentRegionAvail().x, THEME_COLOR);
Ship::GuiWindow::BeginGroupPanel("Aiming/First-Person Camera", ImGui::GetContentRegionAvail());
CVarCheckbox("Right Stick Aiming", CVAR_SETTING("Controls.RightStickAim"),
CheckboxOptions()
@@ -1427,14 +1439,7 @@ void SohInputEditorWindow::DrawCameraControlPanel() {
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
Ship::GuiWindow::BeginGroupPanel("Third-Person Camera", ImGui::GetContentRegionAvail());
CVarCheckbox(
"Free Look", CVAR_SETTING("FreeLook.Enabled"),
CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Enables free look camera control\nNote: You must remap C buttons off of the right stick in the "
"controller config menu, and map the camera stick to the right stick.\n"
"Doesn't work in areas were the game locks the camera.\n"
"Scene reload may be necessary to enable."));
SohGui::mSohMenu->MenuDrawItem(freeLook, ImGui::GetContentRegionAvail().x, THEME_COLOR);
CVarCheckbox("Invert Camera X Axis", CVAR_SETTING("FreeLook.InvertXAxis"),
CheckboxOptions().Color(THEME_COLOR).Tooltip("Inverts the Camera X Axis in:\n-Free look"));
CVarCheckbox(
@@ -1467,16 +1472,8 @@ void SohInputEditorWindow::DrawDpadControlPanel() {
ImVec2 cursor = ImGui::GetCursorPos();
ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5));
Ship::GuiWindow::BeginGroupPanel("D-Pad Options", ImGui::GetContentRegionAvail());
CVarCheckbox("D-pad Support on Pause Screen", CVAR_SETTING("DPadOnPause"),
CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Navigate Pause with the D-pad\nIf used with \"D-pad as Equip Items\", you must hold "
"C-Up to equip instead of navigate"));
CVarCheckbox("D-pad Support in Text Boxes", CVAR_SETTING("DpadInText"),
CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Navigate choices in text boxes, shop item selection, and the file select / name entry "
"screens with the D-pad"));
SohGui::mSohMenu->MenuDrawItem(dpadPause, ImGui::GetContentRegionAvail().x, THEME_COLOR);
SohGui::mSohMenu->MenuDrawItem(dpadText, ImGui::GetContentRegionAvail().x, THEME_COLOR);
if (!CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CVarGetInteger(CVAR_SETTING("DpadInText"), 0)) {
ImGui::BeginDisabled();
@@ -1902,3 +1899,74 @@ void SohInputEditorWindow::DrawElement() {
ImGui::PopStyleColor(3);
ImGui::PopFont();
}
void RegisterInputEditorWidgets() {
dpadOcarina = { .name = "Dpad Ocarina Playback", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
dpadOcarina.CVar(CVAR_SETTING("CustomOcarina.Dpad")).Options(CheckboxOptions().Color(THEME_COLOR));
SohGui::mSohMenu->AddSearchWidget({ dpadOcarina, "Settings", "Controls", "Ocarina Controls", "" });
freeLook = { .name = "Free Look", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
freeLook.CVar(CVAR_SETTING("FreeLook.Enabled"))
.Options(
CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip(
"Enables free look camera control\nNote: You must remap C buttons off of the right stick in the "
"controller config menu, and map the camera stick to the right stick.\n"
"Doesn't work in areas were the game locks the camera.\n"
"Scene reload may be necessary to enable."));
SohGui::mSohMenu->AddSearchWidget({ freeLook, "Settings", "Controls", "Camera Controls" });
mouseControl = { .name = "Enable Mouse Controls", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
mouseControl.CVar(CVAR_SETTING("EnableMouse"))
.Callback([](WidgetInfo& info) {
bool enabled =
CVarGetInteger(CVAR_SETTING("EnableMouse"), 0) && CVarGetInteger(CVAR_SETTING("AutoCaptureMouse"), 1);
auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow());
wnd->SetAutoCaptureMouse(enabled);
})
.Options(
CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Allows for using the mouse to control the camera (must enable Free Look), "
"aim with the shield, and perform quickspin attacks (quickly rotate the mouse then press B)\n"
"Press F2 to toggle mouse capture manually."));
SohGui::mSohMenu->AddSearchWidget({ mouseControl, "Settings", "Controls", "Camera Controls" });
mouseAutoCapture = { .name = "Auto Capture Mouse Input", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
mouseAutoCapture.CVar(CVAR_SETTING("AutoCaptureMouse"))
.Callback([](WidgetInfo& info) {
bool enabled =
CVarGetInteger(CVAR_SETTING("EnableMouse"), 0) && CVarGetInteger(CVAR_SETTING("AutoCaptureMouse"), 1);
auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow());
wnd->SetAutoCaptureMouse(enabled);
})
.Options(CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("When Mouse Controls are enabled, this toggles whether the program will automatically "
"hide the cursor "
"and capture mouse input when closing the menu."));
SohGui::mSohMenu->AddSearchWidget({ mouseAutoCapture, "Settings", "Controls", "Camera Controls" });
rightStickOcarina = { .name = "Right Stick Ocarina Playback", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
rightStickOcarina.CVar(CVAR_SETTING("CustomOcarina.RightStick")).Options(CheckboxOptions().Color(THEME_COLOR));
SohGui::mSohMenu->AddSearchWidget({ rightStickOcarina, "Settings", "Controls", "Ocarina Controls" });
dpadPause = { .name = "D-pad Support on Pause Screen", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
dpadPause.CVar(CVAR_SETTING("DPadOnPause"))
.Options(CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Navigate Pause with the D-pad\nIf used with \"D-pad as Equip Items\", you must hold "
"C-Up to equip instead of navigate"));
SohGui::mSohMenu->AddSearchWidget({ dpadPause, "Settings", "Controls", "Dpad Controls" });
dpadText = { .name = "D-pad Support in Text Boxes", .type = WidgetType::WIDGET_CVAR_CHECKBOX };
dpadText.CVar(CVAR_SETTING("DpadInText"))
.Options(CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Navigate choices in text boxes, shop item selection, and the file select / name entry "
"screens with the D-pad"));
SohGui::mSohMenu->AddSearchWidget({ dpadText, "Settings", "Controls", "Dpad Controls" });
}
static RegisterMenuInitFunc menuInitFunc(RegisterInputEditorWidgets);
@@ -2382,6 +2382,11 @@ void CosmeticsEditorWindow::DrawElement() {
.Color(THEME_COLOR)
.Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene."));
ImGui::EndDisabled();
UIWidgets::CVarCheckbox(
"Randomize All on Randomizer Generation", CVAR_COSMETIC("RandomizeAllOnRandoGen"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Enables randomizing all unlocked cosmetics when you generate a new randomizer."));
UIWidgets::CVarCheckbox(
"Advanced Mode", CVAR_COSMETIC("AdvancedMode"),
UIWidgets::CheckboxOptions()
@@ -2589,6 +2594,14 @@ void Cosmetics_RegisterOnSceneInitHook() {
});
}
void CosmeticsEditorRegisterOnGenerationCompletionHook() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGenerationCompletion>([]() {
if (CVarGetInteger(CVAR_COSMETIC("RandomizeAllOnRandoGen"), 0)) {
CosmeticsEditor_RandomizeAll();
}
});
}
void CosmeticsEditorWindow::InitElement() {
// Convert the `current color` into the format that the ImGui color picker expects
for (auto& [id, cosmeticOption] : cosmeticOptions) {
@@ -2608,6 +2621,7 @@ void CosmeticsEditorWindow::InitElement() {
RegisterOnLoadGameHook();
RegisterOnGameFrameUpdateHook();
Cosmetics_RegisterOnSceneInitHook();
CosmeticsEditorRegisterOnGenerationCompletionHook();
}
void CosmeticsEditor_RandomizeAll() {
@@ -195,7 +195,7 @@ void RegisterCustomLogoTitle() {
COND_HOOK(OnZTitleUpdate, true, OnZTitleUpdatePressButtonToSkip);
}
static RegisterShipInitFunc initFuncAlways(RegisterCustomLogoTitle);
static RegisterShipInitFunc registerCustomLogo(RegisterCustomLogoTitle);
// // // // // //
// Bootsequence
@@ -216,7 +216,7 @@ void RegisterCustomLogoTitleBootsequence() {
COND_HOOK(OnZTitleUpdate, CVAR_BOOTSEQUENCE_VALUE == BOOTSEQUENCE_FILESELECT, OnZTitleUpdateSkipToFileSelect);
}
static RegisterShipInitFunc initFuncBootsequence(RegisterCustomLogoTitleBootsequence, { CVAR_BOOTSEQUENCE_NAME });
static RegisterShipInitFunc registerTitleBootSequence(RegisterCustomLogoTitleBootsequence, { CVAR_BOOTSEQUENCE_NAME });
// // // // // //
// Let it Snow
@@ -230,4 +230,4 @@ void RegisterCustomLogoTitleLetItSnow() {
shouldDrawIceOnSpinningLogo = CVAR_LETITSNOW_VALUE != CVAR_LETITSNOW_DEFAULT;
}
static RegisterShipInitFunc initFuncLetItSnow(RegisterCustomLogoTitleLetItSnow, { CVAR_LETITSNOW_NAME });
static RegisterShipInitFunc registerLetItSnow(RegisterCustomLogoTitleLetItSnow, { CVAR_LETITSNOW_NAME });
@@ -17,4 +17,4 @@ void RegisterTimeFlowFileSelect() {
COND_HOOK(OnFileChooseMain, CVAR_TIMEFLOWFILESELECT_VALUE, OnFileChooseMainTimeFlowFileSelect);
}
static RegisterShipInitFunc initFunc_TimeFlowFileSelect(RegisterTimeFlowFileSelect, { CVAR_TIMEFLOWFILESELECT_NAME });
static RegisterShipInitFunc initFunc(RegisterTimeFlowFileSelect, { CVAR_TIMEFLOWFILESELECT_NAME });
@@ -79,8 +79,41 @@ typedef enum {
TEXT_SARIAS_SONG_CHANNELING_POWER = 0x016D,
TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI = 0x01B3, // 0x1yy for Navi msg range
TEXT_MASK_SHOP_SIGN = 0x0207,
TEXT_WATERFALL = 0x022D,
TEXT_FROGS_UNDERWATER = 0x022E,
TEXT_OUTSIDE_FISHING_POND = 0x023A,
TEXT_HF_SIGN = 0x0301,
TEXT_HC_GREAT_FAIRY_SIGN = 0x0304,
TEXT_DMT_KAK_SIGN = 0x0305,
TEXT_KAK_TO_GY_SIGN = 0x0306,
TEXT_KAK_WELL_SIGN = 0x0307,
TEXT_KAK_DMT_SIGN = 0x0308,
TEXT_DMT_SIGN = 0x309,
TEXT_DMT_DC_SIGN = 0x030A,
TEXT_GC_SIGN = 0x030B,
TEXT_HF_ZR_SIGN = 0x030C,
TEXT_ZD_SIGN = 0x030E,
TEXT_ZF_JABU_SIGN = 0x030F,
TEXT_KF_LW_SIGN = 0x0314,
TEXT_HF_LON_LON_SIGN = 0x0315,
TEXT_LA_SIGN = 0x0317,
TEXT_LA_LAB_SIGN = 0x0318,
TEXT_GV_SIGN = 0x0319,
TEXT_GF_HBA_SIGN = 0x031A,
TEXT_KF_SHOP_SIGN = 0x031E,
TEXT_LINKS_HOUSE_SIGN = 0x031F,
TEXT_KOKIRI_EXIT_SIGN = 0x0320,
TEXT_DMT_GC_SIGN = 0x0321,
TEXT_DMT_DMC_SIGN = 0x0323,
TEXT_DMT_SUMMIT_SIGN = 0x032D,
TEXT_ZD_SHOP_SIGN = 0x0333,
TEXT_OUTSIDE_KOKIRI_SIGN = 0x0339,
TEXT_OUTSIDE_MARKET_SIGN = 0x033A,
TEXT_MIDO_HOUSE_SIGN = 0x033C,
TEXT_KNOW_IT_ALL_HOUSE_SIGN = 0x033D,
TEXT_TWINS_HOUSE_SIGN = 0x033E,
TEXT_SARIAS_HOUSE_SIGN = 0x033F,
TEXT_NO_DIVING_SIGN = 0x0342,
TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN = 0x0346, // 0x3yy for cuttable sign range
TEXT_WARP_MINUET_OF_FOREST = 0x088D,
TEXT_WARP_BOLERO_OF_FIRE = 0x088E,
@@ -88,6 +121,10 @@ typedef enum {
TEXT_WARP_REQUIEM_OF_SPIRIT = 0x0890,
TEXT_WARP_NOCTURNE_OF_SHADOW = 0x0891,
TEXT_WARP_PRELUDE_OF_LIGHT = 0x0892,
TEXT_MIDO_HOME_AFTER_ZELDAS_LETTER = 0x1028,
TEXT_MIDO_SPEAK_TO_MIDO_FIRST_TIME = 0x102F,
TEXT_MIDO_SPEAK_TO_MIDO_AGAIN = 0x1030,
TEXT_MIDO_HOME_BEFORE_ZELDAS_LETTER = 0x1046,
TEXT_SCRUB_POH = 0x10A2,
TEXT_SARIA_SFM = 0x10AD,
TEXT_SCRUB_STICK_UPGRADE = 0x10DC,
+4 -4
View File
@@ -1,5 +1,5 @@
#include "debugconsole.h"
#include <Utils.h>
#include <ship/utils/Utils.h>
#include "savestates.h"
#include "soh/ActorDB.h"
@@ -15,10 +15,10 @@
#define Path _Path
#define PATH_HACK
#include <utils/StringHelper.h>
#include <ship/utils/StringHelper.h>
#include <Window.h>
#include <Context.h>
#include <ship/window/Window.h>
#include <ship/Context.h>
#include <imgui.h>
#include <imgui_internal.h>
#undef PATH_HACK
@@ -3,7 +3,7 @@
#include "z64.h"
#ifdef __cplusplus
#include "GuiWindow.h"
#include <ship/window/gui/GuiWindow.h>
#include <unordered_map>
extern "C" {
#endif
@@ -1,8 +1,8 @@
#ifndef SOH_CONSOLE_H
#define SOH_CONSOLE_H
#include "window/gui/GuiWindow.h"
#include "window/gui/ConsoleWindow.h"
#include <ship/window/gui/GuiWindow.h>
#include <ship/window/gui/ConsoleWindow.h>
class SohConsoleWindow : public Ship::ConsoleWindow {
public:
@@ -1,8 +1,8 @@
#ifndef SOH_GFX_DEBUGGER_H
#define SOH_GFX_DEBUGGER_H
#include "window/gui/GuiWindow.h"
#include "window/gui/GfxDebuggerWindow.h"
#include <ship/window/gui/GuiWindow.h>
#include <libultraship/window/gui/GfxDebuggerWindow.h>
class SohGfxDebuggerWindow : public LUS::GfxDebuggerWindow {
public:
@@ -1228,4 +1228,4 @@ void ActorViewer_RegisterNameTagHooks() {
[](void* actor) { ActorViewer_AddTagForActor(static_cast<Actor*>(actor)); });
}
RegisterShipInitFunc nametagInit(ActorViewer_RegisterNameTagHooks, { CVAR_ACTOR_NAME_TAGS_ENABLED_NAME });
static RegisterShipInitFunc initFunc(ActorViewer_RegisterNameTagHooks, { CVAR_ACTOR_NAME_TAGS_ENABLED_NAME });
@@ -572,7 +572,9 @@ void DrawFlagTableArray16(const FlagTable& flagTable, uint16_t row, uint16_t& fl
PopStyleCheckbox();
if (ImGui::IsItemHovered() && hasDescription) {
ImGui::BeginTooltip();
ImGui::Text("%s", UIWidgets::WrappedText(flagTable.flagDescriptions.at(row * 16 + flagIndex), 60).c_str());
uint16_t index = row * 16 + flagIndex;
const char* desc = flagTable.flagDescriptions.at(index);
ImGui::Text("0x%02X: %s", index, UIWidgets::WrappedText(desc, 60).c_str());
ImGui::EndTooltip();
}
ImGui::PopID();
@@ -930,7 +932,15 @@ void DrawFlagsTab() {
for (int j = 0; j < flagTable.size + 1; j++) {
DrawGroupWithBorder(
[&]() {
ImGui::Text("%s", fmt::format("{:<2x}", j).c_str());
if (j == 0) {
for (int k = 0xF; k >= 0; k--) {
ImGui::SameLine(37.5 + ((0xF - k) * 33.8));
ImGui::Text("%X", k);
}
}
ImGui::Text("%s", fmt::format("{:<2X}", j).c_str());
switch (flagTable.flagTableType) {
case EVENT_CHECK_INF:
DrawFlagTableArray16(flagTable, j, gSaveContext.eventChkInf[j]);
+3 -2
View File
@@ -2,8 +2,9 @@
#include "soh/util.h"
#include "soh/SohGui/UIWidgets.hpp"
#include "soh/SohGui/SohGui.hpp"
#include "ResourceManager.h"
#include "DisplayList.h"
#include <ship/resource/ResourceManager.h>
#include <fast/resource/ResourceType.h>
#include <fast/resource/type/DisplayList.h>
#include "soh/OTRGlobals.h"
#include <array>
@@ -151,7 +151,7 @@ void RegisterValueViewerHooks() {
COND_HOOK(OnGameFrameUpdate, CVAR_VALUE, []() { ValueViewer_SetupDraw(); });
}
RegisterShipInitFunc initFunc(RegisterValueViewerHooks, { CVAR_NAME });
static RegisterShipInitFunc initFunc(RegisterValueViewerHooks, { CVAR_NAME });
void ValueViewerWindow::DrawElement() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
+19
View File
@@ -619,6 +619,7 @@ void FixClubMoblinScale(void* ptr) {
void RegisterEnemyRandomizer() {
COND_ID_HOOK(OnActorInit, ACTOR_EN_MB, CVAR_ENEMY_RANDOMIZER_VALUE, FixClubMoblinScale);
// prevent dark link from triggering a voidout
COND_VB_SHOULD(VB_TRIGGER_VOIDOUT, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, {
Actor* actor = va_arg(args, Actor*);
@@ -647,6 +648,24 @@ void RegisterEnemyRandomizer() {
}
});
// prevent dark link from interfering with ice floors
COND_VB_SHOULD(VB_SET_STATIC_PREV_FLOOR_TYPE, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, {
Player* playerOrDarkLink = va_arg(args, Player*);
if (playerOrDarkLink->actor.id != ACTOR_PLAYER) {
*should = false;
}
});
// prevent dark link from interfering with ice floors
COND_VB_SHOULD(VB_SET_STATIC_FLOOR_TYPE, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, {
Player* playerOrDarkLink = va_arg(args, Player*);
if (playerOrDarkLink->actor.id != ACTOR_PLAYER) {
*should = false;
}
});
// prevent dark link from being grabbed by like likes and therefore grabbing the player
COND_VB_SHOULD(VB_LIKE_LIKE_GRAB_PLAYER, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, {
EnRr* likeLike = va_arg(args, EnRr*);
+2
View File
@@ -112,7 +112,9 @@ typedef enum {
typedef enum {
TIME_TRAVEL_DISABLED,
TIME_TRAVEL_OOT,
TIME_TRAVEL_OOT_MS,
TIME_TRAVEL_ANY,
TIME_TRAVEL_ANY_MS
} TimeTravelType;
typedef enum {
@@ -50,7 +50,7 @@ namespace GameInteractionEffect {
// MARK: - Flags
GameInteractionEffectQueryResult SetSceneFlag::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
@@ -62,7 +62,7 @@ void SetSceneFlag::_Apply() {
}
GameInteractionEffectQueryResult UnsetSceneFlag::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
@@ -74,7 +74,7 @@ void UnsetSceneFlag::_Apply() {
}
GameInteractionEffectQueryResult SetFlag::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
@@ -86,7 +86,7 @@ void SetFlag::_Apply() {
}
GameInteractionEffectQueryResult UnsetFlag::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
@@ -99,7 +99,7 @@ void UnsetFlag::_Apply() {
// MARK: - ModifyHeartContainers
GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else if ((parameters[0] > 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) > 0x140)) ||
(parameters[0] < 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) < 0x10))) {
@@ -115,7 +115,7 @@ void ModifyHeartContainers::_Apply() {
// MARK: - FillMagic
GameInteractionEffectQueryResult FillMagic::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else if (!gSaveContext.isMagicAcquired || gSaveContext.magic >= ((gSaveContext.isDoubleMagicAcquired + 1) * 48)) {
return GameInteractionEffectQueryResult::NotPossible;
@@ -129,7 +129,7 @@ void FillMagic::_Apply() {
// MARK: - EmptyMagic
GameInteractionEffectQueryResult EmptyMagic::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else if (!gSaveContext.isMagicAcquired || gSaveContext.magic <= 0) {
return GameInteractionEffectQueryResult::NotPossible;
@@ -143,7 +143,7 @@ void EmptyMagic::_Apply() {
// MARK: - ModifyRupees
GameInteractionEffectQueryResult ModifyRupees::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else if ((parameters[0] < 0 && gSaveContext.rupees <= 0) ||
(parameters[0] > 0 && gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET))) {
@@ -158,7 +158,7 @@ void ModifyRupees::_Apply() {
// MARK: - NoUI
GameInteractionEffectQueryResult NoUI::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -173,7 +173,7 @@ void NoUI::_Remove() {
// MARK: - ModifyGravity
GameInteractionEffectQueryResult ModifyGravity::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -188,7 +188,7 @@ void ModifyGravity::_Remove() {
// MARK: - ModifyHealth
GameInteractionEffectQueryResult ModifyHealth::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else if ((parameters[0] > 0 && gSaveContext.health == gSaveContext.healthCapacity) ||
(parameters[0] < 0 && (gSaveContext.health + (16 * parameters[0]) <= 0))) {
@@ -204,7 +204,7 @@ void ModifyHealth::_Apply() {
// MARK: - SetPlayerHealth
GameInteractionEffectQueryResult SetPlayerHealth::CanBeApplied() {
Player* player = GET_PLAYER(gPlayState);
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -217,7 +217,7 @@ void SetPlayerHealth::_Apply() {
// MARK: - FreezePlayer
GameInteractionEffectQueryResult FreezePlayer::CanBeApplied() {
Player* player = GET_PLAYER(gPlayState);
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -230,7 +230,7 @@ void FreezePlayer::_Apply() {
// MARK: - BurnPlayer
GameInteractionEffectQueryResult BurnPlayer::CanBeApplied() {
Player* player = GET_PLAYER(gPlayState);
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -243,7 +243,7 @@ void BurnPlayer::_Apply() {
// MARK: - ElectrocutePlayer
GameInteractionEffectQueryResult ElectrocutePlayer::CanBeApplied() {
Player* player = GET_PLAYER(gPlayState);
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -256,7 +256,7 @@ void ElectrocutePlayer::_Apply() {
// MARK: - KnockbackPlayer
GameInteractionEffectQueryResult KnockbackPlayer::CanBeApplied() {
Player* player = GET_PLAYER(gPlayState);
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() ||
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() ||
player->stateFlags2 & PLAYER_STATE2_CRAWLING) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
@@ -269,7 +269,7 @@ void KnockbackPlayer::_Apply() {
// MARK: - ModifyLinkSize
GameInteractionEffectQueryResult ModifyLinkSize::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -284,7 +284,7 @@ void ModifyLinkSize::_Remove() {
// MARK: - InvisibleLink
GameInteractionEffectQueryResult InvisibleLink::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -299,7 +299,7 @@ void InvisibleLink::_Remove() {
// MARK: - PacifistMode
GameInteractionEffectQueryResult PacifistMode::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -314,7 +314,7 @@ void PacifistMode::_Remove() {
// MARK: - DisableZTargeting
GameInteractionEffectQueryResult DisableZTargeting::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -329,7 +329,7 @@ void DisableZTargeting::_Remove() {
// MARK: - WeatherRainstorm
GameInteractionEffectQueryResult WeatherRainstorm::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -344,7 +344,7 @@ void WeatherRainstorm::_Remove() {
// MARK: - ReverseControls
GameInteractionEffectQueryResult ReverseControls::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -359,7 +359,7 @@ void ReverseControls::_Remove() {
// MARK: - ForceEquipBoots
GameInteractionEffectQueryResult ForceEquipBoots::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -374,7 +374,7 @@ void ForceEquipBoots::_Remove() {
// MARK: - ModifyMovementSpeedMultiplier
GameInteractionEffectQueryResult ModifyMovementSpeedMultiplier::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -393,7 +393,7 @@ void ModifyMovementSpeedMultiplier::_Remove() {
// MARK: - OneHitKO
GameInteractionEffectQueryResult OneHitKO::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -408,7 +408,7 @@ void OneHitKO::_Remove() {
// MARK: - ModifyDefenseModifier
GameInteractionEffectQueryResult ModifyDefenseModifier::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -423,7 +423,7 @@ void ModifyDefenseModifier::_Remove() {
// MARK: - GiveOrTakeShield
GameInteractionEffectQueryResult GiveOrTakeShield::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else if ((parameters[0] > 0 && ((gBitFlags[parameters[0] - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) &
gSaveContext.inventory.equipment)) ||
@@ -441,7 +441,7 @@ void GiveOrTakeShield::_Apply() {
// MARK: - TeleportPlayer
GameInteractionEffectQueryResult TeleportPlayer::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -453,7 +453,7 @@ void TeleportPlayer::_Apply() {
// MARK: - ClearAssignedButtons
GameInteractionEffectQueryResult ClearAssignedButtons::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -465,7 +465,7 @@ void ClearAssignedButtons::_Apply() {
// MARK: - SetTimeOfDay
GameInteractionEffectQueryResult SetTimeOfDay::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -477,7 +477,7 @@ void SetTimeOfDay::_Apply() {
// MARK: - SetCollisionViewer
GameInteractionEffectQueryResult SetCollisionViewer::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -492,7 +492,7 @@ void SetCollisionViewer::_Remove() {
// MARK: - RandomizeCosmetics
GameInteractionEffectQueryResult RandomizeCosmetics::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -504,7 +504,7 @@ void RandomizeCosmetics::_Apply() {
// MARK: - PressButton
GameInteractionEffectQueryResult PressButton::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -516,7 +516,7 @@ void PressButton::_Apply() {
// MARK: - PressRandomButton
GameInteractionEffectQueryResult PressRandomButton::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -528,7 +528,7 @@ void PressRandomButton::_Apply() {
// MARK: - AddOrTakeAmmo
GameInteractionEffectQueryResult AddOrTakeAmmo::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::IsSaveLoaded(true)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else if (!GameInteractor::CanAddOrTakeAmmo(parameters[0], parameters[1])) {
return GameInteractionEffectQueryResult::NotPossible;
@@ -542,7 +542,7 @@ void AddOrTakeAmmo::_Apply() {
// MARK: - RandomBombFuseTimer
GameInteractionEffectQueryResult RandomBombFuseTimer::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -557,7 +557,7 @@ void RandomBombFuseTimer::_Remove() {
// MARK: - DisableLedgeGrabs
GameInteractionEffectQueryResult DisableLedgeGrabs::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -572,7 +572,7 @@ void DisableLedgeGrabs::_Remove() {
// MARK: - RandomWind
GameInteractionEffectQueryResult RandomWind::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -587,7 +587,7 @@ void RandomWind::_Remove() {
// MARK: - RandomBonks
GameInteractionEffectQueryResult RandomBonks::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -602,7 +602,7 @@ void RandomBonks::_Remove() {
// MARK: - PlayerInvincibility
GameInteractionEffectQueryResult PlayerInvincibility::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -617,7 +617,7 @@ void PlayerInvincibility::_Remove() {
// MARK: - SlipperyFloor
GameInteractionEffectQueryResult SlipperyFloor::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
@@ -632,10 +632,10 @@ void SlipperyFloor::_Remove() {
// MARK: - SpawnEnemyWithOffset
GameInteractionEffectQueryResult SpawnEnemyWithOffset::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::CanSpawnActor()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
return GameInteractor::RawAction::SpawnEnemyWithOffset(parameters[0], parameters[1]);
return GameInteractionEffectQueryResult::Possible;
}
void SpawnEnemyWithOffset::_Apply() {
@@ -644,10 +644,10 @@ void SpawnEnemyWithOffset::_Apply() {
// MARK: - SpawnActor
GameInteractionEffectQueryResult SpawnActor::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
if (!GameInteractor::CanSpawnActor()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
return GameInteractor::RawAction::SpawnActor(parameters[0], parameters[1]);
return GameInteractionEffectQueryResult::Possible;
}
void SpawnActor::_Apply() {
@@ -44,6 +44,7 @@ DEFINE_HOOK(OnPlayerFirstPersonControl, (Player * player));
DEFINE_HOOK(OnPlayerProcessStick, ());
DEFINE_HOOK(OnPlayerShieldControl, (float_t * sp50, float_t* sp54));
DEFINE_HOOK(OnPlayDestroy, ());
DEFINE_HOOK(OnPlayDrawBegin, ());
DEFINE_HOOK(OnPlayDrawEnd, ());
DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, va_list originalArgs));
DEFINE_HOOK(OnSaveFile, (int32_t fileNum));
@@ -70,12 +71,15 @@ DEFINE_HOOK(OnUpdateFileBossRushOptionSelection, (uint8_t optionIndex, uint8_t o
DEFINE_HOOK(OnUpdateFileRandomizerOptionSelection, (uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileNameSelection, (int16_t charCode));
DEFINE_HOOK(OnFileChooseMain, (void* gameState));
DEFINE_HOOK(OnGenerationCompletion, ());
DEFINE_HOOK(OnSetGameLanguage, ());
DEFINE_HOOK(OnFileDropped, (std::string filePath));
DEFINE_HOOK(OnAssetAltChange, ());
DEFINE_HOOK(OnKaleidoUpdate, ());
DEFINE_HOOK(OnRandomizerItemGivenHooks, (uint32_t rc, GetItemEntry gi, uint8_t isGiSkipped));
DEFINE_HOOK(OnArchipelagoItemReceived, (uint32_t rg));
DEFINE_HOOK(OnRandomizerExternalCheck, (uint32_t rc));
// Audio
DEFINE_HOOK(OnSeqPlayerInit, (int32_t playerIdx, int32_t seqId));
@@ -194,6 +194,10 @@ void GameInteractor_ExecuteOnPlayDestroy() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnPlayDestroy>();
}
void GameInteractor_ExecuteOnPlayDrawBegin() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnPlayDrawBegin>();
}
void GameInteractor_ExecuteOnPlayDrawEnd() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnPlayDrawEnd>();
}
@@ -333,7 +337,6 @@ void GameInteractor_ExecuteOnKaleidoUpdate() {
}
// Mark: Randomizer
void GameInteractor_ExecuteOnRandomizerItemGivenHooks(uint32_t rc, GetItemEntry gi, uint8_t isGiSkipped) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnRandomizerItemGivenHooks>(rc, gi, isGiSkipped);
}
@@ -346,3 +349,8 @@ void GameInteractor_ExecuteOnArchipelagoItemReceived(uint32_t rg) {
void GameInteractor_ExecuteOnRandomizerExternalCheck(uint32_t rc) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnRandomizerExternalCheck>(rc);
}
// Mark: Audio
void GameInteractor_ExecuteOnSeqPlayerInit(int32_t playerIdx, int32_t seqId) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSeqPlayerInit>(playerIdx, seqId);
}
@@ -47,6 +47,7 @@ void GameInteractor_ExecuteOnPlayerShieldControl(float_t* sp50, float_t* sp54);
void GameInteractor_ExecuteOnPlayerProcessStick();
void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price);
void GameInteractor_ExecuteOnPlayDestroy();
void GameInteractor_ExecuteOnPlayDrawBegin();
void GameInteractor_ExecuteOnPlayDrawEnd();
bool GameInteractor_Should(GIVanillaBehavior flag, uint32_t result, ...);
@@ -94,6 +95,9 @@ void GameInteractor_ExecuteOnRandomizerItemGivenHooks(uint32_t rc, GetItemEntry
void GameInteractor_ExecuteOnArchipelagoItemReceived(uint32_t rg);
void GameInteractor_ExecuteOnRandomizerExternalCheck(uint32_t rc);
// Mark: - Audio
void GameInteractor_ExecuteOnSeqPlayerInit(int32_t playerIdx, int32_t seqId);
#ifdef __cplusplus
}
#endif
@@ -1362,6 +1362,22 @@ typedef enum {
// - `*EnDs`
VB_OFFER_BLUE_POTION,
// #### `result`
// ```c
// this->switchFlag >= 0
// ```
// #### `args`
// - `*EnOkarinaTag`
VB_OKARINA_TAG_COMPLETE,
// #### `result`
// ```c
// (this->switchFlag >= 0) && (Flags_GetSwitch(play, this->switchFlag))
// ```
// #### `args`
// - `*EnOkarinaTag`
VB_OKARINA_TAG_COMPLETED,
// #### `result`
// ```c
// CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)
@@ -2155,6 +2171,23 @@ typedef enum {
// - `*EnWood02`
VB_TREE_DROP_COLLECTIBLE,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*ObjWood02`
VB_TREE_SETUP_DRAW,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*ObjWood02`
VB_TREE_DROP_ITEM,
// #### `result`
// ```c
// true
// ```
@@ -2222,6 +2255,69 @@ typedef enum {
// - `s32` limbCount
// - `*Vec3s` frameTable
VB_LOAD_PLAYER_ANIMATION_FRAME,
// #### `result`
// ```c
// DoorWarp1_PlayerInRange(this, play)
// ```
// #### `args`
// - `*DoorWarp1`
VB_BLUE_WARP_CONSIDER_ADULT_IN_RANGE,
// #### `result`
// ```c
// (CVarGetInteger(CVAR_GAMEPLAY_STATS("ShowIngameTimer"), 0) && gSaveContext.fileNum >= 0 && gSaveContext.fileNum
// <= 2)
// ```
// #### `args`
// - `*PlayState`
VB_SHOW_GAMEPLAY_TIMER,
// (this->dyna.actor.params >> 5 & 0x7F) == GI_ICE_TRAP && this->actionFunc == EnBox_Open &&
// this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100
// ```
// #### `args`
// - `*EnBox`
VB_CHEST_USE_ICE_EFFECT,
// #### `result`
// ```c
// arg3 < fabsf(sp1C.x) || arg4 < fabsf(sp1C.y)
// ```
// #### `args`
// - `*DoorShutter`
VB_BE_NEAR_DOOR_SHUTTER,
// #### `result`
// ```c
// CVarGetInteger(CVAR_ENHANCEMENT("3DSceneRender"), 0)
// ```
// #### `args`
// - None
VB_DRAW_2D_BACKGROUND,
// #### `result`
// ```c
// CVarGetInteger(CVAR_ENHANCEMENT("3DSceneRender"), 0)
// ```
// #### `args`
// - None
VB_LOAD_SKYBOX,
// true
// ```
// #### `args`
// - `*Player`
VB_SET_STATIC_PREV_FLOOR_TYPE,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*Player`
VB_SET_STATIC_FLOOR_TYPE,
} GIVanillaBehavior;
#endif
+42 -3
View File
@@ -51,9 +51,48 @@ typedef enum {
/* 0xA9 */ TIMESTAMP_DEFEAT_GANON, // z_boss_ganon2.c
/* 0xA9 */ TIMESTAMP_BOSSRUSH_FINISH, // z_boss_ganon2.c
/* 0xAA */ TIMESTAMP_FOUND_GREG, // z_parameter.c
/* 0xAA */ TIMESTAMP_TRIFORCE_COMPLETED, // z_parameter.c
/* 0xAB */ TIMESTAMP_MAX
/* 0xAB */ TIMESTAMP_TRIFORCE_COMPLETED, // z_parameter.c
/* 0xAC */ TIMESTAMP_FOUND_GOHMA_SOUL,
/* 0xAD */ TIMESTAMP_FOUND_KING_DODONGO_SOUL,
/* 0xAE */ TIMESTAMP_FOUND_BARINADE_SOUL,
/* 0xAF */ TIMESTAMP_FOUND_PHANTOM_GANON_SOUL,
/* 0xB0 */ TIMESTAMP_FOUND_VOLVAGIA_SOUL,
/* 0xB1 */ TIMESTAMP_FOUND_MORPHA_SOUL,
/* 0xB2 */ TIMESTAMP_FOUND_BONGO_BONGO_SOUL,
/* 0xB3 */ TIMESTAMP_FOUND_TWINROVA_SOUL,
/* 0xB5 */ TIMESTAMP_FOUND_GANON_SOUL,
/* 0xB6 */ TIMESTAMP_FOUND_BRONZE_SCALE,
/* 0xB7 */ TIMESTAMP_FOUND_OCARINA_A_BUTTON,
/* 0xB8 */ TIMESTAMP_FOUND_OCARINA_C_UP_BUTTON,
/* 0xB9 */ TIMESTAMP_FOUND_OCARINA_C_DOWN_BUTTON,
/* 0xBA */ TIMESTAMP_FOUND_OCARINA_C_LEFT_BUTTON,
/* 0xBB */ TIMESTAMP_FOUND_OCARINA_C_RIGHT_BUTTON,
/* 0xBC */ TIMESTAMP_FOUND_FISHING_POLE,
/* 0xBD */ TIMESTAMP_FOUND_GUARD_HOUSE_KEY,
/* 0xBE */ TIMESTAMP_FOUND_MARKET_BAZAAR_KEY,
/* 0xBF */ TIMESTAMP_FOUND_MARKET_POTION_SHOP_KEY,
/* 0xC0 */ TIMESTAMP_FOUND_MASK_SHOP_KEY,
/* 0xC1 */ TIMESTAMP_FOUND_MARKET_SHOOTING_GALLERY_KEY,
/* 0xC2 */ TIMESTAMP_FOUND_BOMBCHU_BOWLING_KEY,
/* 0xC3 */ TIMESTAMP_FOUND_TREASURE_CHEST_GAME_BUILDING_KEY,
/* 0xC4 */ TIMESTAMP_FOUND_BOMBCHU_SHOP_KEY,
/* 0xC5 */ TIMESTAMP_FOUND_RICHARDS_HOUSE_KEY,
/* 0xC6 */ TIMESTAMP_FOUND_ALLEY_HOUSE_KEY,
/* 0xC7 */ TIMESTAMP_FOUND_KAK_BAZAAR_KEY,
/* 0xC8 */ TIMESTAMP_FOUND_KAK_POTION_SHOP_KEY,
/* 0xC9 */ TIMESTAMP_FOUND_BOSS_HOUSE_KEY,
/* 0xCA */ TIMESTAMP_FOUND_GRANNYS_POTION_SHOP_KEY,
/* 0xCB */ TIMESTAMP_FOUND_SKULLTULA_HOUSE_KEY,
/* 0xCC */ TIMESTAMP_FOUND_IMPAS_HOUSE_KEY,
/* 0xCD */ TIMESTAMP_FOUND_WINDMILL_KEY,
/* 0xCE */ TIMESTAMP_FOUND_KAK_SHOOTING_GALLERY_KEY,
/* 0xCF */ TIMESTAMP_FOUND_DAMPES_HUT_KEY,
/* 0xD0 */ TIMESTAMP_FOUND_TALONS_HOUSE_KEY,
/* 0xD1 */ TIMESTAMP_FOUND_STABLES_KEY,
/* 0xD2 */ TIMESTAMP_FOUND_BACK_TOWER_KEY,
/* 0xD3 */ TIMESTAMP_FOUND_HYLIA_LAB_KEY,
/* 0xD4 */ TIMESTAMP_FOUND_FISHING_HOLE_KEY,
/* 0xD5 */ TIMESTAMP_MAX
} GameplayStatTimestamp;
typedef enum {
+1 -1
View File
@@ -16,7 +16,7 @@ extern PlayState* gPlayState;
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh_assets.h"
#include "textures/icon_item_static/icon_item_static.h"
#include "consolevariablebridge.h"
#include <libultraship/bridge/consolevariablebridge.h>
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
#include <sstream>
+239
View File
@@ -0,0 +1,239 @@
#include "mod_menu.h"
#include <ship/utils/StringHelper.h>
#include <libultraship/classes.h>
#include "soh/SohGui/SohGui.hpp"
#include "soh/OTRGlobals.h"
#include "soh/resource/type/Skeleton.h"
#include <map>
#include <ranges>
#include <vector>
std::vector<std::string> enabledModFiles;
std::vector<std::string> disabledModFiles;
#define CVAR_ENABLED_MODS_NAME CVAR_GENERAL("EnabledMods")
#define CVAR_ENABLED_MODS_DEFAULT ""
#define CVAR_ENABLED_MODS_VALUE CVarGetString(CVAR_ENABLED_MODS_NAME, CVAR_ENABLED_MODS_DEFAULT)
// "|" was chosen as the separator due to
// it being an invalid character in NTFS
// and being rarely used in ext4
// it is also an ASCII character
// improving portability
// if being an ASCII character is not a requirement,
// other possible candidates include:
// - U+FFFF: non-character
// - any private use character
#define SEPARATOR "|"
void SetEnabledModsCVarValue() {
std::string s = "";
for (auto& modPath : enabledModFiles) {
s += modPath + SEPARATOR;
}
// remove trailing separator if present
if (s.length() != 0) {
s.pop_back();
}
CVarSetString(CVAR_ENABLED_MODS_NAME, s.c_str());
}
std::vector<std::string> GetEnabledModsFromCVar() {
std::string enabledModsCVarValue = CVAR_ENABLED_MODS_VALUE;
return StringHelper::Split(enabledModsCVarValue, SEPARATOR);
}
std::vector<std::string>& GetModFiles(bool enabled) {
return enabled ? enabledModFiles : disabledModFiles;
}
std::shared_ptr<Ship::ArchiveManager> GetArchiveManager() {
return Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager();
}
void UpdateModFiles(bool init = false) {
if (init) {
enabledModFiles.clear();
}
disabledModFiles.clear();
std::vector<std::string> enabledMods = GetEnabledModsFromCVar();
std::string modsPath = Ship::Context::LocateFileAcrossAppDirs("mods", appShortName);
if (modsPath.length() > 0 && std::filesystem::exists(modsPath)) {
if (std::filesystem::is_directory(modsPath)) {
for (const std::filesystem::directory_entry& p : std::filesystem::recursive_directory_iterator(
modsPath, std::filesystem::directory_options::follow_directory_symlink)) {
std::string extension = p.path().extension().string();
if (
#ifndef EXCLUDE_MPQ_SUPPORT
StringHelper::IEquals(extension, ".otr") || StringHelper::IEquals(extension, ".mpq") ||
#endif
StringHelper::IEquals(extension, ".o2r") || StringHelper::IEquals(extension, ".zip")) {
std::string path = p.path().generic_string();
bool shouldBeEnabled = std::find(enabledMods.begin(), enabledMods.end(), path) != enabledMods.end();
if (shouldBeEnabled) {
if (init) {
enabledModFiles.push_back(path);
GetArchiveManager()->AddArchive(path);
}
} else {
disabledModFiles.push_back(path);
}
}
}
}
}
}
extern "C" void gfx_texture_cache_clear();
void AfterModChange() {
SetEnabledModsCVarValue();
// TODO: runtime changes
/*
gfx_texture_cache_clear();
SOH::SkeletonPatcher::ClearSkeletons();
*/
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
// disabled mods are always sorted
std::sort(disabledModFiles.begin(), disabledModFiles.end(), [](const std::string& a, const std::string& b) {
return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(),
[](char c1, char c2) { return std::tolower(c1) < std::tolower(c2); });
});
}
void EnableMod(std::string file) {
disabledModFiles.erase(std::find(disabledModFiles.begin(), disabledModFiles.end(), file));
enabledModFiles.insert(enabledModFiles.begin(), file);
// TODO: runtime changes
// GetArchiveManager()->AddArchive(file);
AfterModChange();
}
void DisableMod(std::string file) {
enabledModFiles.erase(std::find(enabledModFiles.begin(), enabledModFiles.end(), file));
disabledModFiles.insert(disabledModFiles.begin(), file);
// TODO: runtime changes
// GetArchiveManager()->RemoveArchive(file);
AfterModChange();
}
void DrawModInfo(std::string file) {
ImGui::SameLine();
ImGui::Text("%s", file.c_str());
}
void DrawMods(bool enabled) {
std::vector<std::string>& selectedModFiles = GetModFiles(enabled);
if (selectedModFiles.empty()) {
return;
}
bool madeAnyChange = false;
int switchFromIndex = -1;
int switchToIndex = -1;
for (int i = 0; i < selectedModFiles.size(); i += 1) {
std::string file = selectedModFiles[i];
if (UIWidgets::StateButton((file + "_left_right").c_str(), enabled ? ICON_FA_ARROW_LEFT : ICON_FA_ARROW_RIGHT,
ImVec2(25, 25), UIWidgets::ButtonOptions().Color(THEME_COLOR))) {
if (enabled) {
DisableMod(file);
} else {
EnableMod(file);
}
}
// it's not relevant to reorder disabled mods
if (enabled) {
ImGui::SameLine();
if (i == 0) {
ImGui::BeginDisabled();
}
if (UIWidgets::StateButton((file + "_up").c_str(), ICON_FA_ARROW_UP, ImVec2(25, 25),
UIWidgets::ButtonOptions().Color(THEME_COLOR))) {
madeAnyChange = true;
switchFromIndex = i;
switchToIndex = i - 1;
}
if (i == 0) {
ImGui::EndDisabled();
}
ImGui::SameLine();
if (i == selectedModFiles.size() - 1) {
ImGui::BeginDisabled();
}
if (UIWidgets::StateButton((file + "_down").c_str(), ICON_FA_ARROW_DOWN, ImVec2(25, 25),
UIWidgets::ButtonOptions().Color(THEME_COLOR))) {
madeAnyChange = true;
switchFromIndex = i;
switchToIndex = i + 1;
}
if (i == selectedModFiles.size() - 1) {
ImGui::EndDisabled();
}
}
DrawModInfo(file);
}
if (madeAnyChange) {
std::iter_swap(selectedModFiles.begin() + switchFromIndex, selectedModFiles.begin() + switchToIndex);
AfterModChange();
}
}
void ModMenuWindow::DrawElement() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
const ImVec4 yellow = ImVec4(1, 1, 0, 1);
ImGui::TextColored(
yellow, "Mods are currently not reloaded at runtime.\nClose and re-open Ship for the changes to take effect.");
if (UIWidgets::Button("Update", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) {
UpdateModFiles();
}
UIWidgets::Tooltip("Re-check the mods folder for new files");
if (ImGui::BeginTable("tableMods", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
ImGui::TableSetupColumn("Disabled Mods", ImGuiTableColumnFlags_WidthStretch, 200.0f);
ImGui::TableSetupColumn("Enabled Mods", ImGuiTableColumnFlags_WidthStretch, 200.0f);
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::TableHeadersRow();
ImGui::PopItemFlag();
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginChild("Disabled Mods", ImVec2(0, -8))) {
DrawMods(false);
ImGui::EndChild();
}
ImGui::TableNextColumn();
if (ImGui::BeginChild("Enabled Mods", ImVec2(0, -8))) {
DrawMods(true);
ImGui::EndChild();
}
ImGui::EndTable();
}
ImGui::EndDisabled();
}
void ModMenuWindow::InitElement() {
UpdateModFiles(true);
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include <libultraship/libultraship.h>
#ifdef __cplusplus
class ModMenuWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;
void InitElement() override;
void DrawElement() override;
void UpdateElement() override{};
};
#endif
+20 -50
View File
@@ -6,7 +6,6 @@
#include "soh/SaveManager.h"
#include "soh/ResourceManagerHelpers.h"
#include "soh/resource/type/Skeleton.h"
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
#include "soh/Enhancements/boss-rush/BossRush.h"
#include "soh/Enhancements/enhancementTypes.h"
#include "soh/Enhancements/randomizer/3drando/random.hpp"
@@ -50,7 +49,6 @@ extern "C" {
extern SaveContext gSaveContext;
extern PlayState* gPlayState;
extern void Overlay_DisplayText(float duration, const char* text);
}
// GreyScaleEndDlist
@@ -132,10 +130,27 @@ void RegisterOcarinaTimeTravel() {
bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime &&
!nearbyFrogs && !nearbyGossipStone;
bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME);
bool doesntNeedOcarinaOfTime = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2;
bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER);
// TODO: Once Swordless Adult is fixed: Remove the Master Sword check
if (justPlayedSoT && notNearAnySource && (hasOcarinaOfTime || doesntNeedOcarinaOfTime) && hasMasterSword) {
int timeTravelSetting = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0);
bool meetsTimeTravelRequirements = false;
switch (timeTravelSetting) {
case TIME_TRAVEL_ANY:
meetsTimeTravelRequirements = true;
break;
case TIME_TRAVEL_ANY_MS:
meetsTimeTravelRequirements = hasMasterSword;
break;
case TIME_TRAVEL_OOT_MS:
meetsTimeTravelRequirements = hasMasterSword && hasOcarinaOfTime;
break;
case TIME_TRAVEL_OOT:
default:
meetsTimeTravelRequirements = hasOcarinaOfTime;
break;
}
if (justPlayedSoT && notNearAnySource && meetsTimeTravelRequirements) {
SwitchAge();
}
});
@@ -284,49 +299,6 @@ void UpdateHyperEnemiesState() {
}
}
void RegisterBonkDamage() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerBonk>([]() {
uint8_t bonkOption = CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE);
if (bonkOption == BONK_DAMAGE_NONE) {
return;
}
if (bonkOption == BONK_DAMAGE_OHKO) {
gSaveContext.health = 0;
return;
}
uint16_t bonkDamage = 0;
switch (bonkOption) {
case BONK_DAMAGE_QUARTER_HEART:
bonkDamage = 4;
break;
case BONK_DAMAGE_HALF_HEART:
bonkDamage = 8;
break;
case BONK_DAMAGE_1_HEART:
bonkDamage = 16;
break;
case BONK_DAMAGE_2_HEARTS:
bonkDamage = 32;
break;
case BONK_DAMAGE_4_HEARTS:
bonkDamage = 64;
break;
case BONK_DAMAGE_8_HEARTS:
bonkDamage = 128;
break;
default:
break;
}
Health_ChangeBy(gPlayState, -bonkDamage);
// Set invincibility to make Link flash red as a visual damage indicator.
Player* player = GET_PLAYER(gPlayState);
player->invincibilityTimer = 28;
});
}
void UpdateDirtPathFixState(int32_t sceneNum) {
switch (sceneNum) {
case SCENE_HYRULE_FIELD:
@@ -959,7 +931,6 @@ void RegisterCustomSkeletons() {
}
void InitMods() {
BossRush_RegisterHooks();
RandomizerRegisterHooks();
TimeSaverRegisterHooks();
RegisterTTS();
@@ -968,7 +939,6 @@ void InitMods() {
RegisterDeleteFileOnDeath();
RegisterHyperBosses();
UpdateHyperEnemiesState();
RegisterBonkDamage();
RegisterMenuPathFix();
RegisterMirrorModeHandler();
RegisterResetNaviTimer();
@@ -9,7 +9,6 @@
#include "hints.hpp"
#include "shops.hpp"
#include "pool_functions.hpp"
//#include "debug.hpp"
#include "soh/Enhancements/randomizer/static_data.h"
#include "soh/Enhancements/debugger/performanceTimer.h"
@@ -685,9 +684,9 @@ void LookForExternalArea(Region* currentRegion, std::set<Region*>& alreadyChecke
void SetAreas() {
auto ctx = Rando::Context::GetInstance();
// RANDOTODO give entrances an enum like RandomizerCheck, the give them all areas here,
// then use those areas to not need to recursivly find ItemLocation areas when an identifying entrance's area
for (int regionType = 0; regionType < RR_MARKER_AREAS_END; regionType++) {
// RANDOTODO give entrances an enum like RandomizerCheck, then give them all areas here,
// then use those areas to not need to recursively find ItemLocation areas when identifying entrance's area
for (int regionType = 0; regionType < RR_MAX; regionType++) {
Region* region = &areaTable[regionType];
std::set<RandomizerArea> areas = region->GetAllAreas();
std::set<Region*> regionsToSet = { region };
@@ -974,8 +973,7 @@ static void RandomizeDungeonRewards() {
return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD;
});
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA) ||
ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS)
if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS)
.Is(RO_DUNGEON_REWARDS_VANILLA)) { // Place dungeon rewards in vanilla locations
for (RandomizerCheck loc : Rando::StaticData::dungeonRewardLocations) {
ctx->GetItemLocation(loc)->PlaceVanillaItem();
@@ -2257,6 +2257,11 @@ void StaticData::HintTable_Init() {
/*french*/ "As-tu récemment ressenti une vague de #puissance magique#? Un mystérieux hibou m'a dit qu'elle provenait du #[[1]]#.^Tu devrais aller y jeter un coup d'oeil, @!\x0B",
{QM_GREEN, QM_RED}, {}, TEXTBOX_TYPE_BLUE));
hintTextTable[RHT_MIDO_HINT] = HintText(CustomMessage("You'll never find the #Kokiri Sword# I hid in #[[1]]#!",
/*german*/ "Du wirst nie das #Kokiri-Schwert# finden, das ich in #[[1]]# versteckt habe!",
/*french*/ "Pfeuuh! Tu n'trouveras jamais l'#Epée Kokiri# que j'ai cachée dans #[[1]]#!",
{QM_GREEN, QM_RED}));
hintTextTable[RHT_LOACH_HINT] = HintText(CustomMessage("What?^You wanna know about the&%rHyrule Loach%w?^It's a big fish, but it's so rare that I'll give my %g[[1]]%w to anyone who catches it. Seriously!",
/*german*/ "Was?^Du willst etwas über die&%rhylianische Forelle%w wissen?&Es ist ein riesiger Fisch,&der unfassbar selten ist!^Wenn Du mir eine bringst, |springt|springen| für Dich&%g[[1]]%w dabei raus.&Ganz im Ernst!",
/*french*/ "Quoi?&Tu veux en savoir plus sur le&%rBrochet d'Hyrule%w?^C'est un gros poisson, mais il&est si rare que je donne&%g[[1]]%w&à celui qui l'attrape.^Ouais, j'suis sérieux!",
@@ -2102,6 +2102,30 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
/*german*/ "Man erzählt sich, daß eine #Kiste im Labor am See# #[[1]]# enthielte.",
/*french*/ "Selon moi, une #caisse dans un laboratoire# contient #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_TREE_HYRULE_FIELD] =
HintText(CustomMessage("They say that a #tree in Hyrule Field# contains #[[1]]#.",
/*german*/ "",
/*french*/ "Selon moi, un #arbre dans la Plaine d'Hyrule# cache #[[1]]#.", { QM_RED, QM_GREEN }));
hintTextTable[RHT_TREE_MARKET] =
HintText(CustomMessage("They say that a #tree in Hyrule Market# contains #[[1]]#.",
/*german*/ "",
/*french*/ "Selon moi, un #arbre sur la Place du Marché# cache #[[1]]#.", { QM_RED, QM_GREEN }));
hintTextTable[RHT_TREE_HYRULE_CASTLE] =
HintText(CustomMessage("They say that a #tree in Hyrule Castle# contains #[[1]]#.",
/*german*/ "",
/*french*/ "Selon moi, un #arbre au Château d'Hyrule# cache #[[1]]#.", { QM_RED, QM_GREEN }));
hintTextTable[RHT_TREE_ZORAS_RIVER] =
HintText(CustomMessage("They say that a #tree in Zora's River# contains #[[1]]#.",
/*german*/ "",
/*french*/ "Selon moi, un #arbre à la Rivière Zora# cache #[[1]]#.", { QM_RED, QM_GREEN }));
hintTextTable[RHT_TREE_ZORAS_FOUNTAIN] =
HintText(CustomMessage("They say that a #tree in Zora's Fountain# contains #[[1]]#.",
/*german*/ "",
/*french*/ "Selon moi, un #arbre à la Fontaine Zora# cache #[[1]]#.", { QM_RED, QM_GREEN }));
hintTextTable[RHT_TREE_LON_LON_RANCH] =
HintText(CustomMessage("They say that a #tree in Lon Lon Ranch# contains #[[1]]#.",
/*german*/ "",
/*french*/ "Selon moi, un #arbre au Ranch Lon Lon# cache #[[1]]#.", { QM_RED, QM_GREEN }));
// clang-format on
}
} // namespace Rando
@@ -426,7 +426,7 @@ void StaticData::HintTable_Init_Item() {
CustomMessage("a tree killer", /*german*/"ein Baumtöter", /*french*/"un coupeur d'arbres")});
// /*spanish*/un destructor de árboles
hintTextTable[RHT_BROKEN_SWORD] = HintText(CustomMessage("the Broken Goron's Sword", /*german*/"das zerbrochene Goronen-Schwert", /*french*/"l'Épée Brisée de Goron"),
hintTextTable[RHT_BROKEN_SWORD] = HintText(CustomMessage("the Broken Goron's Sword", /*german*/"das Zerbr. Goronen-Schwert", /*french*/"l'Épée Brisée de Goron"),
// /*spanish*/la espada goron rota
{
CustomMessage("a trade quest item", /*german*/"ein Handelsgegenstand", /*french*/"un objet de quête d'échanges"),
@@ -604,17 +604,23 @@ void GenerateItemPool() {
ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL);
PlaceItemsForType(RCTYPE_POT, overworldPotsActive, dungeonPotsActive);
// Shuffle Trees
bool treesActive = (bool)ctx->GetOption(RSK_SHUFFLE_TREES);
PlaceItemsForType(RCTYPE_TREE, treesActive, false);
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC)) {
PlaceItemsForType(RCTYPE_NLTREE, treesActive, false);
}
// Shuffle Crates
bool overworldCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) ||
ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL);
bool overworldNLCratesActive = ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) &&
(ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) ||
ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL));
bool dungeonCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_DUNGEONS) ||
ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL);
PlaceItemsForType(RCTYPE_CRATE, overworldCratesActive, dungeonCratesActive);
PlaceItemsForType(RCTYPE_NLCRATE, overworldNLCratesActive, dungeonCratesActive);
PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive);
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC)) {
PlaceItemsForType(RCTYPE_NLCRATE, overworldCratesActive, dungeonCratesActive);
}
auto fsMode = ctx->GetOption(RSK_FISHSANITY);
if (fsMode.IsNot(RO_FISHSANITY_OFF)) {
@@ -861,7 +867,7 @@ void GenerateItemPool() {
AddItemToMainPool(RG_GERUDO_MEMBERSHIP_CARD);
ctx->possibleIceTrapModels.push_back(RG_GERUDO_MEMBERSHIP_CARD);
} else if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) {
AddItemToPool(PendingJunkPool, RG_GERUDO_MEMBERSHIP_CARD);
AddItemToPool(ItemPool, RG_GERUDO_MEMBERSHIP_CARD);
ctx->PlaceItemInLocation(RC_TH_FREED_CARPENTERS, RG_ICE_TRAP, false, true);
} else {
ctx->PlaceItemInLocation(RC_TH_FREED_CARPENTERS, RG_GERUDO_MEMBERSHIP_CARD, false, true);
@@ -990,13 +996,44 @@ void GenerateItemPool() {
AddItemsToPool(ItemPool, shopsanityRupees); // Shopsanity gets extra large rupees
}
// Shuffle Fairies
if (ctx->GetOption(RSK_SHUFFLE_FAIRIES)) {
for (auto rc : Rando::StaticData::GetOverworldFairyLocations()) {
// Shuffle Fountain Fairies
if (ctx->GetOption(RSK_SHUFFLE_FOUNTAIN_FAIRIES)) {
for (auto rc : Rando::StaticData::GetFountainFairyLocations()) {
AddItemToMainPool(GetJunkItem());
}
// 8 extra for Ganon's Castle + 2 Dodongo's Cavern Gossip Stone + 3 Shadow Temple
int extra = 13;
// 8 extra for Ganon's Castle
int extra = 8;
for (int i = 0; i < extra; i++) {
AddItemToMainPool(GetJunkItem());
}
}
// Shuffle Gossip Stone Fairies
if (ctx->GetOption(RSK_SHUFFLE_STONE_FAIRIES)) {
for (auto rc : Rando::StaticData::GetStoneFairyLocations()) {
AddItemToMainPool(GetJunkItem());
}
// 2 Dodongo's Cavern Gossip Stone
int extra = 2;
for (int i = 0; i < extra; i++) {
AddItemToMainPool(GetJunkItem());
}
}
// Shuffle Bean Fairies
if (ctx->GetOption(RSK_SHUFFLE_BEAN_FAIRIES)) {
for (auto rc : Rando::StaticData::GetBeanFairyLocations()) {
AddItemToMainPool(GetJunkItem());
}
}
// Shuffle Song Fairies
if (ctx->GetOption(RSK_SHUFFLE_SONG_FAIRIES)) {
for (auto rc : Rando::StaticData::GetSongFairyLocations()) {
AddItemToMainPool(GetJunkItem());
}
// 3 Shadow Temple
int extra = 3;
extra += ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla() ? 0 : 2;
extra += ctx->GetDungeon(Rando::WATER_TEMPLE)->IsVanilla() ? 0 : 3;
extra += ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsVanilla() ? 2 : 1;
@@ -65,13 +65,9 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
Random_Init(finalHash);
ctx->SetHash(std::to_string(finalHash));
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
VanillaFill(); // Just place items in their vanilla locations
} else { // Fill locations with logic
int ret = Fill();
if (ret < 0) {
return ret;
}
int ret = Fill();
if (ret < 0) {
return ret;
}
GenerateHash();
@@ -5,7 +5,7 @@
#include "rando_main.hpp"
#include "../context.h"
#include <libultraship/bridge.h>
#include <Context.h>
#include <ship/Context.h>
#include <libultraship/libultra/types.h>
#include "soh/OTRGlobals.h"
#include "soh/cvar_prefixes.h"
@@ -434,12 +434,12 @@ void InitTrickNames() {
};
trickNameTable[RG_BROKEN_SWORD] = {
Text{ "Broken Biggoron's Sword", "Épée brisée de Grogoron",
"zerbr. Biggoron-Schwert" }, // "Espada de Biggoron rota"
Text{ "Broken Giant's Knife", "Lame des Géants brisée", "zerbr. Langschwert" }, // "Daga gigante rota"
Text{ "Broken Noble Sword", "Épée noble brisée", "zerbr. Edelschwert" }, // "Espada noble rota"
Text{ "Broken Picori Blade", "Épée Minish brisée", "zerbr. Schwert der Minish" }, // "Espada minish rota"
"Zerbr. Biggoron-Schwert" }, // "Espada de Biggoron rota"
Text{ "Broken Giant's Knife", "Lame des Géants brisée", "Zerbr. Langschwert" }, // "Daga gigante rota"
Text{ "Broken Noble Sword", "Épée noble brisée", "Zerbr. Edelschwert" }, // "Espada noble rota"
Text{ "Broken Picori Blade", "Épée Minish brisée", "Zerbr. Schwert der Minish" }, // "Espada minish rota"
Text{ "Decayed Master Sword", "Épée de légende pourrie",
"zerfr. Master-Schwert" }, // "Espada decadente de leyenda"
"Zerf. Master-Schwert" }, // "Espada decadente de leyenda"
};
trickNameTable[RG_PRESCRIPTION] = {
Text{ "Biggoron's Prescription", "Ordonnance de Grogoron", "Biggorons Rezept" }, // "Receta de Biggoron"
@@ -691,7 +691,7 @@ void InitTrickNames() {
trickNameTable[RG_RUTOS_LETTER] = {
Text{ "Bottle with Maggie's Letter", "Flacon avec lettre de Maggy",
"Flasche (Dolores Brief)" }, // "Carta de Dolores"
"Flasche (Dolores' Brief)" }, // "Carta de Dolores"
Text{ "Bottle with Letter to Kafei", "Flacon avec lettre pour Kafei",
"Flasche (Brief an Kafei)" }, // "Carta para Kafei"
Text{ "Bottle with Zelda's Letter", "Flacon avec Lettre de Zelda",
@@ -717,7 +717,7 @@ void InitTrickNames() {
};
trickNameTable[RG_SARIAS_SONG] = {
Text{ "Mido's Song", "La chanson de Mido", "Midos Lied" }, // "La canción de Mido"
Text{ "Kass' Theme", "Le thème de Kass", "Kashiwa Thema" }, // "El tema de Kass"
Text{ "Kass' Theme", "Le thème de Kass", "Kashiwas Thema" }, // "El tema de Kass"
Text{ "Tune of Echoes", "Chant des Échos ", "Melodie des Echos" }, // "Melodía del Eco"
};
trickNameTable[RG_SUNS_SONG] = {
@@ -916,7 +916,7 @@ void InitTrickNames() {
};
trickNameTable[RG_MORPHA_SOUL] = {
Text{ "Dihydrogen Monoxide", "Monoxyde de Dihydrogène", "Dihydrogenmonoxid" },
Text{ "Morpha Molecules", "Molécule de Morpha", "Morphas Molekyle" },
Text{ "Morpha Molecules", "Molécule de Morpha", "Morphas Moleküle" },
Text{ "Wet Stuff", "Truc Mouillé", "nasses Zeug" },
};
trickNameTable[RG_BONGO_BONGO_SOUL] = {
@@ -1114,7 +1114,7 @@ void InitTrickNames() {
};
trickNameTable[GI_CUCCO] = {
Text{"D.I.Y. Alarm Clock", "Réveille-matin improvisé", "Improvisierter Wecker"}, // "Alarma emplumada"
Text{"Kakariko Cucco", "Cocotte Cocorico", "Kakariko Huhn" }, // "Cuco de Kakariko"
Text{"Kakariko Cucco", "Cocotte Cocorico", "Kakariko-Huhn" }, // "Cuco de Kakariko"
Text{"Hatched Cucco", "Cocotte éclose", "Geschlüpftes Küken" }, // "Pollo"
};
trickNameTable[GI_MASK_KEATON] = {
@@ -1169,4 +1169,4 @@ Text GetIceTrapName(uint8_t id) {
}
// Randomly get the easy, medium, or hard name for the given item id
return RandomElement(trickNameTable[id]);
}
}
@@ -26,10 +26,10 @@
#include <filesystem>
#include <variables.h>
#include <Context.h>
#include <ship/Context.h>
#include <soh/OTRGlobals.h>
#include "consolevariablebridge.h"
#include <libultraship/bridge/consolevariablebridge.h>
using json = nlohmann::ordered_json;
using namespace Rando;
@@ -647,7 +647,7 @@ void PlandomizerOverlayText(std::pair<Rando::Item, uint32_t> drawObject) {
imageMax.y - ImGui::CalcTextSize(std::to_string(drawObject.second).c_str()).y - 2);
ImGui::SetCursorScreenPos(textPos);
ImGui::Text(std::to_string(drawObject.second).c_str());
ImGui::Text("%s", std::to_string(drawObject.second).c_str());
// Overlay item info
if (drawObject.first.GetRandomizerGet() >= RG_PROGRESSIVE_HOOKSHOT &&
@@ -665,7 +665,7 @@ void PlandomizerOverlayText(std::pair<Rando::Item, uint32_t> drawObject) {
ImGui::SetCursorScreenPos(textPos);
std::string overlayText = "+";
overlayText += extractNumberInParentheses(drawObject.first.GetName().english.c_str());
ImGui::Text(overlayText.c_str());
ImGui::Text("%s", overlayText.c_str());
}
if (drawObject.first.GetRandomizerGet() >= RG_FOREST_TEMPLE_BOSS_KEY &&
drawObject.first.GetRandomizerGet() <= RG_GANONS_CASTLE_BOSS_KEY) {
@@ -678,7 +678,7 @@ void PlandomizerOverlayText(std::pair<Rando::Item, uint32_t> drawObject) {
break;
}
}
ImGui::Text(shortName.c_str());
ImGui::Text("%s", shortName.c_str());
}
if (drawObject.first.GetRandomizerGet() >= RG_OCARINA_A_BUTTON &&
drawObject.first.GetRandomizerGet() <= RG_OCARINA_C_RIGHT_BUTTON) {
@@ -691,7 +691,7 @@ void PlandomizerOverlayText(std::pair<Rando::Item, uint32_t> drawObject) {
break;
}
}
ImGui::Text(shortName.c_str());
ImGui::Text("%s", shortName.c_str());
}
}
@@ -1066,7 +1066,7 @@ void PlandomizerDrawHintsWindow() {
ImGui::SeparatorText(hintData.hintName.c_str());
ImGui::Text("Current Hint: ");
ImGui::SameLine();
ImGui::TextWrapped(hintData.hintText.c_str());
ImGui::TextWrapped("%s", hintData.hintText.c_str());
if (spoilerHintData.size() > 0) {
hintInputText = plandoHintData[index].hintText.c_str();
@@ -1115,9 +1115,9 @@ void PlandomizerDrawLocationsWindow(RandomizerCheckArea rcArea) {
auto randoArea = Rando::StaticData::GetLocation(checkID)->GetArea();
if (rcArea == RCAREA_INVALID || rcArea == randoArea) {
ImGui::TableNextColumn();
ImGui::TextWrapped(spoilerData.checkName.c_str());
ImGui::TextWrapped("%s", spoilerData.checkName.c_str());
ImGui::TableNextColumn();
ImGui::TextWrapped(spoilerData.checkRewardItem.GetName().english.c_str());
ImGui::TextWrapped("%s", spoilerData.checkRewardItem.GetName().english.c_str());
ImGui::TableNextColumn();
PlandomizerDrawItemSlots(index);
if (plandoLogData[index].checkRewardItem.GetRandomizerGet() == RG_ICE_TRAP) {
@@ -43,7 +43,7 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) {
objComb->unk_1B0 -= 50;
const auto beehiveIdentity = ObjectExtension::GetInstance().Get<BeehiveIdentity>(&objComb->actor);
if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && beehiveIdentity == nullptr &&
if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && beehiveIdentity != nullptr &&
!Flags_GetRandomizerInf(beehiveIdentity->randomizerInf)) {
if (objComb->unk_1B0 <= -5000) {
objComb->unk_1B0 = 1500;
@@ -55,7 +55,10 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) {
if ((objComb->collider.base.acFlags & AC_HIT) != 0) {
objComb->collider.base.acFlags &= ~AC_HIT;
s32 dmgFlags = objComb->collider.elements[0].info.acHitInfo->toucher.dmgFlags;
if (dmgFlags & 0x4001F866) {
bool slingBowDmg = RAND_GET_OPTION(RSK_SLINGBOW_BREAK_BEEHIVES) && (dmgFlags & (DMG_ARROW | DMG_SLINGSHOT));
if ((dmgFlags & 0x4001F866) && !slingBowDmg) {
objComb->unk_1B0 = 1500;
} else {
ObjComb_Break(objComb, play);
@@ -82,9 +85,11 @@ void ObjComb_RandomizerInit(void* actor) {
void ObjComb_RandomizerUpdate(void* actor) {
ObjComb* combActor = reinterpret_cast<ObjComb*>(actor);
PlayState* play = gPlayState;
combActor->unk_1B2 += 0x2EE0;
combActor->actionFunc(combActor, play);
combActor->actor.shape.rot.x =
static_cast<int16_t>(Math_SinS(combActor->unk_1B2)) * CLAMP_MIN(combActor->unk_1B0, 0) +
combActor->actor.home.rot.x;
Math_SinS(combActor->unk_1B2) * CLAMP_MIN(combActor->unk_1B0, 0) + combActor->actor.home.rot.x;
}
void RegisterShuffleBeehives() {
@@ -94,7 +99,7 @@ void RegisterShuffleBeehives() {
COND_ID_HOOK(OnActorUpdate, ACTOR_OBJ_COMB, shouldRegister, ObjComb_RandomizerUpdate);
}
static RegisterShipInitFunc initFunc(RegisterShuffleBeehives, { "IS_RANDO" });
static RegisterShipInitFunc registerShuffleBeehives(RegisterShuffleBeehives, { "IS_RANDO" });
void Rando::StaticData::RegisterBeehiveLocations() {
static bool registered = false;
@@ -138,4 +143,4 @@ void Rando::StaticData::RegisterBeehiveLocations() {
}
static ObjectExtension::Register<BeehiveIdentity> RegisterBeehiveIdentity;
static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterBeehiveLocations);
static RegisterShipInitFunc registerBeehiveLocations(Rando::StaticData::RegisterBeehiveLocations);
@@ -58,7 +58,7 @@ void RegisterShuffleCows() {
});
}
static RegisterShipInitFunc initFunc(RegisterShuffleCows, { "IS_RANDO" });
static RegisterShipInitFunc registerShuffleCows(RegisterShuffleCows, { "IS_RANDO" });
void Rando::StaticData::RegisterCowLocations() {
static bool registered = false;
@@ -79,4 +79,4 @@ void Rando::StaticData::RegisterCowLocations() {
// clang-format-on
}
static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterCowLocations);
static RegisterShipInitFunc registerCowLocations(Rando::StaticData::RegisterCowLocations);
@@ -336,7 +336,7 @@ void Rando::StaticData::RegisterCrateLocations() {
locationTable[RC_GF_SOUTHMOST_CENTER_CRATE] = Location::Crate(RC_GF_SOUTHMOST_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(315, -1534), "Southmost Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_SOUTHMOST_CENTER_CRATE));
locationTable[RC_GF_MID_SOUTH_CENTER_CRATE] = Location::Crate(RC_GF_MID_SOUTH_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(315, -1594), "Middle South Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_MID_SOUTH_CENTER_CRATE));
locationTable[RC_GF_MID_NORTH_CENTER_CRATE] = Location::Crate(RC_GF_MID_NORTH_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(310, -1782), "Middle North Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_MID_NORTH_CENTER_CRATE));
locationTable[RR_GF_NORTHMOST_CENTER_CRATE] = Location::Crate(RR_GF_NORTHMOST_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(310, -1842), "Northmost Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTHMOST_CENTER_CRATE));
locationTable[RC_GF_NORTHMOST_CENTER_CRATE] = Location::Crate(RC_GF_NORTHMOST_CENTER_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(310, -1842), "Northmost Center Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_NORTHMOST_CENTER_CRATE));
locationTable[RC_GF_OUTSKIRTS_NE_CRATE] = Location::Crate(RC_GF_OUTSKIRTS_NE_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-60, -2210), "Outskirts Northeast Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_OUTSKIRTS_NE_CRATE));
locationTable[RC_GF_OUTSKIRTS_NW_CRATE] = Location::Crate(RC_GF_OUTSKIRTS_NW_CRATE, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(-120, -2210), "Outskirts Northwest Crate", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_OUTSKIRTS_NW_CRATE));
locationTable[RC_GF_HBA_RANGE_CRATE_2] = Location::Crate(RC_GF_HBA_RANGE_CRATE_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_GERUDOS_FORTRESS, TWO_ACTOR_PARAMS(4090, -1780), "Horseback Archery Range Crate 2", RHT_CRATE_GERUDOS_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_HBA_RANGE_CRATE_2));
@@ -597,5 +597,5 @@ void Rando::StaticData::RegisterCrateLocations() {
static ObjectExtension::Register<CrateIdentity> RegisterCrateIdentity;
static ObjectExtension::Register<SmallCrateIdentity> RegisterSmallCrateIdentity;
static RegisterShipInitFunc initFunc(RegisterShuffleCrates, { "IS_RANDO" });
static RegisterShipInitFunc locFunc(Rando::StaticData::RegisterCrateLocations);
static RegisterShipInitFunc registerShuffleCrates(RegisterShuffleCrates, { "IS_RANDO" });
static RegisterShipInitFunc registerCrateLocations(Rando::StaticData::RegisterCrateLocations);
+223 -219
View File
@@ -89,7 +89,11 @@ static bool SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params, FairyType f
}
void RegisterShuffleFairies() {
bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_FAIRIES);
bool shouldRegisterFountain = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_FOUNTAIN_FAIRIES);
bool shouldRegisterStone = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_STONE_FAIRIES);
bool shouldRegisterBean = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_BEAN_FAIRIES);
bool shouldRegisterSong = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_SONG_FAIRIES);
bool shouldRegister = shouldRegisterFountain || shouldRegisterStone || shouldRegisterBean || shouldRegisterSong;
// Grant item when picking up fairy.
COND_VB_SHOULD(VB_FAIRY_HEAL, shouldRegister, {
@@ -106,7 +110,7 @@ void RegisterShuffleFairies() {
});
// Spawn fairies in fairy fountains
COND_VB_SHOULD(VB_SPAWN_FOUNTAIN_FAIRIES, shouldRegister, {
COND_VB_SHOULD(VB_SPAWN_FOUNTAIN_FAIRIES, shouldRegisterFountain, {
Actor* actor = va_arg(args, Actor*);
bool fairySpawned = false;
s16 grottoId = (gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN) ? Grotto_CurrentGrotto() : 0;
@@ -122,7 +126,7 @@ void RegisterShuffleFairies() {
});
// Spawn 3 fairies when playing Song of Storms next to a planted bean
COND_VB_SHOULD(VB_SPAWN_BEAN_STALK_FAIRIES, shouldRegister, {
COND_VB_SHOULD(VB_SPAWN_BEAN_STALK_FAIRIES, shouldRegisterBean, {
ObjBean* objBean = va_arg(args, ObjBean*);
bool fairySpawned = false;
for (s16 index = 0; index < 3; index++) {
@@ -138,7 +142,7 @@ void RegisterShuffleFairies() {
});
// Spawn a fairy from a ShotSun when playing the right song near it
COND_VB_SHOULD(VB_SPAWN_SONG_FAIRY, shouldRegister, {
COND_VB_SHOULD(VB_SPAWN_SONG_FAIRY, shouldRegisterSong, {
ShotSun* shotSun = va_arg(args, ShotSun*);
if (SpawnFairy(shotSun->actor.world.pos.x, shotSun->actor.world.pos.y, shotSun->actor.world.pos.z,
TWO_ACTOR_PARAMS(0x1000, (int32_t)shotSun->actor.world.pos.z), FAIRY_HEAL_BIG)) {
@@ -147,7 +151,7 @@ void RegisterShuffleFairies() {
});
// Handle playing both misc songs and song of storms in front of a gossip stone.
COND_VB_SHOULD(VB_SPAWN_GOSSIP_STONE_FAIRY, shouldRegister, {
COND_VB_SHOULD(VB_SPAWN_GOSSIP_STONE_FAIRY, shouldRegisterStone, {
EnGs* gossipStone = va_arg(args, EnGs*);
FairyType fairyType = FAIRY_HEAL;
@@ -196,229 +200,229 @@ void Rando::StaticData::RegisterFairyLocations() {
return;
registered = true;
// clang-format off
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1800, "Fairy Grotto Fairy 1", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1801, "Fairy Grotto Fairy 2", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1802, "Fairy Grotto Fairy 3", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1803, "Fairy Grotto Fairy 4", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1804, "Fairy Grotto Fairy 5", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1805, "Fairy Grotto Fairy 6", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1806, "Fairy Grotto Fairy 7", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1807, "Fairy Grotto Fairy 8", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0300, "Fairy Grotto Fairy 1", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0301, "Fairy Grotto Fairy 2", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0302, "Fairy Grotto Fairy 3", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0303, "Fairy Grotto Fairy 4", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0304, "Fairy Grotto Fairy 5", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0305, "Fairy Grotto Fairy 6", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0306, "Fairy Grotto Fairy 7", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_ZR_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0307, "Fairy Grotto Fairy 8", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F00, "Fairy Grotto Fairy 1", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_1));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F01, "Fairy Grotto Fairy 2", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_2));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F02, "Fairy Grotto Fairy 3", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_3));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F03, "Fairy Grotto Fairy 4", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_4));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F04, "Fairy Grotto Fairy 5", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_5));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F05, "Fairy Grotto Fairy 6", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_6));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F06, "Fairy Grotto Fairy 7", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_7));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_HF_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F07, "Fairy Grotto Fairy 8", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_8));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C00, "Fairy Grotto Fairy 1", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C01, "Fairy Grotto Fairy 2", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C02, "Fairy Grotto Fairy 3", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C03, "Fairy Grotto Fairy 4", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C04, "Fairy Grotto Fairy 5", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C05, "Fairy Grotto Fairy 6", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C06, "Fairy Grotto Fairy 7", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_ZD_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C07, "Fairy Grotto Fairy 8", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D00, "Fairy Grotto Fairy 1", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_1));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_2] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D01, "Fairy Grotto Fairy 2", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_2));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_3] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D02, "Fairy Grotto Fairy 3", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_3));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_4] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D03, "Fairy Grotto Fairy 4", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_4));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_5] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D04, "Fairy Grotto Fairy 5", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_5));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_6] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D05, "Fairy Grotto Fairy 6", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_6));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_7] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D06, "Fairy Grotto Fairy 7", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_7));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_8] = Location::Fairy(RC_GF_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D07, "Fairy Grotto Fairy 8", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_8));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_1] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1800, "Fairy Grotto Fairy 1", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_2] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1801, "Fairy Grotto Fairy 2", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_3] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1802, "Fairy Grotto Fairy 3", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_4] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1803, "Fairy Grotto Fairy 4", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_5] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1804, "Fairy Grotto Fairy 5", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_6] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1805, "Fairy Grotto Fairy 6", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_7] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1806, "Fairy Grotto Fairy 7", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7));
locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_8] = Location::FountainFairy(RC_SFM_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1807, "Fairy Grotto Fairy 8", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_1] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0300, "Fairy Grotto Fairy 1", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_2] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0301, "Fairy Grotto Fairy 2", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_3] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0302, "Fairy Grotto Fairy 3", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_4] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0303, "Fairy Grotto Fairy 4", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_5] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0304, "Fairy Grotto Fairy 5", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_6] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0305, "Fairy Grotto Fairy 6", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_7] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0306, "Fairy Grotto Fairy 7", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7));
locationTable[RC_ZR_FAIRY_GROTTO_FAIRY_8] = Location::FountainFairy(RC_ZR_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_FAIRYS_FOUNTAIN, 0x0307, "Fairy Grotto Fairy 8", RHT_ZR_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_1] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F00, "Fairy Grotto Fairy 1", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_1));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_2] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F01, "Fairy Grotto Fairy 2", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_2));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_3] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F02, "Fairy Grotto Fairy 3", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_3));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_4] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F03, "Fairy Grotto Fairy 4", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_4));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_5] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F04, "Fairy Grotto Fairy 5", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_5));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_6] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F05, "Fairy Grotto Fairy 6", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_6));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_7] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F06, "Fairy Grotto Fairy 7", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_7));
locationTable[RC_HF_FAIRY_GROTTO_FAIRY_8] = Location::FountainFairy(RC_HF_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_FAIRYS_FOUNTAIN, 0x0F07, "Fairy Grotto Fairy 8", RHT_HF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FAIRY_GROTTO_FAIRY_8));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_1] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C00, "Fairy Grotto Fairy 1", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_2] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C01, "Fairy Grotto Fairy 2", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_3] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C02, "Fairy Grotto Fairy 3", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_4] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C03, "Fairy Grotto Fairy 4", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_5] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C04, "Fairy Grotto Fairy 5", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_6] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C05, "Fairy Grotto Fairy 6", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_7] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C06, "Fairy Grotto Fairy 7", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7));
locationTable[RC_ZD_FAIRY_GROTTO_FAIRY_8] = Location::FountainFairy(RC_ZD_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_FAIRYS_FOUNTAIN, 0x1C07, "Fairy Grotto Fairy 8", RHT_ZD_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_1] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D00, "Fairy Grotto Fairy 1", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_1));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_2] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D01, "Fairy Grotto Fairy 2", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_2));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_3] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_3, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D02, "Fairy Grotto Fairy 3", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_3));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_4] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_4, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D03, "Fairy Grotto Fairy 4", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_4));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_5] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_5, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D04, "Fairy Grotto Fairy 5", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_5));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_6] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_6, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D05, "Fairy Grotto Fairy 6", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_6));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_7] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_7, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D06, "Fairy Grotto Fairy 7", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_7));
locationTable[RC_GF_FAIRY_GROTTO_FAIRY_8] = Location::FountainFairy(RC_GF_FAIRY_GROTTO_FAIRY_8, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_FAIRYS_FOUNTAIN, 0x1D07, "Fairy Grotto Fairy 8", RHT_GF_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_FAIRY_GROTTO_FAIRY_8));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x00, "Shield Grave Fairy 1", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x01, "Shield Grave Fairy 2", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x02, "Shield Grave Fairy 3", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x03, "Shield Grave Fairy 4", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x04, "Shield Grave Fairy 5", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x05, "Shield Grave Fairy 6", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x06, "Shield Grave Fairy 7", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8] = Location::Fairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x07, "Shield Grave Fairy 8", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_1] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_1, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x00, "Scrubs Fairy 1", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_2] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_2, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x01, "Scrubs Fairy 2", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_3] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_3, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x02, "Scrubs Fairy 3", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_4] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_4, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x03, "Scrubs Fairy 4", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_5] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_5, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x04, "Scrubs Fairy 5", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_6] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_6, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x05, "Scrubs Fairy 6", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_7] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_7, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x06, "Scrubs Fairy 7", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_8] = Location::Fairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x07, "Scrubs Fairy 8", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x00, "MQ Scrubs Fairy 1", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x01, "MQ Scrubs Fairy 2", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x02, "MQ Scrubs Fairy 3", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x03, "MQ Scrubs Fairy 4", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x04, "MQ Scrubs Fairy 5", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x05, "MQ Scrubs Fairy 6", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x06, "MQ Scrubs Fairy 7", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8] = Location::Fairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x07, "MQ Scrubs Fairy 8", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8));
locationTable[RC_COLOSSUS_OASIS_FAIRY_1] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x00, "Oasis Fairy 1", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_1));
locationTable[RC_COLOSSUS_OASIS_FAIRY_2] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x01, "Oasis Fairy 2", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_2));
locationTable[RC_COLOSSUS_OASIS_FAIRY_3] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x02, "Oasis Fairy 3", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_3));
locationTable[RC_COLOSSUS_OASIS_FAIRY_4] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_4, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x03, "Oasis Fairy 4", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_4));
locationTable[RC_COLOSSUS_OASIS_FAIRY_5] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_5, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x04, "Oasis Fairy 5", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_5));
locationTable[RC_COLOSSUS_OASIS_FAIRY_6] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_6, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x05, "Oasis Fairy 6", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_6));
locationTable[RC_COLOSSUS_OASIS_FAIRY_7] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_7, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x06, "Oasis Fairy 7", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_7));
locationTable[RC_COLOSSUS_OASIS_FAIRY_8] = Location::Fairy(RC_COLOSSUS_OASIS_FAIRY_8, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x07, "Oasis Fairy 8", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_8));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x00, "Shield Grave Fairy 1", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x01, "Shield Grave Fairy 2", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x02, "Shield Grave Fairy 3", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x03, "Shield Grave Fairy 4", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x04, "Shield Grave Fairy 5", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x05, "Shield Grave Fairy 6", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x06, "Shield Grave Fairy 7", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7));
locationTable[RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8] = Location::FountainFairy(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVE_WITH_FAIRYS_FOUNTAIN, 0x07, "Shield Grave Fairy 8", RHT_GRAVEYARD_SHIELD_GRAVE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_1] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_1, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x00, "Scrubs Fairy 1", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_2] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_2, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x01, "Scrubs Fairy 2", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_3] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_3, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x02, "Scrubs Fairy 3", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_4] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_4, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x03, "Scrubs Fairy 4", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_5] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_5, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x04, "Scrubs Fairy 5", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_6] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_6, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x05, "Scrubs Fairy 6", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_7] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_7, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x06, "Scrubs Fairy 7", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7));
locationTable[RC_GANONS_CASTLE_SCRUBS_FAIRY_8] = Location::FountainFairy(RC_GANONS_CASTLE_SCRUBS_FAIRY_8, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x07, "Scrubs Fairy 8", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x00, "MQ Scrubs Fairy 1", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x01, "MQ Scrubs Fairy 2", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x02, "MQ Scrubs Fairy 3", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x03, "MQ Scrubs Fairy 4", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x04, "MQ Scrubs Fairy 5", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x05, "MQ Scrubs Fairy 6", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x06, "MQ Scrubs Fairy 7", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7));
locationTable[RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8] = Location::FountainFairy(RC_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, RCQUEST_MQ, RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, 0x07, "MQ Scrubs Fairy 8", RHT_GANONS_CASTLE_SCRUBS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8));
locationTable[RC_COLOSSUS_OASIS_FAIRY_1] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x00, "Oasis Fairy 1", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_1));
locationTable[RC_COLOSSUS_OASIS_FAIRY_2] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x01, "Oasis Fairy 2", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_2));
locationTable[RC_COLOSSUS_OASIS_FAIRY_3] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x02, "Oasis Fairy 3", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_3));
locationTable[RC_COLOSSUS_OASIS_FAIRY_4] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_4, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x03, "Oasis Fairy 4", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_4));
locationTable[RC_COLOSSUS_OASIS_FAIRY_5] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_5, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x04, "Oasis Fairy 5", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_5));
locationTable[RC_COLOSSUS_OASIS_FAIRY_6] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_6, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x05, "Oasis Fairy 6", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_6));
locationTable[RC_COLOSSUS_OASIS_FAIRY_7] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_7, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x06, "Oasis Fairy 7", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_7));
locationTable[RC_COLOSSUS_OASIS_FAIRY_8] = Location::FountainFairy(RC_COLOSSUS_OASIS_FAIRY_8, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x07, "Oasis Fairy 8", RHT_COLOSSUS_OASIS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_OASIS_FAIRY_8));
locationTable[RC_ZR_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_ZR_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0300, "Bean Sprout Fairy 1", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_1));
locationTable[RC_ZR_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_ZR_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0301, "Bean Sprout Fairy 2", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_2));
locationTable[RC_ZR_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_ZR_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0302, "Bean Sprout Fairy 3", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_3));
locationTable[RC_KF_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_KF_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0900, "Bean Sprout Fairy 1", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_1));
locationTable[RC_KF_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_KF_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0901, "Bean Sprout Fairy 2", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_2));
locationTable[RC_KF_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_KF_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0902, "Bean Sprout Fairy 3", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_3));
locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0400, "Bean Sprout Near Bridge Fairy 1", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1));
locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0401, "Bean Sprout Near Bridge Fairy 2", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2));
locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0402, "Bean Sprout Near Bridge Fairy 3", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3));
locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1200, "Bean Sprout Near Theatre Fairy 1", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1));
locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1201, "Bean Sprout Near Theatre Fairy 2", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2));
locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3] = Location::Fairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1202, "Bean Sprout Near Theatre Fairy 3", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3));
locationTable[RC_LH_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_LH_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0100, "Bean Sprout Fairy 1", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_1));
locationTable[RC_LH_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_LH_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0101, "Bean Sprout Fairy 2", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_2));
locationTable[RC_LH_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_LH_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0102, "Bean Sprout Fairy 3", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_3));
locationTable[RC_GV_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_GV_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0300, "Bean Sprout Fairy 1", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_1));
locationTable[RC_GV_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_GV_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0301, "Bean Sprout Fairy 2", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_2));
locationTable[RC_GV_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_GV_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0302, "Bean Sprout Fairy 3", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_3));
locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1800, "Bean Sprout Fairy 1", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1));
locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1801, "Bean Sprout Fairy 2", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2));
locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1802, "Bean Sprout Fairy 3", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3));
locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0300, "Bean Sprout Fairy 1", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1));
locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0301, "Bean Sprout Fairy 2", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2));
locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0302, "Bean Sprout Fairy 3", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3));
locationTable[RC_DMC_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_DMC_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0300, "Bean Sprout Fairy 1", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_1));
locationTable[RC_DMC_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_DMC_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0301, "Bean Sprout Fairy 2", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_2));
locationTable[RC_DMC_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_DMC_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0302, "Bean Sprout Fairy 3", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_3));
locationTable[RC_DMT_BEAN_SPROUT_FAIRY_1] = Location::Fairy(RC_DMT_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0600, "Bean Sprout Fairy 1", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_1));
locationTable[RC_DMT_BEAN_SPROUT_FAIRY_2] = Location::Fairy(RC_DMT_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0601, "Bean Sprout Fairy 2", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_2));
locationTable[RC_DMT_BEAN_SPROUT_FAIRY_3] = Location::Fairy(RC_DMT_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0602, "Bean Sprout Fairy 3", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_3));
locationTable[RC_ZR_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_ZR_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0300, "Bean Sprout Fairy 1", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_1));
locationTable[RC_ZR_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_ZR_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0301, "Bean Sprout Fairy 2", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_2));
locationTable[RC_ZR_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_ZR_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, 0x0302, "Bean Sprout Fairy 3", RHT_ZR_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_BEAN_SPROUT_FAIRY_3));
locationTable[RC_KF_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_KF_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0900, "Bean Sprout Fairy 1", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_1));
locationTable[RC_KF_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_KF_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0901, "Bean Sprout Fairy 2", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_2));
locationTable[RC_KF_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_KF_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, 0x0902, "Bean Sprout Fairy 3", RHT_KF_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BEAN_SPROUT_FAIRY_3));
locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0400, "Bean Sprout Near Bridge Fairy 1", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1));
locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0401, "Bean Sprout Near Bridge Fairy 2", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2));
locationTable[RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x0402, "Bean Sprout Near Bridge Fairy 3", RHT_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3));
locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1200, "Bean Sprout Near Theatre Fairy 1", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1));
locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1201, "Bean Sprout Near Theatre Fairy 2", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2));
locationTable[RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3] = Location::BeanFairy(RC_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, 0x1202, "Bean Sprout Near Theatre Fairy 3", RHT_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3));
locationTable[RC_LH_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_LH_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0100, "Bean Sprout Fairy 1", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_1));
locationTable[RC_LH_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_LH_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0101, "Bean Sprout Fairy 2", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_2));
locationTable[RC_LH_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_LH_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, 0x0102, "Bean Sprout Fairy 3", RHT_LH_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_BEAN_SPROUT_FAIRY_3));
locationTable[RC_GV_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_GV_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0300, "Bean Sprout Fairy 1", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_1));
locationTable[RC_GV_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_GV_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0301, "Bean Sprout Fairy 2", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_2));
locationTable[RC_GV_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_GV_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, 0x0302, "Bean Sprout Fairy 3", RHT_GV_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_BEAN_SPROUT_FAIRY_3));
locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1800, "Bean Sprout Fairy 1", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1));
locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1801, "Bean Sprout Fairy 2", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2));
locationTable[RC_COLOSSUS_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, 0x1802, "Bean Sprout Fairy 3", RHT_COLOSSUS_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3));
locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0300, "Bean Sprout Fairy 1", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1));
locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0301, "Bean Sprout Fairy 2", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2));
locationTable[RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_GRAVEYARD_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, 0x0302, "Bean Sprout Fairy 3", RHT_GRAVEYARD_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3));
locationTable[RC_DMC_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_DMC_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0300, "Bean Sprout Fairy 1", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_1));
locationTable[RC_DMC_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_DMC_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0301, "Bean Sprout Fairy 2", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_2));
locationTable[RC_DMC_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_DMC_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, 0x0302, "Bean Sprout Fairy 3", RHT_DMC_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_BEAN_SPROUT_FAIRY_3));
locationTable[RC_DMT_BEAN_SPROUT_FAIRY_1] = Location::BeanFairy(RC_DMT_BEAN_SPROUT_FAIRY_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0600, "Bean Sprout Fairy 1", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_1));
locationTable[RC_DMT_BEAN_SPROUT_FAIRY_2] = Location::BeanFairy(RC_DMT_BEAN_SPROUT_FAIRY_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0601, "Bean Sprout Fairy 2", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_2));
locationTable[RC_DMT_BEAN_SPROUT_FAIRY_3] = Location::BeanFairy(RC_DMT_BEAN_SPROUT_FAIRY_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, 0x0602, "Bean Sprout Fairy 3", RHT_DMT_BEAN_SPROUT_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_BEAN_SPROUT_FAIRY_3));
locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -680), "ToT Left Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY));
locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -680), "ToT Left Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -615), "ToT Left Center Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY));
locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -615), "ToT Left Center Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -550), "ToT Right Center Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY));
locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -550), "ToT Right Center Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -485), "ToT Right Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY));
locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -485), "ToT Right Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DMC_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMC_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS( 0, 1656), "Gossip Stone Fairy", RHT_DMC_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_STONE_FAIRY));
locationTable[RC_DMC_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMC_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(0x1000, 1656), "Gossip Stone Big Fairy", RHT_DMC_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DMT_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS( 0, -3935), "Gossip Stone Fairy", RHT_DMT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GOSSIP_STONE_FAIRY));
locationTable[RC_DMT_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, -3935), "Gossip Stone Big Fairy", RHT_DMT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_COLOSSUS_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_COLOSSUS_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS( 0, 1320), "Gossip Stone Fairy", RHT_COLOSSUS_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY));
locationTable[RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(0x1000, 1320), "Gossip Stone Big Fairy", RHT_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, RCQUEST_VANILLA,RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS( 0, -1520), "Gossip Stone Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY));
locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, RCQUEST_VANILLA,RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(0x1000, -1520), "Gossip Stone Big Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS( 0, -916), "MQ Gossip Stone Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY));
locationTable[RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(0x1000, -916), "MQ Gossip Stone Big Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_GV_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GV_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS( 0, -2340), "Gossip Stone Fairy", RHT_GV_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_GOSSIP_STONE_FAIRY));
locationTable[RC_GV_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GV_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(0x1000, -2340), "Gossip Stone Big Fairy", RHT_GV_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_GC_MAZE_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GC_MAZE_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS( 0, -1265), "Maze Gossip Stone Fairy", RHT_GC_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY));
locationTable[RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(0x1000, -1265), "Maze Gossip Stone Big Fairy", RHT_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS( 0, 1496), "Medigoron Gossip Stone Fairy", RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY));
locationTable[RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(0x1000, 1496), "Medigoron Gossip Stone Big Fairy", RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_GRAVEYARD_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_GRAVEYARD_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS( 0, -75), "Gossip Stone Fairy", RHT_GRAVEYARD_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY));
locationTable[RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(0x1000, -75), "Gossip Stone Big Fairy", RHT_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HC_MALON_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HC_MALON_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS( 0, 3445), "Malon Gossip Stone Fairy", RHT_HC_MALON_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY));
locationTable[RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(0x1000, 3445), "Malon Gossip Stone Big Fairy", RHT_HC_MALON_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS( 0, 1041), "Rock Wall Gossip Stone Fairy", RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY));
locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(0x1000, 1041), "Rock Wall Gossip Stone Big Fairy", RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0xC, 735), "Storms Grotto Gossip Stone Fairy", RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x100C, 735), "Storms Grotto Gossip Stone Big Fairy", RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -2230), "Deku Tree Left Gossip Stone Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY));
locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -2230), "Deku Tree Left Gossip Stone Big Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -700), "Deku Tree Right Gossip Stone Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY));
locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -700), "Deku Tree Right Gossip Stone Big Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_KF_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -1223), "Gossip Stone Fairy", RHT_KF_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_GOSSIP_STONE_FAIRY));
locationTable[RC_KF_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -1223), "Gossip Stone Big Fairy", RHT_KF_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x1B, -236), "Storms Gossip Stone Fairy", RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x101B, -236), "Storms Gossip Stone Big Fairy", RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LH_LAB_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LH_LAB_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 3212), "Lab Gossip Stone Fairy", RHT_LH_LAB_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY));
locationTable[RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 3212), "Lab Gossip Stone Big Fairy", RHT_LH_LAB_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 8395), "Southeast Gossip Stone Fairy", RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY));
locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 8395), "Southeast Gossip Stone Big Fairy", RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 7984), "Southwest Gossip Stone Fairy", RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY));
locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 7984), "Southwest Gossip Stone Big Fairy", RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LW_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LW_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS( 0, 2300), "Gossip Stone Fairy", RHT_LW_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_GOSSIP_STONE_FAIRY));
locationTable[RC_LW_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LW_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, 2300), "Gossip Stone Big Fairy", RHT_LW_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, 1370), "Maze Lower Gossip Stone Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY));
locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, 1370), "Maze Lower Gossip Stone Big Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, 740), "Maze Upper Gossip Stone Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY));
locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, 740), "Maze Upper Gossip Stone Big Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_SFM_SARIA_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, -2300), "Saria Gossip Stone Fairy", RHT_SFM_SARIA_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY));
locationTable[RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, -2300), "Saria Gossip Stone Big Fairy", RHT_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZD_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZD_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS( 0, -1600), "Gossip Stone Fairy", RHT_ZD_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_GOSSIP_STONE_FAIRY));
locationTable[RC_ZD_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZD_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(0x1000, -1600), "Gossip Stone Big Fairy", RHT_ZD_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZF_FAIRY_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS( 0, 2205), "Fairy Gossip Stone Fairy", RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY));
locationTable[RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(0x1000, 2205), "Fairy Gossip Stone Big Fairy", RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZF_JABU_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZF_JABU_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS( 0, -985), "Jabu Gossip Stone Fairy", RHT_ZF_JABU_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY));
locationTable[RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(0x1000, -985), "Jabu Gossip Stone Big Fairy", RHT_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS( 0, -1070), "Near Grottos Gossip Stone Fairy", RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY));
locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(0x1000, -1070), "Near Grottos Gossip Stone Big Fairy", RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS( 0, -1650), "Near Domain Gossip Stone Fairy", RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY));
locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(0x1000, -1650), "Near Domain Gossip Stone Big Fairy", RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x11, -357), "Cow Grotto Gossip Stone Fairy", RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1011, -357), "Cow Grotto Gossip Stone Big Fairy", RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x10, -236), "Near Market Gossip Stone Fairy", RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1010, -236), "Near Market Gossip Stone Big Fairy", RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x14, -236), "Southeast Gossip Stone Fairy", RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1014, -236), "Southeast Gossip Stone Big Fairy", RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x13, -236), "Open Grotto Gossip Stone Fairy", RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1013, -236), "Open Grotto Gossip Stone Big Fairy", RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0xA, -236), "Open Grotto Gossip Stone Fairy", RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x100A, -236), "Open Grotto Gossip Stone Big Fairy", RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x4, -236), "Open Grotto Gossip Stone Fairy", RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1004, -236), "Open Grotto Gossip Stone Big Fairy", RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x1A, -236), "Tunnel Grotto Gossip Stone Fairy", RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x101A, -236), "Tunnel Grotto Gossip Stone Big Fairy", RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x8, -236), "Storms Grotto Gossip Stone Fairy", RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1008, -236), "Storms Grotto Gossip Stone Big Fairy", RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY] = Location::Fairy(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x6, -236), "Upper Grotto Gossip Stone Fairy", RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::Fairy(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1006, -236), "Upper Grotto Gossip Stone Big Fairy", RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -680), "ToT Left Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY));
locationTable[RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -680), "ToT Left Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -615), "ToT Left Center Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY));
locationTable[RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -615), "ToT Left Center Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -550), "ToT Right Center Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY));
locationTable[RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -550), "ToT Right Center Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS( 0, -485), "ToT Right Gossip Stone Fairy", RHT_TOT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY));
locationTable[RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_MARKET, SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY, TWO_ACTOR_PARAMS(0x1000, -485), "ToT Right Gossip Stone Big Fairy", RHT_TOT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DMC_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DMC_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS( 0, 1656), "Gossip Stone Fairy", RHT_DMC_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_STONE_FAIRY));
locationTable[RC_DMC_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DMC_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(0x1000, 1656), "Gossip Stone Big Fairy", RHT_DMC_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DMT_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DMT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS( 0, -3935), "Gossip Stone Fairy", RHT_DMT_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GOSSIP_STONE_FAIRY));
locationTable[RC_DMT_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DMT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, -3935), "Gossip Stone Big Fairy", RHT_DMT_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_COLOSSUS_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_COLOSSUS_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS( 0, 1320), "Gossip Stone Fairy", RHT_COLOSSUS_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY));
locationTable[RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, TWO_ACTOR_PARAMS(0x1000, 1320), "Gossip Stone Big Fairy", RHT_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, RCQUEST_VANILLA,RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS( 0, -1520), "Gossip Stone Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY));
locationTable[RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, RCQUEST_VANILLA,RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(0x1000, -1520), "Gossip Stone Big Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS( 0, -916), "MQ Gossip Stone Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY));
locationTable[RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, RCQUEST_MQ, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(0x1000, -916), "MQ Gossip Stone Big Fairy", RHT_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_GV_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_GV_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS( 0, -2340), "Gossip Stone Fairy", RHT_GV_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_GOSSIP_STONE_FAIRY));
locationTable[RC_GV_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_GV_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, TWO_ACTOR_PARAMS(0x1000, -2340), "Gossip Stone Big Fairy", RHT_GV_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_GC_MAZE_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_GC_MAZE_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS( 0, -1265), "Maze Gossip Stone Fairy", RHT_GC_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY));
locationTable[RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(0x1000, -1265), "Maze Gossip Stone Big Fairy", RHT_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS( 0, 1496), "Medigoron Gossip Stone Fairy", RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY));
locationTable[RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(0x1000, 1496), "Medigoron Gossip Stone Big Fairy", RHT_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_GRAVEYARD_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_GRAVEYARD_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS( 0, -75), "Gossip Stone Fairy", RHT_GRAVEYARD_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY));
locationTable[RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, TWO_ACTOR_PARAMS(0x1000, -75), "Gossip Stone Big Fairy", RHT_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HC_MALON_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HC_MALON_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS( 0, 3445), "Malon Gossip Stone Fairy", RHT_HC_MALON_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY));
locationTable[RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HC_MALON_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(0x1000, 3445), "Malon Gossip Stone Big Fairy", RHT_HC_MALON_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS( 0, 1041), "Rock Wall Gossip Stone Fairy", RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY));
locationTable[RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(0x1000, 1041), "Rock Wall Gossip Stone Big Fairy", RHT_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0xC, 735), "Storms Grotto Gossip Stone Fairy", RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x100C, 735), "Storms Grotto Gossip Stone Big Fairy", RHT_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -2230), "Deku Tree Left Gossip Stone Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY));
locationTable[RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -2230), "Deku Tree Left Gossip Stone Big Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -700), "Deku Tree Right Gossip Stone Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY));
locationTable[RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -700), "Deku Tree Right Gossip Stone Big Fairy", RHT_KF_DEKU_TREE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_KF_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_KF_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS( 0, -1223), "Gossip Stone Fairy", RHT_KF_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_GOSSIP_STONE_FAIRY));
locationTable[RC_KF_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_KF_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(0x1000, -1223), "Gossip Stone Big Fairy", RHT_KF_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x1B, -236), "Storms Gossip Stone Fairy", RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x101B, -236), "Storms Gossip Stone Big Fairy", RHT_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LH_LAB_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_LH_LAB_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 3212), "Lab Gossip Stone Fairy", RHT_LH_LAB_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY));
locationTable[RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_LH_LAB_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 3212), "Lab Gossip Stone Big Fairy", RHT_LH_LAB_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 8395), "Southeast Gossip Stone Fairy", RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY));
locationTable[RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 8395), "Southeast Gossip Stone Big Fairy", RHT_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS( 0, 7984), "Southwest Gossip Stone Fairy", RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY));
locationTable[RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 7984), "Southwest Gossip Stone Big Fairy", RHT_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LW_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_LW_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS( 0, 2300), "Gossip Stone Fairy", RHT_LW_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_GOSSIP_STONE_FAIRY));
locationTable[RC_LW_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_LW_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, 2300), "Gossip Stone Big Fairy", RHT_LW_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, 1370), "Maze Lower Gossip Stone Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY));
locationTable[RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, 1370), "Maze Lower Gossip Stone Big Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, 740), "Maze Upper Gossip Stone Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY));
locationTable[RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, 740), "Maze Upper Gossip Stone Big Fairy", RHT_SFM_MAZE_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_SFM_SARIA_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_SFM_SARIA_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS( 0, -2300), "Saria Gossip Stone Fairy", RHT_SFM_SARIA_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY));
locationTable[RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_SACRED_FOREST_MEADOW, TWO_ACTOR_PARAMS(0x1000, -2300), "Saria Gossip Stone Big Fairy", RHT_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZD_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZD_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS( 0, -1600), "Gossip Stone Fairy", RHT_ZD_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_GOSSIP_STONE_FAIRY));
locationTable[RC_ZD_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZD_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(0x1000, -1600), "Gossip Stone Big Fairy", RHT_ZD_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZF_FAIRY_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS( 0, 2205), "Fairy Gossip Stone Fairy", RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY));
locationTable[RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(0x1000, 2205), "Fairy Gossip Stone Big Fairy", RHT_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZF_JABU_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZF_JABU_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS( 0, -985), "Jabu Gossip Stone Fairy", RHT_ZF_JABU_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY));
locationTable[RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(0x1000, -985), "Jabu Gossip Stone Big Fairy", RHT_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS( 0, -1070), "Near Grottos Gossip Stone Fairy", RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY));
locationTable[RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(0x1000, -1070), "Near Grottos Gossip Stone Big Fairy", RHT_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS( 0, -1650), "Near Domain Gossip Stone Fairy", RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY));
locationTable[RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(0x1000, -1650), "Near Domain Gossip Stone Big Fairy", RHT_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x11, -357), "Cow Grotto Gossip Stone Fairy", RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1011, -357), "Cow Grotto Gossip Stone Big Fairy", RHT_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x10, -236), "Near Market Gossip Stone Fairy", RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1010, -236), "Near Market Gossip Stone Big Fairy", RHT_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x14, -236), "Southeast Gossip Stone Fairy", RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1014, -236), "Southeast Gossip Stone Big Fairy", RHT_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x13, -236), "Open Grotto Gossip Stone Fairy", RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1013, -236), "Open Grotto Gossip Stone Big Fairy", RHT_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0xA, -236), "Open Grotto Gossip Stone Fairy", RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x100A, -236), "Open Grotto Gossip Stone Big Fairy", RHT_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x4, -236), "Open Grotto Gossip Stone Fairy", RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1004, -236), "Open Grotto Gossip Stone Big Fairy", RHT_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x1A, -236), "Tunnel Grotto Gossip Stone Fairy", RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x101A, -236), "Tunnel Grotto Gossip Stone Big Fairy", RHT_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x8, -236), "Storms Grotto Gossip Stone Fairy", RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1008, -236), "Storms Grotto Gossip Stone Big Fairy", RHT_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY] = Location::StoneFairy(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS( 0x6, -236), "Upper Grotto Gossip Stone Fairy", RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY));
locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG] = Location::StoneFairy(RC_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1006, -236), "Upper Grotto Gossip Stone Big Fairy", RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG));
locationTable[RC_LH_ISLAND_SUN_FAIRY] = Location::Fairy(RC_LH_ISLAND_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 7319), "Island Sun's Song Fairy", RHT_LH_ISLAND_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_ISLAND_SUN_FAIRY));
locationTable[RC_HF_POND_STORMS_FAIRY] = Location::Fairy(RC_HF_POND_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(0x1000, 5012), "Pond Song of Storms Fairy", RHT_HF_POND_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_POND_STORMS_FAIRY));
locationTable[RC_HF_FENCE_GROTTO_STORMS_FAIRY] = Location::Fairy(RC_HF_FENCE_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -308), "Deku Scrub Grotto Storms Fairy", RHT_HF_FENCE_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FENCE_GROTTO_STORMS_FAIRY));
locationTable[RC_DMT_FLAG_SUN_FAIRY] = Location::Fairy(RC_DMT_FLAG_SUN_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, 464), "Flag Sun's Song Fairy", RHT_DMT_FLAG_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_FLAG_SUN_FAIRY));
locationTable[RC_DMT_COW_GROTTO_STORMS_FAIRY] = Location::Fairy(RC_DMT_COW_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -311), "Cow Grotto Song of Storms Fairy", RHT_DMT_COW_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_STORMS_FAIRY));
locationTable[RC_LW_SHORTCUT_STORMS_FAIRY] = Location::Fairy(RC_LW_SHORTCUT_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, -795), "Shortcuts Song of Storms Fairy", RHT_LW_SHORTCUT_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_STORMS_FAIRY));
locationTable[RC_TH_KITCHEN_SUN_FAIRY] = Location::Fairy(RC_TH_KITCHEN_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(0x1000, -621), "Kitchen Sun's Song Fairy", RHT_TH_KITCHEN_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_KITCHEN_SUN_FAIRY));
locationTable[RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY] = Location::Fairy(RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, 741), "Scrub Grotto Sun's Song Fairy", RHT_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY));
locationTable[RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY] = Location::Fairy(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_ROYAL_FAMILYS_TOMB, TWO_ACTOR_PARAMS(0x1000, 1476), "Royal Family's Tomb Sun's Song Fairy", RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY));
locationTable[RC_LH_ISLAND_SUN_FAIRY] = Location::SongFairy(RC_LH_ISLAND_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, TWO_ACTOR_PARAMS(0x1000, 7319), "Island Sun's Song Fairy", RHT_LH_ISLAND_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_ISLAND_SUN_FAIRY));
locationTable[RC_HF_POND_STORMS_FAIRY] = Location::SongFairy(RC_HF_POND_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(0x1000, 5012), "Pond Song of Storms Fairy", RHT_HF_POND_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_POND_STORMS_FAIRY));
locationTable[RC_HF_FENCE_GROTTO_STORMS_FAIRY] = Location::SongFairy(RC_HF_FENCE_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -308), "Deku Scrub Grotto Storms Fairy", RHT_HF_FENCE_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FENCE_GROTTO_STORMS_FAIRY));
locationTable[RC_DMT_FLAG_SUN_FAIRY] = Location::SongFairy(RC_DMT_FLAG_SUN_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, 464), "Flag Sun's Song Fairy", RHT_DMT_FLAG_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_FLAG_SUN_FAIRY));
locationTable[RC_DMT_COW_GROTTO_STORMS_FAIRY] = Location::SongFairy(RC_DMT_COW_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -311), "Cow Grotto Song of Storms Fairy", RHT_DMT_COW_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_STORMS_FAIRY));
locationTable[RC_LW_SHORTCUT_STORMS_FAIRY] = Location::SongFairy(RC_LW_SHORTCUT_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, -795), "Shortcuts Song of Storms Fairy", RHT_LW_SHORTCUT_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_STORMS_FAIRY));
locationTable[RC_TH_KITCHEN_SUN_FAIRY] = Location::SongFairy(RC_TH_KITCHEN_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(0x1000, -621), "Kitchen Sun's Song Fairy", RHT_TH_KITCHEN_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_KITCHEN_SUN_FAIRY));
locationTable[RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY] = Location::SongFairy(RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, 741), "Deku Scrub Grotto Sun's Song Fairy", RHT_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY));
locationTable[RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY] = Location::SongFairy(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_ROYAL_FAMILYS_TOMB, TWO_ACTOR_PARAMS(0x1000, 1476), "Royal Family's Tomb Sun's Song Fairy", RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY));
locationTable[RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1896), "After Boulder Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY));
locationTable[RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "Four Armos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY));
locationTable[RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 54), "Beamos Song of Storms Fairy", RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY));
locationTable[RC_SHADOW_TEMPLE_PIT_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 3339), "Pit Room Song of Storms Fairy", RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY));
locationTable[RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -127), "Wind Hint Sun's Song Fairy", RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY));
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY] = Location::Fairy(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1531), "Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY));
locationTable[RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY] = Location::Fairy(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, RCQUEST_VANILLA,RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(0x1000, 1186), "Entrance Song of Storms Fairy", RHT_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY));
locationTable[RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY] = Location::Fairy(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, RCQUEST_VANILLA,RCAREA_GERUDO_TRAINING_GROUND,SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(0x1000, -445), "Entrance Song of Storms Fairy", RHT_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY));
locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY] = Location::Fairy(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(0x1000, 587), "Spirit Trial Beamos Sun's Song Fairy", RHT_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY));
locationTable[RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY] = Location::SongFairy(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1896), "After Boulder Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY));
locationTable[RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY] = Location::SongFairy(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "Four Armos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY));
locationTable[RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 54), "Beamos Song of Storms Fairy", RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY));
locationTable[RC_SHADOW_TEMPLE_PIT_STORM_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_PIT_STORM_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 3339), "Pit Room Song of Storms Fairy", RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY));
locationTable[RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -127), "Wind Hint Sun's Song Fairy", RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY));
locationTable[RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY] = Location::SongFairy(RC_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1531), "Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY));
locationTable[RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY] = Location::SongFairy(RC_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, RCQUEST_VANILLA,RCAREA_ICE_CAVERN, SCENE_ICE_CAVERN, TWO_ACTOR_PARAMS(0x1000, 1186), "Entrance Song of Storms Fairy", RHT_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY));
locationTable[RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY] = Location::SongFairy(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, RCQUEST_VANILLA,RCAREA_GERUDO_TRAINING_GROUND,SCENE_GERUDO_TRAINING_GROUND, TWO_ACTOR_PARAMS(0x1000, -445), "Entrance Song of Storms Fairy", RHT_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY));
locationTable[RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY] = Location::SongFairy(RC_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_GANONS_CASTLE, SCENE_INSIDE_GANONS_CASTLE, TWO_ACTOR_PARAMS(0x1000, 587), "Spirit Trial Beamos Sun's Song Fairy", RHT_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY));
locationTable[RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY] = Location::Fairy(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -551), "MQ Lower Loop Stalfos Room Sun's Song Fairy", RHT_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY));
locationTable[RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY] = Location::Fairy(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1563), "MQ Lower Loop Behind Iron Knuckle Sun's Song Fairy", RHT_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY));
locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY] = Location::Fairy(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -540), "MQ Before Dark Link Pilar Sun's Song Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY));
locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY] = Location::Fairy(RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1501), "MQ Before Dark Link Left Song of Storms Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY));
locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY] = Location::Fairy(RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1504), "MQ Before Dark Link Right Sun's Song Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY));
locationTable[RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "MQ Dinalfos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY));
locationTable[RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 55), "MQ Beamos Song of Storms Fairy", RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY));
locationTable[RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 3342), "MQ Pit Room Song of Storms Fairy", RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY));
locationTable[RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY] = Location::Fairy(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -127), "MQ Wind Hint Sun's Song Fairy", RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY));
locationTable[RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY] = Location::Fairy(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -437), "MQ East Cell Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY));
locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY] = Location::Fairy(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1458), "MQ Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY));
locationTable[RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY] = Location::SongFairy(RC_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -551), "MQ Lower Loop Stalfos Room Sun's Song Fairy", RHT_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY));
locationTable[RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY] = Location::SongFairy(RC_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1563), "MQ Lower Loop Behind Iron Knuckle Sun's Song Fairy", RHT_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY));
locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY] = Location::SongFairy(RC_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -540), "MQ Before Dark Link Pilar Sun's Song Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY));
locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY] = Location::SongFairy(RC_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1501), "MQ Before Dark Link Left Song of Storms Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY));
locationTable[RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY] = Location::SongFairy(RC_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, RCQUEST_MQ, RCAREA_WATER_TEMPLE, SCENE_WATER_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1504), "MQ Before Dark Link Right Sun's Song Fairy", RHT_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY));
locationTable[RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY] = Location::SongFairy(RC_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, RCQUEST_MQ, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "MQ Dinalfos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY));
locationTable[RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 55), "MQ Beamos Song of Storms Fairy", RHT_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY));
locationTable[RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, 3342), "MQ Pit Room Song of Storms Fairy", RHT_SHADOW_TEMPLE_PIT_STORM_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY));
locationTable[RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY] = Location::SongFairy(RC_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, RCQUEST_MQ, RCAREA_SHADOW_TEMPLE, SCENE_SHADOW_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -127), "MQ Wind Hint Sun's Song Fairy", RHT_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY));
locationTable[RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY] = Location::SongFairy(RC_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -437), "MQ East Cell Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY));
locationTable[RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY] = Location::SongFairy(RC_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, RCQUEST_MQ, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, TWO_ACTOR_PARAMS(0x1000, -1458), "MQ Basement Sun's Song Fairy", RHT_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY));
// clang-format on
}
static ObjectExtension::Register<FairyIdentity> RegisterFairyIdentity;
static RegisterShipInitFunc registerShuffleFairies(RegisterShuffleFairies, { "IS_RANDO" });
static RegisterShipInitFunc registerShuffleFairiesLocations(Rando::StaticData::RegisterFairyLocations);
static RegisterShipInitFunc registerFairyLocations(Rando::StaticData::RegisterFairyLocations);
@@ -287,4 +287,4 @@ void Rando::StaticData::RegisterFreestandingLocations() {
}
static RegisterShipInitFunc registerShuffleFreestanding(RegisterShuffleFreestanding, { "IS_RANDO" });
static RegisterShipInitFunc registerShuffleFreestandingLocations(Rando::StaticData::RegisterFreestandingLocations);
static RegisterShipInitFunc registerFreestandingLocations(Rando::StaticData::RegisterFreestandingLocations);
@@ -15,11 +15,10 @@ extern PlayState* gPlayState;
extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
void DrawTypeOfGrass(EnKusa* grassActor, Gfx* bushDList, Gfx* grassDList, PlayState* play) {
// Actor params is -255 for regrowable grass.
if (grassActor->actor.params == -255) {
Gfx_DrawDListOpa(play, grassDList);
} else {
if ((grassActor->actor.params & 3) == 0) {
Gfx_DrawDListOpa(play, bushDList);
} else {
Gfx_DrawDListOpa(play, grassDList);
}
}
@@ -531,4 +530,4 @@ void Rando::StaticData::RegisterGrassLocations() {
static ObjectExtension::Register<GrassIdentity> RegisterGrassIdentity;
static RegisterShipInitFunc registerShuffleGrass(RegisterShuffleGrass, { "IS_RANDO" });
static RegisterShipInitFunc registerShuffleGrassLocations(Rando::StaticData::RegisterGrassLocations);
static RegisterShipInitFunc registerGrassLocations(Rando::StaticData::RegisterGrassLocations);
@@ -661,4 +661,4 @@ void Rando::StaticData::RegisterPotLocations() {
static ObjectExtension::Register<PotIdentity> RegisterPotIdentity;
static RegisterShipInitFunc registerShufflePots(RegisterShufflePots, { "IS_RANDO" });
static RegisterShipInitFunc registerShufflePotLocations(Rando::StaticData::RegisterPotLocations);
static RegisterShipInitFunc registerPotLocations(Rando::StaticData::RegisterPotLocations);
@@ -0,0 +1,265 @@
#include <soh/OTRGlobals.h>
#include "soh_assets.h"
#include "static_data.h"
#include "soh/ObjectExtension/ObjectExtension.h"
extern "C" {
#include "variables.h"
#include "src/overlays/actors/ovl_En_Wood02/z_en_wood02.h"
#include "objects/object_wood02/object_wood02.h"
#include "soh/Enhancements/enhancementTypes.h"
extern PlayState* gPlayState;
void EnWood02_Draw(Actor*, PlayState*);
}
static Gfx* D_80B3BF54[] = {
(Gfx*)object_wood02_DL_0078D0, (Gfx*)object_wood02_DL_007CA0, (Gfx*)object_wood02_DL_0080D0,
(Gfx*)object_wood02_DL_000090, (Gfx*)object_wood02_DL_000340, (Gfx*)object_wood02_DL_000340,
(Gfx*)object_wood02_DL_000700,
};
static Gfx* D_80B3BF70[] = {
(Gfx*)object_wood02_DL_007968,
(Gfx*)object_wood02_DL_007D38,
(Gfx*)object_wood02_DL_0081A8,
NULL,
NULL,
NULL,
(Gfx*)object_wood02_DL_007AD0,
(Gfx*)object_wood02_DL_007E20,
(Gfx*)object_wood02_DL_008350,
(Gfx*)object_wood02_DL_000160,
(Gfx*)object_wood02_DL_000440,
(Gfx*)object_wood02_DL_000700,
};
extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
uint8_t EnWood02_RandomizerHoldsItem(EnWood02* treeActor, PlayState* play) {
const auto treeIdentity = ObjectExtension::GetInstance().Get<TreeIdentity>(&treeActor->actor);
if (treeIdentity == nullptr) {
return false;
}
// Don't pull randomized item if tree isn't randomized or is already checked
return IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get() &&
!Flags_GetRandomizerInf(treeIdentity->randomizerInf) && treeIdentity->randomizerCheck != RC_UNKNOWN_CHECK;
}
extern "C" void EnWood02_RandomizerDraw(Actor* thisx, PlayState* play) {
GetItemCategory getItemCategory;
GetItemEntry smallCrateItem;
auto treeActor = (EnWood02*)thisx;
int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED);
int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0);
int isVanilla =
csmc == CSMC_DISABLED || csmc == CSMC_SIZE || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY));
const auto treeIdentity = ObjectExtension::GetInstance().Get<TreeIdentity>(&treeActor->actor);
if (treeIdentity == nullptr) {
return;
}
if (isVanilla || treeIdentity == nullptr || treeIdentity->randomizerCheck == RC_UNKNOWN_CHECK) {
getItemCategory = ITEM_CATEGORY_JUNK;
} else {
smallCrateItem = Rando::Context::GetInstance()->GetFinalGIEntry(treeIdentity->randomizerCheck, true, GI_NONE);
getItemCategory = smallCrateItem.getItemCategory;
// If they have bombchus, don't consider the bombchu item major
if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU &&
((smallCrateItem.modIndex == MOD_RANDOMIZER && smallCrateItem.getItemId == RG_PROGRESSIVE_BOMBCHUS) ||
(smallCrateItem.modIndex == MOD_NONE &&
(smallCrateItem.getItemId == GI_BOMBCHUS_5 || smallCrateItem.getItemId == GI_BOMBCHUS_10 ||
smallCrateItem.getItemId == GI_BOMBCHUS_20)))) {
getItemCategory = ITEM_CATEGORY_JUNK;
// If it's a bottle and they already have one, consider the item lesser
} else if ((smallCrateItem.modIndex == MOD_RANDOMIZER &&
smallCrateItem.getItemId >= RG_BOTTLE_WITH_RED_POTION &&
smallCrateItem.getItemId <= RG_BOTTLE_WITH_POE) ||
(smallCrateItem.modIndex == MOD_NONE &&
(smallCrateItem.getItemId == GI_BOTTLE || smallCrateItem.getItemId == GI_MILK_BOTTLE))) {
if (gSaveContext.inventory.items[SLOT_BOTTLE_1] != ITEM_NONE) {
getItemCategory = ITEM_CATEGORY_LESSER;
}
}
}
GraphicsContext* gfxCtx = play->state.gfxCtx;
OPEN_DISPS(gfxCtx);
Matrix_Push();
// Change texture
switch (getItemCategory) {
case ITEM_CATEGORY_MAJOR:
Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY);
Gfx_DrawDListOpa(play, (Gfx*)gSmallMajorCrateDL);
break;
case ITEM_CATEGORY_SKULLTULA_TOKEN:
Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY);
Gfx_DrawDListOpa(play, (Gfx*)gSmallTokenCrateDL);
break;
case ITEM_CATEGORY_SMALL_KEY:
Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY);
Gfx_DrawDListOpa(play, (Gfx*)gSmallSmallKeyCrateDL);
break;
case ITEM_CATEGORY_BOSS_KEY:
Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY);
Gfx_DrawDListOpa(play, (Gfx*)gSmallBossKeyCrateDL);
break;
case ITEM_CATEGORY_LESSER:
Matrix_Scale(0.1, 0.05, 0.1, MTXMODE_APPLY);
switch (smallCrateItem.itemId) {
case ITEM_HEART_PIECE:
case ITEM_HEART_PIECE_2:
case ITEM_HEART_CONTAINER:
Gfx_DrawDListOpa(play, (Gfx*)gSmallHeartCrateDL);
break;
default:
Gfx_DrawDListOpa(play, (Gfx*)gSmallMinorCrateDL);
break;
}
case ITEM_CATEGORY_JUNK:
default:
Matrix_Scale(0.04, 0.02, 0.04, MTXMODE_APPLY);
Gfx_DrawDListOpa(play, (Gfx*)gLargeJunkCrateDL);
break;
}
Matrix_Pop();
CLOSE_DISPS(gfxCtx);
}
void EnWood02_RandomizerSpawnCollectible(EnWood02* treeActor, PlayState* play) {
const auto treeIdentity = ObjectExtension::GetInstance().Get<TreeIdentity>(&treeActor->actor);
if (treeIdentity == nullptr) {
return;
}
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &treeActor->actor.world.pos, ITEM00_SOH_DUMMY);
item00->randoInf = treeIdentity->randomizerInf;
item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(treeIdentity->randomizerCheck, true, GI_NONE);
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
item00->actor.velocity.y = 0.0f;
item00->actor.world.pos.y += 120.0f;
item00->actor.speedXZ = 2.0f;
item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f);
// clear randomizerCheck to prevent multiple bonks,
// reloading area without collecting drop won't persist this
treeIdentity->randomizerCheck = RC_UNKNOWN_CHECK;
}
void EnWood02_RandomizerInit(void* actorRef) {
EnWood02* treeActor = static_cast<EnWood02*>(actorRef);
if (treeActor->actor.params <= WOOD_TREE_KAKARIKO_ADULT) {
auto treeIdentity = OTRGlobals::Instance->gRandomizer->IdentifyTree(
gPlayState->sceneNum, (s16)treeActor->actor.world.pos.x, (s16)treeActor->actor.world.pos.z);
ObjectExtension::GetInstance().Set<TreeIdentity>(actorRef, std::move(treeIdentity));
}
}
void RegisterShuffleTrees() {
bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TREES).Get();
COND_ID_HOOK(OnActorInit, ACTOR_EN_WOOD02, shouldRegister, EnWood02_RandomizerInit);
COND_VB_SHOULD(VB_TREE_SETUP_DRAW, shouldRegister, {
EnWood02* treeActor = va_arg(args, EnWood02*);
if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) {
EnWood02_RandomizerDraw(&treeActor->actor, gPlayState);
}
});
COND_VB_SHOULD(VB_TREE_DROP_ITEM, shouldRegister, {
EnWood02* treeActor = va_arg(args, EnWood02*);
if (EnWood02_RandomizerHoldsItem(treeActor, gPlayState)) {
EnWood02_RandomizerSpawnCollectible(treeActor, gPlayState);
// QoL, drop golden skulltula alongside item
if ((treeActor->unk_14C < 0 || treeActor->unk_14C >= 0x64) && treeActor->actor.home.rot.z != 0) {
Vec3f dropsSpawnPt = treeActor->actor.world.pos;
dropsSpawnPt.y += 200.0f;
treeActor->actor.home.rot.z &= 0x1FFF;
treeActor->actor.home.rot.z |= 0xE000;
Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_SW, dropsSpawnPt.x, dropsSpawnPt.y,
dropsSpawnPt.z, 0, treeActor->actor.world.rot.y, 0, treeActor->actor.home.rot.z, true);
treeActor->actor.home.rot.z = 0;
}
*should = false;
}
});
}
void Rando::StaticData::RegisterTreeLocations() {
// clang-format off
// Trees
// Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Vanilla Spoiler Collection Check
locationTable[RC_MARKET_TREE] = Location::Tree(RC_MARKET_TREE, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_DAY, TWO_ACTOR_PARAMS(-100, 240), "Tree in Hyrule Market", RHT_TREE_MARKET, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MARKET_TREE));
locationTable[RC_HC_NEAR_GUARDS_TREE_1] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1209, 2242), "Tree Near Guards 1", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_1));
locationTable[RC_HC_NEAR_GUARDS_TREE_2] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(943, 2051), "Tree Near Guards 2", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_2));
locationTable[RC_HC_NEAR_GUARDS_TREE_3] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(827, 1428), "Tree Near Guards 3", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_3));
locationTable[RC_HC_NEAR_GUARDS_TREE_4] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(421, 1397), "Tree Near Guards 4", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_4));
locationTable[RC_HC_NEAR_GUARDS_TREE_5] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-73, 1459), "Tree Near Guards 5", RHT_TREE_HYRULE_CASTLE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_5));
locationTable[RC_HC_NEAR_GUARDS_TREE_6] = Location::Tree(RC_HC_NEAR_GUARDS_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1494, 2108), "Tree Near Guards 6", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NEAR_GUARDS_TREE_6));
locationTable[RC_HC_SKULLTULA_TREE] = Location::Tree(RC_HC_SKULLTULA_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-145, 2961), "HC GS Tree", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_SKULLTULA_TREE));
locationTable[RC_HC_GROTTO_TREE] = Location::Tree(RC_HC_GROTTO_TREE, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(924, 872), "Tree Near Storms Grotto", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_GROTTO_TREE));
locationTable[RC_HC_NL_TREE_1] = Location::NLTree(RC_HC_NL_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-331, 1438), "NL Tree Near Guards 1", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NL_TREE_1));
locationTable[RC_HC_NL_TREE_2] = Location::NLTree(RC_HC_NL_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(1022, 1444), "NL Tree Near Guards 2", RHT_TREE_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_NL_TREE_2));
locationTable[RC_HF_NEAR_KAK_TREE] = Location::Tree(RC_HF_NEAR_KAK_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3276, 971), "Tree Outside Kakariko", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_KAK_TREE));
locationTable[RC_HF_NEAR_KAK_SMALL_TREE] = Location::Tree(RC_HF_NEAR_KAK_SMALL_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2076, -91), "Small Tree Outside Kakariko", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_KAK_SMALL_TREE));
locationTable[RC_HF_NEAR_MARKET_TREE_1] = Location::Tree(RC_HF_NEAR_MARKET_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1041, 1022), "Tree Near HC Entrance Grotto 1", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_1));
locationTable[RC_HF_NEAR_MARKET_TREE_2] = Location::Tree(RC_HF_NEAR_MARKET_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1244, 819), "Tree Near HC Entrance Grotto 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_2));
locationTable[RC_HF_NEAR_MARKET_TREE_3] = Location::Tree(RC_HF_NEAR_MARKET_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1448, 620), "Tree Near HC Entrance Grotto 3", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_MARKET_TREE_3));
locationTable[RC_HF_NEAR_LLR_TREE] = Location::Tree(RC_HF_NEAR_LLR_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-1907, 5409), "Tree Outside Lon Lon Ranch", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_LLR_TREE));
locationTable[RC_HF_NEAR_LH_TREE] = Location::Tree(RC_HF_NEAR_LH_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4377, 13662), "Tree Outside Lake Hylia", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_LH_TREE));
locationTable[RC_HF_CHILD_NEAR_GV_TREE] = Location::Tree(RC_HF_CHILD_NEAR_GV_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6270, 8579), "Child Near Gerudo Valley Tree", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_NEAR_GV_TREE));
locationTable[RC_HF_ADULT_NEAR_GV_TREE] = Location::Tree(RC_HF_ADULT_NEAR_GV_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-6241, 7097), "Adult Near Gerudo Valley Tree", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_ADULT_NEAR_GV_TREE));
locationTable[RC_HF_NEAR_ZR_TREE] = Location::Tree(RC_HF_NEAR_ZR_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3117, 4239), "Tree Outside Zora's River", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NEAR_ZR_TREE));
locationTable[RC_HF_NORTHWEST_TREE_1] = Location::Tree(RC_HF_NORTHWEST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4777, 136), "Tree in Northwest 1", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_1));
locationTable[RC_HF_NORTHWEST_TREE_2] = Location::Tree(RC_HF_NORTHWEST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4188, 263), "Tree in Northwest 2", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_2));
locationTable[RC_HF_NORTHWEST_TREE_3] = Location::Tree(RC_HF_NORTHWEST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5000, -147), "Tree in Northwest 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_3));
locationTable[RC_HF_NORTHWEST_TREE_4] = Location::Tree(RC_HF_NORTHWEST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4463, -182), "Tree in Northwest 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_4));
locationTable[RC_HF_NORTHWEST_TREE_5] = Location::Tree(RC_HF_NORTHWEST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-5262, 398), "Tree in Northwest 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_5));
locationTable[RC_HF_NORTHWEST_TREE_6] = Location::Tree(RC_HF_NORTHWEST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4391, 891), "Tree in Northwest 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_NORTHWEST_TREE_6));
locationTable[RC_HF_EAST_TREE_1] = Location::Tree(RC_HF_EAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3817, 7119), "Tree in East 1", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_1));
locationTable[RC_HF_EAST_TREE_2] = Location::Tree(RC_HF_EAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(4365, 7182), "Tree in East 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_2));
locationTable[RC_HF_EAST_TREE_3] = Location::Tree(RC_HF_EAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3837, 7479), "Tree in East 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_3));
locationTable[RC_HF_EAST_TREE_4] = Location::Tree(RC_HF_EAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3377, 7201), "Tree in East 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_4));
locationTable[RC_HF_EAST_TREE_5] = Location::Tree(RC_HF_EAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3408, 6676), "Tree in East 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_5));
locationTable[RC_HF_EAST_TREE_6] = Location::Tree(RC_HF_EAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(3935, 6279), "Tree in East 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_EAST_TREE_6));
locationTable[RC_HF_SOUTHEAST_TREE_1] = Location::Tree(RC_HF_SOUTHEAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(915, 12557), "Tree in Southeast 1", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_1));
locationTable[RC_HF_SOUTHEAST_TREE_2] = Location::Tree(RC_HF_SOUTHEAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(350, 11605), "Tree in Southeast 2", RHT_TREE_HYRULE_FIELD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_2));
locationTable[RC_HF_SOUTHEAST_TREE_3] = Location::Tree(RC_HF_SOUTHEAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(470, 12494), "Tree in Southeast 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_3));
locationTable[RC_HF_SOUTHEAST_TREE_4] = Location::Tree(RC_HF_SOUTHEAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(614, 12357), "Tree in Southeast 4", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_4));
locationTable[RC_HF_SOUTHEAST_TREE_5] = Location::Tree(RC_HF_SOUTHEAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1114, 12156), "Tree in Southeast 5", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_5));
locationTable[RC_HF_SOUTHEAST_TREE_6] = Location::Tree(RC_HF_SOUTHEAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(549, 11204), "Tree in Southeast 6", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_6));
locationTable[RC_HF_SOUTHEAST_TREE_7] = Location::Tree(RC_HF_SOUTHEAST_TREE_7, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(49, 11405), "Tree in Southeast 7", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_7));
locationTable[RC_HF_SOUTHEAST_TREE_8] = Location::Tree(RC_HF_SOUTHEAST_TREE_8, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-29, 12005), "Tree in Southeast 8", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_8));
locationTable[RC_HF_SOUTHEAST_TREE_9] = Location::Tree(RC_HF_SOUTHEAST_TREE_9, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1514,13157), "Tree in Southeast 9", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_9));
locationTable[RC_HF_SOUTHEAST_TREE_10] = Location::Tree(RC_HF_SOUTHEAST_TREE_10, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-509,12954), "Tree in Southeast 10", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_10));
locationTable[RC_HF_SOUTHEAST_TREE_11] = Location::Tree(RC_HF_SOUTHEAST_TREE_11, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-430,12354), "Tree in Southeast 11", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_11));
locationTable[RC_HF_SOUTHEAST_TREE_12] = Location::Tree(RC_HF_SOUTHEAST_TREE_12, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(69,12153), "Tree in Southeast 12", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_12));
locationTable[RC_HF_SOUTHEAST_TREE_13] = Location::Tree(RC_HF_SOUTHEAST_TREE_13, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-129,12554), "Tree in Southeast 13", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_13));
locationTable[RC_HF_SOUTHEAST_TREE_14] = Location::Tree(RC_HF_SOUTHEAST_TREE_14, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(950,11545), "Tree in Southeast 14", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_14));
locationTable[RC_HF_SOUTHEAST_TREE_15] = Location::Tree(RC_HF_SOUTHEAST_TREE_15, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(949,12205), "Tree in Southeast 15", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_15));
locationTable[RC_HF_SOUTHEAST_TREE_16] = Location::Tree(RC_HF_SOUTHEAST_TREE_16, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(469,13154), "Tree in Southeast 16", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_16));
locationTable[RC_HF_SOUTHEAST_TREE_17] = Location::Tree(RC_HF_SOUTHEAST_TREE_17, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(535,12957), "Tree in Southeast 17", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_17));
locationTable[RC_HF_SOUTHEAST_TREE_18] = Location::Tree(RC_HF_SOUTHEAST_TREE_18, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1515,12497), "Tree in Southeast 18", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_18));
locationTable[RC_HF_SOUTHEAST_TREE_19] = Location::Tree(RC_HF_SOUTHEAST_TREE_19, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-786,11293), "Tree in Southeast 19", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_SOUTHEAST_TREE_19));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_1] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1535, 11943), "Child Tree in Southeast Corner 1", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_1));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_2] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2135,11883), "Child Tree in Southeast Corner 2", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_2));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_3] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_3, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(2134,12543), "Child Tree in Southeast Corner 3", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_3));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_4] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_4, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1734,11542), "Child Tree in Southeast Corner 4", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_4));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_5] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_5, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1234,11743), "Child Tree in Southeast Corner 5", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_5));
locationTable[RC_HF_CHILD_SOUTHEAST_TREE_6] = Location::Tree(RC_HF_CHILD_SOUTHEAST_TREE_6, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(1155,12343), "Child Tree in Southeast Corner 6", RHT_TREE_HYRULE_FIELD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_CHILD_SOUTHEAST_TREE_6));
locationTable[RC_HF_TEKTITE_GROTTO_TREE] = Location::Tree(RC_HF_TEKTITE_GROTTO_TREE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(-4976, 2812), "Tektite Grotto Tree", RHT_TREE_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_TEKTITE_GROTTO_TREE));
locationTable[RC_ZF_TREE] = Location::Tree(RC_ZF_TREE, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(186, 2222), "Tree in Zora's Fountain", RHT_TREE_ZORAS_FOUNTAIN, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_TREE));
locationTable[RC_ZR_TREE] = Location::Tree(RC_ZR_TREE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, TWO_ACTOR_PARAMS(-1690, 554), "Tree in Zoras River", RHT_TREE_ZORAS_RIVER, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZR_TREE));
locationTable[RC_KAK_TREE] = Location::Tree(RC_KAK_TREE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-860, 522), "Kakariko GS Tree", RHT_TREE_KAKARIKO, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_TREE));
locationTable[RC_LLR_TREE] = Location::Tree(RC_LLR_TREE, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(1309, -2241), "Lon Lon Ranch GS Tree", RHT_TREE_LON_LON_RANCH, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TREE));
// clang-format on
}
static ObjectExtension::Register<TreeIdentity> RegisterPotIdentity;
static RegisterShipInitFunc registerShuffleTrees(RegisterShuffleTrees, { "IS_RANDO" });
static RegisterShipInitFunc registerTreeLocations(Rando::StaticData::RegisterTreeLocations);
+18 -6
View File
@@ -54,7 +54,10 @@ Context::Context() {
&mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
&mOptions[RSK_SHUFFLE_ADULT_TRADE],
&mOptions[RSK_SHUFFLE_100_GS_REWARD],
&mOptions[RSK_SHUFFLE_FAIRIES],
&mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES],
&mOptions[RSK_SHUFFLE_STONE_FAIRIES],
&mOptions[RSK_SHUFFLE_BEAN_FAIRIES],
&mOptions[RSK_SHUFFLE_SONG_FAIRIES],
&mOptions[RSK_GOSSIP_STONE_HINTS],
};
}
@@ -126,8 +129,7 @@ void Context::PlaceItemInLocation(const RandomizerCheck locKey, const Randomizer
SPDLOG_DEBUG(StaticData::RetrieveItem(item).GetName().GetEnglish() + " placed at " +
StaticData::GetLocation(locKey)->GetName() + "\n");
if (applyEffectImmediately || mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_GLITCHLESS) ||
mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_VANILLA)) {
if (applyEffectImmediately || mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_GLITCHLESS)) {
StaticData::RetrieveItem(item).ApplyEffect();
}
@@ -163,12 +165,16 @@ bool Context::IsQuestOfLocationActive(RandomizerCheck rc) {
void Context::GenerateLocationPool() {
allLocations.clear();
overworldLocations.clear();
for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) {
dungeon->locations.clear();
}
for (Location& location : StaticData::GetLocationTable()) {
// skip RCs that shouldn't be in the pool for any reason (i.e. settings, unsupported check type, etc.)
// TODO: Exclude checks for some of the older shuffles from the pool too i.e. Frog Songs, Scrubs, etc.)
if (location.GetRandomizerCheck() == RC_UNKNOWN_CHECK ||
location.GetRandomizerCheck() == RC_TRIFORCE_COMPLETED || // already in pool
(location.GetRandomizerCheck() == RC_MASTER_SWORD_PEDESTAL &&
(location.GetRandomizerCheck() == RC_TOT_MASTER_SWORD &&
mOptions[RSK_SHUFFLE_MASTER_SWORD].Is(RO_GENERIC_OFF)) ||
(location.GetRandomizerCheck() == RC_KAK_100_GOLD_SKULLTULA_REWARD &&
mOptions[RSK_SHUFFLE_100_GS_REWARD].Is(RO_GENERIC_OFF)) ||
@@ -191,9 +197,15 @@ void Context::GenerateLocationPool() {
(location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_OFF)) ||
(location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) ||
(location.GetRCType() == RCTYPE_NLCRATE && (mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF) ||
!mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC))) ||
mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) ||
(location.GetRCType() == RCTYPE_SMALL_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) ||
(location.GetRCType() == RCTYPE_FAIRY && !mOptions[RSK_SHUFFLE_FAIRIES]) ||
(location.GetRCType() == RCTYPE_FOUNTAIN_FAIRY && !mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES]) ||
(location.GetRCType() == RCTYPE_STONE_FAIRY && !mOptions[RSK_SHUFFLE_STONE_FAIRIES]) ||
(location.GetRCType() == RCTYPE_BEAN_FAIRY && !mOptions[RSK_SHUFFLE_BEAN_FAIRIES]) ||
(location.GetRCType() == RCTYPE_SONG_FAIRY && !mOptions[RSK_SHUFFLE_SONG_FAIRIES]) ||
(location.GetRCType() == RCTYPE_TREE && !mOptions[RSK_SHUFFLE_TREES]) ||
(location.GetRCType() == RCTYPE_NLTREE &&
(!mOptions[RSK_SHUFFLE_TREES] || mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) ||
(location.GetRCType() == RCTYPE_FREESTANDING &&
mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) ||
(location.GetRCType() == RCTYPE_BEEHIVE && !mOptions[RSK_SHUFFLE_BEEHIVES])) {
@@ -5,7 +5,7 @@
#include "variables.h"
#include "functions.h"
#include "macros.h"
#include <consolevariablebridge.h>
#include <libultraship/bridge/consolevariablebridge.h>
extern "C" {
#include "src/overlays/actors/ovl_Fishing/z_fishing.h"
@@ -1,4 +1,4 @@
#include <libultraship/bridge.h>
#include <libultraship/bridge.h>
#include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/enhancementTypes.h"
@@ -49,6 +49,7 @@ extern "C" {
#include "src/overlays/actors/ovl_En_Ds/z_en_ds.h"
#include "src/overlays/actors/ovl_En_Gm/z_en_gm.h"
#include "src/overlays/actors/ovl_En_Js/z_en_js.h"
#include "src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h"
#include "src/overlays/actors/ovl_En_Door/z_en_door.h"
#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
#include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h"
@@ -413,8 +414,10 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() {
getItemEntry.modIndex == MOD_RANDOMIZER) &&
(getItemEntry.getItemCategory == ITEM_CATEGORY_JUNK ||
getItemEntry.getItemCategory == ITEM_CATEGORY_SKULLTULA_TOKEN ||
getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER))))) {
getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER ||
// Treat small keys as junk if Skeleton Key is obtained.
(getItemEntry.getItemCategory == ITEM_CATEGORY_SMALL_KEY &&
Flags_GetRandomizerInf(RAND_INF_HAS_SKELETON_KEY))))))) {
Item_DropCollectible(gPlayState, &spawnPos, static_cast<int16_t>(ITEM00_SOH_GIVE_ITEM_ENTRY | 0x8000));
isGiSkipped = 1;
@@ -960,7 +963,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
*should = !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) && LINK_IS_ADULT &&
gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KAKARIKO_VILLAGE &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER);
CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && gSaveContext.cutsceneIndex < 0xFFF0;
break;
case VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD: {
// Don't require a bomb bag to get prize in rando
@@ -976,7 +979,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
break;
}
case VB_GIVE_ITEM_MASTER_SWORD:
if (RAND_GET_OPTION(RSK_SHUFFLE_MASTER_SWORD)) {
if (RAND_GET_OPTION(RSK_SHUFFLE_MASTER_SWORD) || RAND_GET_OPTION(RSK_STARTING_MASTER_SWORD)) {
*should = false;
} else {
*should = true;
@@ -1111,20 +1114,59 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
}
if (item00->itemEntry.modIndex == MOD_NONE) {
std::string message;
switch (gSaveContext.language) {
case LANGUAGE_FRA:
message = "Vous obtenez: ";
break;
case LANGUAGE_GER:
message = "Du erhältst: ";
break;
case LANGUAGE_ENG:
default:
message = "You found ";
break;
}
Notification::Emit({
.itemIcon = GetTextureForItemId(item00->itemEntry.itemId),
.message = "You found ",
.message = message,
.suffix = SohUtils::GetItemName(item00->itemEntry.itemId),
});
} else if (item00->itemEntry.modIndex == MOD_RANDOMIZER) {
std::string message;
std::string itemName;
if (!(item00->itemEntry.getItemId == RG_ARCHIPELAGO_ITEM_PROGRESSIVE ||
item00->itemEntry.getItemId == RG_ARCHIPELAGO_ITEM_USEFUL ||
item00->itemEntry.getItemId == RG_ARCHIPELAGO_ITEM_JUNK)) {
switch (gSaveContext.language) {
case LANGUAGE_FRA:
message = "Vous obtenez: ";
itemName = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId)
.GetName()
.french;
break;
case LANGUAGE_GER:
message = "Du erhältst: ";
itemName = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId)
.GetName()
.german;
break;
case LANGUAGE_ENG:
default:
message = "You found ";
itemName = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId)
.GetName()
.english;
break;
}
Notification::Emit({
.message = "You found ",
.suffix = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId)
.GetName()
.english,
.message = message,
.suffix = itemName,
});
}
}
@@ -1184,7 +1226,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
break;
}
case VB_SELL_POES_TO_POE_COLLECTOR: {
if (!Flags_GetRandomizerInf(RAND_INF_10_BIG_POES) && HIGH_SCORE(HS_POE_POINTS) >= 1000) {
if (!Flags_GetRandomizerInf(RAND_INF_10_BIG_POES) && HIGH_SCORE(HS_POE_POINTS) >= 1000 &&
!(GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS)) {
EnGb* enGb = va_arg(args, EnGb*);
enGb->textId = 0x70F8;
Message_ContinueTextbox(gPlayState, enGb->textId);
@@ -1421,6 +1464,30 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
*should |= RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_OFF;
break;
}
case VB_OKARINA_TAG_COMPLETE: {
if (gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL) {
auto dungeon =
OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL);
if (dungeon->IsVanilla()) {
EnOkarinaTag* enOkarinaTag = va_arg(args, EnOkarinaTag*);
if (enOkarinaTag->switchFlag >= 0 && Flags_GetSwitch(gPlayState, enOkarinaTag->switchFlag)) {
Flags_UnsetSwitch(gPlayState, enOkarinaTag->switchFlag);
*should = false;
}
}
}
break;
}
case VB_OKARINA_TAG_COMPLETED: {
if (gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL) {
auto dungeon =
OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL);
if (dungeon->IsVanilla()) {
*should = false;
}
}
break;
}
case VB_GRANNY_SAY_INSUFFICIENT_RUPEES: {
if (EnDs_RandoCanGetGrannyItem()) {
*should = gSaveContext.rupees <
@@ -1537,7 +1604,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
break;
}
case VB_GERUDO_GUARD_SET_ACTION_AFTER_TALK:
if (gPlayState->msgCtx.choiceIndex == 0) {
if (gPlayState->msgCtx.choiceIndex == 0 && gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS) {
EnGe2* enGe2 = va_arg(args, EnGe2*);
EnGe2_SetupCapturePlayer(enGe2, gPlayState);
*should = false;
@@ -1806,6 +1873,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
case VB_GIVE_ITEM_WATER_MEDALLION:
case VB_GIVE_ITEM_SPIRIT_MEDALLION:
case VB_GIVE_ITEM_SHADOW_MEDALLION:
case VB_CHEST_USE_ICE_EFFECT:
*should = false;
break;
case VB_GIVE_ITEM_SKULL_TOKEN:
@@ -2207,6 +2275,15 @@ void RandomizerOnActorInitHandler(void* actorRef) {
return;
}
// Turn MQ switch into toggle
if (actor->id == ACTOR_OBJ_SWITCH && gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL && (actor->params & 7) == 3) {
auto dungeon =
OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(SCENE_BOTTOM_OF_THE_WELL);
if (dungeon->IsMQ()) {
actor->params |= 0x10;
}
}
// In ER, once Link has spawned we know the scene has loaded, so we can sanitize the last known entrance type
if (actor->id == ACTOR_PLAYER && RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) {
Grotto_SanitizeEntranceType();
+2 -2
View File
@@ -52,7 +52,7 @@ void Item::ApplyEffect() const {
if (!logic->CalculatingAvailableChecks) {
logic->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), true);
}
logic->SetInLogic(logicVal, true);
logic->Set(logicVal, true);
}
void Item::UndoEffect() const {
@@ -61,7 +61,7 @@ void Item::UndoEffect() const {
if (!logic->CalculatingAvailableChecks) {
logic->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), false);
}
logic->SetInLogic(logicVal, false);
logic->Set(logicVal, false);
}
const Text& Item::GetName() const {
+12 -12
View File
@@ -35,10 +35,10 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_DINS_FIRE] = Item(RG_DINS_FIRE, Text{ "Din's Fire", "Feu de Din", "Dins Feuerinferno" }, ITEMTYPE_ITEM, GI_DINS_FIRE, true, LOGIC_DINS_FIRE, RHT_DINS_FIRE, ITEM_DINS_FIRE, OBJECT_GI_GODDESS, GID_DINS_FIRE, 0xAD, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_FARORES_WIND] = Item(RG_FARORES_WIND, Text{ "Farore's Wind", "Vent de Farore", "Farores Donnersturm" }, ITEMTYPE_ITEM, GI_FARORES_WIND, true, LOGIC_FARORES_WIND, RHT_FARORES_WIND, ITEM_FARORES_WIND, OBJECT_GI_GODDESS, GID_FARORES_WIND, 0xAE, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_NAYRUS_LOVE] = Item(RG_NAYRUS_LOVE, Text{ "Nayru's Love", "Amour de Nayru", "Nayrus Umarmung" }, ITEMTYPE_ITEM, GI_NAYRUS_LOVE, true, LOGIC_NAYRUS_LOVE, RHT_NAYRUS_LOVE, ITEM_NAYRUS_LOVE, OBJECT_GI_GODDESS, GID_NAYRUS_LOVE, 0xAF, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_FIRE_ARROWS] = Item(RG_FIRE_ARROWS, Text{ "Fire Arrow", "Flèche de Feu", "Feuer-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_FIRE, true, LOGIC_FIRE_ARROWS, RHT_FIRE_ARROWS, ITEM_ARROW_FIRE, OBJECT_GI_M_ARROW, GID_ARROW_FIRE, 0x70, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ICE_ARROWS] = Item(RG_ICE_ARROWS, Text{ "Ice Arrow", "Flèche de Glace", "Eis-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_ICE, true, LOGIC_ICE_ARROWS, RHT_ICE_ARROWS, ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x71, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_LIGHT_ARROWS] = Item(RG_LIGHT_ARROWS, Text{ "Light Arrow", "Flèche de Lumière", "Licht-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_LIGHT, true, LOGIC_LIGHT_ARROWS, RHT_LIGHT_ARROWS, ITEM_ARROW_LIGHT, OBJECT_GI_M_ARROW, GID_ARROW_LIGHT, 0x72, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_GERUDO_MEMBERSHIP_CARD] = Item(RG_GERUDO_MEMBERSHIP_CARD, Text{ "Gerudo Membership Card", "Carte Gerudo", "Gerudo-Pass" }, ITEMTYPE_ITEM, GI_GERUDO_CARD, true, LOGIC_GERUDO_CARD, RHT_GERUDO_MEMBERSHIP_CARD, ITEM_GERUDO_CARD, OBJECT_GI_GERUDO, GID_GERUDO_CARD, 0x7B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_FIRE_ARROWS] = Item(RG_FIRE_ARROWS, Text{ "Fire Arrow", "Flèche de Feu", "Feuer-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_FIRE, true, LOGIC_FIRE_ARROWS, RHT_FIRE_ARROWS, ITEM_ARROW_FIRE, OBJECT_GI_M_ARROW, GID_ARROW_FIRE, 0x70, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ICE_ARROWS] = Item(RG_ICE_ARROWS, Text{ "Ice Arrow", "Flèche de Glace", "Eis-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_ICE, true, LOGIC_ICE_ARROWS, RHT_ICE_ARROWS, ITEM_ARROW_ICE, OBJECT_GI_M_ARROW, GID_ARROW_ICE, 0x71, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_LIGHT_ARROWS] = Item(RG_LIGHT_ARROWS, Text{ "Light Arrow", "Flèche de Lumière", "Licht-Pfeile" }, ITEMTYPE_ITEM, GI_ARROW_LIGHT, true, LOGIC_LIGHT_ARROWS, RHT_LIGHT_ARROWS, ITEM_ARROW_LIGHT, OBJECT_GI_M_ARROW, GID_ARROW_LIGHT, 0x72, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_GERUDO_MEMBERSHIP_CARD] = Item(RG_GERUDO_MEMBERSHIP_CARD, Text{ "Gerudo Membership Card", "Carte Gerudo", "Gerudo-Paß" }, ITEMTYPE_ITEM, GI_GERUDO_CARD, true, LOGIC_GERUDO_CARD, RHT_GERUDO_MEMBERSHIP_CARD, ITEM_GERUDO_CARD, OBJECT_GI_GERUDO, GID_GERUDO_CARD, 0x7B, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_MAGIC_BEAN] = Item(RG_MAGIC_BEAN, Text{ "Magic Bean", "Haricots Magiques", "Wundererbse" }, ITEMTYPE_ITEM, GI_BEAN, true, LOGIC_MAGIC_BEAN, RHT_MAGIC_BEAN, ITEM_BEAN, OBJECT_GI_BEAN, GID_BEAN, 0x48, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_MAGIC_BEAN_PACK] = Item(RG_MAGIC_BEAN_PACK, Text{ "Magic Bean Pack", "Paquet de Haricots Magiques", "Wundererbsen-Packung" }, ITEMTYPE_ITEM, RG_MAGIC_BEAN_PACK, true, LOGIC_MAGIC_BEAN, RHT_MAGIC_BEAN_PACK, RG_MAGIC_BEAN_PACK, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_DOUBLE_DEFENSE] = Item(RG_DOUBLE_DEFENSE, Text{ "Double Defense", "Double Défence", "Doppelte Verteidigung" }, ITEMTYPE_ITEM, RG_DOUBLE_DEFENSE, true, LOGIC_DOUBLE_DEFENSE, RHT_DOUBLE_DEFENSE, RG_DOUBLE_DEFENSE, OBJECT_GI_HEARTS, GID_HEART_CONTAINER, 0xE9, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
@@ -48,10 +48,10 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_ZELDAS_LETTER] = Item(RG_ZELDAS_LETTER, Text{ "Zelda's Letter", "Lettre de Zelda", "Zeldas Brief" }, ITEMTYPE_ITEM, GI_LETTER_ZELDA, true, LOGIC_ZELDAS_LETTER, RHT_ZELDAS_LETTER, ITEM_LETTER_ZELDA, OBJECT_GI_LETTER, GID_LETTER_ZELDA, 0x69, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_POCKET_EGG] = Item(RG_POCKET_EGG, Text{ "Pocket Egg", "Oeuf de poche", "Ei" }, ITEMTYPE_ITEM, GI_POCKET_EGG, true, LOGIC_POCKET_EGG, RHT_POCKET_EGG, ITEM_POCKET_EGG, OBJECT_GI_EGG, GID_EGG, 0x01, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_COJIRO] = Item(RG_COJIRO, Text{ "Cojiro", "P'tit Poulet", "Henni" }, ITEMTYPE_ITEM, GI_COJIRO, true, LOGIC_COJIRO, RHT_COJIRO, ITEM_COJIRO, OBJECT_GI_NIWATORI, GID_COJIRO, 0x02, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ODD_MUSHROOM] = Item(RG_ODD_MUSHROOM, Text{ "Odd Mushroom", "Champigon Suspect", "Schimmelpilz" }, ITEMTYPE_ITEM, GI_ODD_MUSHROOM, true, LOGIC_ODD_MUSHROOM, RHT_ODD_MUSHROOM, ITEM_ODD_MUSHROOM, OBJECT_GI_MUSHROOM, GID_ODD_MUSHROOM, 0x03, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ODD_MUSHROOM] = Item(RG_ODD_MUSHROOM, Text{ "Odd Mushroom", "Champignon Suspect", "Schimmelpilz" }, ITEMTYPE_ITEM, GI_ODD_MUSHROOM, true, LOGIC_ODD_MUSHROOM, RHT_ODD_MUSHROOM, ITEM_ODD_MUSHROOM, OBJECT_GI_MUSHROOM, GID_ODD_MUSHROOM, 0x03, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ODD_POTION] = Item(RG_ODD_POTION, Text{ "Odd Potion", "Mixture Suspecte", "Modertrank" }, ITEMTYPE_ITEM, GI_ODD_POTION, true, LOGIC_ODD_POULTICE, RHT_ODD_POTION, ITEM_ODD_POTION, OBJECT_GI_POWDER, GID_ODD_POTION, 0x04, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_POACHERS_SAW] = Item(RG_POACHERS_SAW, Text{ "Poacher's Saw", "Scie du Chasseur", "Säge" }, ITEMTYPE_ITEM, GI_SAW, true, LOGIC_POACHERS_SAW, RHT_POACHERS_SAW, ITEM_SAW, OBJECT_GI_SAW, GID_SAW, 0x05, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "zerbr. Goronen-Schwert" }, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, LOGIC_BROKEN_SWORD, RHT_BROKEN_SWORD, ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_BROKEN_SWORD] = Item(RG_BROKEN_SWORD, Text{ "Broken Goron's Sword", "Épée Brisée de Goron", "Zerbr. Goronen-Schwert" }, ITEMTYPE_ITEM, GI_SWORD_BROKEN, true, LOGIC_BROKEN_SWORD, RHT_BROKEN_SWORD, ITEM_SWORD_BROKEN, OBJECT_GI_BROKENSWORD, GID_SWORD_BROKEN, 0x08, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_PRESCRIPTION] = Item(RG_PRESCRIPTION, Text{ "Prescription", "Ordonnance", "Rezept" }, ITEMTYPE_ITEM, GI_PRESCRIPTION, true, LOGIC_PRESCRIPTION, RHT_PRESCRIPTION, ITEM_PRESCRIPTION, OBJECT_GI_PRESCRIPTION, GID_PRESCRIPTION, 0x09, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_EYEBALL_FROG] = Item(RG_EYEBALL_FROG, Text{ "Eyeball Frog", "Crapaud-qui-louche", "Glotzfrosch" }, ITEMTYPE_ITEM, GI_FROG, true, LOGIC_EYEBALL_FROG, RHT_EYEBALL_FROG, ITEM_FROG, OBJECT_GI_FROG, GID_FROG, 0x0D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_EYEDROPS] = Item(RG_EYEDROPS, Text{ "World's Finest Eyedrops", "Super Gouttes", "Augentropfen" }, ITEMTYPE_ITEM, GI_EYEDROPS, true, LOGIC_EYEDROPS, RHT_EYEDROPS, ITEM_EYEDROPS, OBJECT_GI_EYE_LOTION, GID_EYEDROPS, 0x0E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
@@ -64,7 +64,7 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_PROGRESSIVE_BOMB_BAG] = Item(RG_PROGRESSIVE_BOMB_BAG, Text{ "Progressive Bomb Bag", "Sac de Bombes (prog.)", "Bombentasche (prog.)" }, ITEMTYPE_ITEM, 0x82, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_PROGRESSIVE_BOMB_BAG, ITEM_CATEGORY_MAJOR, true);
itemTable[RG_PROGRESSIVE_BOW] = Item(RG_PROGRESSIVE_BOW, Text{ "Progressive Bow", "Arc (prog.)", "Bogen (prog.)" }, ITEMTYPE_ITEM, 0x83, true, LOGIC_PROGRESSIVE_BOW, RHT_PROGRESSIVE_BOW, ITEM_CATEGORY_MAJOR, true);
itemTable[RG_PROGRESSIVE_SLINGSHOT] = Item(RG_PROGRESSIVE_SLINGSHOT, Text{ "Progressive Slingshot", "Lance-Pierre (prog.)", "Schleuder (prog.)" }, ITEMTYPE_ITEM, 0x84, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_PROGRESSIVE_SLINGSHOT, ITEM_CATEGORY_MAJOR, true);
itemTable[RG_PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Geldbörse (prog.)" }, ITEMTYPE_ITEM, 0x85, true, LOGIC_PROGRESSIVE_WALLET, RHT_PROGRESSIVE_WALLET, ITEM_CATEGORY_MAJOR, true);
itemTable[RG_PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Börse (prog.)" }, ITEMTYPE_ITEM, 0x85, true, LOGIC_PROGRESSIVE_WALLET, RHT_PROGRESSIVE_WALLET, ITEM_CATEGORY_MAJOR, true);
itemTable[RG_PROGRESSIVE_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{ "Progressive Scale", "Écaille (prog.)", "Zora-Schuppe (prog.)" }, ITEMTYPE_ITEM, 0x86, true, LOGIC_PROGRESSIVE_SCALE, RHT_PROGRESSIVE_SCALE, ITEM_CATEGORY_MAJOR, true);
itemTable[RG_PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{ "Progressive Nut Capacity", "Capacité de Noix (prog.)", "Nuß-Kapazität (prog.)" }, ITEMTYPE_ITEM, 0x87, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_PROGRESSIVE_NUT_UPGRADE, ITEM_CATEGORY_MAJOR, true);
itemTable[RG_PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{ "Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Stab-Kapazität (prog.)" }, ITEMTYPE_ITEM, 0x88, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_PROGRESSIVE_STICK_UPGRADE, ITEM_CATEGORY_MAJOR, true);
@@ -363,7 +363,7 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_MAGIC_INF] = Item(RG_MAGIC_INF, Text{ "Infinite Magic Meter", "Magie Infinie", "Unendliche Magische Kraft" }, ITEMTYPE_ITEM, RG_MAGIC_INF, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_INF, RG_MAGIC_INF, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_BOMBCHU_INF] = Item(RG_BOMBCHU_INF, Text{ "Infinite Bombchus", "Missiles Teigneux Infinis", "Unendliche Krabbelminentasche" }, ITEMTYPE_ITEM, RG_BOMBCHU_INF, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_INF, RG_BOMBCHU_INF, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_BOMBCHU_INF].SetCustomDrawFunc(Randomizer_DrawBombchuBag);
itemTable[RG_WALLET_INF] = Item(RG_WALLET_INF, Text{ "Infinite Wallet", "Bourse Infinie", "Unendliche Geldbörse" }, ITEMTYPE_ITEM, RG_WALLET_INF, true, LOGIC_PROGRESSIVE_WALLET, RHT_WALLET_INF, RG_WALLET_INF, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_WALLET_INF] = Item(RG_WALLET_INF, Text{ "Infinite Wallet", "Bourse Infinie", "Unendliche Börse" }, ITEMTYPE_ITEM, RG_WALLET_INF, true, LOGIC_PROGRESSIVE_WALLET, RHT_WALLET_INF, RG_WALLET_INF, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_SKELETON_KEY] = Item(RG_SKELETON_KEY, Text{ "Skeleton Key", "Clé Squelette", "Skelettschlüssel" }, ITEMTYPE_ITEM, GI_STONE_OF_AGONY, true, LOGIC_SKELETON_KEY, RHT_SKELETON_KEY, RG_SKELETON_KEY, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_SKELETON_KEY].SetCustomDrawFunc(Randomizer_DrawSkeletonKey);
@@ -393,10 +393,10 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_GOLDEN_GAUNTLETS] = Item(RG_GOLDEN_GAUNTLETS, Text{ "Golden Gauntlets", "Gantelets d'or", "Titanhandschuhe" }, ITEMTYPE_ITEM, GI_GAUNTLETS_GOLD, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_GOLDEN_GAUNTLETS, ITEM_GAUNTLETS_GOLD, OBJECT_GI_GLOVES, GID_GAUNTLETS_GOLD, 0x5C, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_SILVER_SCALE] = Item(RG_SILVER_SCALE, Text{ "Silver Scale", "Écaille d'argent", "Silberne Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_SCALE, RHT_SILVER_SCALE, ITEM_SCALE_SILVER, OBJECT_GI_SCALE, GID_SCALE_SILVER, 0xCD, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_GOLDEN_SCALE] = Item(RG_GOLDEN_SCALE, Text{ "Golden Scale", "Écaille d'or", "Goldene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_GOLDEN, true, LOGIC_PROGRESSIVE_SCALE, RHT_GOLDEN_SCALE, ITEM_SCALE_GOLDEN, OBJECT_GI_SCALE, GID_SCALE_GOLDEN, 0xCE, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_ADULT_WALLET] = Item(RG_ADULT_WALLET, Text{ "Adult Wallet", "Grande Bourse", "Große Geldbörse" }, ITEMTYPE_ITEM, GI_WALLET_ADULT, true, LOGIC_PROGRESSIVE_WALLET, RHT_ADULT_WALLET, ITEM_WALLET_ADULT, OBJECT_GI_PURSE, GID_WALLET_ADULT, 0x5E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_GIANT_WALLET] = Item(RG_GIANT_WALLET, Text{ "Giant Wallet", "Bourse de Géant", "Riesengeldbörse" }, ITEMTYPE_ITEM, GI_WALLET_GIANT, true, LOGIC_PROGRESSIVE_WALLET, RHT_GIANT_WALLET, ITEM_WALLET_GIANT, OBJECT_GI_PURSE, GID_WALLET_GIANT, 0x5F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_TYCOON_WALLET] = Item(RG_TYCOON_WALLET, Text{ "Tycoon Wallet", "Bourse de Magnat", "Goldene Geldbörse" }, ITEMTYPE_ITEM, RG_TYCOON_WALLET, true, LOGIC_PROGRESSIVE_WALLET, RHT_TYCOON_WALLET, RG_TYCOON_WALLET, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_CHILD_WALLET] = Item(RG_CHILD_WALLET, Text{ "Child Wallet", "Petite Bourse", "Kindergeldbörse" }, ITEMTYPE_ITEM, RG_CHILD_WALLET, true, LOGIC_PROGRESSIVE_WALLET, RHT_CHILD_WALLET, RG_CHILD_WALLET, OBJECT_GI_PURSE, GID_WALLET_ADULT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_ADULT_WALLET] = Item(RG_ADULT_WALLET, Text{ "Adult Wallet", "Grande Bourse", "Große Börse" }, ITEMTYPE_ITEM, GI_WALLET_ADULT, true, LOGIC_PROGRESSIVE_WALLET, RHT_ADULT_WALLET, ITEM_WALLET_ADULT, OBJECT_GI_PURSE, GID_WALLET_ADULT, 0x5E, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_GIANT_WALLET] = Item(RG_GIANT_WALLET, Text{ "Giant Wallet", "Bourse de Géant", "Riesenbörse" }, ITEMTYPE_ITEM, GI_WALLET_GIANT, true, LOGIC_PROGRESSIVE_WALLET, RHT_GIANT_WALLET, ITEM_WALLET_GIANT, OBJECT_GI_PURSE, GID_WALLET_GIANT, 0x5F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
itemTable[RG_TYCOON_WALLET] = Item(RG_TYCOON_WALLET, Text{ "Tycoon Wallet", "Bourse de Magnat", "Goldene Börse" }, ITEMTYPE_ITEM, RG_TYCOON_WALLET, true, LOGIC_PROGRESSIVE_WALLET, RHT_TYCOON_WALLET, RG_TYCOON_WALLET, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_CHILD_WALLET] = Item(RG_CHILD_WALLET, Text{ "Child Wallet", "Petite Bourse", "Kinderbörse" }, ITEMTYPE_ITEM, RG_CHILD_WALLET, true, LOGIC_PROGRESSIVE_WALLET, RHT_CHILD_WALLET, RG_CHILD_WALLET, OBJECT_GI_PURSE, GID_WALLET_ADULT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_DEKU_NUT_CAPACITY_30] = Item(RG_DEKU_NUT_CAPACITY_30, Text{ "Deku Nut Capacity (30)", "Capacité de noix Mojo (30)", "Deku-Nuß-Kapazität (30)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_DEKU_NUT_CAPACITY_30, ITEM_NUT_UPGRADE_30, OBJECT_GI_NUTS, GID_NUTS, 0xA7, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_DEKU_NUT_CAPACITY_40] = Item(RG_DEKU_NUT_CAPACITY_40, Text{ "Deku Nut Capacity (40)", "Capacité de noix Mojo (40)", "Deku-Nuß-Kapazität (40)" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_40, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_DEKU_NUT_CAPACITY_40, ITEM_NUT_UPGRADE_40, OBJECT_GI_NUTS, GID_NUTS, 0xA8, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
itemTable[RG_DEKU_STICK_CAPACITY_20] = Item(RG_DEKU_STICK_CAPACITY_20, Text{ "Deku Stick Capacity (20)", "Capacité de Bâtons Mojo (20)", "Deku-Stab-Kapazität (20)" }, ITEMTYPE_ITEM, GI_STICK_UPGRADE_20, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_DEKU_STICK_CAPACITY_20, ITEM_STICK_UPGRADE_20, OBJECT_GI_STICK, GID_STICK, 0x90, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_LESSER, MOD_NONE);
+49 -5
View File
@@ -567,6 +567,24 @@ Rando::Location Rando::Location::SmallCrate(RandomizerCheck rc, RandomizerCheckQ
false, collectionCheck };
}
Rando::Location Rando::Location::Tree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck) {
return { rc, quest_, RCTYPE_TREE, area_, ACTOR_EN_WOOD02,
scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem,
false, collectionCheck };
}
Rando::Location Rando::Location::NLTree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck) {
return { rc, quest_, RCTYPE_NLTREE, area_, ACTOR_EN_WOOD02,
scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem,
false, collectionCheck };
}
Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_) {
return { rc, quest_, RCTYPE_GOSSIP_STONE, area_, ACTOR_EN_GS,
@@ -574,11 +592,37 @@ Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQu
false };
}
Rando::Location Rando::Location::Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) {
return { rc, quest_, RCTYPE_FAIRY, area_, ACTOR_EN_ELF, scene_, actorParams_, std::move(shortName_),
hintKey, RG_NONE, false, collectionCheck };
Rando::Location Rando::Location::FountainFairy(RandomizerCheck rc, RandomizerCheckQuest quest_,
RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_,
std::string&& shortName_, RandomizerHintTextKey hintKey,
SpoilerCollectionCheck collectionCheck) {
return { rc, quest_, RCTYPE_FOUNTAIN_FAIRY, area_, ACTOR_EN_ELF,
scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE,
false, collectionCheck };
}
Rando::Location Rando::Location::StoneFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) {
return { rc, quest_, RCTYPE_STONE_FAIRY, area_, ACTOR_EN_ELF,
scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE,
false, collectionCheck };
}
Rando::Location Rando::Location::BeanFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) {
return { rc, quest_, RCTYPE_BEAN_FAIRY, area_, ACTOR_EN_ELF,
scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE,
false, collectionCheck };
}
Rando::Location Rando::Location::SongFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) {
return { rc, quest_, RCTYPE_SONG_FAIRY, area_, ACTOR_EN_ELF,
scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE,
false, collectionCheck };
}
Rando::Location Rando::Location::Grass(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
+23 -3
View File
@@ -246,6 +246,14 @@ class Location {
RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck);
static Location Tree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_,
int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey,
RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck);
static Location NLTree(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_,
int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey,
RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck);
static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_);
@@ -255,9 +263,21 @@ class Location {
static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
ActorID actorId_, SceneID scene_, std::string&& shortName_);
static Location Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_,
int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey,
SpoilerCollectionCheck collectionCheck);
static Location FountainFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck);
static Location StoneFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck);
static Location BeanFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck);
static Location SongFairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck);
static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_,
std::string&& shortName_);
@@ -106,7 +106,8 @@ bool LocationAccess::CanBuy(bool calculatingAvailableChecks) const {
const auto& loc = Rando::StaticData::GetLocation(location);
const auto& itemLoc = OTRGlobals::Instance->gRandoContext->GetItemLocation(location);
if (loc->GetRCType() == RCTYPE_SHOP || loc->GetRCType() == RCTYPE_SCRUB || loc->GetRCType() == RCTYPE_MERCHANT) {
if (loc->GetRCType() == RCTYPE_SHOP || loc->GetRCType() == RCTYPE_SCRUB || loc->GetRCType() == RCTYPE_MERCHANT ||
location == RC_ZR_MAGIC_BEAN_SALESMAN) {
// Checks should only be identified while playing
if (calculatingAvailableChecks && itemLoc->GetCheckStatus() != RCSHOW_IDENTIFIED) {
return CanBuyAnother(GetMinimumPrice(loc));
@@ -617,7 +618,7 @@ void Region::ResetVariables() {
bool Region::MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge) {
// if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if
// adult is here it's also Certain Access
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) {
if (logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 7)) {
if (anyAge) {
return Here(condition);
}
@@ -627,10 +628,9 @@ bool Region::MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAg
} else if (Adult() && logic->IsAdult) {
return condition();
// if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and
// meet the adult universe's access condition We only need to do it as child, as only child access matters
// meet the adult universe's access condition. We only need to do it as child, as only child access matters
// for this check, as adult access is assumed based on keys
} else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) {
bool result = false;
} else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(SCENE_SPIRIT_TEMPLE, 6))) {
// store current age variables
bool pastAdult = logic->IsAdult;
bool pastChild = logic->IsChild;
@@ -638,7 +638,7 @@ bool Region::MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAg
// First check if the check is possible as child
logic->IsChild = true;
logic->IsAdult = false;
result = condition();
bool result = condition();
// If so, check again as adult. both have to be true for result to be true
if (result) {
logic->IsChild = false;
@@ -763,10 +763,6 @@ bool AdultCanAccess(const RandomizerRegion region) {
return areaTable[region].Adult();
}
bool HasAccessTo(const RandomizerRegion region) {
return areaTable[region].HasAccess();
}
Rando::Context* ctx;
std::shared_ptr<Rando::Logic> logic;
@@ -775,10 +771,10 @@ void RegionTable_Init() {
ctx = Context::GetInstance().get();
logic = ctx->GetLogic(); // RANDOTODO do not hardcode, instead allow accepting a Logic class somehow
grottoEvents = {
EventAccess(&logic->GossipStoneFairy, [] { return logic->CallGossipFairy(); }),
EventAccess(&logic->ButterflyFairy, [] { return logic->CanUse(RG_STICKS); }),
EventAccess(&logic->BugShrub, [] { return logic->CanCutShrubs(); }),
EventAccess(&logic->LoneFish, [] { return true; }),
EventAccess(LOGIC_GOSSIP_STONE_FAIRY, [] { return logic->CallGossipFairy(); }),
EventAccess(LOGIC_BUTTERFLY_FAIRY, [] { return logic->CanUse(RG_STICKS); }),
EventAccess(LOGIC_BUG_SHRUB, [] { return logic->CanCutShrubs(); }),
EventAccess(LOGIC_LONE_FISH, [] { return true; }),
};
// Clear the array from any previous playthrough attempts. This is important so that
// locations which appear in both MQ and Vanilla dungeons don't get set in both areas.
@@ -787,12 +783,13 @@ void RegionTable_Init() {
// clang-format off
areaTable[RR_ROOT] = Region("Root", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {
//Events
EventAccess(&logic->KakarikoVillageGateOpen, []{return ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}),
EventAccess(&logic->THCouldFree1TorchCarpenter, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE);}),
EventAccess(&logic->THCouldFreeDoubleCellCarpenter, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}),
EventAccess(&logic->TH_CouldFreeDeadEndCarpenter, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}),
EventAccess(&logic->THCouldRescueSlopeCarpenter, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}),
EventAccess(&logic->THRescuedAllCarpenters, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE);}),EventAccess(&logic->FreedEpona, []{return (bool)ctx->GetOption(RSK_SKIP_EPONA_RACE);}),
EventAccess(LOGIC_KAKARIKO_GATE_OPEN, []{return ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}),
EventAccess(LOGIC_TH_COULD_FREE_1_TORCH_CARPENTER, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE);}),
EventAccess(LOGIC_TH_COULD_FREE_DOUBLE_CELL_CARPENTER, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}),
EventAccess(LOGIC_TH_COULD_FREE_DEAD_END_CARPENTER, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}),
EventAccess(LOGIC_TH_COULD_FREE_SLOPE_CARPENTER, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) || ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST);}),
EventAccess(LOGIC_TH_RESCUED_ALL_CARPENTERS, []{return ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE);}),
EventAccess(LOGIC_FREED_EPONA, []{return (bool)ctx->GetOption(RSK_SKIP_EPONA_RACE);}),
}, {
//Locations
LOCATION(RC_LINKS_POCKET, true),
@@ -897,7 +894,7 @@ void RegionTable_Init() {
RegionTable_Init_GanonsCastle();
// Set parent regions
for (uint32_t i = RR_ROOT; i <= RR_GANONS_CASTLE; i++) {
for (uint32_t i = RR_ROOT; i < RR_MAX; i++) {
for (LocationAccess& locPair : areaTable[i].locations) {
RandomizerCheck location = locPair.GetLocation();
Rando::Context::GetInstance()->GetItemLocation(location)->SetParentRegion((RandomizerRegion)i);
@@ -22,7 +22,7 @@ class Region;
class EventAccess {
public:
explicit EventAccess(bool* event_, ConditionFn condition_function_)
explicit EventAccess(LogicVal event_, ConditionFn condition_function_)
: event(event_), condition_function(condition_function_) {
}
@@ -37,15 +37,15 @@ class EventAccess {
bool CheckConditionAtAgeTime(bool& age, bool& time);
void EventOccurred() {
*event = true;
logic->Set(event, true);
}
bool GetEvent() const {
return *event;
return logic->Get(event);
}
private:
bool* event;
LogicVal event;
ConditionFn condition_function;
};
@@ -231,7 +231,6 @@ bool CanPlantBean(const RandomizerRegion region);
bool BothAges(const RandomizerRegion region);
bool ChildCanAccess(const RandomizerRegion region);
bool AdultCanAccess(const RandomizerRegion region);
bool HasAccessTo(const RandomizerRegion region);
namespace Regions {
extern void AccessReset();
@@ -19,25 +19,25 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTTOM_OF_THE_WELL_PERIMETER] = Region("Bottom of the Well Perimeter", SCENE_BOTTOM_OF_THE_WELL, {
//Events
EventAccess(&logic->StickPot, []{return true;}),
EventAccess(&logic->NutPot, []{return true;}),
EventAccess(&logic->LoweredWaterInsideBotw, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
EventAccess(LOGIC_STICK_POT, []{return true;}),
EventAccess(LOGIC_NUT_POT, []{return true;}),
EventAccess(LOGIC_BOTW_LOWERED_WATER, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
}, {
//Locations
LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives()),
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->LoweredWaterInsideBotw || logic->CanOpenUnderwaterChest()),
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->LoweredWaterInsideBotw || logic->CanOpenUnderwaterChest()),
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()),
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->CanOpenUnderwaterChest()),
LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, (logic->CanBreakPots() && logic->LoweredWaterInsideBotw) || logic->CanUse(RG_BOOMERANG)),
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, (logic->CanBreakPots() && logic->Get(LOGIC_BOTW_LOWERED_WATER)) || logic->CanUse(RG_BOOMERANG)),
}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild && logic->CanPassEnemy(RE_BIG_SKULLTULA);}),
Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}),
Entrance(RR_BOTTOM_OF_THE_WELL_SOUTHWEST_ROOM, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}),
Entrance(RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}),
Entrance(RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM, []{return logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE);}),
Entrance(RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM, []{return logic->LoweredWaterInsideBotw && logic->IsChild;}),
Entrance(RR_BOTTOM_OF_THE_WELL_KEESE_BEAMOS_ROOM, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 3);}),
Entrance(RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM, []{return logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE);}),
Entrance(RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM, []{return logic->Get(LOGIC_BOTW_LOWERED_WATER) && logic->IsChild;}),
//Falling down into basement requires nothing, but falling down somewhere specific requires lens or lens trick
//kinda questionable given several drops are blocked by rocks, but that's how it was handled before and on N64
Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, []{return true;}),
@@ -56,7 +56,7 @@ void RegionTable_Init_BottomOfTheWell() {
}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}),
Entrance(RR_BOTTOM_OF_THE_WELL_INNER_ROOMS, []{return logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}),
Entrance(RR_BOTTOM_OF_THE_WELL_INNER_ROOMS, []{return logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 3);}),
Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT, []{return true;}),
Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT_PLATFORM, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}),
});
@@ -79,7 +79,7 @@ void RegionTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, logic->CanBreakPots() && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH))),
}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH));}),
Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 3) && (ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH));}),
Entrance(RR_BOTTOM_OF_THE_WELL_LIKE_LIKE_CAGE, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}),
//not sure if this lens check is needed, these holes are a bit too easy to find, but it matches existing logic
Entrance(RR_BOTTOM_OF_THE_WELL_BASEMENT_USEFUL_BOMB_FLOWERS, []{return ctx->GetTrickOption(RT_LENS_BOTW) || logic->CanUse(RG_LENS_OF_TRUTH);}),
@@ -97,15 +97,15 @@ void RegionTable_Init_BottomOfTheWell() {
//If the player can voidwarp into one of these rooms they will need splitting up, and Fake walls will need specifying into middle and the rest moved to perimeter
areaTable[RR_BOTTOM_OF_THE_WELL_INNER_ROOMS] = Region("Bottom of the Well Inner Rooms", SCENE_BOTTOM_OF_THE_WELL, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}),
}, {
//Locations
LOCATION(RC_BOTTOM_OF_THE_WELL_GS_WEST_INNER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
LOCATION(RC_BOTTOM_OF_THE_WELL_GS_EAST_INNER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, []{return logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 3);}),
Entrance(RR_BOTTOM_OF_THE_WELL_BEHIND_FAKE_WALLS, []{return logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 3);}),
});
areaTable[RR_BOTTOM_OF_THE_WELL_COFFIN_ROOM] = Region("Bottom of the Well Coffin Room", SCENE_BOTTOM_OF_THE_WELL, {}, {
@@ -115,7 +115,7 @@ void RegionTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)),
}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE);}),
Entrance(RR_BOTTOM_OF_THE_WELL_PERIMETER, []{return logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE);}),
});
areaTable[RR_BOTTOM_OF_THE_WELL_DEAD_HAND_ROOM] = Region("Bottom of the Well Dead Hand Room", SCENE_BOTTOM_OF_THE_WELL, {}, {
@@ -192,11 +192,11 @@ void RegionTable_Init_BottomOfTheWell() {
areaTable[RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER] = Region("Bottom of the Well MQ Perimeter", SCENE_BOTTOM_OF_THE_WELL, {
//Events
//technically obsolete due to a wonder item fairy which only needs a projectile, but we don't have an event var for it yet
EventAccess(&logic->FairyPot, []{return Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets();}),
EventAccess(LOGIC_FAIRY_POT, []{return Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets();}),
//It is possible to hit the water switch with a pot from RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE, however the hitbox for making it activate is very unintuitive
//You have to throw the pot from further back to hit the switch from the front instead of the top, trying to hit the "fingers" directly
//This unintuitiveness means it should be a trick. ZL is needed to get a clear path to carry the pot
EventAccess(&logic->LoweredWaterInsideBotw, []{return logic->CanJumpslash() || logic->CanUseProjectile();}),
EventAccess(LOGIC_BOTW_LOWERED_WATER, []{return logic->CanJumpslash() || logic->CanUseProjectile();}),
}, {
//Locations
//Implies CanBreakPots()
@@ -207,16 +207,16 @@ void RegionTable_Init_BottomOfTheWell() {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild;}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_WEST_ROOM_SWITCH, []{return Here(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash();}) && logic->CanPassEnemy(RE_BIG_SKULLTULA);}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2) && logic->CanUseProjectile();}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_ROOM, []{return logic->IsChild && logic->LoweredWaterInsideBotw;}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2) && logic->CanUseProjectile();}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_ROOM, []{return logic->IsChild && logic->Get(LOGIC_BOTW_LOWERED_WATER);}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_MIDDLE, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT, []{return true;}),
});
areaTable[RR_BOTTOM_OF_THE_WELL_MQ_WEST_ROOM_SWITCH] = Region("Bottom of the Well MQ West Room Switch", SCENE_BOTTOM_OF_THE_WELL, {
//Events
EventAccess(&logic->OpenedWestRoomMQBotw, []{return true;}),
EventAccess(LOGIC_BOTW_MQ_OPENED_WEST_ROOM, []{return true;}),
}, {}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->BlastOrSmash() && (logic->CanPassEnemy(RE_BIG_SKULLTULA) || ctx->GetTrickOption(RT_BOTW_MQ_PITS));}),
@@ -231,15 +231,15 @@ void RegionTable_Init_BottomOfTheWell() {
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)),
}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return (logic->LoweredWaterInsideBotw || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return (logic->Get(LOGIC_BOTW_LOWERED_WATER) || logic->HasItem(RG_BRONZE_SCALE)) && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}),
});
areaTable[RR_BOTTOM_OF_THE_WELL_MQ_LOCKED_CAGE] = Region("Bottom of the Well MQ Locked Cage", SCENE_BOTTOM_OF_THE_WELL, {
//Events
EventAccess(&logic->OpenedMiddleHoleMQBotw, []{return logic->HasExplosives();}),
EventAccess(LOGIC_BOTW_MQ_OPENED_MIDDLE_HOLE, []{return logic->HasExplosives();}),
}, {}, {
//Exits
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->IsChild && logic->SmallKeys(RR_BOTTOM_OF_THE_WELL, 2);}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_PERIMETER, []{return logic->IsChild && logic->SmallKeys(SCENE_BOTTOM_OF_THE_WELL, 2);}),
});
areaTable[RR_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_ROOM] = Region("Bottom of the Well MQ Dead Hand Room", SCENE_BOTTOM_OF_THE_WELL, {}, {
@@ -268,7 +268,7 @@ void RegionTable_Init_BottomOfTheWell() {
//Also you get cheap shotted on entry sometimes.
//An MQ lens trick is recommended here, and a review of this room for OHKO logic what that is added is advised.
//In the meantime I assume damage taken or the easy answer (nuts)
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->OpenedWestRoomMQBotw && (logic->TakeDamage() || logic->CanUse(RG_NUTS)) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_GS_WEST_INNER_ROOM, logic->Get(LOGIC_BOTW_MQ_OPENED_WEST_ROOM) && (logic->TakeDamage() || logic->CanUse(RG_NUTS)) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, logic->CanBreakPots()),
LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, logic->CanBreakPots()),
@@ -279,7 +279,7 @@ void RegionTable_Init_BottomOfTheWell() {
}, {
//Exits
//If a relevant trick causes you to be able to warp into here without going through PERIMETER, a new eventAccess will be needed for lowering the gates with ZL
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SWITCH_PLATFORM, []{return logic->OpenedMiddleHoleMQBotw;}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SWITCH_PLATFORM, []{return logic->Get(LOGIC_BOTW_MQ_OPENED_MIDDLE_HOLE);}),
Entrance(RR_BOTTOM_OF_THE_WELL_MQ_BASEMENT, []{return true;}),
});
@@ -18,8 +18,8 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_LOBBY] = Region("Deku Tree Lobby", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_MAP_CHEST, true),
@@ -61,8 +61,8 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_COMPASS_ROOM] = Region("Deku Tree Compass Room", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_COMPASS_CHEST, true),
@@ -78,8 +78,8 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_BASEMENT_LOWER] = Region("Deku Tree Basement Lower", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_BASEMENT_CHEST, true),
@@ -91,7 +91,7 @@ void RegionTable_Init_DekuTree() {
//Exits
Entrance(RR_DEKU_TREE_LOBBY, []{return true;}),
Entrance(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return Here(RR_DEKU_TREE_BASEMENT_LOWER, []{return logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW);});}),
Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || HasAccessTo(RR_DEKU_TREE_BASEMENT_UPPER);}),
Entrance(RR_DEKU_TREE_BASEMENT_UPPER, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->CanGroundJump() || logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK);}),
Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return false;}),
});
@@ -125,8 +125,8 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_BASEMENT_TORCH_ROOM] = Region("Deku Tree Basement Torch Room", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_1, logic->CanCutShrubs()),
@@ -139,8 +139,8 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_BASEMENT_BACK_LOBBY] = Region("Deku Tree Basement Back Lobby", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}),
}, {
//Location
LOCATION(RC_DEKU_TREE_BASEMENT_LARVAE_GRASS_1, logic->CanCutShrubs()),
@@ -162,8 +162,9 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_BASEMENT_UPPER] = Region("Deku Tree Basement Upper", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK, []{return true;}),
}, {}, {
//Exits
Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return true;}),
@@ -191,8 +192,8 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_MQ_1F] = Region("Deku Tree MQ 1F", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanKillEnemy(RE_WITHERED_DEKU_BABA);}),
EventAccess(&logic->BrokeDeku1FWeb, []{return logic->HasFireSource();}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanKillEnemy(RE_WITHERED_DEKU_BABA);}),
EventAccess(LOGIC_DEKU_TREE_1F_BROKE_WEB, []{return logic->HasFireSource();}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_MQ_LOBBY_GRASS_1, logic->CanCutShrubs()),
@@ -208,7 +209,7 @@ void RegionTable_Init_DekuTree() {
//Swim is not required because you can jump with enough momentum to hit land.
//You even avoid fall damage if you hit the shallow water, though it's obscure knowledge so may be a trick
//if it is, then we need a landing room with (IsAdult || HasItem(RG_BRONZE_SCALE) || TakeDamage() || that trick) to reach basement
Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->BrokeDeku1FWeb;}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->Get(LOGIC_DEKU_TREE_1F_BROKE_WEB);}),
//is it possible to recoil from here to the ledge with a trick?
});
@@ -230,9 +231,9 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_MQ_3F] = Region("Deku Tree MQ 3F", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(&logic->BrokeDeku1FWeb, []{return true;}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_TREE_1F_BROKE_WEB, []{return true;}),
}, {
//Locations
//Implies CanKillEnemy(RE_GOHMA_LARVA)
@@ -293,8 +294,8 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_MQ_BASEMENT] = Region("Deku Tree MQ Basement", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_MQ_BASEMENT_CHEST, logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW)),
@@ -307,14 +308,14 @@ void RegionTable_Init_DekuTree() {
Entrance(RR_DEKU_TREE_MQ_1F, []{return true;}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM, []{return Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanHitEyeTargets();});}),
//includes RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM Access, other fire sources clear directly from there
Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanHitEyeTargets();}) && logic->ClearedMQDekuSERoom && Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanUse(RG_STICKS);});}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->PushedDekuBasementBlock || logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanHitEyeTargets();}) && logic->Get(LOGIC_DEKU_TREE_MQ_CLEARED_SE_ROOM) && Here(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->CanUse(RG_STICKS);});}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->IsAdult || ctx->GetTrickOption(RT_DEKU_B1_SKIP) || logic->CanGroundJump() || logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK) || logic->CanUse(RG_HOVER_BOOTS);}),
});
areaTable[RR_DEKU_TREE_MQ_BASEMENT_SOUTHEAST_ROOM] = Region("Deku Tree MQ Southeast Room", SCENE_DEKU_TREE, {
//Events
//Implies CanKillEnemy(RE_GOHMA_LARVA)
EventAccess(&logic->ClearedMQDekuSERoom, []{return logic->CanKillEnemy(RE_MAD_SCRUB);}),
EventAccess(LOGIC_DEKU_TREE_MQ_CLEARED_SE_ROOM, []{return logic->CanKillEnemy(RE_MAD_SCRUB);}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_1, logic->CanCutShrubs()),
@@ -324,13 +325,13 @@ void RegionTable_Init_DekuTree() {
}, {
//Exits
Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return logic->HasFireSource();}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->ClearedMQDekuSERoom;}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return logic->Get(LOGIC_DEKU_TREE_MQ_CLEARED_SE_ROOM);}),
});
areaTable[RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT] = Region("Deku Tree MQ Basement Water Room Front", SCENE_DEKU_TREE, {
//Events
//It's possible to get this with bow if you have move while in first person and one-point skips on, noticeably harder and jankier as child, but that's a trick
EventAccess(&logic->MQDekuWaterRoomTorches, []{return logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_STICKS) && (ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield())));}),
EventAccess(LOGIC_DEKU_TREE_MQ_WATER_ROOM_TORCHES, []{return logic->CanUse(RG_FIRE_ARROWS) || (logic->CanUse(RG_STICKS) && (ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield())));}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, true),
@@ -345,8 +346,8 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_BACK] = Region("Deku Tree MQ Basement Water Room Back", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanKillEnemy(RE_WITHERED_DEKU_BABA);}),
EventAccess(&logic->MQDekuWaterRoomTorches, []{return logic->HasFireSource();}),
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanKillEnemy(RE_WITHERED_DEKU_BABA);}),
EventAccess(LOGIC_DEKU_TREE_MQ_WATER_ROOM_TORCHES, []{return logic->HasFireSource();}),
}, {
//Locations
//it blocks the chest while stunned unless you stun it from afar while it's slightly off the ground
@@ -355,7 +356,7 @@ void RegionTable_Init_DekuTree() {
LOCATION(RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2, logic->CanCutShrubs()),
}, {
//Exits
Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHWEST_ROOM, []{return logic->MQDekuWaterRoomTorches && logic->CanPassEnemy(RE_BIG_SKULLTULA, logic->CanUse(RG_SONG_OF_TIME) ? ED_CLOSE : ED_SHORT_JUMPSLASH);}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_SOUTHWEST_ROOM, []{return logic->Get(LOGIC_DEKU_TREE_MQ_WATER_ROOM_TORCHES) && logic->CanPassEnemy(RE_BIG_SKULLTULA, logic->CanUse(RG_SONG_OF_TIME) ? ED_CLOSE : ED_SHORT_JUMPSLASH);}),
Entrance(RR_DEKU_TREE_MQ_BASEMENT_WATER_ROOM_FRONT, []{return ctx->GetTrickOption(RT_DEKU_MQ_LOG) || (logic->IsChild && logic->CanShield()) || logic->CanUse(RG_LONGSHOT) || logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)));}),
});
@@ -372,8 +373,8 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_MQ_BASEMENT_GRAVE_ROOM] = Region("Deku Tree MQ Basement Grave Room", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();})
EventAccess(LOGIC_DEKU_BABA_STICKS, []{return logic->CanGetDekuBabaSticks();}),
EventAccess(LOGIC_DEKU_BABA_NUTS, []{return logic->CanGetDekuBabaNuts();})
}, {
//Locations
LOCATION(RC_DEKU_TREE_MQ_GS_BASEMENT_GRAVES_ROOM, logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_SONG_OF_TIME) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG))),
@@ -403,7 +404,7 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_MQ_BASEMENT_LEDGE] = Region("Deku Tree MQ Basement Ledge", SCENE_DEKU_TREE, {
//Events
EventAccess(&logic->PushedDekuBasementBlock, []{return true;}),
EventAccess(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK, []{return true;}),
}, {
//Locations
LOCATION(RC_DEKU_TREE_MQ_DEKU_SCRUB, logic->CanStunDeku()),
@@ -416,7 +417,7 @@ void RegionTable_Init_DekuTree() {
Entrance(RR_DEKU_TREE_MQ_BASEMENT, []{return true;}),
//If strength 0 is shuffled, add hovers or block push to the stick check
//recoiling to skip swim is possible, but would be a trick
Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->HasFireSource() || (/*logic->PushedDekuBasementBlock && */logic->CanUse(RG_STICKS));}) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}),
Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return Here(RR_DEKU_TREE_MQ_BASEMENT_LEDGE, []{return logic->HasFireSource() || (/*logic->Get(LOGIC_DEKU_TREE_PUSHED_BASEMENT_BLOCK) && */logic->CanUse(RG_STICKS));}) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}),
});
areaTable[RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM] = Region("Deku Tree MQ Outside Boss Room", SCENE_DEKU_TREE, {}, {
@@ -449,11 +450,11 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_BOSS_ROOM] = Region("Deku Tree Boss Room", SCENE_DEKU_TREE_BOSS, {
// Events
EventAccess(&logic->DekuTreeClear, []{return logic->CanKillEnemy(RE_GOHMA);}),
EventAccess(LOGIC_DEKU_TREE_CLEAR, []{return logic->CanKillEnemy(RE_GOHMA);}),
}, {
// Locations
LOCATION(RC_QUEEN_GOHMA, logic->DekuTreeClear),
LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_HEART, logic->DekuTreeClear),
LOCATION(RC_QUEEN_GOHMA, logic->Get(LOGIC_DEKU_TREE_CLEAR)),
LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_HEART, logic->Get(LOGIC_DEKU_TREE_CLEAR)),
LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_GRASS_1, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_GRASS_2, logic->CanCutShrubs()),
LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_GRASS_3, logic->CanCutShrubs()),
@@ -465,7 +466,7 @@ void RegionTable_Init_DekuTree() {
}, {
// Exits
Entrance(RR_DEKU_TREE_BOSS_EXIT, []{return true;}),
Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return logic->DekuTreeClear;}, false),
Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return logic->Get(LOGIC_DEKU_TREE_CLEAR);}, false),
});
// clang-format on

Some files were not shown because too many files have changed in this diff Show More